Refactor TaskViewUtils to launch adjacent GroupedViewTaskView
* TaskViewUtils only used one TVS, now it can use multiple necessary for staged split. * Consolidate creating RemoteAnimationTargets into TaskViewSimulators/TransformParams into RemoteTargetGluer Test: Swipe to overview, tap on running task. Swipe to overview, tap on adjacent task (single + split) Bug: 195675206 Change-Id: I31e4aece60e2eaf94ce87ffc736b33fe7e0e5804
This commit is contained in:
@@ -96,6 +96,7 @@ import com.android.launcher3.util.VibratorWrapper;
|
||||
import com.android.launcher3.util.WindowBounds;
|
||||
import com.android.quickstep.BaseActivityInterface.AnimationFactory;
|
||||
import com.android.quickstep.GestureState.GestureEndTarget;
|
||||
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.util.ActivityInitListener;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
@@ -434,7 +435,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// RecentsView never updates the display rotation until swipe-up, force update
|
||||
// RecentsOrientedState before passing to TaskViewSimulator.
|
||||
mRecentsView.updateRecentsRotation();
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
|
||||
.setOrientationState(mRecentsView.getPagedViewOrientedState()));
|
||||
|
||||
// If we've already ended the gesture and are going home, don't prepare recents UI,
|
||||
@@ -753,6 +754,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
super.onRecentsAnimationStart(controller, targets);
|
||||
ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targets.apps.length);
|
||||
mRemoteTargetHandles = mTargetGluer.assignTargetsForSplitScreen(targets);
|
||||
mRecentsAnimationController = controller;
|
||||
mRecentsAnimationTargets = targets;
|
||||
|
||||
@@ -763,7 +766,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// orientation state is independent of which remote target handle we use since both
|
||||
// should be pointing to the same one. Just choose index 0 for now since that works for
|
||||
// both split and non-split
|
||||
RecentsOrientedState orientationState = mRemoteTargetHandles[0].mTaskViewSimulator
|
||||
RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator()
|
||||
.getOrientationState();
|
||||
DeviceProfile dp = orientationState.getLauncherDeviceProfile();
|
||||
if (targets.minimizedHomeBounds != null && primaryTaskTarget != null) {
|
||||
@@ -1350,7 +1353,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
RemoteAnimationTargetCompat runningTaskTarget, float startProgress) {
|
||||
// Directly animate the app to PiP (picture-in-picture) mode
|
||||
final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask();
|
||||
final RecentsOrientedState orientationState = mRemoteTargetHandles[0].mTaskViewSimulator
|
||||
final RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator()
|
||||
.getOrientationState();
|
||||
final int windowRotation = calculateWindowRotation(runningTaskTarget, orientationState);
|
||||
final int homeRotation = orientationState.getRecentsActivityRotation();
|
||||
@@ -1386,7 +1389,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
// is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
|
||||
if (homeRotation == ROTATION_0
|
||||
&& (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) {
|
||||
builder.setFromRotation(mRemoteTargetHandles[0].mTaskViewSimulator, windowRotation,
|
||||
builder.setFromRotation(mRemoteTargetHandles[0].getTaskViewSimulator(), windowRotation,
|
||||
taskInfo.displayCutoutInsets);
|
||||
}
|
||||
final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build();
|
||||
@@ -1756,7 +1759,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
* depend on proper class initialization.
|
||||
*/
|
||||
protected void initAfterSubclassConstructor() {
|
||||
initTransitionEndpoints(mRemoteTargetHandles[0].mTaskViewSimulator
|
||||
initTransitionEndpoints(mRemoteTargetHandles[0].getTaskViewSimulator()
|
||||
.getOrientationState().getLauncherDeviceProfile());
|
||||
}
|
||||
|
||||
@@ -1774,7 +1777,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
|
||||
protected void linkRecentsViewScroll() {
|
||||
SurfaceTransactionApplier.create(mRecentsView, applier -> {
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
|
||||
.setSyncTransactionApplier(applier));
|
||||
runOnRecentsAnimationStart(() ->
|
||||
mRecentsAnimationTargets.addReleaseCheck(applier));
|
||||
@@ -1910,18 +1913,19 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||
boolean notSwipingPipToHome = mRecentsAnimationTargets != null && !mIsSwipingPipToHome;
|
||||
boolean setRecentsScroll = mRecentsViewScrollLinked && mRecentsView != null;
|
||||
for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
|
||||
AnimatorControllerWithResistance playbackController = remoteHandle.mPlaybackController;
|
||||
AnimatorControllerWithResistance playbackController =
|
||||
remoteHandle.getPlaybackController();
|
||||
if (playbackController != null) {
|
||||
playbackController.setProgress(Math.max(mCurrentShift.value,
|
||||
getScaleProgressDueToScroll()), mDragLengthFactor);
|
||||
}
|
||||
|
||||
if (notSwipingPipToHome) {
|
||||
TaskViewSimulator taskViewSimulator = remoteHandle.mTaskViewSimulator;
|
||||
TaskViewSimulator taskViewSimulator = remoteHandle.getTaskViewSimulator();
|
||||
if (setRecentsScroll) {
|
||||
taskViewSimulator.setScroll(mRecentsView.getScrollOffset());
|
||||
}
|
||||
taskViewSimulator.apply(remoteHandle.mTransformParams);
|
||||
taskViewSimulator.apply(remoteHandle.getTransformParams());
|
||||
}
|
||||
}
|
||||
ProtoTracer.INSTANCE.get(mContext).scheduleFrameUpdate();
|
||||
|
||||
@@ -105,7 +105,7 @@ public class FallbackSwipeHandler extends
|
||||
mRunningOverHome = ActivityManagerWrapper.isHomeTask(mGestureState.getRunningTask());
|
||||
if (mRunningOverHome) {
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||
remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
|
||||
FallbackSwipeHandler.this::updateHomeActivityTransformDuringSwipeUp));
|
||||
}
|
||||
}
|
||||
@@ -115,7 +115,8 @@ public class FallbackSwipeHandler extends
|
||||
super.initTransitionEndpoints(dp);
|
||||
if (mRunningOverHome) {
|
||||
// Full screen scale should be independent of remote target handle
|
||||
mMaxLauncherScale = 1 / mRemoteTargetHandles[0].mTaskViewSimulator.getFullScreenScale();
|
||||
mMaxLauncherScale = 1 / mRemoteTargetHandles[0].getTaskViewSimulator()
|
||||
.getFullScreenScale();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,21 +215,21 @@ public class FallbackSwipeHandler extends
|
||||
mHomeAlpha.value = Utilities.boundToRange(1 - mCurrentShift.value, 0, 1);
|
||||
mVerticalShiftForScale.value = mCurrentShift.value;
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||
remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
|
||||
FallbackHomeAnimationFactory.this
|
||||
::updateHomeActivityTransformDuringHomeAnim));
|
||||
} else {
|
||||
mHomeAlpha = new AnimatedFloat(this::updateHomeAlpha);
|
||||
mHomeAlpha.value = 0;
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||
remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
|
||||
FallbackHomeAnimationFactory.this
|
||||
::updateHomeActivityTransformDuringHomeAnim));
|
||||
}
|
||||
|
||||
mRecentsAlpha.value = 1;
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||
remoteTargetHandle.getTransformParams().setHomeBuilderProxy(
|
||||
FallbackHomeAnimationFactory.this
|
||||
::updateRecentsActivityTransformDuringHomeAnim));
|
||||
}
|
||||
|
||||
@@ -183,13 +183,13 @@ public class LauncherSwipeHandlerV2 extends
|
||||
Rect crop = new Rect();
|
||||
// We can assume there is only one remote target here because staged split never animates
|
||||
// into the app icon, only into the homescreen
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.getCurrentCropRect().roundOut(crop);
|
||||
mRemoteTargetHandles[0].getTaskViewSimulator().getCurrentCropRect().roundOut(crop);
|
||||
Size windowSize = new Size(crop.width(), crop.height());
|
||||
int fallbackBackgroundColor =
|
||||
FloatingWidgetView.getDefaultBackgroundColor(mContext, runningTaskTarget);
|
||||
FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
|
||||
hostView, backgroundLocation, windowSize,
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.getCurrentCornerRadius(),
|
||||
mRemoteTargetHandles[0].getTaskViewSimulator().getCurrentCornerRadius(),
|
||||
isTargetTranslucent, fallbackBackgroundColor);
|
||||
|
||||
return new FloatingViewHomeAnimationFactory(floatingWidgetView) {
|
||||
|
||||
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.quickstep;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.LauncherSplitScreenListener;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
import com.android.quickstep.util.TransformParams;
|
||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||
|
||||
/**
|
||||
* Glues together the necessary components to animate a remote target using a
|
||||
* {@link TaskViewSimulator}
|
||||
*/
|
||||
public class RemoteTargetGluer {
|
||||
private final RemoteTargetHandle[] mRemoteTargetHandles;
|
||||
private SplitConfigurationOptions.StagedSplitBounds mStagedSplitBounds;
|
||||
|
||||
/**
|
||||
* Use this constructor if remote targets are split-screen independent
|
||||
*/
|
||||
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy,
|
||||
RemoteAnimationTargets targets) {
|
||||
mRemoteTargetHandles = createHandles(context, sizingStrategy, targets.apps.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this constructor if you want the number of handles created to match the number of active
|
||||
* running tasks
|
||||
*/
|
||||
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
|
||||
int[] splitIds = LauncherSplitScreenListener.INSTANCE.getNoCreate()
|
||||
.getRunningSplitTaskIds();
|
||||
mRemoteTargetHandles = createHandles(context, sizingStrategy, splitIds.length == 2 ? 2 : 1);
|
||||
}
|
||||
|
||||
private RemoteTargetHandle[] createHandles(Context context,
|
||||
BaseActivityInterface sizingStrategy, int numHandles) {
|
||||
RemoteTargetHandle[] handles = new RemoteTargetHandle[numHandles];
|
||||
for (int i = 0; i < numHandles; i++) {
|
||||
TaskViewSimulator tvs = new TaskViewSimulator(context, sizingStrategy);
|
||||
TransformParams transformParams = new TransformParams();
|
||||
handles[i] = new RemoteTargetHandle(tvs, transformParams);
|
||||
}
|
||||
return handles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pairs together {@link TaskViewSimulator}s and {@link TransformParams} into a
|
||||
* {@link RemoteTargetHandle}
|
||||
* Assigns only the apps associated with {@param targets} into their own TaskViewSimulators.
|
||||
* Length of targets.apps should match that of {@link #mRemoteTargetHandles}.
|
||||
*
|
||||
* If split screen may be active when this is called, you might want to use
|
||||
* {@link #assignTargetsForSplitScreen(RemoteAnimationTargets)}
|
||||
*/
|
||||
public RemoteTargetHandle[] assignTargets(RemoteAnimationTargets targets) {
|
||||
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
|
||||
RemoteAnimationTargetCompat primaryTaskTarget = targets.apps[i];
|
||||
mRemoteTargetHandles[i].mTransformParams.setTargetSet(
|
||||
createRemoteAnimationTargetsForTarget(primaryTaskTarget, targets));
|
||||
mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
|
||||
}
|
||||
return mRemoteTargetHandles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@link #assignTargets(RemoteAnimationTargets)}, except this matches the
|
||||
* apps in targets.apps to that of the split screened tasks. If split screen is active, then
|
||||
* {@link #mRemoteTargetHandles} index 0 will be the left/top task, index one right/bottom
|
||||
*/
|
||||
public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) {
|
||||
int[] splitIds = LauncherSplitScreenListener.INSTANCE.getNoCreate()
|
||||
.getRunningSplitTaskIds();
|
||||
RemoteAnimationTargetCompat primaryTaskTarget;
|
||||
RemoteAnimationTargetCompat secondaryTaskTarget;
|
||||
if (mRemoteTargetHandles.length == 1) {
|
||||
// If we're not in split screen, the splitIds count doesn't really matter since we
|
||||
// should always hit this case. Right now there's no use case for multiple app targets
|
||||
// without being in split screen
|
||||
primaryTaskTarget = targets.apps[0];
|
||||
mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget, null);
|
||||
} else {
|
||||
// split screen
|
||||
primaryTaskTarget = targets.findTask(splitIds[0]);
|
||||
secondaryTaskTarget = targets.findTask(splitIds[1]);
|
||||
|
||||
RemoteAnimationTargetCompat dividerTarget = targets.getNonAppTargetOfType(
|
||||
TYPE_DOCK_DIVIDER);
|
||||
mStagedSplitBounds = new SplitConfigurationOptions.StagedSplitBounds(
|
||||
primaryTaskTarget.screenSpaceBounds,
|
||||
secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
|
||||
mRemoteTargetHandles[0].mTransformParams.setTargetSet(
|
||||
createRemoteAnimationTargetsForTarget(primaryTaskTarget, targets));
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
|
||||
mStagedSplitBounds);
|
||||
|
||||
mRemoteTargetHandles[1].mTransformParams.setTargetSet(
|
||||
createRemoteAnimationTargetsForTarget(secondaryTaskTarget, targets));
|
||||
mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget,
|
||||
mStagedSplitBounds);
|
||||
}
|
||||
return mRemoteTargetHandles;
|
||||
}
|
||||
|
||||
private RemoteAnimationTargets createRemoteAnimationTargetsForTarget(
|
||||
RemoteAnimationTargetCompat target,
|
||||
RemoteAnimationTargets targets) {
|
||||
return new RemoteAnimationTargets(new RemoteAnimationTargetCompat[]{target},
|
||||
targets.wallpapers, targets.nonApps, targets.targetMode);
|
||||
}
|
||||
|
||||
public RemoteTargetHandle[] getRemoteTargetHandles() {
|
||||
return mRemoteTargetHandles;
|
||||
}
|
||||
|
||||
public SplitConfigurationOptions.StagedSplitBounds getStagedSplitBounds() {
|
||||
return mStagedSplitBounds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Container to keep together all the associated objects whose properties need to be updated to
|
||||
* animate a single remote app target
|
||||
*/
|
||||
public static class RemoteTargetHandle {
|
||||
private final TaskViewSimulator mTaskViewSimulator;
|
||||
private final TransformParams mTransformParams;
|
||||
@Nullable
|
||||
private AnimatorControllerWithResistance mPlaybackController;
|
||||
|
||||
public RemoteTargetHandle(TaskViewSimulator taskViewSimulator,
|
||||
TransformParams transformParams) {
|
||||
mTransformParams = transformParams;
|
||||
mTaskViewSimulator = taskViewSimulator;
|
||||
}
|
||||
|
||||
public TaskViewSimulator getTaskViewSimulator() {
|
||||
return mTaskViewSimulator;
|
||||
}
|
||||
|
||||
public TransformParams getTransformParams() {
|
||||
return mTransformParams;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AnimatorControllerWithResistance getPlaybackController() {
|
||||
return mPlaybackController;
|
||||
}
|
||||
|
||||
public void setPlaybackController(
|
||||
@Nullable AnimatorControllerWithResistance playbackController) {
|
||||
mPlaybackController = playbackController;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,10 @@
|
||||
*/
|
||||
package com.android.quickstep;
|
||||
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
|
||||
|
||||
import static com.android.launcher3.anim.Interpolators.ACCEL_1_5;
|
||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
||||
import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_SELECT;
|
||||
import static com.android.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.content.Context;
|
||||
@@ -40,8 +37,7 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||
import com.android.quickstep.util.ActiveGestureLog;
|
||||
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
|
||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||
import com.android.quickstep.util.AppCloseConfig;
|
||||
import com.android.quickstep.util.LauncherSplitScreenListener;
|
||||
@@ -60,6 +56,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
RecentsAnimationCallbacks.RecentsAnimationListener{
|
||||
|
||||
protected static final Rect TEMP_RECT = new Rect();
|
||||
protected final RemoteTargetGluer mTargetGluer;
|
||||
|
||||
protected DeviceProfile mDp;
|
||||
|
||||
@@ -67,8 +64,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
protected final RecentsAnimationDeviceState mDeviceState;
|
||||
protected final GestureState mGestureState;
|
||||
|
||||
protected final RemoteTargetHandle[] mRemoteTargetHandles;
|
||||
protected SplitConfigurationOptions.StagedSplitBounds mStagedSplitBounds;
|
||||
protected RemoteTargetHandle[] mRemoteTargetHandles;
|
||||
|
||||
// Shift in the range of [0, 1].
|
||||
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
|
||||
@@ -98,39 +94,30 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
primaryTVS.getOrientationState().update(
|
||||
mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
|
||||
mDeviceState.getRotationTouchHelper().getDisplayRotation());
|
||||
mRemoteTargetHandles = new RemoteTargetHandle[mIsSwipeForStagedSplit ? 2 : 1];
|
||||
mRemoteTargetHandles[0] = new RemoteTargetHandle(primaryTVS, transformParams);
|
||||
|
||||
if (mIsSwipeForStagedSplit) {
|
||||
TaskViewSimulator secondaryTVS = new TaskViewSimulator(context,
|
||||
gestureState.getActivityInterface());
|
||||
secondaryTVS.getOrientationState().update(
|
||||
mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
|
||||
mDeviceState.getRotationTouchHelper().getDisplayRotation());
|
||||
mRemoteTargetHandles[1] = new RemoteTargetHandle(secondaryTVS, new TransformParams());
|
||||
}
|
||||
mTargetGluer = new RemoteTargetGluer(mContext, mGestureState.getActivityInterface());
|
||||
mRemoteTargetHandles = mTargetGluer.getRemoteTargetHandles();
|
||||
}
|
||||
|
||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||
mDp = dp;
|
||||
mTransitionDragLength = mGestureState.getActivityInterface().getSwipeUpDestinationAndLength(
|
||||
dp, mContext, TEMP_RECT, mRemoteTargetHandles[0].mTaskViewSimulator
|
||||
dp, mContext, TEMP_RECT, mRemoteTargetHandles[0].getTaskViewSimulator()
|
||||
.getOrientationState().getOrientationHandler());
|
||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||
|
||||
for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
|
||||
PendingAnimation pendingAnimation = new PendingAnimation(mTransitionDragLength * 2);
|
||||
TaskViewSimulator taskViewSimulator = remoteHandle.mTaskViewSimulator;
|
||||
TaskViewSimulator taskViewSimulator = remoteHandle.getTaskViewSimulator();
|
||||
taskViewSimulator.setDp(dp);
|
||||
taskViewSimulator.addAppToOverviewAnim(pendingAnimation, LINEAR);
|
||||
AnimatorPlaybackController playbackController =
|
||||
pendingAnimation.createPlaybackController();
|
||||
|
||||
remoteHandle.mPlaybackController = AnimatorControllerWithResistance.createForRecents(
|
||||
remoteHandle.setPlaybackController(AnimatorControllerWithResistance.createForRecents(
|
||||
playbackController, mContext, taskViewSimulator.getOrientationState(),
|
||||
mDp, taskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
|
||||
taskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE
|
||||
);
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,7 +144,7 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
|
||||
protected PagedOrientationHandler getOrientationHandler() {
|
||||
// OrientationHandler should be independent of remote target, can directly take one
|
||||
return mRemoteTargetHandles[0].mTaskViewSimulator
|
||||
return mRemoteTargetHandles[0].getTaskViewSimulator()
|
||||
.getOrientationState().getOrientationHandler();
|
||||
}
|
||||
|
||||
@@ -246,8 +233,8 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
for (int i = 0, mRemoteTargetHandlesLength = mRemoteTargetHandles.length;
|
||||
i < mRemoteTargetHandlesLength; i++) {
|
||||
RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
|
||||
TaskViewSimulator tvs = remoteHandle.mTaskViewSimulator;
|
||||
tvs.apply(remoteHandle.mTransformParams.setProgress(startProgress));
|
||||
TaskViewSimulator tvs = remoteHandle.getTaskViewSimulator();
|
||||
tvs.apply(remoteHandle.getTransformParams().setProgress(startProgress));
|
||||
|
||||
startRects[i] = new RectF(tvs.getCurrentCropRect());
|
||||
tvs.applyWindowToHomeRotation(outMatrix);
|
||||
@@ -266,53 +253,10 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
/** @return only the TaskViewSimulators from {@link #mRemoteTargetHandles} */
|
||||
protected TaskViewSimulator[] getRemoteTaskViewSimulators() {
|
||||
return Arrays.stream(mRemoteTargetHandles)
|
||||
.map(remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator)
|
||||
.map(remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator())
|
||||
.toArray(TaskViewSimulator[]::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||
RecentsAnimationTargets targets) {
|
||||
ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targets.apps.length);
|
||||
RemoteAnimationTargetCompat dividerTarget = targets.getNonAppTargetOfType(
|
||||
TYPE_DOCK_DIVIDER);
|
||||
RemoteAnimationTargetCompat primaryTaskTarget;
|
||||
RemoteAnimationTargetCompat secondaryTaskTarget;
|
||||
|
||||
// TODO(b/197568823) Determine if we need to exclude assistant as one of the targets we
|
||||
// animate
|
||||
if (!mIsSwipeForStagedSplit) {
|
||||
primaryTaskTarget = targets.findTask(mGestureState.getRunningTaskId());
|
||||
mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
|
||||
|
||||
if (primaryTaskTarget != null) {
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget);
|
||||
}
|
||||
} else {
|
||||
int[] taskIds = LauncherSplitScreenListener.INSTANCE.getNoCreate()
|
||||
.getRunningSplitTaskIds();
|
||||
// We're in staged split
|
||||
primaryTaskTarget = targets.findTask(taskIds[0]);
|
||||
secondaryTaskTarget = targets.findTask(taskIds[1]);
|
||||
mStagedSplitBounds = new SplitConfigurationOptions.StagedSplitBounds(
|
||||
primaryTaskTarget.screenSpaceBounds,
|
||||
secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
|
||||
mStagedSplitBounds);
|
||||
mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget,
|
||||
mStagedSplitBounds);
|
||||
mRemoteTargetHandles[0].mTransformParams.setTargetSet(
|
||||
createRemoteAnimationTargetsForTarget(primaryTaskTarget));
|
||||
mRemoteTargetHandles[1].mTransformParams.setTargetSet(
|
||||
createRemoteAnimationTargetsForTarget(secondaryTaskTarget));
|
||||
}
|
||||
}
|
||||
|
||||
private RemoteAnimationTargets createRemoteAnimationTargetsForTarget(
|
||||
RemoteAnimationTargetCompat target) {
|
||||
return new RemoteAnimationTargets(new RemoteAnimationTargetCompat[]{target},
|
||||
null, null, MODE_CLOSING);
|
||||
}
|
||||
/**
|
||||
* Creates an animation that transforms the current app window into the home app.
|
||||
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
|
||||
@@ -329,8 +273,8 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
i < mRemoteTargetHandlesLength; i++) {
|
||||
RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
|
||||
out[i] = getWindowAnimationToHomeInternal(homeAnimationFactory,
|
||||
targetRect, remoteHandle.mTransformParams, remoteHandle.mTaskViewSimulator,
|
||||
startRects[i], homeToWindowPositionMap);
|
||||
targetRect, remoteHandle.getTransformParams(),
|
||||
remoteHandle.getTaskViewSimulator(), startRects[i], homeToWindowPositionMap);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -445,21 +389,6 @@ public abstract class SwipeUpAnimationLogic implements
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Container to keep together all the associated objects whose properties need to be updated to
|
||||
* animate a single remote app target
|
||||
*/
|
||||
public static class RemoteTargetHandle {
|
||||
public TaskViewSimulator mTaskViewSimulator;
|
||||
public TransformParams mTransformParams;
|
||||
public AnimatorControllerWithResistance mPlaybackController;
|
||||
public RemoteTargetHandle(TaskViewSimulator taskViewSimulator,
|
||||
TransformParams transformParams) {
|
||||
mTransformParams = transformParams;
|
||||
mTaskViewSimulator = taskViewSimulator;
|
||||
}
|
||||
}
|
||||
|
||||
public interface RunningWindowAnim {
|
||||
void end();
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ import android.view.View;
|
||||
import android.window.TransitionInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.launcher3.BaseActivity;
|
||||
import com.android.launcher3.DeviceProfile;
|
||||
@@ -67,6 +66,7 @@ import com.android.launcher3.model.data.ItemInfo;
|
||||
import com.android.launcher3.statehandlers.DepthController;
|
||||
import com.android.launcher3.statemanager.StateManager;
|
||||
import com.android.launcher3.util.DisplayController;
|
||||
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
|
||||
import com.android.quickstep.util.MultiValueUpdateListener;
|
||||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||
import com.android.quickstep.util.TaskViewSimulator;
|
||||
@@ -151,28 +151,7 @@ public final class TaskViewUtils {
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
RemoteAnimationTargetCompat[] nonAppTargets, DepthController depthController,
|
||||
PendingAnimation out) {
|
||||
boolean isRunningTask = v.isRunningTask();
|
||||
TransformParams params = null;
|
||||
TaskViewSimulator tsv = null;
|
||||
// TODO(b/195675206) handle two TSVs here
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
|
||||
params = v.getRecentsView().getRemoteTargetHandles()[0].mTransformParams;
|
||||
tsv = v.getRecentsView().getRemoteTargetHandles()[0].mTaskViewSimulator;
|
||||
}
|
||||
createRecentsWindowAnimator(v, skipViewChanges, appTargets, wallpaperTargets, nonAppTargets,
|
||||
depthController, out, params, tsv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an animation that controls the window of the opening targets for the recents launch
|
||||
* animation.
|
||||
*/
|
||||
public static void createRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
|
||||
RemoteAnimationTargetCompat[] appTargets,
|
||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||
RemoteAnimationTargetCompat[] nonAppTargets, DepthController depthController,
|
||||
PendingAnimation out, @Nullable TransformParams params,
|
||||
@Nullable TaskViewSimulator tsv) {
|
||||
RecentsView recentsView = v.getRecentsView();
|
||||
boolean isQuickSwitch = v.isEndQuickswitchCuj();
|
||||
v.setEndQuickswitchCuj(false);
|
||||
|
||||
@@ -183,16 +162,27 @@ public final class TaskViewUtils {
|
||||
inLiveTileMode ? MODE_CLOSING : MODE_OPENING);
|
||||
final RemoteAnimationTargetCompat navBarTarget = targets.getNavBarRemoteAnimationTarget();
|
||||
|
||||
if (params == null) {
|
||||
SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
|
||||
targets.addReleaseCheck(applier);
|
||||
SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v);
|
||||
targets.addReleaseCheck(applier);
|
||||
|
||||
params = new TransformParams()
|
||||
.setSyncTransactionApplier(applier)
|
||||
.setTargetSet(targets);
|
||||
RemoteTargetHandle[] remoteTargetHandles;
|
||||
RemoteTargetHandle[] recentsViewHandles = recentsView.getRemoteTargetHandles();
|
||||
if (v.isRunningTask()) {
|
||||
// Re-use existing handles
|
||||
remoteTargetHandles = recentsViewHandles;
|
||||
} else {
|
||||
RemoteTargetGluer gluer = new RemoteTargetGluer(v.getContext(),
|
||||
recentsView.getSizeStrategy(), targets);
|
||||
if (recentsViewHandles != null && recentsViewHandles.length > 1) {
|
||||
remoteTargetHandles = gluer.assignTargetsForSplitScreen(targets);
|
||||
} else {
|
||||
remoteTargetHandles = gluer.assignTargets(targets);
|
||||
}
|
||||
}
|
||||
for (RemoteTargetHandle remoteTargetGluer : remoteTargetHandles) {
|
||||
remoteTargetGluer.getTransformParams().setSyncTransactionApplier(applier);
|
||||
}
|
||||
|
||||
final RecentsView recentsView = v.getRecentsView();
|
||||
int taskIndex = recentsView.indexOfChild(v);
|
||||
Context context = v.getContext();
|
||||
DeviceProfile dp = BaseActivity.fromContext(context).getDeviceProfile();
|
||||
@@ -202,45 +192,51 @@ public final class TaskViewUtils {
|
||||
float gridTranslationSecondary = recentsView.getGridTranslationSecondary(taskIndex);
|
||||
int startScroll = recentsView.getScrollOffset(taskIndex);
|
||||
|
||||
TaskViewSimulator topMostSimulator = null;
|
||||
RemoteTargetHandle[] topMostSimulators = null;
|
||||
|
||||
if (tsv == null && targets.apps.length > 0) {
|
||||
tsv = new TaskViewSimulator(context, recentsView.getSizeStrategy());
|
||||
tsv.setDp(dp);
|
||||
if (!v.isRunningTask()) {
|
||||
// TVSs already initialized from the running task, no need to re-init
|
||||
for (RemoteTargetHandle targetHandle : remoteTargetHandles) {
|
||||
TaskViewSimulator tvsLocal = targetHandle.getTaskViewSimulator();
|
||||
tvsLocal.setDp(dp);
|
||||
|
||||
// RecentsView never updates the display rotation until swipe-up so the value may
|
||||
// be stale. Use the display value instead.
|
||||
int displayRotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
|
||||
tsv.getOrientationState().update(displayRotation, displayRotation);
|
||||
// RecentsView never updates the display rotation until swipe-up so the value may
|
||||
// be stale. Use the display value instead.
|
||||
int displayRotation = DisplayController.INSTANCE.get(context).getInfo().rotation;
|
||||
tvsLocal.getOrientationState().update(displayRotation, displayRotation);
|
||||
|
||||
tsv.setPreview(targets.apps[targets.apps.length - 1]);
|
||||
tsv.fullScreenProgress.value = 0;
|
||||
tsv.recentsViewScale.value = 1;
|
||||
if (showAsGrid) {
|
||||
tsv.taskSecondaryTranslation.value = gridTranslationSecondary;
|
||||
tvsLocal.fullScreenProgress.value = 0;
|
||||
tvsLocal.recentsViewScale.value = 1;
|
||||
if (showAsGrid) {
|
||||
tvsLocal.taskSecondaryTranslation.value = gridTranslationSecondary;
|
||||
}
|
||||
tvsLocal.setScroll(startScroll);
|
||||
|
||||
// Fade in the task during the initial 20% of the animation
|
||||
out.addFloat(targetHandle.getTransformParams(), TransformParams.TARGET_ALPHA, 0, 1,
|
||||
clampToProgress(LINEAR, 0, 0.2f));
|
||||
}
|
||||
tsv.setScroll(startScroll);
|
||||
|
||||
// Fade in the task during the initial 20% of the animation
|
||||
out.addFloat(params, TransformParams.TARGET_ALPHA, 0, 1,
|
||||
clampToProgress(LINEAR, 0, 0.2f));
|
||||
}
|
||||
|
||||
if (tsv != null) {
|
||||
out.setFloat(tsv.fullScreenProgress,
|
||||
for (RemoteTargetHandle targetHandle : remoteTargetHandles) {
|
||||
TaskViewSimulator tvsLocal = targetHandle.getTaskViewSimulator();
|
||||
out.setFloat(tvsLocal.fullScreenProgress,
|
||||
AnimatedFloat.VALUE, 1, TOUCH_RESPONSE_INTERPOLATOR);
|
||||
out.setFloat(tsv.recentsViewScale,
|
||||
AnimatedFloat.VALUE, tsv.getFullScreenScale(), TOUCH_RESPONSE_INTERPOLATOR);
|
||||
out.setFloat(tvsLocal.recentsViewScale,
|
||||
AnimatedFloat.VALUE, tvsLocal.getFullScreenScale(),
|
||||
TOUCH_RESPONSE_INTERPOLATOR);
|
||||
if (showAsGrid) {
|
||||
out.setFloat(tsv.taskSecondaryTranslation, AnimatedFloat.VALUE, 0,
|
||||
out.setFloat(tvsLocal.taskSecondaryTranslation, AnimatedFloat.VALUE, 0,
|
||||
TOUCH_RESPONSE_INTERPOLATOR_ACCEL_DEACCEL);
|
||||
}
|
||||
out.setFloat(tsv.recentsViewScroll, AnimatedFloat.VALUE, 0,
|
||||
out.setFloat(tvsLocal.recentsViewScroll, AnimatedFloat.VALUE, 0,
|
||||
TOUCH_RESPONSE_INTERPOLATOR);
|
||||
|
||||
TaskViewSimulator finalTsv = tsv;
|
||||
TransformParams finalParams = params;
|
||||
out.addOnFrameCallback(() -> finalTsv.apply(finalParams));
|
||||
out.addOnFrameCallback(() -> {
|
||||
for (RemoteTargetHandle handle : remoteTargetHandles) {
|
||||
handle.getTaskViewSimulator().apply(handle.getTransformParams());
|
||||
}
|
||||
});
|
||||
if (navBarTarget != null) {
|
||||
final Rect cropRect = new Rect();
|
||||
out.addOnFrameListener(new MultiValueUpdateListener() {
|
||||
@@ -253,15 +249,20 @@ public final class TaskViewUtils {
|
||||
public void onUpdate(float percent, boolean initOnly) {
|
||||
final SurfaceParams.Builder navBuilder =
|
||||
new SurfaceParams.Builder(navBarTarget.leash);
|
||||
if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
|
||||
finalTsv.getCurrentCropRect().round(cropRect);
|
||||
navBuilder.withMatrix(finalTsv.getCurrentMatrix())
|
||||
.withWindowCrop(cropRect)
|
||||
.withAlpha(mNavFadeIn.value);
|
||||
} else {
|
||||
navBuilder.withAlpha(mNavFadeOut.value);
|
||||
|
||||
// TODO Do we need to operate over multiple TVSs for the navbar leash?
|
||||
for (RemoteTargetHandle handle : remoteTargetHandles) {
|
||||
if (mNavFadeIn.value > mNavFadeIn.getStartValue()) {
|
||||
TaskViewSimulator taskViewSimulator = handle.getTaskViewSimulator();
|
||||
taskViewSimulator.getCurrentCropRect().round(cropRect);
|
||||
navBuilder.withMatrix(taskViewSimulator.getCurrentMatrix())
|
||||
.withWindowCrop(cropRect)
|
||||
.withAlpha(mNavFadeIn.value);
|
||||
} else {
|
||||
navBuilder.withAlpha(mNavFadeOut.value);
|
||||
}
|
||||
handle.getTransformParams().applySurfaceParams(navBuilder.build());
|
||||
}
|
||||
finalParams.applySurfaceParams(navBuilder.build());
|
||||
}
|
||||
});
|
||||
} else if (inLiveTileMode) {
|
||||
@@ -273,14 +274,16 @@ public final class TaskViewUtils {
|
||||
controller.animateNavigationBarToApp(RECENTS_LAUNCH_DURATION);
|
||||
}
|
||||
}
|
||||
topMostSimulator = tsv;
|
||||
topMostSimulators = remoteTargetHandles;
|
||||
}
|
||||
|
||||
if (!skipViewChanges && parallaxCenterAndAdjacentTask && topMostSimulator != null) {
|
||||
if (!skipViewChanges && parallaxCenterAndAdjacentTask && topMostSimulators.length > 0) {
|
||||
out.addFloat(v, VIEW_ALPHA, 1, 0, clampToProgress(LINEAR, 0.2f, 0.4f));
|
||||
|
||||
TaskViewSimulator simulatorToCopy = topMostSimulator;
|
||||
simulatorToCopy.apply(params);
|
||||
RemoteTargetHandle[] simulatorCopies = topMostSimulators;
|
||||
for (RemoteTargetHandle handle : simulatorCopies) {
|
||||
handle.getTaskViewSimulator().apply(handle.getTransformParams());
|
||||
}
|
||||
|
||||
// Mt represents the overall transformation on the thumbnailView relative to the
|
||||
// Launcher's rootView
|
||||
@@ -294,36 +297,49 @@ public final class TaskViewUtils {
|
||||
// During animation we apply transformation on the thumbnailView (and not the rootView)
|
||||
// to follow the TaskViewSimulator. So the final matrix applied on the thumbnailView is:
|
||||
// Mt K(0)` K(t) Mt`
|
||||
TaskThumbnailView ttv = v.getThumbnail();
|
||||
RectF tvBounds = new RectF(0, 0, ttv.getWidth(), ttv.getHeight());
|
||||
float[] tvBoundsMapped = new float[]{0, 0, ttv.getWidth(), ttv.getHeight()};
|
||||
getDescendantCoordRelativeToAncestor(ttv, ttv.getRootView(), tvBoundsMapped, false);
|
||||
RectF tvBoundsInRoot = new RectF(
|
||||
tvBoundsMapped[0], tvBoundsMapped[1],
|
||||
tvBoundsMapped[2], tvBoundsMapped[3]);
|
||||
TaskThumbnailView[] thumbnails = v.getThumbnails();
|
||||
Matrix[] mt = new Matrix[simulatorCopies.length];
|
||||
Matrix[] mti = new Matrix[simulatorCopies.length];
|
||||
for (int i = 0; i < thumbnails.length; i++) {
|
||||
TaskThumbnailView ttv = thumbnails[i];
|
||||
RectF localBounds = new RectF(0, 0, ttv.getWidth(), ttv.getHeight());
|
||||
float[] tvBoundsMapped = new float[]{0, 0, ttv.getWidth(), ttv.getHeight()};
|
||||
getDescendantCoordRelativeToAncestor(ttv, ttv.getRootView(), tvBoundsMapped, false);
|
||||
RectF localBoundsInRoot = new RectF(
|
||||
tvBoundsMapped[0], tvBoundsMapped[1],
|
||||
tvBoundsMapped[2], tvBoundsMapped[3]);
|
||||
Matrix localMt = new Matrix();
|
||||
localMt.setRectToRect(localBounds, localBoundsInRoot, ScaleToFit.FILL);
|
||||
mt[i] = localMt;
|
||||
|
||||
Matrix mt = new Matrix();
|
||||
mt.setRectToRect(tvBounds, tvBoundsInRoot, ScaleToFit.FILL);
|
||||
|
||||
Matrix mti = new Matrix();
|
||||
mt.invert(mti);
|
||||
|
||||
Matrix k0i = new Matrix();
|
||||
simulatorToCopy.getCurrentMatrix().invert(k0i);
|
||||
Matrix localMti = new Matrix();
|
||||
localMti.invert(localMt);
|
||||
mti[i] = localMti;
|
||||
}
|
||||
|
||||
Matrix[] k0i = new Matrix[simulatorCopies.length];
|
||||
for (int i = 0; i < simulatorCopies.length; i++) {
|
||||
k0i[i] = new Matrix();
|
||||
simulatorCopies[i].getTaskViewSimulator().getCurrentMatrix().invert(k0i[i]);
|
||||
}
|
||||
Matrix animationMatrix = new Matrix();
|
||||
out.addOnFrameCallback(() -> {
|
||||
animationMatrix.set(mt);
|
||||
animationMatrix.postConcat(k0i);
|
||||
animationMatrix.postConcat(simulatorToCopy.getCurrentMatrix());
|
||||
animationMatrix.postConcat(mti);
|
||||
ttv.setAnimationMatrix(animationMatrix);
|
||||
for (int i = 0; i < simulatorCopies.length; i++) {
|
||||
animationMatrix.set(mt[i]);
|
||||
animationMatrix.postConcat(k0i[i]);
|
||||
animationMatrix.postConcat(simulatorCopies[i]
|
||||
.getTaskViewSimulator().getCurrentMatrix());
|
||||
animationMatrix.postConcat(mti[i]);
|
||||
thumbnails[i].setAnimationMatrix(animationMatrix);
|
||||
}
|
||||
});
|
||||
|
||||
out.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
ttv.setAnimationMatrix(null);
|
||||
for (TaskThumbnailView ttv : thumbnails) {
|
||||
ttv.setAnimationMatrix(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+4
-5
@@ -46,7 +46,6 @@ import com.android.launcher3.Utilities;
|
||||
import com.android.launcher3.anim.AnimatorListeners;
|
||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||
import com.android.launcher3.anim.PendingAnimation;
|
||||
import com.android.launcher3.statemanager.StatefulActivity;
|
||||
import com.android.quickstep.AnimatedFloat;
|
||||
import com.android.quickstep.GestureState;
|
||||
import com.android.quickstep.OverviewComponentObserver;
|
||||
@@ -260,16 +259,16 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||
|
||||
void initDp(DeviceProfile dp) {
|
||||
initTransitionEndpoints(dp);
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.setPreviewBounds(
|
||||
mRemoteTargetHandles[0].getTaskViewSimulator().setPreviewBounds(
|
||||
new Rect(0, 0, dp.widthPx, dp.heightPx), dp.getInsets());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateFinalShift() {
|
||||
mRemoteTargetHandles[0].mPlaybackController
|
||||
mRemoteTargetHandles[0].getPlaybackController()
|
||||
.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.apply(
|
||||
mRemoteTargetHandles[0].mTransformParams);
|
||||
mRemoteTargetHandles[0].getTaskViewSimulator().apply(
|
||||
mRemoteTargetHandles[0].getTransformParams());
|
||||
}
|
||||
|
||||
AnimatedFloat getCurrentShift() {
|
||||
|
||||
@@ -112,6 +112,11 @@ public class GroupedTaskView extends TaskView {
|
||||
SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskThumbnailView[] getThumbnails() {
|
||||
return new TaskThumbnailView[]{mSnapshotView, mSnapshotView2};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecycle() {
|
||||
super.onRecycle();
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.quickstep.views;
|
||||
import static android.view.Surface.ROTATION_0;
|
||||
import static android.view.View.MeasureSpec.EXACTLY;
|
||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
|
||||
|
||||
import static com.android.launcher3.AbstractFloatingView.TYPE_TASK_MENU;
|
||||
import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
|
||||
@@ -53,7 +52,6 @@ import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_RECENTS;
|
||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
|
||||
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
@@ -146,7 +144,8 @@ import com.android.quickstep.RecentsAnimationTargets;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
|
||||
import com.android.quickstep.RemoteAnimationTargets;
|
||||
import com.android.quickstep.SwipeUpAnimationLogic.RemoteTargetHandle;
|
||||
import com.android.quickstep.RemoteTargetGluer;
|
||||
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskOverlayFactory;
|
||||
import com.android.quickstep.TaskThumbnailCache;
|
||||
@@ -325,7 +324,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
view.runActionOnRemoteHandles(new Consumer<RemoteTargetHandle>() {
|
||||
@Override
|
||||
public void accept(RemoteTargetHandle remoteTargetHandle) {
|
||||
remoteTargetHandle.mTaskViewSimulator.recentsViewScale.value =
|
||||
remoteTargetHandle.getTaskViewSimulator().recentsViewScale.value =
|
||||
scale;
|
||||
}
|
||||
});
|
||||
@@ -828,7 +827,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
|
||||
mSyncTransactionApplier = new SurfaceTransactionApplier(this);
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
|
||||
.setSyncTransactionApplier(mSyncTransactionApplier));
|
||||
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
|
||||
mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
|
||||
@@ -847,7 +846,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
|
||||
mSyncTransactionApplier = null;
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
|
||||
.setSyncTransactionApplier(null));
|
||||
executeSideTaskLaunchCallback();
|
||||
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
|
||||
@@ -937,7 +936,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
|
||||
int runningTaskViewId = getTaskViewIdFromTaskId(taskId);
|
||||
if (mRunningTaskViewId != -1 && mRunningTaskViewId == runningTaskViewId) {
|
||||
TransformParams params = mRemoteTargetHandles[0].mTransformParams;
|
||||
TransformParams params = mRemoteTargetHandles[0].getTransformParams();
|
||||
RemoteAnimationTargets targets = params.getTargetSet();
|
||||
if (targets != null && targets.findTask(taskId) != null) {
|
||||
launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
|
||||
@@ -1481,10 +1480,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// to reset the params after it settles in Overview from swipe up so that we don't
|
||||
// render with obsolete param values.
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||
remoteTargetHandle.mTaskViewSimulator.taskPrimaryTranslation.value = 0;
|
||||
remoteTargetHandle.mTaskViewSimulator.taskSecondaryTranslation.value = 0;
|
||||
remoteTargetHandle.mTaskViewSimulator.fullScreenProgress.value = 0;
|
||||
remoteTargetHandle.mTaskViewSimulator.recentsViewScale.value = 1;
|
||||
TaskViewSimulator simulator = remoteTargetHandle.getTaskViewSimulator();
|
||||
simulator.taskPrimaryTranslation.value = 0;
|
||||
simulator.taskSecondaryTranslation.value = 0;
|
||||
simulator.fullScreenProgress.value = 0;
|
||||
simulator.recentsViewScale.value = 1;
|
||||
});
|
||||
|
||||
// Similar to setRunningTaskHidden below, reapply the state before runningTaskView is
|
||||
@@ -1540,7 +1540,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
// Propagate DeviceProfile change event.
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator.setDp(dp));
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator().setDp(dp));
|
||||
mActionsView.setDp(dp);
|
||||
mOrientationState.setDeviceProfile(dp);
|
||||
|
||||
@@ -1877,7 +1877,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
}
|
||||
setEnableDrawingLiveTile(false);
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.getTransformParams()
|
||||
.setTargetSet(null));
|
||||
|
||||
// These are relatively expensive and don't need to be done this frame (RecentsView isn't
|
||||
@@ -2590,7 +2590,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
// alpha is set to 0 so that it can be recycled in the view pool properly
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && taskView.isRunningTask()) {
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||
TransformParams params = remoteTargetHandle.mTransformParams;
|
||||
TransformParams params = remoteTargetHandle.getTransformParams();
|
||||
anim.setFloat(params, TransformParams.TARGET_ALPHA, 0,
|
||||
clampToProgress(ACCEL, 0, 0.5f));
|
||||
});
|
||||
@@ -2613,7 +2613,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
&& taskView.isRunningTask()) {
|
||||
anim.addOnFrameCallback(() -> {
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
|
||||
.taskSecondaryTranslation.value = mOrientationHandler
|
||||
.getSecondaryValue(taskView.getTranslationX(),
|
||||
taskView.getTranslationY()
|
||||
@@ -2782,7 +2782,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
anim.addOnFrameCallback(() -> {
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle ->
|
||||
remoteTargetHandle.mTaskViewSimulator
|
||||
remoteTargetHandle.getTaskViewSimulator()
|
||||
.taskPrimaryTranslation.value =
|
||||
TaskView.GRID_END_TRANSLATION_X.get(taskView));
|
||||
redrawLiveTile();
|
||||
@@ -2855,7 +2855,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
anim.addOnFrameCallback(() -> {
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle ->
|
||||
remoteTargetHandle.mTaskViewSimulator
|
||||
remoteTargetHandle.getTaskViewSimulator()
|
||||
.taskPrimaryTranslation.value =
|
||||
mOrientationHandler.getPrimaryValue(
|
||||
child.getTranslationX(),
|
||||
@@ -3533,7 +3533,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mLastComputedTaskEndPushOutDistance = null;
|
||||
updatePageOffsets();
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
|
||||
.setScroll(getScrollOffset()));
|
||||
setImportantForAccessibility(isModal() ? IMPORTANT_FOR_ACCESSIBILITY_NO
|
||||
: IMPORTANT_FOR_ACCESSIBILITY_AUTO);
|
||||
@@ -3599,7 +3599,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
|
||||
&& i == getRunningTaskIndex()) {
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
|
||||
.taskPrimaryTranslation.value = totalTranslation);
|
||||
redrawLiveTile();
|
||||
}
|
||||
@@ -3707,7 +3707,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY());
|
||||
}
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
|
||||
.recentsViewSecondaryTranslation.value = translation);
|
||||
}
|
||||
|
||||
@@ -4023,7 +4023,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
&& runningTaskIndex != taskIndex) {
|
||||
for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
|
||||
anim.play(ObjectAnimator.ofFloat(
|
||||
remoteHandle.mTaskViewSimulator.taskPrimaryTranslation,
|
||||
remoteHandle.getTaskViewSimulator().taskPrimaryTranslation,
|
||||
AnimatedFloat.VALUE,
|
||||
primaryTranslation));
|
||||
}
|
||||
@@ -4107,7 +4107,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
mPendingAnimation.add(anim);
|
||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||
runActionOnRemoteHandles(
|
||||
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||
remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator()
|
||||
.addOverviewToAppAnim(mPendingAnimation, interpolator));
|
||||
mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
|
||||
}
|
||||
@@ -4201,9 +4201,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
public void redrawLiveTile() {
|
||||
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||
TransformParams params = remoteTargetHandle.mTransformParams;
|
||||
TransformParams params = remoteTargetHandle.getTransformParams();
|
||||
if (params.getTargetSet() != null) {
|
||||
remoteTargetHandle.mTaskViewSimulator.apply(params);
|
||||
remoteTargetHandle.getTaskViewSimulator().apply(params);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -4224,44 +4224,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
recentsAnimationTargets.addReleaseCheck(mSyncTransactionApplier);
|
||||
}
|
||||
|
||||
RemoteAnimationTargetCompat dividerTarget =
|
||||
recentsAnimationTargets.getNonAppTargetOfType(TYPE_DOCK_DIVIDER);
|
||||
// TODO Consolidate this shared code with SwipeUpAnimationLogic (or maybe just reuse
|
||||
// what that class has and pass it into here)
|
||||
mRemoteTargetHandles = new RemoteTargetHandle[dividerTarget == null ? 1 : 2];
|
||||
TaskViewSimulator primaryTvs = createTaskViewSimulator();
|
||||
mRemoteTargetHandles[0] = new RemoteTargetHandle(primaryTvs, new TransformParams());
|
||||
if (dividerTarget == null) {
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator
|
||||
.setPreview(recentsAnimationTargets.apps[0], null);
|
||||
mRemoteTargetHandles[0].mTransformParams.setTargetSet(recentsAnimationTargets);
|
||||
} else {
|
||||
TaskViewSimulator secondaryTvs = createTaskViewSimulator();
|
||||
secondaryTvs.setOrientationState(mOrientationState);
|
||||
secondaryTvs.recentsViewScale.value = 1;
|
||||
|
||||
mRemoteTargetHandles[1] = new RemoteTargetHandle(secondaryTvs, new TransformParams());
|
||||
RemoteAnimationTargetCompat primaryTaskTarget = recentsAnimationTargets.apps[0];
|
||||
RemoteAnimationTargetCompat secondaryTaskTarget = recentsAnimationTargets.apps[1];
|
||||
mSplitBoundsConfig = new SplitConfigurationOptions.StagedSplitBounds(
|
||||
primaryTaskTarget.screenSpaceBounds,
|
||||
secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
|
||||
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget,
|
||||
mSplitBoundsConfig);
|
||||
mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget,
|
||||
mSplitBoundsConfig);
|
||||
RemoteAnimationTargets rats = new RemoteAnimationTargets(
|
||||
new RemoteAnimationTargetCompat[]{primaryTaskTarget},
|
||||
recentsAnimationTargets.wallpapers, recentsAnimationTargets.nonApps,
|
||||
MODE_CLOSING
|
||||
);
|
||||
RemoteAnimationTargets splitRats = new RemoteAnimationTargets(
|
||||
new RemoteAnimationTargetCompat[]{secondaryTaskTarget},
|
||||
recentsAnimationTargets.wallpapers, recentsAnimationTargets.nonApps,
|
||||
MODE_CLOSING
|
||||
);
|
||||
mRemoteTargetHandles[0].mTransformParams.setTargetSet(rats);
|
||||
mRemoteTargetHandles[1].mTransformParams.setTargetSet(splitRats);
|
||||
RemoteTargetGluer gluer = new RemoteTargetGluer(getContext(), getSizeStrategy());
|
||||
mRemoteTargetHandles = gluer.assignTargetsForSplitScreen(recentsAnimationTargets);
|
||||
mSplitBoundsConfig = gluer.getStagedSplitBounds();
|
||||
for (RemoteTargetHandle remoteTargetHandle : mRemoteTargetHandles) {
|
||||
TaskViewSimulator tvs = remoteTargetHandle.getTaskViewSimulator();
|
||||
tvs.setOrientationState(mOrientationState);
|
||||
tvs.setDp(mActivity.getDeviceProfile());
|
||||
tvs.recentsViewScale.value = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4276,14 +4246,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
}
|
||||
}
|
||||
|
||||
private TaskViewSimulator createTaskViewSimulator() {
|
||||
TaskViewSimulator tvs = new TaskViewSimulator(getContext(), getSizeStrategy());
|
||||
tvs.setOrientationState(mOrientationState);
|
||||
tvs.setDp(mActivity.getDeviceProfile());
|
||||
tvs.recentsViewScale.value = 1;
|
||||
return tvs;
|
||||
}
|
||||
|
||||
public void finishRecentsAnimation(boolean toRecents, Runnable onFinishComplete) {
|
||||
finishRecentsAnimation(toRecents, true /* shouldPip */, onFinishComplete);
|
||||
}
|
||||
@@ -4778,7 +4740,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||
|
||||
private void dispatchScrollChanged() {
|
||||
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||
remoteTargetHandle.mTaskViewSimulator.setScroll(getScrollOffset()));
|
||||
remoteTargetHandle.getTaskViewSimulator().setScroll(getScrollOffset()));
|
||||
for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
|
||||
mScrollListeners.get(i).onScrollChanged();
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ import com.android.launcher3.util.TransformingTouchDelegate;
|
||||
import com.android.launcher3.util.ViewPool.Reusable;
|
||||
import com.android.quickstep.RecentsModel;
|
||||
import com.android.quickstep.RemoteAnimationTargets;
|
||||
import com.android.quickstep.SwipeUpAnimationLogic.RemoteTargetHandle;
|
||||
import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle;
|
||||
import com.android.quickstep.SystemUiProxy;
|
||||
import com.android.quickstep.TaskIconCache;
|
||||
import com.android.quickstep.TaskOverlayFactory;
|
||||
@@ -592,6 +592,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
return mSnapshotView;
|
||||
}
|
||||
|
||||
/** TODO(b/197033698) Remove all usages of above method and migrate to this one */
|
||||
public TaskThumbnailView[] getThumbnails() {
|
||||
return new TaskThumbnailView[]{mSnapshotView};
|
||||
}
|
||||
|
||||
public IconView getIconView() {
|
||||
return mIconView;
|
||||
}
|
||||
@@ -618,13 +623,12 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||
mIsClickableAsLiveTile = false;
|
||||
RecentsView recentsView = getRecentsView();
|
||||
RemoteAnimationTargets targets;
|
||||
RemoteTargetHandle[] remoteTargetHandles =
|
||||
recentsView.mRemoteTargetHandles;
|
||||
RemoteTargetHandle[] remoteTargetHandles = recentsView.mRemoteTargetHandles;
|
||||
if (remoteTargetHandles.length == 1) {
|
||||
targets = remoteTargetHandles[0].mTransformParams.getTargetSet();
|
||||
targets = remoteTargetHandles[0].getTransformParams().getTargetSet();
|
||||
} else {
|
||||
TransformParams topLeftParams = remoteTargetHandles[0].mTransformParams;
|
||||
TransformParams rightBottomParams = remoteTargetHandles[1].mTransformParams;
|
||||
TransformParams topLeftParams = remoteTargetHandles[0].getTransformParams();
|
||||
TransformParams rightBottomParams = remoteTargetHandles[1].getTransformParams();
|
||||
RemoteAnimationTargetCompat[] apps = Stream.concat(
|
||||
Arrays.stream(topLeftParams.getTargetSet().apps),
|
||||
Arrays.stream(rightBottomParams.getTargetSet().apps))
|
||||
|
||||
Reference in New Issue
Block a user