Merge "Add a Visual Indicator for fullscreen to freeform transitions" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
164d3ac990
@@ -16,10 +16,13 @@
|
||||
|
||||
package com.android.wm.shell.desktopmode;
|
||||
|
||||
import static com.android.wm.shell.desktopmode.EnterDesktopTaskTransitionHandler.FINAL_FREEFORM_SCALE;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.RectEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
@@ -32,12 +35,12 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.view.WindowlessWindowManager;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.android.wm.shell.R;
|
||||
import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
|
||||
import com.android.wm.shell.ShellTaskOrganizer;
|
||||
import com.android.wm.shell.common.DisplayController;
|
||||
import com.android.wm.shell.common.DisplayLayout;
|
||||
import com.android.wm.shell.common.SyncTransactionQueue;
|
||||
|
||||
/**
|
||||
@@ -56,6 +59,9 @@ public class DesktopModeVisualIndicator {
|
||||
private final SyncTransactionQueue mSyncQueue;
|
||||
private SurfaceControlViewHost mViewHost;
|
||||
|
||||
private View mView;
|
||||
private boolean mIsFullscreen;
|
||||
|
||||
public DesktopModeVisualIndicator(SyncTransactionQueue syncQueue,
|
||||
ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
|
||||
Context context, SurfaceControl taskSurface, ShellTaskOrganizer taskOrganizer,
|
||||
@@ -67,21 +73,19 @@ public class DesktopModeVisualIndicator {
|
||||
mTaskSurface = taskSurface;
|
||||
mTaskOrganizer = taskOrganizer;
|
||||
mRootTdaOrganizer = taskDisplayAreaOrganizer;
|
||||
createView();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and animate the indicator for the exit desktop mode transition.
|
||||
* Create a fullscreen indicator with no animation
|
||||
*/
|
||||
public void createFullscreenIndicator() {
|
||||
private void createView() {
|
||||
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
final Resources resources = mContext.getResources();
|
||||
final DisplayMetrics metrics = resources.getDisplayMetrics();
|
||||
final int screenWidth = metrics.widthPixels;
|
||||
final int screenHeight = metrics.heightPixels;
|
||||
final int padding = mDisplayController
|
||||
.getDisplayLayout(mTaskInfo.displayId).stableInsets().top;
|
||||
final ImageView v = new ImageView(mContext);
|
||||
v.setImageResource(R.drawable.desktop_windowing_transition_background);
|
||||
mView = new View(mContext);
|
||||
final SurfaceControl.Builder builder = new SurfaceControl.Builder();
|
||||
mRootTdaOrganizer.attachToDisplayArea(mTaskInfo.displayId, builder);
|
||||
mLeash = builder
|
||||
@@ -101,7 +105,7 @@ public class DesktopModeVisualIndicator {
|
||||
mViewHost = new SurfaceControlViewHost(mContext,
|
||||
mDisplayController.getDisplay(mTaskInfo.displayId), windowManager,
|
||||
"FullscreenVisualIndicator");
|
||||
mViewHost.setView(v, lp);
|
||||
mViewHost.setView(mView, lp);
|
||||
// We want this indicator to be behind the dragged task, but in front of all others.
|
||||
t.setRelativeLayer(mLeash, mTaskSurface, -1);
|
||||
|
||||
@@ -109,17 +113,56 @@ public class DesktopModeVisualIndicator {
|
||||
transaction.merge(t);
|
||||
t.close();
|
||||
});
|
||||
final Rect startBounds = new Rect(padding, padding,
|
||||
screenWidth - padding, screenHeight - padding);
|
||||
final VisualIndicatorAnimator animator = VisualIndicatorAnimator.fullscreenIndicator(v,
|
||||
startBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create fullscreen indicator and fades it in.
|
||||
*/
|
||||
public void createFullscreenIndicator() {
|
||||
mIsFullscreen = true;
|
||||
mView.setBackgroundResource(R.drawable.desktop_windowing_transition_background);
|
||||
final VisualIndicatorAnimator animator = VisualIndicatorAnimator.toFullscreenAnimator(
|
||||
mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a fullscreen indicator. Animator fades it in while expanding the bounds outwards.
|
||||
*/
|
||||
public void createFullscreenIndicatorWithAnimatedBounds() {
|
||||
mIsFullscreen = true;
|
||||
mView.setBackgroundResource(R.drawable.desktop_windowing_transition_background);
|
||||
final VisualIndicatorAnimator animator = VisualIndicatorAnimator
|
||||
.toFullscreenAnimatorWithAnimatedBounds(mView,
|
||||
mDisplayController.getDisplayLayout(mTaskInfo.displayId));
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes existing fullscreen indicator and animates it to freeform bounds
|
||||
*/
|
||||
public void transitionFullscreenIndicatorToFreeform() {
|
||||
mIsFullscreen = false;
|
||||
final VisualIndicatorAnimator animator = VisualIndicatorAnimator.toFreeformAnimator(
|
||||
mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes the existing freeform indicator and animates it to fullscreen
|
||||
*/
|
||||
public void transitionFreeformIndicatorToFullscreen() {
|
||||
mIsFullscreen = true;
|
||||
final VisualIndicatorAnimator animator =
|
||||
VisualIndicatorAnimator.toFullscreenAnimatorWithAnimatedBounds(
|
||||
mView, mDisplayController.getDisplayLayout(mTaskInfo.displayId));
|
||||
animator.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the indicator and its components when it is no longer needed.
|
||||
*/
|
||||
public void releaseFullscreenIndicator() {
|
||||
public void releaseVisualIndicator() {
|
||||
if (mViewHost == null) return;
|
||||
if (mViewHost != null) {
|
||||
mViewHost.release();
|
||||
@@ -136,20 +179,28 @@ public class DesktopModeVisualIndicator {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if visual indicator is fullscreen
|
||||
*/
|
||||
public boolean isFullscreen() {
|
||||
return mIsFullscreen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Animator for Desktop Mode transitions which supports bounds and alpha animation.
|
||||
*/
|
||||
private static class VisualIndicatorAnimator extends ValueAnimator {
|
||||
private static final int FULLSCREEN_INDICATOR_DURATION = 200;
|
||||
private static final float SCALE_ADJUSTMENT_PERCENT = 0.015f;
|
||||
private static final float FULLSCREEN_SCALE_ADJUSTMENT_PERCENT = 0.015f;
|
||||
private static final float INDICATOR_FINAL_OPACITY = 0.7f;
|
||||
|
||||
private final ImageView mView;
|
||||
private final View mView;
|
||||
private final Rect mStartBounds;
|
||||
private final Rect mEndBounds;
|
||||
private final RectEvaluator mRectEvaluator;
|
||||
|
||||
private VisualIndicatorAnimator(ImageView view, Rect startBounds,
|
||||
private VisualIndicatorAnimator(View view, Rect startBounds,
|
||||
Rect endBounds) {
|
||||
mView = view;
|
||||
mStartBounds = new Rect(startBounds);
|
||||
@@ -161,30 +212,66 @@ public class DesktopModeVisualIndicator {
|
||||
/**
|
||||
* Create animator for visual indicator of fullscreen transition
|
||||
*
|
||||
* @param view the view for this indicator
|
||||
* @param startBounds the starting bounds of the fullscreen indicator
|
||||
* @param view the view for this indicator
|
||||
* @param displayLayout information about the display the transitioning task is currently on
|
||||
*/
|
||||
public static VisualIndicatorAnimator fullscreenIndicator(ImageView view,
|
||||
Rect startBounds) {
|
||||
view.getDrawable().setBounds(startBounds);
|
||||
int width = startBounds.width();
|
||||
int height = startBounds.height();
|
||||
Rect endBounds = new Rect((int) (startBounds.left - (SCALE_ADJUSTMENT_PERCENT * width)),
|
||||
(int) (startBounds.top - (SCALE_ADJUSTMENT_PERCENT * height)),
|
||||
(int) (startBounds.right + (SCALE_ADJUSTMENT_PERCENT * width)),
|
||||
(int) (startBounds.bottom + (SCALE_ADJUSTMENT_PERCENT * height)));
|
||||
VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
|
||||
view, startBounds, endBounds);
|
||||
public static VisualIndicatorAnimator toFullscreenAnimator(@NonNull View view,
|
||||
@NonNull DisplayLayout displayLayout) {
|
||||
final Rect bounds = getMaxBounds(displayLayout);
|
||||
final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
|
||||
view, bounds, bounds);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
setupFullscreenIndicatorAnimation(animator);
|
||||
setupIndicatorAnimation(animator);
|
||||
return animator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create animator for visual indicator of fullscreen transition
|
||||
*
|
||||
* @param view the view for this indicator
|
||||
* @param displayLayout information about the display the transitioning task is currently on
|
||||
*/
|
||||
public static VisualIndicatorAnimator toFullscreenAnimatorWithAnimatedBounds(
|
||||
@NonNull View view, @NonNull DisplayLayout displayLayout) {
|
||||
final int padding = displayLayout.stableInsets().top;
|
||||
Rect startBounds = new Rect(padding, padding,
|
||||
displayLayout.width() - padding, displayLayout.height() - padding);
|
||||
view.getBackground().setBounds(startBounds);
|
||||
|
||||
final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
|
||||
view, startBounds, getMaxBounds(displayLayout));
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
setupIndicatorAnimation(animator);
|
||||
return animator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add necessary listener for animation of fullscreen indicator
|
||||
* Create animator for visual indicator of freeform transition
|
||||
*
|
||||
* @param view the view for this indicator
|
||||
* @param displayLayout information about the display the transitioning task is currently on
|
||||
*/
|
||||
private static void setupFullscreenIndicatorAnimation(
|
||||
VisualIndicatorAnimator animator) {
|
||||
public static VisualIndicatorAnimator toFreeformAnimator(@NonNull View view,
|
||||
@NonNull DisplayLayout displayLayout) {
|
||||
final float adjustmentPercentage = 1f - FINAL_FREEFORM_SCALE;
|
||||
final int width = displayLayout.width();
|
||||
final int height = displayLayout.height();
|
||||
Rect endBounds = new Rect((int) (adjustmentPercentage * width / 2),
|
||||
(int) (adjustmentPercentage * height / 2),
|
||||
(int) (displayLayout.width() - (adjustmentPercentage * width / 2)),
|
||||
(int) (displayLayout.height() - (adjustmentPercentage * height / 2)));
|
||||
final VisualIndicatorAnimator animator = new VisualIndicatorAnimator(
|
||||
view, getMaxBounds(displayLayout), endBounds);
|
||||
animator.setInterpolator(new DecelerateInterpolator());
|
||||
setupIndicatorAnimation(animator);
|
||||
return animator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add necessary listener for animation of indicator
|
||||
*/
|
||||
private static void setupIndicatorAnimation(@NonNull VisualIndicatorAnimator animator) {
|
||||
animator.addUpdateListener(a -> {
|
||||
if (animator.mView != null) {
|
||||
animator.updateBounds(a.getAnimatedFraction(), animator.mView);
|
||||
@@ -196,7 +283,7 @@ public class DesktopModeVisualIndicator {
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
animator.mView.getDrawable().setBounds(animator.mEndBounds);
|
||||
animator.mView.getBackground().setBounds(animator.mEndBounds);
|
||||
}
|
||||
});
|
||||
animator.setDuration(FULLSCREEN_INDICATOR_DURATION);
|
||||
@@ -210,9 +297,12 @@ public class DesktopModeVisualIndicator {
|
||||
* @param fraction fraction to use, compared against previous fraction
|
||||
* @param view the view to update
|
||||
*/
|
||||
private void updateBounds(float fraction, ImageView view) {
|
||||
private void updateBounds(float fraction, View view) {
|
||||
if (mStartBounds.equals(mEndBounds)) {
|
||||
return;
|
||||
}
|
||||
Rect currentBounds = mRectEvaluator.evaluate(fraction, mStartBounds, mEndBounds);
|
||||
view.getDrawable().setBounds(currentBounds);
|
||||
view.getBackground().setBounds(currentBounds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,5 +313,23 @@ public class DesktopModeVisualIndicator {
|
||||
private void updateIndicatorAlpha(float fraction, View view) {
|
||||
view.setAlpha(fraction * INDICATOR_FINAL_OPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the max bounds of a fullscreen indicator
|
||||
*/
|
||||
private static Rect getMaxBounds(@NonNull DisplayLayout displayLayout) {
|
||||
final int padding = displayLayout.stableInsets().top;
|
||||
final int width = displayLayout.width() - 2 * padding;
|
||||
final int height = displayLayout.height() - 2 * padding;
|
||||
Rect endBounds = new Rect((int) (padding
|
||||
- (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * width)),
|
||||
(int) (padding
|
||||
- (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * height)),
|
||||
(int) (displayLayout.width() - padding
|
||||
+ (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * width)),
|
||||
(int) (displayLayout.height() - padding
|
||||
+ (FULLSCREEN_SCALE_ADJUSTMENT_PERCENT * height)));
|
||||
return endBounds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ class DesktopTasksController(
|
||||
}
|
||||
|
||||
/** Move a task to desktop */
|
||||
fun moveToDesktop(task: ActivityManager.RunningTaskInfo) {
|
||||
fun moveToDesktop(task: RunningTaskInfo) {
|
||||
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToDesktop: %d", task.taskId)
|
||||
|
||||
val wct = WindowContainerTransaction()
|
||||
@@ -181,7 +181,7 @@ class DesktopTasksController(
|
||||
}
|
||||
|
||||
/** Move a task to fullscreen */
|
||||
fun moveToFullscreen(task: ActivityManager.RunningTaskInfo) {
|
||||
fun moveToFullscreen(task: RunningTaskInfo) {
|
||||
ProtoLog.v(WM_SHELL_DESKTOP_MODE, "moveToFullscreen: %d", task.taskId)
|
||||
|
||||
val wct = WindowContainerTransaction()
|
||||
@@ -206,7 +206,7 @@ class DesktopTasksController(
|
||||
}
|
||||
|
||||
/** Move a task to the front **/
|
||||
fun moveTaskToFront(taskInfo: ActivityManager.RunningTaskInfo) {
|
||||
fun moveTaskToFront(taskInfo: RunningTaskInfo) {
|
||||
val wct = WindowContainerTransaction()
|
||||
wct.reorder(taskInfo.token, true)
|
||||
if (Transitions.ENABLE_SHELL_TRANSITIONS) {
|
||||
@@ -273,7 +273,7 @@ class DesktopTasksController(
|
||||
request: TransitionRequestInfo
|
||||
): WindowContainerTransaction? {
|
||||
// Check if we should skip handling this transition
|
||||
val task: ActivityManager.RunningTaskInfo? = request.triggerTask
|
||||
val task: RunningTaskInfo? = request.triggerTask
|
||||
val shouldHandleRequest =
|
||||
when {
|
||||
// Only handle open or to front transitions
|
||||
@@ -382,16 +382,15 @@ class DesktopTasksController(
|
||||
taskSurface: SurfaceControl,
|
||||
y: Float
|
||||
) {
|
||||
val statusBarHeight = displayController
|
||||
.getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
|
||||
if (taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
|
||||
val statusBarHeight = getStatusBarHeight(taskInfo)
|
||||
if (y <= statusBarHeight && visualIndicator == null) {
|
||||
visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
|
||||
displayController, context, taskSurface, shellTaskOrganizer,
|
||||
rootTaskDisplayAreaOrganizer)
|
||||
visualIndicator?.createFullscreenIndicator()
|
||||
visualIndicator?.createFullscreenIndicatorWithAnimatedBounds()
|
||||
} else if (y > statusBarHeight && visualIndicator != null) {
|
||||
visualIndicator?.releaseFullscreenIndicator()
|
||||
visualIndicator?.releaseVisualIndicator()
|
||||
visualIndicator = null
|
||||
}
|
||||
}
|
||||
@@ -407,15 +406,72 @@ class DesktopTasksController(
|
||||
taskInfo: RunningTaskInfo,
|
||||
y: Float
|
||||
) {
|
||||
val statusBarHeight = displayController
|
||||
.getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
|
||||
val statusBarHeight = getStatusBarHeight(taskInfo)
|
||||
if (y <= statusBarHeight && taskInfo.windowingMode == WINDOWING_MODE_FREEFORM) {
|
||||
visualIndicator?.releaseFullscreenIndicator()
|
||||
visualIndicator?.releaseVisualIndicator()
|
||||
visualIndicator = null
|
||||
moveToFullscreenWithAnimation(taskInfo)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform checks required on drag move. Create/release fullscreen indicator and transitions
|
||||
* indicator to freeform or fullscreen dimensions as needed.
|
||||
*
|
||||
* @param taskInfo the task being dragged.
|
||||
* @param taskSurface SurfaceControl of dragged task.
|
||||
* @param y coordinate of dragged task. Used for checks against status bar height.
|
||||
*/
|
||||
fun onDragPositioningMoveThroughStatusBar(
|
||||
taskInfo: RunningTaskInfo,
|
||||
taskSurface: SurfaceControl,
|
||||
y: Float
|
||||
) {
|
||||
if (visualIndicator == null) {
|
||||
visualIndicator = DesktopModeVisualIndicator(syncQueue, taskInfo,
|
||||
displayController, context, taskSurface, shellTaskOrganizer,
|
||||
rootTaskDisplayAreaOrganizer)
|
||||
visualIndicator?.createFullscreenIndicator()
|
||||
}
|
||||
val indicator = visualIndicator ?: return
|
||||
if (y >= getFreeformTransitionStatusBarDragThreshold(taskInfo)) {
|
||||
if (indicator.isFullscreen) {
|
||||
indicator.transitionFullscreenIndicatorToFreeform()
|
||||
}
|
||||
} else if (!indicator.isFullscreen) {
|
||||
indicator.transitionFreeformIndicatorToFullscreen()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform checks required when drag ends under status bar area.
|
||||
*
|
||||
* @param taskInfo the task being dragged.
|
||||
* @param y height of drag, to be checked against status bar height.
|
||||
*/
|
||||
fun onDragPositioningEndThroughStatusBar(
|
||||
taskInfo: RunningTaskInfo,
|
||||
freeformBounds: Rect
|
||||
) {
|
||||
moveToDesktopWithAnimation(taskInfo, freeformBounds)
|
||||
visualIndicator?.releaseVisualIndicator()
|
||||
visualIndicator = null
|
||||
}
|
||||
|
||||
|
||||
private fun getStatusBarHeight(taskInfo: RunningTaskInfo): Int {
|
||||
return displayController.getDisplayLayout(taskInfo.displayId)?.stableInsets()?.top ?: 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the threshold at which we transition a task into freeform when dragging a
|
||||
* fullscreen task down from the status bar
|
||||
*/
|
||||
private fun getFreeformTransitionStatusBarDragThreshold(taskInfo: RunningTaskInfo): Int {
|
||||
return 2 * getStatusBarHeight(taskInfo)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a listener to find out about changes in the visibility of freeform tasks.
|
||||
*
|
||||
|
||||
@@ -79,6 +79,7 @@ import java.util.function.Supplier;
|
||||
|
||||
public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
private static final String TAG = "DesktopModeWindowDecorViewModel";
|
||||
|
||||
private final DesktopModeWindowDecoration.Factory mDesktopModeWindowDecorFactory;
|
||||
private final ActivityTaskManager mActivityTaskManager;
|
||||
private final ShellTaskOrganizer mTaskOrganizer;
|
||||
@@ -542,7 +543,7 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
mTransitionDragActive = false;
|
||||
final int statusBarHeight = getStatusBarHeight(
|
||||
relevantDecor.mTaskInfo.displayId);
|
||||
if (ev.getY() > statusBarHeight) {
|
||||
if (ev.getY() > 2 * statusBarHeight) {
|
||||
if (DesktopModeStatus.isProto2Enabled()) {
|
||||
mPauseRelayoutForTask = relevantDecor.mTaskInfo.taskId;
|
||||
centerAndMoveToDesktopWithAnimation(relevantDecor, ev);
|
||||
@@ -567,9 +568,11 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
return;
|
||||
}
|
||||
if (mTransitionDragActive) {
|
||||
final int statusBarHeight = mDisplayController
|
||||
.getDisplayLayout(
|
||||
relevantDecor.mTaskInfo.displayId).stableInsets().top;
|
||||
mDesktopTasksController.ifPresent(
|
||||
c -> c.onDragPositioningMoveThroughStatusBar(relevantDecor.mTaskInfo,
|
||||
relevantDecor.mTaskSurface, ev.getY()));
|
||||
final int statusBarHeight = getStatusBarHeight(
|
||||
relevantDecor.mTaskInfo.displayId);
|
||||
if (ev.getY() > statusBarHeight) {
|
||||
if (!mDragToDesktopAnimationStarted) {
|
||||
mDragToDesktopAnimationStarted = true;
|
||||
@@ -644,7 +647,8 @@ public class DesktopModeWindowDecorViewModel implements WindowDecorViewModel {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mDesktopTasksController.ifPresent(
|
||||
c -> c.moveToDesktopWithAnimation(relevantDecor.mTaskInfo,
|
||||
c -> c.onDragPositioningEndThroughStatusBar(
|
||||
relevantDecor.mTaskInfo,
|
||||
calculateFreeformBounds(FINAL_FREEFORM_SCALE)));
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user