Add GroupedTaskView for gestures in staged split.
* Currently only works for portrait 50/50 split * Have gesture swipe animation flow use multiple TaskViewSimulators, one for each app in split * Added new APIs in shell to query for actively running tasks to determine if we're in split screen * Lots of UI polish needed during gesture * Launching into staged split after live tile ends not implemented yet. Bug: 181704764 Change-Id: Ib90e99e1e10b19121e8709385e1334b9380d6502
This commit is contained in:
parent
242c8c0b0f
commit
17c4b33db6
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<!-- NOTE! don't add dimensions for margins / paddings / sizes that change per orientation to this
|
||||||
|
file, they need to be loaded at runtime. -->
|
||||||
|
|
||||||
|
<!-- DOUBLE NOTE! Don't deviate IDs from task.xml since this layout acts as a "subclass" (read as
|
||||||
|
"bad code"). How can we use the view pool in RecentsView to use task.xml layout with using
|
||||||
|
GroupedTaskView.java class? Is that possible (while still keeping code in separate class) ? -->
|
||||||
|
|
||||||
|
<com.android.quickstep.views.GroupedTaskView
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:clipChildren="false"
|
||||||
|
android:defaultFocusHighlightEnabled="false"
|
||||||
|
android:focusable="true">
|
||||||
|
|
||||||
|
<com.android.quickstep.views.TaskThumbnailView
|
||||||
|
android:id="@+id/snapshot"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
<com.android.quickstep.views.TaskThumbnailView
|
||||||
|
android:id="@+id/bottomright_snapshot"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
|
<com.android.quickstep.views.IconView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="@dimen/task_thumbnail_icon_size"
|
||||||
|
android:layout_height="@dimen/task_thumbnail_icon_size"
|
||||||
|
android:focusable="false"
|
||||||
|
android:importantForAccessibility="no"/>
|
||||||
|
</com.android.quickstep.views.GroupedTaskView>
|
|
@ -63,7 +63,7 @@ public class RecentsActivityTest {
|
||||||
|
|
||||||
RunningTaskInfo placeholderTask = new RunningTaskInfo();
|
RunningTaskInfo placeholderTask = new RunningTaskInfo();
|
||||||
placeholderTask.taskId = 22;
|
placeholderTask.taskId = 22;
|
||||||
frv.showCurrentTask(placeholderTask);
|
frv.showCurrentTask(new RunningTaskInfo[]{placeholderTask});
|
||||||
doLayout(activity);
|
doLayout(activity);
|
||||||
|
|
||||||
ThumbnailData thumbnailData = new ThumbnailData();
|
ThumbnailData thumbnailData = new ThumbnailData();
|
||||||
|
|
|
@ -99,6 +99,7 @@ import com.android.quickstep.util.ActivityInitListener;
|
||||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||||
import com.android.quickstep.util.InputConsumerProxy;
|
import com.android.quickstep.util.InputConsumerProxy;
|
||||||
import com.android.quickstep.util.InputProxyHandlerFactory;
|
import com.android.quickstep.util.InputProxyHandlerFactory;
|
||||||
|
import com.android.quickstep.util.LauncherSplitScreenListener;
|
||||||
import com.android.quickstep.util.MotionPauseDetector;
|
import com.android.quickstep.util.MotionPauseDetector;
|
||||||
import com.android.quickstep.util.ProtoTracer;
|
import com.android.quickstep.util.ProtoTracer;
|
||||||
import com.android.quickstep.util.RecentsOrientedState;
|
import com.android.quickstep.util.RecentsOrientedState;
|
||||||
|
@ -106,6 +107,7 @@ import com.android.quickstep.util.RectFSpringAnim;
|
||||||
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
import com.android.quickstep.util.StaggeredWorkspaceAnim;
|
||||||
import com.android.quickstep.util.SurfaceTransactionApplier;
|
import com.android.quickstep.util.SurfaceTransactionApplier;
|
||||||
import com.android.quickstep.util.SwipePipToHomeAnimator;
|
import com.android.quickstep.util.SwipePipToHomeAnimator;
|
||||||
|
import com.android.quickstep.util.TaskViewSimulator;
|
||||||
import com.android.quickstep.util.TransformParams;
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
import com.android.quickstep.views.TaskView;
|
||||||
|
@ -222,7 +224,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
protected final TaskAnimationManager mTaskAnimationManager;
|
protected final TaskAnimationManager mTaskAnimationManager;
|
||||||
|
|
||||||
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
|
// Either RectFSpringAnim (if animating home) or ObjectAnimator (from mCurrentShift) otherwise
|
||||||
private RunningWindowAnim mRunningWindowAnim;
|
private RunningWindowAnim[] mRunningWindowAnim;
|
||||||
// Possible second animation running at the same time as mRunningWindowAnim
|
// Possible second animation running at the same time as mRunningWindowAnim
|
||||||
private Animator mParallelRunningAnim;
|
private Animator mParallelRunningAnim;
|
||||||
private boolean mIsMotionPaused;
|
private boolean mIsMotionPaused;
|
||||||
|
@ -253,6 +255,10 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
|
|
||||||
private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
|
private SwipePipToHomeAnimator mSwipePipToHomeAnimator;
|
||||||
protected boolean mIsSwipingPipToHome;
|
protected boolean mIsSwipingPipToHome;
|
||||||
|
// TODO(b/195473090) no split PIP for now, remove once we have more clarity
|
||||||
|
// can try to have RectFSpringAnim evaluate multiple rects at once
|
||||||
|
private final SwipePipToHomeAnimator[] mSwipePipToHomeAnimators =
|
||||||
|
new SwipePipToHomeAnimator[2];
|
||||||
|
|
||||||
// Interpolate RecentsView scale from start of quick switch scroll until this scroll threshold
|
// Interpolate RecentsView scale from start of quick switch scroll until this scroll threshold
|
||||||
private final float mQuickSwitchScaleScrollThreshold;
|
private final float mQuickSwitchScaleScrollThreshold;
|
||||||
|
@ -426,7 +432,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
// RecentsView never updates the display rotation until swipe-up, force update
|
// RecentsView never updates the display rotation until swipe-up, force update
|
||||||
// RecentsOrientedState before passing to TaskViewSimulator.
|
// RecentsOrientedState before passing to TaskViewSimulator.
|
||||||
mRecentsView.updateRecentsRotation();
|
mRecentsView.updateRecentsRotation();
|
||||||
mTaskViewSimulator.setOrientationState(mRecentsView.getPagedViewOrientedState());
|
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||||
|
.setOrientationState(mRecentsView.getPagedViewOrientedState()));
|
||||||
|
|
||||||
// If we've already ended the gesture and are going home, don't prepare recents UI,
|
// If we've already ended the gesture and are going home, don't prepare recents UI,
|
||||||
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
|
// as that will set the state as BACKGROUND_APP, overriding the animation to NORMAL.
|
||||||
|
@ -519,7 +526,21 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void notifyGestureAnimationStartToRecents() {
|
protected void notifyGestureAnimationStartToRecents() {
|
||||||
mRecentsView.onGestureAnimationStart(mGestureState.getRunningTask());
|
ActivityManager.RunningTaskInfo[] runningTasks;
|
||||||
|
if (mIsSwipeForStagedSplit) {
|
||||||
|
int[] splitTaskIds =
|
||||||
|
LauncherSplitScreenListener.INSTANCE.getNoCreate().getSplitTaskIds();
|
||||||
|
runningTasks = new ActivityManager.RunningTaskInfo[splitTaskIds.length];
|
||||||
|
for (int i = 0; i < splitTaskIds.length; i++) {
|
||||||
|
int taskId = splitTaskIds[i];
|
||||||
|
ActivityManager.RunningTaskInfo rti = new ActivityManager.RunningTaskInfo();
|
||||||
|
rti.taskId = taskId;
|
||||||
|
runningTasks[i] = rti;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
runningTasks = new ActivityManager.RunningTaskInfo[]{mGestureState.getRunningTask()};
|
||||||
|
}
|
||||||
|
mRecentsView.onGestureAnimationStart(runningTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void launcherFrameDrawn() {
|
private void launcherFrameDrawn() {
|
||||||
|
@ -606,15 +627,15 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
if (animate) {
|
if (animate) {
|
||||||
ValueAnimator reapplyWindowTransformAnim = ValueAnimator.ofFloat(0, 1);
|
ValueAnimator reapplyWindowTransformAnim = ValueAnimator.ofFloat(0, 1);
|
||||||
reapplyWindowTransformAnim.addUpdateListener(anim -> {
|
reapplyWindowTransformAnim.addUpdateListener(anim -> {
|
||||||
if (mRunningWindowAnim == null) {
|
if (mRunningWindowAnim == null || mRunningWindowAnim.length == 0) {
|
||||||
applyWindowTransform();
|
applyScrollAndTransform();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
reapplyWindowTransformAnim.setDuration(RECENTS_ATTACH_DURATION).start();
|
reapplyWindowTransformAnim.setDuration(RECENTS_ATTACH_DURATION).start();
|
||||||
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED,
|
mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED,
|
||||||
reapplyWindowTransformAnim::cancel);
|
reapplyWindowTransformAnim::cancel);
|
||||||
} else {
|
} else {
|
||||||
applyWindowTransform();
|
applyScrollAndTransform();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,7 +699,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSysUiFlags(mCurrentShift.value);
|
updateSysUiFlags(mCurrentShift.value);
|
||||||
applyWindowTransform();
|
applyScrollAndTransform();
|
||||||
|
|
||||||
updateLauncherTransitionProgress();
|
updateLauncherTransitionProgress();
|
||||||
}
|
}
|
||||||
|
@ -724,24 +745,23 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
@Override
|
@Override
|
||||||
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
public void onRecentsAnimationStart(RecentsAnimationController controller,
|
||||||
RecentsAnimationTargets targets) {
|
RecentsAnimationTargets targets) {
|
||||||
ActiveGestureLog.INSTANCE.addLog("startRecentsAnimationCallback", targets.apps.length);
|
super.onRecentsAnimationStart(controller, targets);
|
||||||
mRecentsAnimationController = controller;
|
mRecentsAnimationController = controller;
|
||||||
mRecentsAnimationTargets = targets;
|
mRecentsAnimationTargets = targets;
|
||||||
mTransformParams.setTargetSet(mRecentsAnimationTargets);
|
|
||||||
RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(
|
|
||||||
mGestureState.getRunningTaskId());
|
|
||||||
|
|
||||||
if (runningTaskTarget != null) {
|
|
||||||
mTaskViewSimulator.setPreview(runningTaskTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only initialize the device profile, if it has not been initialized before, as in some
|
// Only initialize the device profile, if it has not been initialized before, as in some
|
||||||
// configurations targets.homeContentInsets may not be correct.
|
// configurations targets.homeContentInsets may not be correct.
|
||||||
if (mActivity == null) {
|
if (mActivity == null) {
|
||||||
DeviceProfile dp = mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile();
|
RemoteAnimationTargetCompat primaryTaskTarget = targets.apps[0];
|
||||||
if (targets.minimizedHomeBounds != null && runningTaskTarget != null) {
|
// 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
|
||||||
|
.getOrientationState();
|
||||||
|
DeviceProfile dp = orientationState.getLauncherDeviceProfile();
|
||||||
|
if (targets.minimizedHomeBounds != null && primaryTaskTarget != null) {
|
||||||
Rect overviewStackBounds = mActivityInterface
|
Rect overviewStackBounds = mActivityInterface
|
||||||
.getOverviewWindowBounds(targets.minimizedHomeBounds, runningTaskTarget);
|
.getOverviewWindowBounds(targets.minimizedHomeBounds, primaryTaskTarget);
|
||||||
dp = dp.getMultiWindowProfile(mContext,
|
dp = dp.getMultiWindowProfile(mContext,
|
||||||
new WindowBounds(overviewStackBounds, targets.homeContentInsets));
|
new WindowBounds(overviewStackBounds, targets.homeContentInsets));
|
||||||
} else {
|
} else {
|
||||||
|
@ -751,7 +771,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
dp.updateInsets(targets.homeContentInsets);
|
dp.updateInsets(targets.homeContentInsets);
|
||||||
dp.updateIsSeascape(mContext);
|
dp.updateIsSeascape(mContext);
|
||||||
initTransitionEndpoints(dp);
|
initTransitionEndpoints(dp);
|
||||||
mTaskViewSimulator.getOrientationState().setMultiWindowMode(dp.isMultiWindowMode);
|
orientationState.setMultiWindowMode(dp.isMultiWindowMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify when the animation starts
|
// Notify when the animation starts
|
||||||
|
@ -869,9 +889,17 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
private void endRunningWindowAnim(boolean cancel) {
|
private void endRunningWindowAnim(boolean cancel) {
|
||||||
if (mRunningWindowAnim != null) {
|
if (mRunningWindowAnim != null) {
|
||||||
if (cancel) {
|
if (cancel) {
|
||||||
mRunningWindowAnim.cancel();
|
for (RunningWindowAnim r : mRunningWindowAnim) {
|
||||||
|
if (r != null) {
|
||||||
|
r.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mRunningWindowAnim.end();
|
for (RunningWindowAnim r : mRunningWindowAnim) {
|
||||||
|
if (r != null) {
|
||||||
|
r.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mParallelRunningAnim != null) {
|
if (mParallelRunningAnim != null) {
|
||||||
|
@ -1181,15 +1209,17 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
|
createHomeAnimationFactory(cookies, duration, isTranslucent, appCanEnterPip,
|
||||||
runningTaskTarget);
|
runningTaskTarget);
|
||||||
mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome() && appCanEnterPip;
|
mIsSwipingPipToHome = homeAnimFactory.supportSwipePipToHome() && appCanEnterPip;
|
||||||
final RectFSpringAnim windowAnim;
|
final RectFSpringAnim[] windowAnim;
|
||||||
if (mIsSwipingPipToHome) {
|
if (mIsSwipingPipToHome) {
|
||||||
mSwipePipToHomeAnimator = createWindowAnimationToPip(
|
mSwipePipToHomeAnimator = createWindowAnimationToPip(
|
||||||
homeAnimFactory, runningTaskTarget, start);
|
homeAnimFactory, runningTaskTarget, start);
|
||||||
windowAnim = mSwipePipToHomeAnimator;
|
mSwipePipToHomeAnimators[0] = mSwipePipToHomeAnimator;
|
||||||
|
windowAnim = mSwipePipToHomeAnimators;
|
||||||
} else {
|
} else {
|
||||||
mSwipePipToHomeAnimator = null;
|
mSwipePipToHomeAnimator = null;
|
||||||
windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
|
windowAnim = createWindowAnimationToHome(start, homeAnimFactory);
|
||||||
windowAnim.addAnimatorListener(new AnimationSuccessListener() {
|
|
||||||
|
windowAnim[0].addAnimatorListener(new AnimationSuccessListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationSuccess(Animator animator) {
|
public void onAnimationSuccess(Animator animator) {
|
||||||
if (mRecentsAnimationController == null) {
|
if (mRecentsAnimationController == null) {
|
||||||
|
@ -1203,15 +1233,22 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
windowAnim.start(mContext, velocityPxPerMs);
|
mRunningWindowAnim = new RunningWindowAnim[windowAnim.length];
|
||||||
mRunningWindowAnim = RunningWindowAnim.wrap(windowAnim);
|
for (int i = 0, windowAnimLength = windowAnim.length; i < windowAnimLength; i++) {
|
||||||
|
RectFSpringAnim windowAnimation = windowAnim[i];
|
||||||
|
if (windowAnimation == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
windowAnimation.start(mContext, velocityPxPerMs);
|
||||||
|
mRunningWindowAnim[i] = RunningWindowAnim.wrap(windowAnimation);
|
||||||
|
}
|
||||||
homeAnimFactory.setSwipeVelocity(velocityPxPerMs.y);
|
homeAnimFactory.setSwipeVelocity(velocityPxPerMs.y);
|
||||||
homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
|
homeAnimFactory.playAtomicAnimation(velocityPxPerMs.y);
|
||||||
mLauncherTransitionController = null;
|
mLauncherTransitionController = null;
|
||||||
|
|
||||||
if (mRecentsView != null) {
|
if (mRecentsView != null) {
|
||||||
mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget(),
|
mRecentsView.onPrepareGestureEndAnimation(null, mGestureState.getEndTarget(),
|
||||||
mTaskViewSimulator);
|
getRemoteTaskViewSimulators());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
AnimatorSet animatorSet = new AnimatorSet();
|
AnimatorSet animatorSet = new AnimatorSet();
|
||||||
|
@ -1253,11 +1290,12 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
animatorSet.play(windowAnim);
|
animatorSet.play(windowAnim);
|
||||||
if (mRecentsView != null) {
|
if (mRecentsView != null) {
|
||||||
mRecentsView.onPrepareGestureEndAnimation(
|
mRecentsView.onPrepareGestureEndAnimation(
|
||||||
animatorSet, mGestureState.getEndTarget(), mTaskViewSimulator);
|
animatorSet, mGestureState.getEndTarget(),
|
||||||
|
getRemoteTaskViewSimulators());
|
||||||
}
|
}
|
||||||
animatorSet.setDuration(duration).setInterpolator(interpolator);
|
animatorSet.setDuration(duration).setInterpolator(interpolator);
|
||||||
animatorSet.start();
|
animatorSet.start();
|
||||||
mRunningWindowAnim = RunningWindowAnim.wrap(animatorSet);
|
mRunningWindowAnim = new RunningWindowAnim[]{RunningWindowAnim.wrap(animatorSet)};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1272,16 +1310,21 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO(b/195473090) handle multiple task simulators (if needed) for PIP
|
||||||
|
*/
|
||||||
private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
|
private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory,
|
||||||
RemoteAnimationTargetCompat runningTaskTarget, float startProgress) {
|
RemoteAnimationTargetCompat runningTaskTarget, float startProgress) {
|
||||||
// Directly animate the app to PiP (picture-in-picture) mode
|
// Directly animate the app to PiP (picture-in-picture) mode
|
||||||
final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask();
|
final ActivityManager.RunningTaskInfo taskInfo = mGestureState.getRunningTask();
|
||||||
final RecentsOrientedState orientationState = mTaskViewSimulator.getOrientationState();
|
final RecentsOrientedState orientationState = mRemoteTargetHandles[0].mTaskViewSimulator
|
||||||
|
.getOrientationState();
|
||||||
final int windowRotation = calculateWindowRotation(runningTaskTarget, orientationState);
|
final int windowRotation = calculateWindowRotation(runningTaskTarget, orientationState);
|
||||||
final int homeRotation = orientationState.getRecentsActivityRotation();
|
final int homeRotation = orientationState.getRecentsActivityRotation();
|
||||||
|
|
||||||
final Matrix homeToWindowPositionMap = new Matrix();
|
final Matrix homeToWindowPositionMap = new Matrix();
|
||||||
final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
|
final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap,
|
||||||
|
startProgress)[0];
|
||||||
// Move the startRect to Launcher space as floatingIconView runs in Launcher
|
// Move the startRect to Launcher space as floatingIconView runs in Launcher
|
||||||
final Matrix windowToHomePositionMap = new Matrix();
|
final Matrix windowToHomePositionMap = new Matrix();
|
||||||
homeToWindowPositionMap.invert(windowToHomePositionMap);
|
homeToWindowPositionMap.invert(windowToHomePositionMap);
|
||||||
|
@ -1310,7 +1353,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
// is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
|
// is not ROTATION_0 (which implies the rotation is turned on in launcher settings).
|
||||||
if (homeRotation == ROTATION_0
|
if (homeRotation == ROTATION_0
|
||||||
&& (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) {
|
&& (windowRotation == ROTATION_90 || windowRotation == ROTATION_270)) {
|
||||||
builder.setFromRotation(mTaskViewSimulator, windowRotation,
|
builder.setFromRotation(mRemoteTargetHandles[0].mTaskViewSimulator, windowRotation,
|
||||||
taskInfo.displayCutoutInsets);
|
taskInfo.displayCutoutInsets);
|
||||||
}
|
}
|
||||||
final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build();
|
final SwipePipToHomeAnimator swipePipToHomeAnimator = builder.build();
|
||||||
|
@ -1340,7 +1383,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
|
mGestureState.setState(STATE_END_TARGET_ANIMATION_FINISHED);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setupWindowAnimation(swipePipToHomeAnimator);
|
setupWindowAnimation(new RectFSpringAnim[]{swipePipToHomeAnimator});
|
||||||
return swipePipToHomeAnimator;
|
return swipePipToHomeAnimator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1367,19 +1410,19 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
* @param homeAnimationFactory The home animation factory.
|
* @param homeAnimationFactory The home animation factory.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
protected RectFSpringAnim[] createWindowAnimationToHome(float startProgress,
|
||||||
HomeAnimationFactory homeAnimationFactory) {
|
HomeAnimationFactory homeAnimationFactory) {
|
||||||
RectFSpringAnim anim =
|
RectFSpringAnim[] anim =
|
||||||
super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
|
super.createWindowAnimationToHome(startProgress, homeAnimationFactory);
|
||||||
setupWindowAnimation(anim);
|
setupWindowAnimation(anim);
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupWindowAnimation(RectFSpringAnim anim) {
|
private void setupWindowAnimation(RectFSpringAnim[] anims) {
|
||||||
anim.addOnUpdateListener((v, r, p) -> {
|
anims[0].addOnUpdateListener((v, r, p) -> {
|
||||||
updateSysUiFlags(Math.max(p, mCurrentShift.value));
|
updateSysUiFlags(Math.max(p, mCurrentShift.value));
|
||||||
});
|
});
|
||||||
anim.addAnimatorListener(new AnimationSuccessListener() {
|
anims[0].addAnimatorListener(new AnimationSuccessListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onAnimationSuccess(Animator animator) {
|
public void onAnimationSuccess(Animator animator) {
|
||||||
if (mRecentsView != null) {
|
if (mRecentsView != null) {
|
||||||
|
@ -1391,7 +1434,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (mRecentsAnimationTargets != null) {
|
if (mRecentsAnimationTargets != null) {
|
||||||
mRecentsAnimationTargets.addReleaseCheck(anim);
|
mRecentsAnimationTargets.addReleaseCheck(anims[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1639,7 +1682,7 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
* if applicable. This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
|
* if applicable. This should happen before {@link #finishRecentsControllerToHome(Runnable)}.
|
||||||
*/
|
*/
|
||||||
private void maybeFinishSwipePipToHome() {
|
private void maybeFinishSwipePipToHome() {
|
||||||
if (mIsSwipingPipToHome && mSwipePipToHomeAnimator != null) {
|
if (mIsSwipingPipToHome && mSwipePipToHomeAnimators[0] != null) {
|
||||||
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
|
SystemUiProxy.INSTANCE.get(mContext).stopSwipePipToHome(
|
||||||
mSwipePipToHomeAnimator.getComponentName(),
|
mSwipePipToHomeAnimator.getComponentName(),
|
||||||
mSwipePipToHomeAnimator.getDestinationBounds(),
|
mSwipePipToHomeAnimator.getDestinationBounds(),
|
||||||
|
@ -1680,8 +1723,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
* depend on proper class initialization.
|
* depend on proper class initialization.
|
||||||
*/
|
*/
|
||||||
protected void initAfterSubclassConstructor() {
|
protected void initAfterSubclassConstructor() {
|
||||||
initTransitionEndpoints(
|
initTransitionEndpoints(mRemoteTargetHandles[0].mTaskViewSimulator
|
||||||
mTaskViewSimulator.getOrientationState().getLauncherDeviceProfile());
|
.getOrientationState().getLauncherDeviceProfile());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void performHapticFeedback() {
|
protected void performHapticFeedback() {
|
||||||
|
@ -1698,7 +1741,8 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
|
|
||||||
protected void linkRecentsViewScroll() {
|
protected void linkRecentsViewScroll() {
|
||||||
SurfaceTransactionApplier.create(mRecentsView, applier -> {
|
SurfaceTransactionApplier.create(mRecentsView, applier -> {
|
||||||
mTransformParams.setSyncTransactionApplier(applier);
|
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||||
|
.setSyncTransactionApplier(applier));
|
||||||
runOnRecentsAnimationStart(() ->
|
runOnRecentsAnimationStart(() ->
|
||||||
mRecentsAnimationTargets.addReleaseCheck(applier));
|
mRecentsAnimationTargets.addReleaseCheck(applier));
|
||||||
});
|
});
|
||||||
|
@ -1824,19 +1868,25 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
/**
|
/**
|
||||||
* Applies the transform on the recents animation
|
* Applies the transform on the recents animation
|
||||||
*/
|
*/
|
||||||
protected void applyWindowTransform() {
|
protected void applyScrollAndTransform() {
|
||||||
if (mWindowTransitionController != null) {
|
|
||||||
mWindowTransitionController.setProgress(
|
|
||||||
Math.max(mCurrentShift.value, getScaleProgressDueToScroll()),
|
|
||||||
mDragLengthFactor);
|
|
||||||
}
|
|
||||||
// No need to apply any transform if there is ongoing swipe-pip-to-home animator since
|
// No need to apply any transform if there is ongoing swipe-pip-to-home animator since
|
||||||
// that animator handles the leash solely.
|
// that animator handles the leash solely.
|
||||||
if (mRecentsAnimationTargets != null && !mIsSwipingPipToHome) {
|
boolean notSwipingPipToHome = mRecentsAnimationTargets != null && !mIsSwipingPipToHome;
|
||||||
if (mRecentsViewScrollLinked && mRecentsView != null) {
|
boolean setRecentsScroll = mRecentsViewScrollLinked && mRecentsView != null;
|
||||||
mTaskViewSimulator.setScroll(mRecentsView.getScrollOffset());
|
for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
|
||||||
|
AnimatorControllerWithResistance playbackController = remoteHandle.mPlaybackController;
|
||||||
|
if (playbackController != null) {
|
||||||
|
playbackController.setProgress(Math.max(mCurrentShift.value,
|
||||||
|
getScaleProgressDueToScroll()), mDragLengthFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (notSwipingPipToHome) {
|
||||||
|
TaskViewSimulator taskViewSimulator = remoteHandle.mTaskViewSimulator;
|
||||||
|
if (setRecentsScroll) {
|
||||||
|
taskViewSimulator.setScroll(mRecentsView.getScrollOffset());
|
||||||
|
}
|
||||||
|
taskViewSimulator.apply(remoteHandle.mTransformParams);
|
||||||
}
|
}
|
||||||
mTaskViewSimulator.apply(mTransformParams);
|
|
||||||
}
|
}
|
||||||
ProtoTracer.INSTANCE.get(mContext).scheduleFrameUpdate();
|
ProtoTracer.INSTANCE.get(mContext).scheduleFrameUpdate();
|
||||||
}
|
}
|
||||||
|
@ -1891,7 +1941,6 @@ public abstract class AbsSwipeUpHandler<T extends StatefulActivity<S>,
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Factory {
|
public interface Factory {
|
||||||
|
|
||||||
AbsSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs);
|
AbsSwipeUpHandler newHandler(GestureState gestureState, long touchTimeMs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ import com.android.launcher3.statehandlers.DepthController;
|
||||||
import com.android.launcher3.statemanager.BaseState;
|
import com.android.launcher3.statemanager.BaseState;
|
||||||
import com.android.launcher3.statemanager.StatefulActivity;
|
import com.android.launcher3.statemanager.StatefulActivity;
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||||
|
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||||
import com.android.launcher3.util.WindowBounds;
|
import com.android.launcher3.util.WindowBounds;
|
||||||
import com.android.launcher3.views.ScrimView;
|
import com.android.launcher3.views.ScrimView;
|
||||||
import com.android.quickstep.SysUINavigationMode.Mode;
|
import com.android.quickstep.SysUINavigationMode.Mode;
|
||||||
|
@ -200,11 +201,37 @@ public abstract class BaseActivityInterface<STATE_TYPE extends BaseState<STATE_T
|
||||||
recentsView.switchToScreenshot(thumbnailData, runnable);
|
recentsView.switchToScreenshot(thumbnailData, runnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the task size in {@param outRect} taking split screened windows into account.
|
||||||
|
* We assume combined height of both tasks will be same as one normal task, then we'll modify
|
||||||
|
* the task height/width based on the ratio of task screen space bounds from
|
||||||
|
* {@param splitInfo}
|
||||||
|
*
|
||||||
|
* @param desiredStageBounds whether task size for top/left or bottom/right needs to be computed
|
||||||
|
*/
|
||||||
|
public final void calculateStagedSplitTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
||||||
|
SplitConfigurationOptions.StagedSplitBounds splitInfo,
|
||||||
|
@SplitConfigurationOptions.StagePosition int desiredStageBounds) {
|
||||||
|
calculateTaskSize(context, dp, outRect);
|
||||||
|
|
||||||
|
// TODO(b/181705607) Change for landscape vs portrait
|
||||||
|
float totalHeight = splitInfo.mLeftTopBounds.height()
|
||||||
|
+ splitInfo.mRightBottomBounds.height()
|
||||||
|
+ splitInfo.mDividerBounds.height() / 2f;
|
||||||
|
float topTaskPercent = splitInfo.mLeftTopBounds.height() / totalHeight;
|
||||||
|
if (desiredStageBounds == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) {
|
||||||
|
float diff = outRect.height() * (1f - topTaskPercent);
|
||||||
|
outRect.bottom -= diff;
|
||||||
|
} else {
|
||||||
|
float diff = outRect.height() * topTaskPercent;
|
||||||
|
outRect.top += diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the taskView size for the provided device configuration.
|
* Calculates the taskView size for the provided device configuration.
|
||||||
*/
|
*/
|
||||||
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect,
|
public final void calculateTaskSize(Context context, DeviceProfile dp, Rect outRect) {
|
||||||
PagedOrientationHandler orientedState) {
|
|
||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
if (dp.overviewShowAsGrid) {
|
if (dp.overviewShowAsGrid) {
|
||||||
Rect gridRect = new Rect();
|
Rect gridRect = new Rect();
|
||||||
|
|
|
@ -57,7 +57,7 @@ public final class FallbackActivityInterface extends
|
||||||
@Override
|
@Override
|
||||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
|
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
|
||||||
PagedOrientationHandler orientationHandler) {
|
PagedOrientationHandler orientationHandler) {
|
||||||
calculateTaskSize(context, dp, outRect, orientationHandler);
|
calculateTaskSize(context, dp, outRect);
|
||||||
if (dp.isVerticalBarLayout()
|
if (dp.isVerticalBarLayout()
|
||||||
&& SysUINavigationMode.INSTANCE.get(context).getMode() != NO_BUTTON) {
|
&& SysUINavigationMode.INSTANCE.get(context).getMode() != NO_BUTTON) {
|
||||||
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
|
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
|
||||||
|
|
|
@ -28,6 +28,7 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACT
|
||||||
|
|
||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.ActivityManager;
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -101,7 +102,9 @@ public class FallbackSwipeHandler extends
|
||||||
|
|
||||||
mRunningOverHome = ActivityManagerWrapper.isHomeTask(mGestureState.getRunningTask());
|
mRunningOverHome = ActivityManagerWrapper.isHomeTask(mGestureState.getRunningTask());
|
||||||
if (mRunningOverHome) {
|
if (mRunningOverHome) {
|
||||||
mTransformParams.setHomeBuilderProxy(this::updateHomeActivityTransformDuringSwipeUp);
|
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||||
|
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||||
|
FallbackSwipeHandler.this::updateHomeActivityTransformDuringSwipeUp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +112,8 @@ public class FallbackSwipeHandler extends
|
||||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||||
super.initTransitionEndpoints(dp);
|
super.initTransitionEndpoints(dp);
|
||||||
if (mRunningOverHome) {
|
if (mRunningOverHome) {
|
||||||
mMaxLauncherScale = 1 / mTaskViewSimulator.getFullScreenScale();
|
// Full screen scale should be independent of remote target handle
|
||||||
|
mMaxLauncherScale = 1 / mRemoteTargetHandles[0].mTaskViewSimulator.getFullScreenScale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +178,8 @@ public class FallbackSwipeHandler extends
|
||||||
protected void notifyGestureAnimationStartToRecents() {
|
protected void notifyGestureAnimationStartToRecents() {
|
||||||
if (mRunningOverHome) {
|
if (mRunningOverHome) {
|
||||||
if (SysUINavigationMode.getMode(mContext).hasGestures) {
|
if (SysUINavigationMode.getMode(mContext).hasGestures) {
|
||||||
mRecentsView.onGestureAnimationStartOnHome(mGestureState.getRunningTask());
|
mRecentsView.onGestureAnimationStartOnHome(
|
||||||
|
new ActivityManager.RunningTaskInfo[]{mGestureState.getRunningTask()});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
super.notifyGestureAnimationStartToRecents();
|
super.notifyGestureAnimationStartToRecents();
|
||||||
|
@ -202,19 +207,24 @@ public class FallbackSwipeHandler extends
|
||||||
mHomeAlpha = new AnimatedFloat();
|
mHomeAlpha = new AnimatedFloat();
|
||||||
mHomeAlpha.value = Utilities.boundToRange(1 - mCurrentShift.value, 0, 1);
|
mHomeAlpha.value = Utilities.boundToRange(1 - mCurrentShift.value, 0, 1);
|
||||||
mVerticalShiftForScale.value = mCurrentShift.value;
|
mVerticalShiftForScale.value = mCurrentShift.value;
|
||||||
mTransformParams.setHomeBuilderProxy(
|
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||||
this::updateHomeActivityTransformDuringHomeAnim);
|
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||||
|
FallbackHomeAnimationFactory.this
|
||||||
|
::updateHomeActivityTransformDuringHomeAnim));
|
||||||
} else {
|
} else {
|
||||||
mHomeAlpha = new AnimatedFloat(this::updateHomeAlpha);
|
mHomeAlpha = new AnimatedFloat(this::updateHomeAlpha);
|
||||||
mHomeAlpha.value = 0;
|
mHomeAlpha.value = 0;
|
||||||
|
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||||
mHomeAlphaParams.setHomeBuilderProxy(
|
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||||
this::updateHomeActivityTransformDuringHomeAnim);
|
FallbackHomeAnimationFactory.this
|
||||||
|
::updateHomeActivityTransformDuringHomeAnim));
|
||||||
}
|
}
|
||||||
|
|
||||||
mRecentsAlpha.value = 1;
|
mRecentsAlpha.value = 1;
|
||||||
mTransformParams.setBaseBuilderProxy(
|
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||||
this::updateRecentsActivityTransformDuringHomeAnim);
|
remoteTargetHandle.mTransformParams.setHomeBuilderProxy(
|
||||||
|
FallbackHomeAnimationFactory.this
|
||||||
|
::updateRecentsActivityTransformDuringHomeAnim));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
|
|
|
@ -71,7 +71,7 @@ public final class LauncherActivityInterface extends
|
||||||
@Override
|
@Override
|
||||||
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
|
public int getSwipeUpDestinationAndLength(DeviceProfile dp, Context context, Rect outRect,
|
||||||
PagedOrientationHandler orientationHandler) {
|
PagedOrientationHandler orientationHandler) {
|
||||||
calculateTaskSize(context, dp, outRect, orientationHandler);
|
calculateTaskSize(context, dp, outRect);
|
||||||
if (dp.isVerticalBarLayout() && SysUINavigationMode.getMode(context) != Mode.NO_BUTTON) {
|
if (dp.isVerticalBarLayout() && SysUINavigationMode.getMode(context) != Mode.NO_BUTTON) {
|
||||||
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
|
return dp.isSeascape() ? outRect.left : (dp.widthPx - outRect.right);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class LauncherSwipeHandlerV2 extends
|
||||||
mActivity.setHintUserWillBeActive();
|
mActivity.setHintUserWillBeActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!canUseWorkspaceView || appCanEnterPip) {
|
if (!canUseWorkspaceView || appCanEnterPip || mIsSwipeForStagedSplit) {
|
||||||
return new LauncherHomeAnimationFactory();
|
return new LauncherHomeAnimationFactory();
|
||||||
}
|
}
|
||||||
if (workspaceView instanceof LauncherAppWidgetHostView) {
|
if (workspaceView instanceof LauncherAppWidgetHostView) {
|
||||||
|
@ -181,14 +181,16 @@ public class LauncherSwipeHandlerV2 extends
|
||||||
final float floatingWidgetAlpha = isTargetTranslucent ? 0 : 1;
|
final float floatingWidgetAlpha = isTargetTranslucent ? 0 : 1;
|
||||||
RectF backgroundLocation = new RectF();
|
RectF backgroundLocation = new RectF();
|
||||||
Rect crop = new Rect();
|
Rect crop = new Rect();
|
||||||
mTaskViewSimulator.getCurrentCropRect().roundOut(crop);
|
// 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);
|
||||||
Size windowSize = new Size(crop.width(), crop.height());
|
Size windowSize = new Size(crop.width(), crop.height());
|
||||||
int fallbackBackgroundColor =
|
int fallbackBackgroundColor =
|
||||||
FloatingWidgetView.getDefaultBackgroundColor(mContext, runningTaskTarget);
|
FloatingWidgetView.getDefaultBackgroundColor(mContext, runningTaskTarget);
|
||||||
FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
|
FloatingWidgetView floatingWidgetView = FloatingWidgetView.getFloatingWidgetView(mActivity,
|
||||||
hostView, backgroundLocation, windowSize,
|
hostView, backgroundLocation, windowSize,
|
||||||
mTaskViewSimulator.getCurrentCornerRadius(), isTargetTranslucent,
|
mRemoteTargetHandles[0].mTaskViewSimulator.getCurrentCornerRadius(),
|
||||||
fallbackBackgroundColor);
|
isTargetTranslucent, fallbackBackgroundColor);
|
||||||
|
|
||||||
return new FloatingViewHomeAnimationFactory(floatingWidgetView) {
|
return new FloatingViewHomeAnimationFactory(floatingWidgetView) {
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||||
|
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME;
|
||||||
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
|
@ -30,6 +31,7 @@ import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
|
import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,8 +95,16 @@ public class RecentsAnimationCallbacks implements
|
||||||
RemoteAnimationTargetCompat[] appTargets,
|
RemoteAnimationTargetCompat[] appTargets,
|
||||||
RemoteAnimationTargetCompat[] wallpaperTargets,
|
RemoteAnimationTargetCompat[] wallpaperTargets,
|
||||||
Rect homeContentInsets, Rect minimizedHomeBounds) {
|
Rect homeContentInsets, Rect minimizedHomeBounds) {
|
||||||
|
// Convert appTargets to type RemoteAnimationTarget for all apps except Home app
|
||||||
|
RemoteAnimationTarget[] nonHomeApps = Arrays.stream(appTargets)
|
||||||
|
.filter(remoteAnimationTarget ->
|
||||||
|
remoteAnimationTarget.activityType != ACTIVITY_TYPE_HOME)
|
||||||
|
.map(RemoteAnimationTargetCompat::unwrap)
|
||||||
|
.toArray(RemoteAnimationTarget[]::new);
|
||||||
|
|
||||||
RemoteAnimationTarget[] nonAppTargets =
|
RemoteAnimationTarget[] nonAppTargets =
|
||||||
mSystemUiProxy.onGoingToRecentsLegacy(mCancelled);
|
mSystemUiProxy.onGoingToRecentsLegacy(mCancelled, nonHomeApps);
|
||||||
|
|
||||||
RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
|
RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets,
|
||||||
wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
|
wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets),
|
||||||
homeContentInsets, minimizedHomeBounds);
|
homeContentInsets, minimizedHomeBounds);
|
||||||
|
|
|
@ -77,8 +77,12 @@ public class RemoteAnimationTargets {
|
||||||
* Gets the navigation bar remote animation target if exists.
|
* Gets the navigation bar remote animation target if exists.
|
||||||
*/
|
*/
|
||||||
public RemoteAnimationTargetCompat getNavBarRemoteAnimationTarget() {
|
public RemoteAnimationTargetCompat getNavBarRemoteAnimationTarget() {
|
||||||
|
return getNonAppTargetOfType(TYPE_NAVIGATION_BAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteAnimationTargetCompat getNonAppTargetOfType(int type) {
|
||||||
for (RemoteAnimationTargetCompat target : nonApps) {
|
for (RemoteAnimationTargetCompat target : nonApps) {
|
||||||
if (target.windowType == TYPE_NAVIGATION_BAR) {
|
if (target.windowType == type) {
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package com.android.quickstep;
|
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.ACCEL_1_5;
|
||||||
import static com.android.launcher3.anim.Interpolators.LINEAR;
|
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.launcher3.config.FeatureFlags.PROTOTYPE_APP_CLOSE;
|
||||||
|
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
@ -36,8 +40,11 @@ import com.android.launcher3.anim.AnimationSuccessListener;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
import com.android.launcher3.touch.PagedOrientationHandler;
|
import com.android.launcher3.touch.PagedOrientationHandler;
|
||||||
|
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||||
|
import com.android.quickstep.util.ActiveGestureLog;
|
||||||
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
import com.android.quickstep.util.AnimatorControllerWithResistance;
|
||||||
import com.android.quickstep.util.AppCloseConfig;
|
import com.android.quickstep.util.AppCloseConfig;
|
||||||
|
import com.android.quickstep.util.LauncherSplitScreenListener;
|
||||||
import com.android.quickstep.util.RectFSpringAnim;
|
import com.android.quickstep.util.RectFSpringAnim;
|
||||||
import com.android.quickstep.util.RectFSpringAnim2;
|
import com.android.quickstep.util.RectFSpringAnim2;
|
||||||
import com.android.quickstep.util.TaskViewSimulator;
|
import com.android.quickstep.util.TaskViewSimulator;
|
||||||
|
@ -46,7 +53,11 @@ import com.android.quickstep.util.TransformParams.BuilderProxy;
|
||||||
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
|
import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder;
|
||||||
|
|
||||||
public abstract class SwipeUpAnimationLogic {
|
import java.util.Arrays;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public abstract class SwipeUpAnimationLogic implements
|
||||||
|
RecentsAnimationCallbacks.RecentsAnimationListener{
|
||||||
|
|
||||||
protected static final Rect TEMP_RECT = new Rect();
|
protected static final Rect TEMP_RECT = new Rect();
|
||||||
|
|
||||||
|
@ -55,9 +66,9 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
protected final Context mContext;
|
protected final Context mContext;
|
||||||
protected final RecentsAnimationDeviceState mDeviceState;
|
protected final RecentsAnimationDeviceState mDeviceState;
|
||||||
protected final GestureState mGestureState;
|
protected final GestureState mGestureState;
|
||||||
protected final TaskViewSimulator mTaskViewSimulator;
|
|
||||||
|
|
||||||
protected final TransformParams mTransformParams;
|
protected final RemoteTargetHandle[] mRemoteTargetHandles;
|
||||||
|
protected SplitConfigurationOptions.StagedSplitBounds mStagedSplitBounds;
|
||||||
|
|
||||||
// Shift in the range of [0, 1].
|
// Shift in the range of [0, 1].
|
||||||
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
|
// 0 => preview snapShot is completely visible, and hotseat is completely translated down
|
||||||
|
@ -70,37 +81,56 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
// How much further we can drag past recents, as a factor of mTransitionDragLength.
|
// How much further we can drag past recents, as a factor of mTransitionDragLength.
|
||||||
protected float mDragLengthFactor = 1;
|
protected float mDragLengthFactor = 1;
|
||||||
|
|
||||||
protected AnimatorControllerWithResistance mWindowTransitionController;
|
protected boolean mIsSwipeForStagedSplit;
|
||||||
|
|
||||||
public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
|
public SwipeUpAnimationLogic(Context context, RecentsAnimationDeviceState deviceState,
|
||||||
GestureState gestureState, TransformParams transformParams) {
|
GestureState gestureState, TransformParams transformParams) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mDeviceState = deviceState;
|
mDeviceState = deviceState;
|
||||||
mGestureState = gestureState;
|
mGestureState = gestureState;
|
||||||
mTaskViewSimulator = new TaskViewSimulator(context, gestureState.getActivityInterface());
|
|
||||||
mTransformParams = transformParams;
|
|
||||||
|
|
||||||
mTaskViewSimulator.getOrientationState().update(
|
mIsSwipeForStagedSplit = ENABLE_SPLIT_SELECT.get() &&
|
||||||
|
LauncherSplitScreenListener.INSTANCE.getNoCreate().getSplitTaskIds().length > 1;
|
||||||
|
|
||||||
|
TaskViewSimulator primaryTVS = new TaskViewSimulator(context,
|
||||||
|
gestureState.getActivityInterface());
|
||||||
|
primaryTVS.getOrientationState().update(
|
||||||
mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
|
mDeviceState.getRotationTouchHelper().getCurrentActiveRotation(),
|
||||||
mDeviceState.getRotationTouchHelper().getDisplayRotation());
|
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());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initTransitionEndpoints(DeviceProfile dp) {
|
protected void initTransitionEndpoints(DeviceProfile dp) {
|
||||||
mDp = dp;
|
mDp = dp;
|
||||||
|
|
||||||
mTaskViewSimulator.setDp(dp);
|
|
||||||
mTransitionDragLength = mGestureState.getActivityInterface().getSwipeUpDestinationAndLength(
|
mTransitionDragLength = mGestureState.getActivityInterface().getSwipeUpDestinationAndLength(
|
||||||
dp, mContext, TEMP_RECT,
|
dp, mContext, TEMP_RECT, mRemoteTargetHandles[0].mTaskViewSimulator
|
||||||
mTaskViewSimulator.getOrientationState().getOrientationHandler());
|
.getOrientationState().getOrientationHandler());
|
||||||
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
mDragLengthFactor = (float) dp.heightPx / mTransitionDragLength;
|
||||||
|
|
||||||
PendingAnimation pa = new PendingAnimation(mTransitionDragLength * 2);
|
for (RemoteTargetHandle remoteHandle : mRemoteTargetHandles) {
|
||||||
mTaskViewSimulator.addAppToOverviewAnim(pa, LINEAR);
|
PendingAnimation pendingAnimation = new PendingAnimation(mTransitionDragLength * 2);
|
||||||
AnimatorPlaybackController normalController = pa.createPlaybackController();
|
TaskViewSimulator taskViewSimulator = remoteHandle.mTaskViewSimulator;
|
||||||
mWindowTransitionController = AnimatorControllerWithResistance.createForRecents(
|
taskViewSimulator.setDp(dp);
|
||||||
normalController, mContext, mTaskViewSimulator.getOrientationState(),
|
taskViewSimulator.addAppToOverviewAnim(pendingAnimation, LINEAR);
|
||||||
mDp, mTaskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
|
AnimatorPlaybackController playbackController =
|
||||||
mTaskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE);
|
pendingAnimation.createPlaybackController();
|
||||||
|
|
||||||
|
remoteHandle.mPlaybackController = AnimatorControllerWithResistance.createForRecents(
|
||||||
|
playbackController, mContext, taskViewSimulator.getOrientationState(),
|
||||||
|
mDp, taskViewSimulator.recentsViewScale, AnimatedFloat.VALUE,
|
||||||
|
taskViewSimulator.recentsViewSecondaryTranslation, AnimatedFloat.VALUE
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
|
@ -125,7 +155,9 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
public abstract void updateFinalShift();
|
public abstract void updateFinalShift();
|
||||||
|
|
||||||
protected PagedOrientationHandler getOrientationHandler() {
|
protected PagedOrientationHandler getOrientationHandler() {
|
||||||
return mTaskViewSimulator.getOrientationState().getOrientationHandler();
|
// OrientationHandler should be independent of remote target, can directly take one
|
||||||
|
return mRemoteTargetHandles[0].mTaskViewSimulator
|
||||||
|
.getOrientationState().getOrientationHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract class HomeAnimationFactory {
|
protected abstract class HomeAnimationFactory {
|
||||||
|
@ -207,31 +239,102 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
* @param startProgress The progress of {@link #mCurrentShift} to start thw window from.
|
* @param startProgress The progress of {@link #mCurrentShift} to start thw window from.
|
||||||
* @return {@link RectF} represents the bounds as starting point in window space.
|
* @return {@link RectF} represents the bounds as starting point in window space.
|
||||||
*/
|
*/
|
||||||
protected RectF updateProgressForStartRect(Matrix outMatrix, float startProgress) {
|
protected RectF[] updateProgressForStartRect(Matrix outMatrix, float startProgress) {
|
||||||
mCurrentShift.updateValue(startProgress);
|
mCurrentShift.updateValue(startProgress);
|
||||||
mTaskViewSimulator.apply(mTransformParams.setProgress(startProgress));
|
RectF[] startRects = new RectF[mRemoteTargetHandles.length];
|
||||||
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
|
for (int i = 0, mRemoteTargetHandlesLength = mRemoteTargetHandles.length;
|
||||||
|
i < mRemoteTargetHandlesLength; i++) {
|
||||||
|
RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
|
||||||
|
TaskViewSimulator tvs = remoteHandle.mTaskViewSimulator;
|
||||||
|
tvs.apply(remoteHandle.mTransformParams.setProgress(startProgress));
|
||||||
|
|
||||||
mTaskViewSimulator.applyWindowToHomeRotation(outMatrix);
|
startRects[i] = new RectF(tvs.getCurrentCropRect());
|
||||||
|
tvs.applyWindowToHomeRotation(outMatrix);
|
||||||
final RectF startRect = new RectF(cropRectF);
|
tvs.getCurrentMatrix().mapRect(startRects[i]);
|
||||||
mTaskViewSimulator.getCurrentMatrix().mapRect(startRect);
|
}
|
||||||
return startRect;
|
return startRects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Helper to avoid writing some for-loops to iterate over {@link #mRemoteTargetHandles} */
|
||||||
|
protected void runActionOnRemoteHandles(Consumer<RemoteTargetHandle> consumer) {
|
||||||
|
for (RemoteTargetHandle handle : mRemoteTargetHandles) {
|
||||||
|
consumer.accept(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return only the TaskViewSimulators from {@link #mRemoteTargetHandles} */
|
||||||
|
protected TaskViewSimulator[] getRemoteTaskViewSimulators() {
|
||||||
|
return Arrays.stream(mRemoteTargetHandles)
|
||||||
|
.map(remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator)
|
||||||
|
.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;
|
||||||
|
|
||||||
|
if (!mIsSwipeForStagedSplit) {
|
||||||
|
primaryTaskTarget = targets.findTask(mGestureState.getRunningTaskId());
|
||||||
|
mRemoteTargetHandles[0].mTransformParams.setTargetSet(targets);
|
||||||
|
|
||||||
|
if (primaryTaskTarget != null) {
|
||||||
|
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We're in staged split
|
||||||
|
primaryTaskTarget = targets.apps[0];
|
||||||
|
secondaryTaskTarget = targets.apps[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.
|
* 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.
|
* @param startProgress The progress of {@link #mCurrentShift} to start the window from.
|
||||||
* @param homeAnimationFactory The home animation factory.
|
* @param homeAnimationFactory The home animation factory.
|
||||||
*/
|
*/
|
||||||
protected RectFSpringAnim createWindowAnimationToHome(float startProgress,
|
protected RectFSpringAnim[] createWindowAnimationToHome(float startProgress,
|
||||||
HomeAnimationFactory homeAnimationFactory) {
|
HomeAnimationFactory homeAnimationFactory) {
|
||||||
|
// TODO(b/195473584) compute separate end targets for different staged split
|
||||||
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
final RectF targetRect = homeAnimationFactory.getWindowTargetRect();
|
||||||
|
RectFSpringAnim[] out = new RectFSpringAnim[mRemoteTargetHandles.length];
|
||||||
Matrix homeToWindowPositionMap = new Matrix();
|
Matrix homeToWindowPositionMap = new Matrix();
|
||||||
final RectF startRect = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
|
RectF[] startRects = updateProgressForStartRect(homeToWindowPositionMap, startProgress);
|
||||||
RectF cropRectF = new RectF(mTaskViewSimulator.getCurrentCropRect());
|
for (int i = 0, mRemoteTargetHandlesLength = mRemoteTargetHandles.length;
|
||||||
|
i < mRemoteTargetHandlesLength; i++) {
|
||||||
|
RemoteTargetHandle remoteHandle = mRemoteTargetHandles[i];
|
||||||
|
out[i] = getWindowAnimationToHomeInternal(homeAnimationFactory,
|
||||||
|
targetRect, remoteHandle.mTransformParams, remoteHandle.mTaskViewSimulator,
|
||||||
|
startRects[i], homeToWindowPositionMap);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RectFSpringAnim getWindowAnimationToHomeInternal(
|
||||||
|
HomeAnimationFactory homeAnimationFactory, RectF targetRect,
|
||||||
|
TransformParams transformParams, TaskViewSimulator taskViewSimulator,
|
||||||
|
RectF startRect, Matrix homeToWindowPositionMap) {
|
||||||
|
RectF cropRectF = new RectF(taskViewSimulator.getCurrentCropRect());
|
||||||
// Move the startRect to Launcher space as floatingIconView runs in Launcher
|
// Move the startRect to Launcher space as floatingIconView runs in Launcher
|
||||||
Matrix windowToHomePositionMap = new Matrix();
|
Matrix windowToHomePositionMap = new Matrix();
|
||||||
homeToWindowPositionMap.invert(windowToHomePositionMap);
|
homeToWindowPositionMap.invert(windowToHomePositionMap);
|
||||||
|
@ -240,7 +343,7 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
RectFSpringAnim anim;
|
RectFSpringAnim anim;
|
||||||
if (PROTOTYPE_APP_CLOSE.get()) {
|
if (PROTOTYPE_APP_CLOSE.get()) {
|
||||||
anim = new RectFSpringAnim2(startRect, targetRect, mContext,
|
anim = new RectFSpringAnim2(startRect, targetRect, mContext,
|
||||||
mTaskViewSimulator.getCurrentCornerRadius(),
|
taskViewSimulator.getCurrentCornerRadius(),
|
||||||
homeAnimationFactory.getEndRadius(cropRectF));
|
homeAnimationFactory.getEndRadius(cropRectF));
|
||||||
} else {
|
} else {
|
||||||
anim = new RectFSpringAnim(startRect, targetRect, mContext);
|
anim = new RectFSpringAnim(startRect, targetRect, mContext);
|
||||||
|
@ -248,9 +351,10 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
homeAnimationFactory.setAnimation(anim);
|
homeAnimationFactory.setAnimation(anim);
|
||||||
|
|
||||||
SpringAnimationRunner runner = new SpringAnimationRunner(
|
SpringAnimationRunner runner = new SpringAnimationRunner(
|
||||||
homeAnimationFactory, cropRectF, homeToWindowPositionMap);
|
homeAnimationFactory, cropRectF, homeToWindowPositionMap,
|
||||||
anim.addOnUpdateListener(runner);
|
transformParams, taskViewSimulator);
|
||||||
anim.addAnimatorListener(runner);
|
anim.addAnimatorListener(runner);
|
||||||
|
anim.addOnUpdateListener(runner);
|
||||||
return anim;
|
return anim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,6 +366,7 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
|
|
||||||
final RectF mWindowCurrentRect = new RectF();
|
final RectF mWindowCurrentRect = new RectF();
|
||||||
final Matrix mHomeToWindowPositionMap;
|
final Matrix mHomeToWindowPositionMap;
|
||||||
|
private final TransformParams mLocalTransformParams;
|
||||||
final HomeAnimationFactory mAnimationFactory;
|
final HomeAnimationFactory mAnimationFactory;
|
||||||
|
|
||||||
final AnimatorPlaybackController mHomeAnim;
|
final AnimatorPlaybackController mHomeAnim;
|
||||||
|
@ -271,17 +376,19 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
final float mEndRadius;
|
final float mEndRadius;
|
||||||
|
|
||||||
SpringAnimationRunner(HomeAnimationFactory factory, RectF cropRectF,
|
SpringAnimationRunner(HomeAnimationFactory factory, RectF cropRectF,
|
||||||
Matrix homeToWindowPositionMap) {
|
Matrix homeToWindowPositionMap, TransformParams transformParams,
|
||||||
|
TaskViewSimulator taskViewSimulator) {
|
||||||
mAnimationFactory = factory;
|
mAnimationFactory = factory;
|
||||||
mHomeAnim = factory.createActivityAnimationToHome();
|
mHomeAnim = factory.createActivityAnimationToHome();
|
||||||
mCropRectF = cropRectF;
|
mCropRectF = cropRectF;
|
||||||
mHomeToWindowPositionMap = homeToWindowPositionMap;
|
mHomeToWindowPositionMap = homeToWindowPositionMap;
|
||||||
|
mLocalTransformParams = transformParams;
|
||||||
|
|
||||||
cropRectF.roundOut(mCropRect);
|
cropRectF.roundOut(mCropRect);
|
||||||
|
|
||||||
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
|
// End on a "round-enough" radius so that the shape reveal doesn't have to do too much
|
||||||
// rounding at the end of the animation.
|
// rounding at the end of the animation.
|
||||||
mStartRadius = mTaskViewSimulator.getCurrentCornerRadius();
|
mStartRadius = taskViewSimulator.getCurrentCornerRadius();
|
||||||
mEndRadius = factory.getEndRadius(cropRectF);
|
mEndRadius = factory.getEndRadius(cropRectF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,10 +407,11 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
if (mAnimationFactory.keepWindowOpaque()) {
|
if (mAnimationFactory.keepWindowOpaque()) {
|
||||||
alpha = 1f;
|
alpha = 1f;
|
||||||
}
|
}
|
||||||
mTransformParams
|
mLocalTransformParams
|
||||||
.setTargetAlpha(alpha)
|
.setTargetAlpha(alpha)
|
||||||
.setCornerRadius(cornerRadius);
|
.setCornerRadius(cornerRadius);
|
||||||
mTransformParams.applySurfaceParams(mTransformParams.createSurfaceParams(this));
|
mLocalTransformParams.applySurfaceParams(mLocalTransformParams
|
||||||
|
.createSurfaceParams(this));
|
||||||
mAnimationFactory.update(config, currentRect, progress,
|
mAnimationFactory.update(config, currentRect, progress,
|
||||||
mMatrix.mapRadius(cornerRadius));
|
mMatrix.mapRadius(cornerRadius));
|
||||||
}
|
}
|
||||||
|
@ -332,6 +440,21 @@ public abstract class SwipeUpAnimationLogic {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 {
|
public interface RunningWindowAnim {
|
||||||
void end();
|
void end();
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ package com.android.quickstep;
|
||||||
|
|
||||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.PictureInPictureParams;
|
import android.app.PictureInPictureParams;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
|
@ -632,10 +633,11 @@ public class SystemUiProxy implements ISystemUiProxy,
|
||||||
* @param cancel true if recents starting is being cancelled.
|
* @param cancel true if recents starting is being cancelled.
|
||||||
* @return RemoteAnimationTargets of windows that need to animate but only exist in shell.
|
* @return RemoteAnimationTargets of windows that need to animate but only exist in shell.
|
||||||
*/
|
*/
|
||||||
public RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel) {
|
public RemoteAnimationTarget[] onGoingToRecentsLegacy(boolean cancel,
|
||||||
|
RemoteAnimationTarget[] apps) {
|
||||||
if (mSplitScreen != null) {
|
if (mSplitScreen != null) {
|
||||||
try {
|
try {
|
||||||
return mSplitScreen.onGoingToRecentsLegacy(cancel);
|
return mSplitScreen.onGoingToRecentsLegacy(cancel, apps);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.w(TAG, "Failed call onGoingToRecentsLegacy");
|
Log.w(TAG, "Failed call onGoingToRecentsLegacy");
|
||||||
}
|
}
|
||||||
|
|
|
@ -154,9 +154,10 @@ public final class TaskViewUtils {
|
||||||
boolean isRunningTask = v.isRunningTask();
|
boolean isRunningTask = v.isRunningTask();
|
||||||
TransformParams params = null;
|
TransformParams params = null;
|
||||||
TaskViewSimulator tsv = null;
|
TaskViewSimulator tsv = null;
|
||||||
|
// TODO(b/195675206) handle two TSVs here
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isRunningTask) {
|
||||||
params = v.getRecentsView().getLiveTileParams();
|
params = v.getRecentsView().getRemoteTargetHandles()[0].mTransformParams;
|
||||||
tsv = v.getRecentsView().getLiveTileTaskViewSimulator();
|
tsv = v.getRecentsView().getRemoteTargetHandles()[0].mTaskViewSimulator;
|
||||||
}
|
}
|
||||||
createRecentsWindowAnimator(v, skipViewChanges, appTargets, wallpaperTargets, nonAppTargets,
|
createRecentsWindowAnimator(v, skipViewChanges, appTargets, wallpaperTargets, nonAppTargets,
|
||||||
depthController, out, params, tsv);
|
depthController, out, params, tsv);
|
||||||
|
|
|
@ -99,6 +99,7 @@ import com.android.quickstep.inputconsumers.SysUiOverlayInputConsumer;
|
||||||
import com.android.quickstep.inputconsumers.TaskbarStashInputConsumer;
|
import com.android.quickstep.inputconsumers.TaskbarStashInputConsumer;
|
||||||
import com.android.quickstep.util.ActiveGestureLog;
|
import com.android.quickstep.util.ActiveGestureLog;
|
||||||
import com.android.quickstep.util.AssistantUtilities;
|
import com.android.quickstep.util.AssistantUtilities;
|
||||||
|
import com.android.quickstep.util.LauncherSplitScreenListener;
|
||||||
import com.android.quickstep.util.ProtoTracer;
|
import com.android.quickstep.util.ProtoTracer;
|
||||||
import com.android.quickstep.util.ProxyScreenStatusProvider;
|
import com.android.quickstep.util.ProxyScreenStatusProvider;
|
||||||
import com.android.quickstep.util.SplitScreenBounds;
|
import com.android.quickstep.util.SplitScreenBounds;
|
||||||
|
@ -364,6 +365,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||||
mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
|
mDeviceState.runOnUserUnlocked(this::onUserUnlocked);
|
||||||
mDeviceState.runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
|
mDeviceState.runOnUserUnlocked(mTaskbarManager::onUserUnlocked);
|
||||||
ProtoTracer.INSTANCE.get(this).add(this);
|
ProtoTracer.INSTANCE.get(this).add(this);
|
||||||
|
LauncherSplitScreenListener.INSTANCE.get(this).init();
|
||||||
sConnected = true;
|
sConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,6 +522,7 @@ public class TouchInteractionService extends Service implements PluginListener<O
|
||||||
getSystemService(AccessibilityManager.class)
|
getSystemService(AccessibilityManager.class)
|
||||||
.unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
|
.unregisterSystemAction(SYSTEM_ACTION_ID_ALL_APPS);
|
||||||
|
|
||||||
|
LauncherSplitScreenListener.INSTANCE.get(this).destroy();
|
||||||
mTaskbarManager.destroy();
|
mTaskbarManager.destroy();
|
||||||
sConnected = false;
|
sConnected = false;
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|
|
@ -79,8 +79,10 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||||
* to the home task. This allows us to handle quick-switch similarly to a quick-switching
|
* to the home task. This allows us to handle quick-switch similarly to a quick-switching
|
||||||
* from a foreground task.
|
* from a foreground task.
|
||||||
*/
|
*/
|
||||||
public void onGestureAnimationStartOnHome(RunningTaskInfo homeTaskInfo) {
|
public void onGestureAnimationStartOnHome(RunningTaskInfo[] homeTaskInfo) {
|
||||||
mHomeTaskInfo = homeTaskInfo;
|
// TODO(b/195607777) General fallback love, but this might be correct
|
||||||
|
// Home task should be defined as the front-most task info I think?
|
||||||
|
mHomeTaskInfo = homeTaskInfo[0];
|
||||||
onGestureAnimationStart(homeTaskInfo);
|
onGestureAnimationStart(homeTaskInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +94,8 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||||
@Override
|
@Override
|
||||||
public void onPrepareGestureEndAnimation(
|
public void onPrepareGestureEndAnimation(
|
||||||
@Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
|
@Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
|
||||||
TaskViewSimulator taskViewSimulator) {
|
TaskViewSimulator[] taskViewSimulators) {
|
||||||
super.onPrepareGestureEndAnimation(animatorSet, endTarget, taskViewSimulator);
|
super.onPrepareGestureEndAnimation(animatorSet, endTarget, taskViewSimulators);
|
||||||
if (mHomeTaskInfo != null && endTarget == RECENTS && animatorSet != null) {
|
if (mHomeTaskInfo != null && endTarget == RECENTS && animatorSet != null) {
|
||||||
TaskView tv = getTaskViewByTaskId(mHomeTaskInfo.taskId);
|
TaskView tv = getTaskViewByTaskId(mHomeTaskInfo.taskId);
|
||||||
if (tv != null) {
|
if (tv != null) {
|
||||||
|
@ -133,7 +135,13 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldAddStubTaskView(RunningTaskInfo runningTaskInfo) {
|
protected boolean shouldAddStubTaskView(RunningTaskInfo[] runningTaskInfos) {
|
||||||
|
if (runningTaskInfos.length > 1) {
|
||||||
|
// can't be in split screen w/ home task
|
||||||
|
return super.shouldAddStubTaskView(runningTaskInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
RunningTaskInfo runningTaskInfo = runningTaskInfos[0];
|
||||||
if (mHomeTaskInfo != null && runningTaskInfo != null &&
|
if (mHomeTaskInfo != null && runningTaskInfo != null &&
|
||||||
mHomeTaskInfo.taskId == runningTaskInfo.taskId
|
mHomeTaskInfo.taskId == runningTaskInfo.taskId
|
||||||
&& getTaskViewCount() == 0) {
|
&& getTaskViewCount() == 0) {
|
||||||
|
@ -141,7 +149,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||||
// show the empty recents message instead of showing a stub task and later removing it.
|
// show the empty recents message instead of showing a stub task and later removing it.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return super.shouldAddStubTaskView(runningTaskInfo);
|
return super.shouldAddStubTaskView(runningTaskInfos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -149,6 +157,7 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
||||||
// When quick-switching on 3p-launcher, we add a "stub" tile corresponding to Launcher
|
// When quick-switching on 3p-launcher, we add a "stub" tile corresponding to Launcher
|
||||||
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
|
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
|
||||||
// track the index of the next task appropriately, as if we are switching on any other app.
|
// track the index of the next task appropriately, as if we are switching on any other app.
|
||||||
|
// TODO(b/195607777) Confirm home task info is front-most task and not mixed in with others
|
||||||
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
||||||
if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId && !tasks.isEmpty()) {
|
if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId && !tasks.isEmpty()) {
|
||||||
// Check if the task list has running task
|
// Check if the task list has running task
|
||||||
|
|
|
@ -46,6 +46,7 @@ import com.android.launcher3.Utilities;
|
||||||
import com.android.launcher3.anim.AnimatorListeners;
|
import com.android.launcher3.anim.AnimatorListeners;
|
||||||
import com.android.launcher3.anim.AnimatorPlaybackController;
|
import com.android.launcher3.anim.AnimatorPlaybackController;
|
||||||
import com.android.launcher3.anim.PendingAnimation;
|
import com.android.launcher3.anim.PendingAnimation;
|
||||||
|
import com.android.launcher3.statemanager.StatefulActivity;
|
||||||
import com.android.quickstep.AnimatedFloat;
|
import com.android.quickstep.AnimatedFloat;
|
||||||
import com.android.quickstep.GestureState;
|
import com.android.quickstep.GestureState;
|
||||||
import com.android.quickstep.OverviewComponentObserver;
|
import com.android.quickstep.OverviewComponentObserver;
|
||||||
|
@ -263,14 +264,16 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||||
|
|
||||||
void initDp(DeviceProfile dp) {
|
void initDp(DeviceProfile dp) {
|
||||||
initTransitionEndpoints(dp);
|
initTransitionEndpoints(dp);
|
||||||
mTaskViewSimulator.setPreviewBounds(
|
mRemoteTargetHandles[0].mTaskViewSimulator.setPreviewBounds(
|
||||||
new Rect(0, 0, dp.widthPx, dp.heightPx), dp.getInsets());
|
new Rect(0, 0, dp.widthPx, dp.heightPx), dp.getInsets());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateFinalShift() {
|
public void updateFinalShift() {
|
||||||
mWindowTransitionController.setProgress(mCurrentShift.value, mDragLengthFactor);
|
mRemoteTargetHandles[0].mPlaybackController
|
||||||
mTaskViewSimulator.apply(mTransformParams);
|
.setProgress(mCurrentShift.value, mDragLengthFactor);
|
||||||
|
mRemoteTargetHandles[0].mTaskViewSimulator.apply(
|
||||||
|
mRemoteTargetHandles[0].mTransformParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedFloat getCurrentShift() {
|
AnimatedFloat getCurrentShift() {
|
||||||
|
@ -326,7 +329,8 @@ abstract class SwipeUpGestureTutorialController extends TutorialController {
|
||||||
mFakeIconView.setVisibility(View.INVISIBLE);
|
mFakeIconView.setVisibility(View.INVISIBLE);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift, homeAnimFactory);
|
RectFSpringAnim windowAnim = createWindowAnimationToHome(startShift,
|
||||||
|
homeAnimFactory)[0];
|
||||||
windowAnim.start(mContext, velocityPxPerMs);
|
windowAnim.start(mContext, velocityPxPerMs);
|
||||||
return windowAnim;
|
return windowAnim;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,8 +158,7 @@ public class AnimatorControllerWithResistance {
|
||||||
Rect startRect = new Rect();
|
Rect startRect = new Rect();
|
||||||
PagedOrientationHandler orientationHandler = params.recentsOrientedState
|
PagedOrientationHandler orientationHandler = params.recentsOrientedState
|
||||||
.getOrientationHandler();
|
.getOrientationHandler();
|
||||||
LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect,
|
LauncherActivityInterface.INSTANCE.calculateTaskSize(params.context, params.dp, startRect);
|
||||||
orientationHandler);
|
|
||||||
long distanceToCover = startRect.bottom;
|
long distanceToCover = startRect.bottom;
|
||||||
PendingAnimation resistAnim = params.resistAnim != null
|
PendingAnimation resistAnim = params.resistAnim != null
|
||||||
? params.resistAnim
|
? params.resistAnim
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.android.quickstep.util;
|
||||||
|
|
||||||
|
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.IBinder;
|
||||||
|
|
||||||
|
import com.android.launcher3.util.MainThreadInitializedObject;
|
||||||
|
import com.android.launcher3.util.SplitConfigurationOptions;
|
||||||
|
import com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
|
||||||
|
import com.android.launcher3.util.SplitConfigurationOptions.StageType;
|
||||||
|
import com.android.launcher3.util.SplitConfigurationOptions.StagedSplitTaskPosition;
|
||||||
|
import com.android.quickstep.SystemUiProxy;
|
||||||
|
import com.android.wm.shell.splitscreen.ISplitScreenListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listeners for system wide split screen position and stage changes.
|
||||||
|
* Use {@link #getSplitTaskIds()} to determine which tasks, if any, are in staged split.
|
||||||
|
*/
|
||||||
|
public class LauncherSplitScreenListener extends ISplitScreenListener.Stub {
|
||||||
|
|
||||||
|
public static final MainThreadInitializedObject<LauncherSplitScreenListener> INSTANCE =
|
||||||
|
new MainThreadInitializedObject<>(LauncherSplitScreenListener::new);
|
||||||
|
|
||||||
|
private final StagedSplitTaskPosition mMainStagePosition = new StagedSplitTaskPosition();
|
||||||
|
private final StagedSplitTaskPosition mSideStagePosition = new StagedSplitTaskPosition();
|
||||||
|
|
||||||
|
public LauncherSplitScreenListener(Context context) {
|
||||||
|
mMainStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_MAIN;
|
||||||
|
mSideStagePosition.stageType = SplitConfigurationOptions.STAGE_TYPE_SIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Also call {@link #destroy()} when done. */
|
||||||
|
public void init() {
|
||||||
|
SystemUiProxy.INSTANCE.getNoCreate().registerSplitScreenListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
SystemUiProxy.INSTANCE.getNoCreate().unregisterSplitScreenListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return index 0 will be task in left/top position, index 1 in right/bottom position.
|
||||||
|
* Will return empty array if device is not in staged split
|
||||||
|
*/
|
||||||
|
public int[] getSplitTaskIds() {
|
||||||
|
if (mMainStagePosition.taskId == -1 || mSideStagePosition.taskId == -1) {
|
||||||
|
return new int[]{};
|
||||||
|
}
|
||||||
|
int[] out = new int[2];
|
||||||
|
if (mMainStagePosition.stagePosition == STAGE_POSITION_TOP_OR_LEFT) {
|
||||||
|
out[0] = mMainStagePosition.taskId;
|
||||||
|
out[1] = mSideStagePosition.taskId;
|
||||||
|
} else {
|
||||||
|
out[1] = mMainStagePosition.taskId;
|
||||||
|
out[0] = mSideStagePosition.taskId;
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStagePositionChanged(@StageType int stage, @StagePosition int position) {
|
||||||
|
if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) {
|
||||||
|
mMainStagePosition.stagePosition = position;
|
||||||
|
} else {
|
||||||
|
mSideStagePosition.stagePosition = position;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {
|
||||||
|
// If task is not visible but we are tracking it, stop tracking it
|
||||||
|
if (!visible) {
|
||||||
|
if (mMainStagePosition.taskId == taskId) {
|
||||||
|
resetTaskId(mMainStagePosition);
|
||||||
|
} else if (mSideStagePosition.taskId == taskId) {
|
||||||
|
resetTaskId(mSideStagePosition);
|
||||||
|
} // else it's an un-tracked child
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If stage has moved to undefined, stop tracking the task
|
||||||
|
if (stage == SplitConfigurationOptions.STAGE_TYPE_UNDEFINED) {
|
||||||
|
resetTaskId(taskId == mMainStagePosition.taskId ?
|
||||||
|
mMainStagePosition : mSideStagePosition);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage == SplitConfigurationOptions.STAGE_TYPE_MAIN) {
|
||||||
|
mMainStagePosition.taskId = taskId;
|
||||||
|
} else {
|
||||||
|
mSideStagePosition.taskId = taskId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetTaskId(StagedSplitTaskPosition taskPosition) {
|
||||||
|
taskPosition.taskId = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBinder asBinder() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,8 +42,7 @@ public class LayoutUtils {
|
||||||
PagedOrientationHandler orientationHandler) {
|
PagedOrientationHandler orientationHandler) {
|
||||||
// Track the bottom of the window.
|
// Track the bottom of the window.
|
||||||
Rect taskSize = new Rect();
|
Rect taskSize = new Rect();
|
||||||
LauncherActivityInterface.INSTANCE.calculateTaskSize(
|
LauncherActivityInterface.INSTANCE.calculateTaskSize(context, dp, taskSize);
|
||||||
context, dp, taskSize, orientationHandler);
|
|
||||||
return orientationHandler.getDistanceToBottomOfRect(dp, taskSize);
|
return orientationHandler.getDistanceToBottomOfRect(dp, taskSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ package com.android.quickstep.util;
|
||||||
|
|
||||||
import static com.android.launcher3.states.RotationHelper.deltaRotation;
|
import static com.android.launcher3.states.RotationHelper.deltaRotation;
|
||||||
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
|
import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE;
|
||||||
|
import static com.android.launcher3.util.SplitConfigurationOptions.*;
|
||||||
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
|
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
|
||||||
import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
|
import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
|
||||||
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
|
import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
|
||||||
|
@ -29,6 +30,7 @@ import android.graphics.Point;
|
||||||
import android.graphics.PointF;
|
import android.graphics.PointF;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
@ -49,8 +51,13 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.
|
||||||
*/
|
*/
|
||||||
public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
|
|
||||||
|
private final String TAG = "TaskViewSimulator";
|
||||||
|
private final boolean DEBUG = false;
|
||||||
|
|
||||||
private final Rect mTmpCropRect = new Rect();
|
private final Rect mTmpCropRect = new Rect();
|
||||||
private final RectF mTempRectF = new RectF();
|
private final RectF mTempRectF = new RectF();
|
||||||
|
// Additional offset for split tasks
|
||||||
|
private final Point mSplitOffset = new Point();
|
||||||
private final float[] mTempPoint = new float[2];
|
private final float[] mTempPoint = new float[2];
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
|
@ -63,6 +70,8 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
private final Rect mTaskRect = new Rect();
|
private final Rect mTaskRect = new Rect();
|
||||||
private final PointF mPivot = new PointF();
|
private final PointF mPivot = new PointF();
|
||||||
private DeviceProfile mDp;
|
private DeviceProfile mDp;
|
||||||
|
@StagePosition
|
||||||
|
private int mStagePosition = STAGE_POSITION_UNDEFINED;
|
||||||
|
|
||||||
private final Matrix mMatrix = new Matrix();
|
private final Matrix mMatrix = new Matrix();
|
||||||
private final Matrix mMatrixTmp = new Matrix();
|
private final Matrix mMatrixTmp = new Matrix();
|
||||||
|
@ -89,6 +98,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
// Cached calculations
|
// Cached calculations
|
||||||
private boolean mLayoutValid = false;
|
private boolean mLayoutValid = false;
|
||||||
private int mOrientationStateId;
|
private int mOrientationStateId;
|
||||||
|
private StagedSplitBounds mStagedSplitBounds;
|
||||||
|
|
||||||
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
|
public TaskViewSimulator(Context context, BaseActivityInterface sizeStrategy) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
@ -128,9 +138,19 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
if (mDp == null) {
|
if (mDp == null) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
mSizeStrategy.calculateTaskSize(mContext, mDp, mTaskRect,
|
Rect fullTaskSize = new Rect();
|
||||||
mOrientationState.getOrientationHandler());
|
mSizeStrategy.calculateTaskSize(mContext, mDp, fullTaskSize);
|
||||||
return mOrientationState.getFullScreenScaleAndPivot(mTaskRect, mDp, mPivot);
|
|
||||||
|
if (mStagedSplitBounds != null) {
|
||||||
|
// The task rect changes according to the staged split task sizes, but recents
|
||||||
|
// fullscreen scale and pivot remains the same since the task fits into the existing
|
||||||
|
// sized task space bounds
|
||||||
|
mSizeStrategy.calculateStagedSplitTaskSize(mContext, mDp, mTaskRect, mStagedSplitBounds,
|
||||||
|
mStagePosition);
|
||||||
|
} else {
|
||||||
|
mTaskRect.set(fullTaskSize);
|
||||||
|
}
|
||||||
|
return mOrientationState.getFullScreenScaleAndPivot(fullTaskSize, mDp, mPivot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,6 +162,24 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
runningTarget.screenSpaceBounds.top);
|
runningTarget.screenSpaceBounds.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the targets which the simulator will control specifically for targets to animate when
|
||||||
|
* in split screen
|
||||||
|
*
|
||||||
|
* @param splitInfo set to {@code null} when not in staged split mode
|
||||||
|
*/
|
||||||
|
public void setPreview(RemoteAnimationTargetCompat runningTarget, StagedSplitBounds splitInfo) {
|
||||||
|
setPreview(runningTarget);
|
||||||
|
mStagedSplitBounds = splitInfo;
|
||||||
|
if (mStagedSplitBounds == null) {
|
||||||
|
mStagePosition = STAGE_POSITION_UNDEFINED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mStagePosition = mThumbnailPosition.equals(splitInfo.mLeftTopBounds) ?
|
||||||
|
STAGE_POSITION_TOP_OR_LEFT :
|
||||||
|
STAGE_POSITION_BOTTOM_OR_RIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the targets which the simulator will control
|
* Sets the targets which the simulator will control
|
||||||
*/
|
*/
|
||||||
|
@ -239,6 +277,15 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
getFullScreenScale();
|
getFullScreenScale();
|
||||||
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
|
mThumbnailData.rotation = mOrientationState.getDisplayRotation();
|
||||||
|
|
||||||
|
// TODO(b/195145340) handle non 50-50 split scenarios
|
||||||
|
if (mStagedSplitBounds != null) {
|
||||||
|
if (mStagePosition == STAGE_POSITION_BOTTOM_OR_RIGHT) {
|
||||||
|
// The preview set is for the bottom/right, inset by top/left task
|
||||||
|
mSplitOffset.y = mStagedSplitBounds.mLeftTopBounds.height() +
|
||||||
|
mStagedSplitBounds.mDividerBounds.height() / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// mIsRecentsRtl is the inverse of TaskView RTL.
|
// mIsRecentsRtl is the inverse of TaskView RTL.
|
||||||
boolean isRtlEnabled = !mIsRecentsRtl;
|
boolean isRtlEnabled = !mIsRecentsRtl;
|
||||||
mPositionHelper.updateThumbnailMatrix(
|
mPositionHelper.updateThumbnailMatrix(
|
||||||
|
@ -246,6 +293,9 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
mTaskRect.width(), mTaskRect.height(),
|
mTaskRect.width(), mTaskRect.height(),
|
||||||
mDp, mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
|
mDp, mOrientationState.getRecentsActivityRotation(), isRtlEnabled);
|
||||||
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
|
mPositionHelper.getMatrix().invert(mInversePositionMatrix);
|
||||||
|
if (DEBUG) {
|
||||||
|
Log.d(TAG, " taskRect: " + mTaskRect + " splitOffset: " + mSplitOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
|
float fullScreenProgress = Utilities.boundToRange(this.fullScreenProgress.value, 0, 1);
|
||||||
|
@ -280,6 +330,9 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
recentsViewPrimaryTranslation.value);
|
recentsViewPrimaryTranslation.value);
|
||||||
applyWindowToHomeRotation(mMatrix);
|
applyWindowToHomeRotation(mMatrix);
|
||||||
|
|
||||||
|
// Move lower/right split window into correct position
|
||||||
|
mMatrix.postTranslate(0, mSplitOffset.y);
|
||||||
|
|
||||||
// Crop rect is the inverse of thumbnail matrix
|
// Crop rect is the inverse of thumbnail matrix
|
||||||
mTempRectF.set(-insets.left, -insets.top,
|
mTempRectF.set(-insets.left, -insets.top,
|
||||||
taskWidth + insets.right, taskHeight + insets.bottom);
|
taskWidth + insets.right, taskHeight + insets.bottom);
|
||||||
|
@ -287,6 +340,25 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy {
|
||||||
mTempRectF.roundOut(mTmpCropRect);
|
mTempRectF.roundOut(mTmpCropRect);
|
||||||
|
|
||||||
params.applySurfaceParams(params.createSurfaceParams(this));
|
params.applySurfaceParams(params.createSurfaceParams(this));
|
||||||
|
|
||||||
|
if (!DEBUG) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.d(TAG, "progress: " + fullScreenProgress
|
||||||
|
+ " scale: " + scale
|
||||||
|
+ " recentsViewScale: " + recentsViewScale.value
|
||||||
|
+ " crop: " + mTmpCropRect
|
||||||
|
+ " radius: " + getCurrentCornerRadius()
|
||||||
|
+ " translate: " + mSplitOffset
|
||||||
|
+ " taskW: " + taskWidth + " H: " + taskHeight
|
||||||
|
+ " taskRect: " + mTaskRect
|
||||||
|
+ " taskPrimaryT: " + taskPrimaryTranslation.value
|
||||||
|
+ " recentsPrimaryT: " + recentsViewPrimaryTranslation.value
|
||||||
|
+ " recentsSecondaryT: " + recentsViewSecondaryTranslation.value
|
||||||
|
+ " taskSecondaryT: " + taskSecondaryTranslation.value
|
||||||
|
+ " recentsScroll: " + recentsViewScroll.value
|
||||||
|
+ " pivot: " + mPivot
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
package com.android.quickstep.views;
|
||||||
|
|
||||||
|
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.android.launcher3.DeviceProfile;
|
||||||
|
import com.android.launcher3.R;
|
||||||
|
import com.android.quickstep.RecentsModel;
|
||||||
|
import com.android.quickstep.TaskThumbnailCache;
|
||||||
|
import com.android.quickstep.util.CancellableTask;
|
||||||
|
import com.android.quickstep.util.RecentsOrientedState;
|
||||||
|
import com.android.systemui.shared.recents.model.Task;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TaskView that contains and shows thumbnails for not one, BUT TWO(!!) tasks
|
||||||
|
*
|
||||||
|
* That's right. If you call within the next 5 minutes we'll go ahead and double your order and
|
||||||
|
* send you !! TWO !! Tasks along with their TaskThumbnailViews complimentary. On. The. House.
|
||||||
|
* And not only that, we'll even clean up your thumbnail request if you don't like it.
|
||||||
|
* All the benefits of one TaskView, except DOUBLED!
|
||||||
|
*
|
||||||
|
* (Icon loading sold separately, fees may apply. Shipping & Handling for Overlays not included).
|
||||||
|
*/
|
||||||
|
public class GroupedTaskView extends TaskView {
|
||||||
|
|
||||||
|
private Task mSecondaryTask;
|
||||||
|
private TaskThumbnailView mSnapshotView2;
|
||||||
|
private CancellableTask mThumbnailLoadRequest2;
|
||||||
|
|
||||||
|
public GroupedTaskView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupedTaskView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupedTaskView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFinishInflate() {
|
||||||
|
super.onFinishInflate();
|
||||||
|
mSnapshotView2 = findViewById(R.id.bottomright_snapshot);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(Task primary, Task secondary, RecentsOrientedState orientedState) {
|
||||||
|
super.bind(primary, orientedState);
|
||||||
|
mSecondaryTask = secondary;
|
||||||
|
mTaskIdContainer[1] = secondary.key.id;
|
||||||
|
mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2);
|
||||||
|
mSnapshotView2.bind(secondary);
|
||||||
|
adjustThumbnailBoundsForSplit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskListVisibilityChanged(boolean visible, int changes) {
|
||||||
|
super.onTaskListVisibilityChanged(visible, changes);
|
||||||
|
if (visible) {
|
||||||
|
RecentsModel model = RecentsModel.INSTANCE.get(getContext());
|
||||||
|
TaskThumbnailCache thumbnailCache = model.getThumbnailCache();
|
||||||
|
|
||||||
|
if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
|
||||||
|
mThumbnailLoadRequest2 = thumbnailCache.updateThumbnailInBackground(mSecondaryTask,
|
||||||
|
thumbnailData -> mSnapshotView2.setThumbnail(
|
||||||
|
mSecondaryTask, thumbnailData
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
|
||||||
|
// TODO What's the Icon for this going to look like? :o
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) {
|
||||||
|
mSnapshotView2.setThumbnail(null, null);
|
||||||
|
// Reset the task thumbnail reference as well (it will be fetched from the cache or
|
||||||
|
// reloaded next time we need it)
|
||||||
|
mSecondaryTask.thumbnail = null;
|
||||||
|
}
|
||||||
|
if (needsUpdate(changes, FLAG_UPDATE_ICON)) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void cancelPendingLoadTasks() {
|
||||||
|
super.cancelPendingLoadTasks();
|
||||||
|
if (mThumbnailLoadRequest2 != null) {
|
||||||
|
mThumbnailLoadRequest2.cancel();
|
||||||
|
mThumbnailLoadRequest2 = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRecycle() {
|
||||||
|
super.onRecycle();
|
||||||
|
mSnapshotView2.setThumbnail(mSecondaryTask, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOverlayEnabled(boolean overlayEnabled) {
|
||||||
|
super.setOverlayEnabled(overlayEnabled);
|
||||||
|
mSnapshotView2.setOverlayEnabled(overlayEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void adjustThumbnailBoundsForSplit() {
|
||||||
|
DeviceProfile deviceProfile = mActivity.getDeviceProfile();
|
||||||
|
ViewGroup.LayoutParams primaryLp = mSnapshotView.getLayoutParams();
|
||||||
|
primaryLp.width = mSecondaryTask == null ?
|
||||||
|
MATCH_PARENT :
|
||||||
|
getWidth();
|
||||||
|
int spaceAboveSnapshot = deviceProfile.overviewTaskThumbnailTopMarginPx;
|
||||||
|
// TODO get divider height
|
||||||
|
int dividerBar = 20;
|
||||||
|
primaryLp.height = mSecondaryTask == null ?
|
||||||
|
MATCH_PARENT :
|
||||||
|
(getHeight() - spaceAboveSnapshot - dividerBar) / 2;
|
||||||
|
mSnapshotView.setLayoutParams(primaryLp);
|
||||||
|
|
||||||
|
if (mSecondaryTask == null) {
|
||||||
|
mSnapshotView2.setVisibility(GONE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSnapshotView2.setVisibility(VISIBLE);
|
||||||
|
ViewGroup.LayoutParams secondaryLp = mSnapshotView2.getLayoutParams();
|
||||||
|
secondaryLp.width = getWidth();
|
||||||
|
secondaryLp.height = primaryLp.height;
|
||||||
|
mSnapshotView2.setLayoutParams(secondaryLp);
|
||||||
|
mSnapshotView2.setTranslationY(primaryLp.height + spaceAboveSnapshot + dividerBar);
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ package com.android.quickstep.views;
|
||||||
import static android.view.Surface.ROTATION_0;
|
import static android.view.Surface.ROTATION_0;
|
||||||
import static android.view.View.MeasureSpec.EXACTLY;
|
import static android.view.View.MeasureSpec.EXACTLY;
|
||||||
import static android.view.View.MeasureSpec.makeMeasureSpec;
|
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.TYPE_TASK_MENU;
|
||||||
import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
|
import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType;
|
||||||
|
@ -51,6 +52,7 @@ import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
|
||||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION;
|
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_RECENTS;
|
||||||
import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NO_TASKS;
|
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.Animator;
|
||||||
import android.animation.AnimatorListenerAdapter;
|
import android.animation.AnimatorListenerAdapter;
|
||||||
|
@ -143,11 +145,13 @@ import com.android.quickstep.RecentsAnimationTargets;
|
||||||
import com.android.quickstep.RecentsModel;
|
import com.android.quickstep.RecentsModel;
|
||||||
import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
|
import com.android.quickstep.RecentsModel.TaskVisualsChangeListener;
|
||||||
import com.android.quickstep.RemoteAnimationTargets;
|
import com.android.quickstep.RemoteAnimationTargets;
|
||||||
|
import com.android.quickstep.SwipeUpAnimationLogic.RemoteTargetHandle;
|
||||||
import com.android.quickstep.SystemUiProxy;
|
import com.android.quickstep.SystemUiProxy;
|
||||||
import com.android.quickstep.TaskOverlayFactory;
|
import com.android.quickstep.TaskOverlayFactory;
|
||||||
import com.android.quickstep.TaskThumbnailCache;
|
import com.android.quickstep.TaskThumbnailCache;
|
||||||
import com.android.quickstep.TaskViewUtils;
|
import com.android.quickstep.TaskViewUtils;
|
||||||
import com.android.quickstep.ViewUtils;
|
import com.android.quickstep.ViewUtils;
|
||||||
|
import com.android.quickstep.util.LauncherSplitScreenListener;
|
||||||
import com.android.quickstep.util.LayoutUtils;
|
import com.android.quickstep.util.LayoutUtils;
|
||||||
import com.android.quickstep.util.RecentsOrientedState;
|
import com.android.quickstep.util.RecentsOrientedState;
|
||||||
import com.android.quickstep.util.SplitScreenBounds;
|
import com.android.quickstep.util.SplitScreenBounds;
|
||||||
|
@ -317,7 +321,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
view.setScaleY(scale);
|
view.setScaleY(scale);
|
||||||
view.mLastComputedTaskStartPushOutDistance = null;
|
view.mLastComputedTaskStartPushOutDistance = null;
|
||||||
view.mLastComputedTaskEndPushOutDistance = null;
|
view.mLastComputedTaskEndPushOutDistance = null;
|
||||||
view.mLiveTileTaskViewSimulator.recentsViewScale.value = scale;
|
view.runActionOnRemoteHandles(new Consumer<RemoteTargetHandle>() {
|
||||||
|
@Override
|
||||||
|
public void accept(RemoteTargetHandle remoteTargetHandle) {
|
||||||
|
remoteTargetHandle.mTaskViewSimulator.recentsViewScale.value =
|
||||||
|
scale;
|
||||||
|
}
|
||||||
|
});
|
||||||
view.setTaskViewsResistanceTranslation(view.mTaskViewsSecondaryTranslation);
|
view.setTaskViewsResistanceTranslation(view.mTaskViewsSecondaryTranslation);
|
||||||
view.updatePageOffsets();
|
view.updatePageOffsets();
|
||||||
}
|
}
|
||||||
|
@ -365,8 +375,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
// mTaskGridVerticalDiff and mTopBottomRowHeightDiff summed together provides the top
|
// mTaskGridVerticalDiff and mTopBottomRowHeightDiff summed together provides the top
|
||||||
// position for bottom row of grid tasks.
|
// position for bottom row of grid tasks.
|
||||||
|
|
||||||
protected final TransformParams mLiveTileParams = new TransformParams();
|
protected RemoteTargetHandle[] mRemoteTargetHandles;
|
||||||
protected final TaskViewSimulator mLiveTileTaskViewSimulator;
|
|
||||||
protected final Rect mLastComputedTaskSize = new Rect();
|
protected final Rect mLastComputedTaskSize = new Rect();
|
||||||
protected final Rect mLastComputedGridSize = new Rect();
|
protected final Rect mLastComputedGridSize = new Rect();
|
||||||
protected final Rect mLastComputedGridTaskSize = new Rect();
|
protected final Rect mLastComputedGridTaskSize = new Rect();
|
||||||
|
@ -402,9 +411,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
private final InvariantDeviceProfile mIdp;
|
private final InvariantDeviceProfile mIdp;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getting views should be done via {@link #getTaskViewFromPool()}
|
* Getting views should be done via {@link #getTaskViewFromPool(boolean)}
|
||||||
*/
|
*/
|
||||||
private final ViewPool<TaskView> mTaskViewPool;
|
private final ViewPool<TaskView> mTaskViewPool;
|
||||||
|
private final ViewPool<GroupedTaskView> mGroupedTaskViewPool;
|
||||||
|
|
||||||
private final TaskOverlayFactory mTaskOverlayFactory;
|
private final TaskOverlayFactory mTaskOverlayFactory;
|
||||||
|
|
||||||
|
@ -504,13 +514,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
// Only valid until the launcher state changes to NORMAL
|
// Only valid until the launcher state changes to NORMAL
|
||||||
/**
|
/**
|
||||||
* ID for the current running TaskView view, unique amongst TaskView instances. ID's are set
|
* ID for the current running TaskView view, unique amongst TaskView instances. ID's are set
|
||||||
* through {@link #getTaskViewFromPool()} and incremented by {@link #mTaskViewIdCount}
|
* through {@link #getTaskViewFromPool(boolean)} and incremented by {@link #mTaskViewIdCount}
|
||||||
*/
|
*/
|
||||||
protected int mRunningTaskViewId = -1;
|
protected int mRunningTaskViewId = -1;
|
||||||
private int mTaskViewIdCount;
|
private int mTaskViewIdCount;
|
||||||
private final int[] INVALID_TASK_IDS = new int[]{-1, -1};
|
private final int[] INVALID_TASK_IDS = new int[]{-1, -1};
|
||||||
protected boolean mRunningTaskTileHidden;
|
protected boolean mRunningTaskTileHidden;
|
||||||
private Task mTmpRunningTask;
|
private Task[] mTmpRunningTasks;
|
||||||
protected int mFocusedTaskViewId = -1;
|
protected int mFocusedTaskViewId = -1;
|
||||||
|
|
||||||
private boolean mTaskIconScaledDown = false;
|
private boolean mTaskIconScaledDown = false;
|
||||||
|
@ -626,6 +636,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
mClearAllButton.setOnClickListener(this::dismissAllTasks);
|
mClearAllButton.setOnClickListener(this::dismissAllTasks);
|
||||||
mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
|
mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
|
||||||
10 /* initial size */);
|
10 /* initial size */);
|
||||||
|
// There's only one pair of grouped tasks we can envision at the moment
|
||||||
|
mGroupedTaskViewPool = new ViewPool<>(context, this,
|
||||||
|
R.layout.task_grouped, 2 /* max size */, 1 /* initial size */);
|
||||||
|
|
||||||
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
|
mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources());
|
||||||
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
|
setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
|
||||||
|
@ -656,10 +669,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
// Initialize quickstep specific cache params here, as this is constructed only once
|
// Initialize quickstep specific cache params here, as this is constructed only once
|
||||||
mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
|
mActivity.getViewCache().setCacheSize(R.layout.digital_wellbeing_toast, 5);
|
||||||
|
|
||||||
mLiveTileTaskViewSimulator = new TaskViewSimulator(getContext(), getSizeStrategy());
|
|
||||||
mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
|
|
||||||
mLiveTileTaskViewSimulator.setOrientationState(mOrientationState);
|
|
||||||
|
|
||||||
mTintingColor = getForegroundScrimDimColor(context);
|
mTintingColor = getForegroundScrimDimColor(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,7 +716,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
super.dispatchDraw(canvas);
|
super.dispatchDraw(canvas);
|
||||||
}
|
}
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
|
||||||
&& mLiveTileParams.getTargetSet() != null) {
|
&& mRemoteTargetHandles != null) {
|
||||||
redrawLiveTile();
|
redrawLiveTile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -749,9 +758,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
if (mHandleTaskStackChanges) {
|
if (mHandleTaskStackChanges) {
|
||||||
TaskView taskView = getTaskViewByTaskId(taskId);
|
TaskView taskView = getTaskViewByTaskId(taskId);
|
||||||
if (taskView != null) {
|
if (taskView != null) {
|
||||||
Task task = taskView.getTask();
|
for (TaskView.TaskIdAttributeContainer container :
|
||||||
taskView.getThumbnail().setThumbnail(task, thumbnailData);
|
taskView.getTaskIdAttributeContainers()) {
|
||||||
return task;
|
if (container == null || taskId != container.getTask().key.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
container.getThumbnailView().setThumbnail(container.getTask(), thumbnailData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -812,7 +825,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||||
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
|
TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener);
|
||||||
mSyncTransactionApplier = new SurfaceTransactionApplier(this);
|
mSyncTransactionApplier = new SurfaceTransactionApplier(this);
|
||||||
mLiveTileParams.setSyncTransactionApplier(mSyncTransactionApplier);
|
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||||
|
.setSyncTransactionApplier(mSyncTransactionApplier));
|
||||||
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
|
RecentsModel.INSTANCE.get(getContext()).addThumbnailChangeListener(this);
|
||||||
mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
|
mIPipAnimationListener.setActivityAndRecentsView(mActivity, this);
|
||||||
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
|
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(
|
||||||
|
@ -830,7 +844,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
|
||||||
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
|
TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener);
|
||||||
mSyncTransactionApplier = null;
|
mSyncTransactionApplier = null;
|
||||||
mLiveTileParams.setSyncTransactionApplier(null);
|
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||||
|
.setSyncTransactionApplier(null));
|
||||||
executeSideTaskLaunchCallback();
|
executeSideTaskLaunchCallback();
|
||||||
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
|
RecentsModel.INSTANCE.get(getContext()).removeThumbnailChangeListener(this);
|
||||||
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
|
SystemUiProxy.INSTANCE.get(getContext()).setPinnedStackAnimationListener(null);
|
||||||
|
@ -851,9 +866,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
if (child instanceof TaskView && child != mSplitHiddenTaskView
|
if (child instanceof TaskView && child != mSplitHiddenTaskView
|
||||||
&& child != mMovingTaskView) {
|
&& child != mMovingTaskView) {
|
||||||
TaskView taskView = (TaskView) child;
|
TaskView taskView = (TaskView) child;
|
||||||
mHasVisibleTaskData.delete(taskView.getTaskIds()[0]);
|
for (int i : taskView.getTaskIds()) {
|
||||||
|
mHasVisibleTaskData.delete(i);
|
||||||
|
}
|
||||||
|
if (child instanceof GroupedTaskView) {
|
||||||
|
mGroupedTaskViewPool.recycle((GroupedTaskView)taskView);
|
||||||
|
} else {
|
||||||
|
mTaskViewPool.recycle(taskView);
|
||||||
|
}
|
||||||
taskView.setTaskViewId(-1);
|
taskView.setTaskViewId(-1);
|
||||||
mTaskViewPool.recycle(taskView);
|
|
||||||
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
|
mActionsView.updateHiddenFlags(HIDDEN_NO_TASKS, getTaskViewCount() == 0);
|
||||||
}
|
}
|
||||||
updateTaskStartIndex(child);
|
updateTaskStartIndex(child);
|
||||||
|
@ -906,10 +927,15 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO(b/195675206) Check both taskIDs from runningTaskViewId
|
||||||
|
* and launch if either of them is {@param taskId}
|
||||||
|
*/
|
||||||
public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
|
public void launchSideTaskInLiveTileModeForRestartedApp(int taskId) {
|
||||||
int runningTaskViewId = getTaskViewIdFromTaskId(taskId);
|
int runningTaskViewId = getTaskViewIdFromTaskId(taskId);
|
||||||
if (mRunningTaskViewId != -1 && mRunningTaskViewId == runningTaskViewId) {
|
if (mRunningTaskViewId != -1 && mRunningTaskViewId == runningTaskViewId) {
|
||||||
RemoteAnimationTargets targets = getLiveTileParams().getTargetSet();
|
TransformParams params = mRemoteTargetHandles[0].mTransformParams;
|
||||||
|
RemoteAnimationTargets targets = params.getTargetSet();
|
||||||
if (targets != null && targets.findTask(taskId) != null) {
|
if (targets != null && targets.findTask(taskId) != null) {
|
||||||
launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
|
launchSideTaskInLiveTileMode(taskId, targets.apps, targets.wallpapers,
|
||||||
targets.nonApps);
|
targets.nonApps);
|
||||||
|
@ -1015,10 +1041,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
// Reset the running task when leaving overview since it can still have a reference to
|
// Reset the running task when leaving overview since it can still have a reference to
|
||||||
// its thumbnail
|
// its thumbnail
|
||||||
mTmpRunningTask = null;
|
mTmpRunningTasks = null;
|
||||||
if (mSplitSelectStateController.isSplitSelectActive()) {
|
if (mSplitSelectStateController.isSplitSelectActive()) {
|
||||||
cancelSplitSelect(false);
|
cancelSplitSelect(false);
|
||||||
}
|
}
|
||||||
|
// Remove grouped tasks and recycle once we exit overview
|
||||||
|
int taskCount = getTaskViewCount();
|
||||||
|
for (int i = 0; i < taskCount; i++) {
|
||||||
|
View v = getTaskViewAt(i);
|
||||||
|
if (!(v instanceof GroupedTaskView)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GroupedTaskView gtv = (GroupedTaskView) v;
|
||||||
|
gtv.onTaskListVisibilityChanged(false);
|
||||||
|
removeView(gtv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateLocusId();
|
updateLocusId();
|
||||||
}
|
}
|
||||||
|
@ -1220,18 +1257,32 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
TaskView ignoreResetTaskView =
|
TaskView ignoreResetTaskView =
|
||||||
mIgnoreResetTaskId == -1 ? null : getTaskViewByTaskId(mIgnoreResetTaskId);
|
mIgnoreResetTaskId == -1 ? null : getTaskViewByTaskId(mIgnoreResetTaskId);
|
||||||
|
|
||||||
final int requiredTaskCount = tasks.size();
|
int[] splitTaskIds =
|
||||||
if (getTaskViewCount() != requiredTaskCount) {
|
LauncherSplitScreenListener.INSTANCE.getNoCreate().getSplitTaskIds();
|
||||||
|
int requiredGroupTaskViews = splitTaskIds.length / 2;
|
||||||
|
|
||||||
|
// Subtract half the number of split tasks and not total number because we've already
|
||||||
|
// added a GroupedTaskView when swipe up gesture happens.
|
||||||
|
// This will need to change if we start showing GroupedTaskViews during swipe up from home
|
||||||
|
int requiredTaskViewCount = tasks.size() - requiredGroupTaskViews;
|
||||||
|
|
||||||
|
if (getTaskViewCount() != requiredTaskViewCount) {
|
||||||
if (indexOfChild(mClearAllButton) != -1) {
|
if (indexOfChild(mClearAllButton) != -1) {
|
||||||
removeView(mClearAllButton);
|
removeView(mClearAllButton);
|
||||||
}
|
}
|
||||||
for (int i = getTaskViewCount(); i < requiredTaskCount; i++) {
|
|
||||||
addView(getTaskViewFromPool());
|
for (int i = getTaskViewCount(); i < requiredTaskViewCount; i++) {
|
||||||
|
addView(getTaskViewFromPool(false));
|
||||||
}
|
}
|
||||||
while (getTaskViewCount() > requiredTaskCount) {
|
while (getTaskViewCount() > requiredTaskViewCount) {
|
||||||
removeView(getChildAt(getChildCount() - 1));
|
removeView(getChildAt(getChildCount() - 1));
|
||||||
}
|
}
|
||||||
if (requiredTaskCount > 0) {
|
while (requiredGroupTaskViews > 0) {
|
||||||
|
// Add to front of list
|
||||||
|
addView(getTaskViewFromPool(true), 0);
|
||||||
|
requiredGroupTaskViews--;
|
||||||
|
}
|
||||||
|
if (requiredTaskViewCount > 0) {
|
||||||
addView(mClearAllButton);
|
addView(mClearAllButton);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1245,12 +1296,28 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
+ " runningTaskViewId: " + mRunningTaskViewId
|
+ " runningTaskViewId: " + mRunningTaskViewId
|
||||||
+ " forTaskView: " + getTaskViewFromTaskViewId(mRunningTaskViewId));
|
+ " forTaskView: " + getTaskViewFromTaskViewId(mRunningTaskViewId));
|
||||||
|
|
||||||
// Rebind and reset all task views
|
for (int taskViewIndex = requiredTaskViewCount - 1, taskDataIndex = tasks.size() - 1;
|
||||||
for (int i = requiredTaskCount - 1; i >= 0; i--) {
|
taskViewIndex >= 0;
|
||||||
final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
|
taskViewIndex--, taskDataIndex--) {
|
||||||
final Task task = tasks.get(i);
|
final int pageIndex = requiredTaskViewCount - taskViewIndex - 1 + mTaskViewStartIndex;
|
||||||
|
final Task task = tasks.get(taskDataIndex);
|
||||||
final TaskView taskView = (TaskView) getChildAt(pageIndex);
|
final TaskView taskView = (TaskView) getChildAt(pageIndex);
|
||||||
taskView.bind(task, mOrientationState);
|
if (taskView instanceof GroupedTaskView) {
|
||||||
|
Task leftTop;
|
||||||
|
Task rightBottom;
|
||||||
|
if (task.key.id == splitTaskIds[0]) {
|
||||||
|
leftTop = task;
|
||||||
|
taskDataIndex--;
|
||||||
|
rightBottom = tasks.get(taskDataIndex);
|
||||||
|
} else {
|
||||||
|
rightBottom = task;
|
||||||
|
taskDataIndex--;
|
||||||
|
leftTop = tasks.get(taskDataIndex);
|
||||||
|
}
|
||||||
|
((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState);
|
||||||
|
} else {
|
||||||
|
taskView.bind(task, mOrientationState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep same previous focused task
|
// Keep same previous focused task
|
||||||
|
@ -1270,8 +1337,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
newRunningTaskView = getTaskViewByTaskId(runningTaskId);
|
newRunningTaskView = getTaskViewByTaskId(runningTaskId);
|
||||||
if (newRunningTaskView == null) {
|
if (newRunningTaskView == null) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = requiredTaskCount - 1; i >= 0; i--) {
|
for (int i = requiredTaskViewCount - 1; i >= 0; i--) {
|
||||||
final int pageIndex = requiredTaskCount - i - 1 + mTaskViewStartIndex;
|
final int pageIndex = requiredTaskViewCount - i - 1 + mTaskViewStartIndex;
|
||||||
final TaskView taskView = (TaskView) getChildAt(pageIndex);
|
final TaskView taskView = (TaskView) getChildAt(pageIndex);
|
||||||
int taskViewId = taskView.getTaskViewId();
|
int taskViewId = taskView.getTaskViewId();
|
||||||
sb.append(" taskViewId: " + taskViewId
|
sb.append(" taskViewId: " + taskViewId
|
||||||
|
@ -1354,12 +1421,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
// Since we reuse the same mLiveTileTaskViewSimulator in the RecentsView, we need
|
// Since we reuse the same mLiveTileTaskViewSimulator in the RecentsView, we need
|
||||||
// to reset the params after it settles in Overview from swipe up so that we don't
|
// to reset the params after it settles in Overview from swipe up so that we don't
|
||||||
// render with obsolete param values.
|
// render with obsolete param values.
|
||||||
mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = 0;
|
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||||
mLiveTileTaskViewSimulator.taskSecondaryTranslation.value = 0;
|
remoteTargetHandle.mTaskViewSimulator.taskPrimaryTranslation.value = 0;
|
||||||
mLiveTileTaskViewSimulator.fullScreenProgress.value = 0;
|
remoteTargetHandle.mTaskViewSimulator.taskSecondaryTranslation.value = 0;
|
||||||
mLiveTileTaskViewSimulator.recentsViewScale.value = 1;
|
remoteTargetHandle.mTaskViewSimulator.fullScreenProgress.value = 0;
|
||||||
|
remoteTargetHandle.mTaskViewSimulator.recentsViewScale.value = 1;
|
||||||
mLiveTileParams.setTargetAlpha(1);
|
});
|
||||||
|
|
||||||
// Similar to setRunningTaskHidden below, reapply the state before runningTaskView is
|
// Similar to setRunningTaskHidden below, reapply the state before runningTaskView is
|
||||||
// null.
|
// null.
|
||||||
|
@ -1413,7 +1480,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
setPageSpacing(dp.overviewPageSpacing);
|
setPageSpacing(dp.overviewPageSpacing);
|
||||||
|
|
||||||
// Propagate DeviceProfile change event.
|
// Propagate DeviceProfile change event.
|
||||||
mLiveTileTaskViewSimulator.setDp(dp);
|
runActionOnRemoteHandles(
|
||||||
|
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator.setDp(dp));
|
||||||
mActionsView.setDp(dp);
|
mActionsView.setDp(dp);
|
||||||
mOrientationState.setDeviceProfile(dp);
|
mOrientationState.setDeviceProfile(dp);
|
||||||
|
|
||||||
|
@ -1524,8 +1592,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getTaskSize(Rect outRect) {
|
public void getTaskSize(Rect outRect) {
|
||||||
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect,
|
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), outRect);
|
||||||
mOrientationHandler);
|
|
||||||
mLastComputedTaskSize.set(outRect);
|
mLastComputedTaskSize.set(outRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1533,8 +1600,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
* Returns the size of task selected to enter modal state.
|
* Returns the size of task selected to enter modal state.
|
||||||
*/
|
*/
|
||||||
public Point getSelectedTaskSize() {
|
public Point getSelectedTaskSize() {
|
||||||
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), mTempRect,
|
mSizeStrategy.calculateTaskSize(mActivity, mActivity.getDeviceProfile(), mTempRect);
|
||||||
mOrientationHandler);
|
|
||||||
return new Point(mTempRect.width(), mTempRect.height());
|
return new Point(mTempRect.width(), mTempRect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1667,8 +1733,17 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
visible = lower <= index && index <= upper;
|
visible = lower <= index && index <= upper;
|
||||||
}
|
}
|
||||||
if (visible) {
|
if (visible) {
|
||||||
if (task == mTmpRunningTask) {
|
boolean skipLoadingTask = false;
|
||||||
// Skip loading if this is the task that we are animating into
|
if (mTmpRunningTasks != null) {
|
||||||
|
for (Task t : mTmpRunningTasks) {
|
||||||
|
if (task == t) {
|
||||||
|
// Skip loading if this is the task that we are animating into
|
||||||
|
skipLoadingTask = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (skipLoadingTask) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!mHasVisibleTaskData.get(task.key.id)) {
|
if (!mHasVisibleTaskData.get(task.key.id)) {
|
||||||
|
@ -1743,7 +1818,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setEnableDrawingLiveTile(false);
|
setEnableDrawingLiveTile(false);
|
||||||
mLiveTileParams.setTargetSet(null);
|
runActionOnRemoteHandles(remoteTargetHandle -> remoteTargetHandle.mTransformParams
|
||||||
|
.setTargetSet(null));
|
||||||
|
|
||||||
// These are relatively expensive and don't need to be done this frame (RecentsView isn't
|
// These are relatively expensive and don't need to be done this frame (RecentsView isn't
|
||||||
// visible anyway), so defer by a frame to get off the critical path, e.g. app to home.
|
// visible anyway), so defer by a frame to get off the critical path, e.g. app to home.
|
||||||
|
@ -1810,8 +1886,10 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
* Handle the edge case where Recents could increment task count very high over long
|
* Handle the edge case where Recents could increment task count very high over long
|
||||||
* period of device usage. Probably will never happen, but meh.
|
* period of device usage. Probably will never happen, but meh.
|
||||||
*/
|
*/
|
||||||
private TaskView getTaskViewFromPool() {
|
private <T extends TaskView> T getTaskViewFromPool(boolean isGrouped) {
|
||||||
TaskView taskView = mTaskViewPool.getView();
|
T taskView = isGrouped ?
|
||||||
|
(T) mGroupedTaskViewPool.getView() :
|
||||||
|
(T) mTaskViewPool.getView();
|
||||||
taskView.setTaskViewId(mTaskViewIdCount);
|
taskView.setTaskViewId(mTaskViewIdCount);
|
||||||
if (mTaskViewIdCount == Integer.MAX_VALUE) {
|
if (mTaskViewIdCount == Integer.MAX_VALUE) {
|
||||||
mTaskViewIdCount = 0;
|
mTaskViewIdCount = 0;
|
||||||
|
@ -1847,7 +1925,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
/**
|
/**
|
||||||
* Called when a gesture from an app is starting.
|
* Called when a gesture from an app is starting.
|
||||||
*/
|
*/
|
||||||
public void onGestureAnimationStart(RunningTaskInfo runningTaskInfo) {
|
public void onGestureAnimationStart(RunningTaskInfo[] runningTaskInfo) {
|
||||||
mGestureActive = true;
|
mGestureActive = true;
|
||||||
// This needs to be called before the other states are set since it can create the task view
|
// This needs to be called before the other states are set since it can create the task view
|
||||||
if (mOrientationState.setGestureActive(true)) {
|
if (mOrientationState.setGestureActive(true)) {
|
||||||
|
@ -1914,7 +1992,7 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
*/
|
*/
|
||||||
public void onPrepareGestureEndAnimation(
|
public void onPrepareGestureEndAnimation(
|
||||||
@Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
|
@Nullable AnimatorSet animatorSet, GestureState.GestureEndTarget endTarget,
|
||||||
TaskViewSimulator taskViewSimulator) {
|
TaskViewSimulator[] taskViewSimulators) {
|
||||||
mCurrentGestureEndTarget = endTarget;
|
mCurrentGestureEndTarget = endTarget;
|
||||||
if (endTarget == GestureState.GestureEndTarget.RECENTS) {
|
if (endTarget == GestureState.GestureEndTarget.RECENTS) {
|
||||||
setEnableFreeScroll(true);
|
setEnableFreeScroll(true);
|
||||||
|
@ -1931,13 +2009,16 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
runningTaskView.getGridTranslationX(),
|
runningTaskView.getGridTranslationX(),
|
||||||
runningTaskView.getGridTranslationY());
|
runningTaskView.getGridTranslationY());
|
||||||
}
|
}
|
||||||
if (animatorSet == null) {
|
for (TaskViewSimulator tvs : taskViewSimulators) {
|
||||||
setGridProgress(1);
|
if (animatorSet == null) {
|
||||||
taskViewSimulator.taskPrimaryTranslation.value = runningTaskPrimaryGridTranslation;
|
setGridProgress(1);
|
||||||
} else {
|
tvs.taskPrimaryTranslation.value =
|
||||||
animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
|
runningTaskPrimaryGridTranslation;
|
||||||
animatorSet.play(taskViewSimulator.taskPrimaryTranslation.animateToValue(
|
} else {
|
||||||
runningTaskPrimaryGridTranslation));
|
animatorSet.play(ObjectAnimator.ofFloat(this, RECENTS_GRID_PROGRESS, 1));
|
||||||
|
animatorSet.play(tvs.taskPrimaryTranslation.animateToValue(
|
||||||
|
runningTaskPrimaryGridTranslation));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1966,7 +2047,21 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
/**
|
/**
|
||||||
* Returns true if we should add a stub taskView for the running task id
|
* Returns true if we should add a stub taskView for the running task id
|
||||||
*/
|
*/
|
||||||
protected boolean shouldAddStubTaskView(RunningTaskInfo runningTaskInfo) {
|
protected boolean shouldAddStubTaskView(RunningTaskInfo[] runningTaskInfos) {
|
||||||
|
if (runningTaskInfos.length > 1) {
|
||||||
|
// * Always create new view for GroupedTaskView
|
||||||
|
// * Remove existing associated taskViews for tasks currently in split
|
||||||
|
for (RunningTaskInfo rti : runningTaskInfos) {
|
||||||
|
TaskView taskView = getTaskViewByTaskId(rti.taskId);
|
||||||
|
if (taskView == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
taskView.onTaskListVisibilityChanged(false);
|
||||||
|
removeView(taskView);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
RunningTaskInfo runningTaskInfo = runningTaskInfos[0];
|
||||||
return runningTaskInfo != null && getTaskViewByTaskId(runningTaskInfo.taskId) == null;
|
return runningTaskInfo != null && getTaskViewByTaskId(runningTaskInfo.taskId) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1976,29 +2071,44 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
* All subsequent calls to reload will keep the task as the first item until {@link #reset()}
|
* All subsequent calls to reload will keep the task as the first item until {@link #reset()}
|
||||||
* is called. Also scrolls the view to this task.
|
* is called. Also scrolls the view to this task.
|
||||||
*/
|
*/
|
||||||
public void showCurrentTask(RunningTaskInfo runningTaskInfo) {
|
public void showCurrentTask(RunningTaskInfo[] runningTaskInfo) {
|
||||||
int runningTaskViewId = -1;
|
int runningTaskViewId = -1;
|
||||||
|
boolean needGroupTaskView = runningTaskInfo.length > 1;
|
||||||
|
RunningTaskInfo taskInfo = runningTaskInfo[0];
|
||||||
if (shouldAddStubTaskView(runningTaskInfo)) {
|
if (shouldAddStubTaskView(runningTaskInfo)) {
|
||||||
boolean wasEmpty = getChildCount() == 0;
|
boolean wasEmpty = getChildCount() == 0;
|
||||||
// Add an empty view for now until the task plan is loaded and applied
|
// Add an empty view for now until the task plan is loaded and applied
|
||||||
final TaskView taskView = getTaskViewFromPool();
|
final TaskView taskView;
|
||||||
|
if (needGroupTaskView) {
|
||||||
|
taskView = getTaskViewFromPool(true);
|
||||||
|
RunningTaskInfo secondaryTaskInfo = runningTaskInfo[1];
|
||||||
|
mTmpRunningTasks = new Task[]{
|
||||||
|
Task.from(new TaskKey(taskInfo), taskInfo, false),
|
||||||
|
Task.from(new TaskKey(secondaryTaskInfo), secondaryTaskInfo, false)
|
||||||
|
};
|
||||||
|
addView(taskView, mTaskViewStartIndex);
|
||||||
|
((GroupedTaskView)taskView).bind(mTmpRunningTasks[0], mTmpRunningTasks[1],
|
||||||
|
mOrientationState);
|
||||||
|
} else {
|
||||||
|
taskView = getTaskViewFromPool(false);
|
||||||
|
addView(taskView, mTaskViewStartIndex);
|
||||||
|
// The temporary running task is only used for the duration between the start of the
|
||||||
|
// gesture and the task list is loaded and applied
|
||||||
|
mTmpRunningTasks = new Task[]{Task.from(new TaskKey(taskInfo), taskInfo, false)};
|
||||||
|
taskView.bind(mTmpRunningTasks[0], mOrientationState);
|
||||||
|
}
|
||||||
runningTaskViewId = taskView.getTaskViewId();
|
runningTaskViewId = taskView.getTaskViewId();
|
||||||
addView(taskView, mTaskViewStartIndex);
|
|
||||||
if (wasEmpty) {
|
if (wasEmpty) {
|
||||||
addView(mClearAllButton);
|
addView(mClearAllButton);
|
||||||
}
|
}
|
||||||
// The temporary running task is only used for the duration between the start of the
|
|
||||||
// gesture and the task list is loaded and applied
|
|
||||||
mTmpRunningTask = Task.from(new TaskKey(runningTaskInfo), runningTaskInfo, false);
|
|
||||||
taskView.bind(mTmpRunningTask, mOrientationState);
|
|
||||||
|
|
||||||
// Measure and layout immediately so that the scroll values is updated instantly
|
// Measure and layout immediately so that the scroll values is updated instantly
|
||||||
// as the user might be quick-switching
|
// as the user might be quick-switching
|
||||||
measure(makeMeasureSpec(getMeasuredWidth(), EXACTLY),
|
measure(makeMeasureSpec(getMeasuredWidth(), EXACTLY),
|
||||||
makeMeasureSpec(getMeasuredHeight(), EXACTLY));
|
makeMeasureSpec(getMeasuredHeight(), EXACTLY));
|
||||||
layout(getLeft(), getTop(), getRight(), getBottom());
|
layout(getLeft(), getTop(), getRight(), getBottom());
|
||||||
} else if (getTaskViewByTaskId(runningTaskInfo.taskId) != null) {
|
} else if (!needGroupTaskView && getTaskViewByTaskId(taskInfo.taskId) != null) {
|
||||||
runningTaskViewId = getTaskViewByTaskId(runningTaskInfo.taskId).getTaskViewId();
|
runningTaskViewId = getTaskViewByTaskId(taskInfo.taskId).getTaskViewId();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean runningTaskTileHidden = mRunningTaskTileHidden;
|
boolean runningTaskTileHidden = mRunningTaskTileHidden;
|
||||||
|
@ -2413,8 +2523,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
// Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
|
// Use setFloat instead of setViewAlpha as we want to keep the view visible even when it's
|
||||||
// alpha is set to 0 so that it can be recycled in the view pool properly
|
// alpha is set to 0 so that it can be recycled in the view pool properly
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && taskView.isRunningTask()) {
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && taskView.isRunningTask()) {
|
||||||
anim.setFloat(mLiveTileParams, TransformParams.TARGET_ALPHA, 0,
|
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||||
clampToProgress(ACCEL, 0, 0.5f));
|
TransformParams params = remoteTargetHandle.mTransformParams;
|
||||||
|
anim.setFloat(params, TransformParams.TARGET_ALPHA, 0,
|
||||||
|
clampToProgress(ACCEL, 0, 0.5f));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(ACCEL, 0, 0.5f));
|
anim.setFloat(taskView, VIEW_ALPHA, 0, clampToProgress(ACCEL, 0, 0.5f));
|
||||||
FloatProperty<TaskView> secondaryViewTranslate =
|
FloatProperty<TaskView> secondaryViewTranslate =
|
||||||
|
@ -2433,10 +2546,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
|
||||||
&& taskView.isRunningTask()) {
|
&& taskView.isRunningTask()) {
|
||||||
anim.addOnFrameCallback(() -> {
|
anim.addOnFrameCallback(() -> {
|
||||||
mLiveTileTaskViewSimulator.taskSecondaryTranslation.value =
|
runActionOnRemoteHandles(
|
||||||
mOrientationHandler.getSecondaryValue(
|
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||||
taskView.getTranslationX(),
|
.taskSecondaryTranslation.value = mOrientationHandler
|
||||||
taskView.getTranslationY());
|
.getSecondaryValue(taskView.getTranslationX(),
|
||||||
|
taskView.getTranslationY()
|
||||||
|
));
|
||||||
redrawLiveTile();
|
redrawLiveTile();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2487,7 +2602,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
boolean showAsGrid = showAsGrid();
|
boolean showAsGrid = showAsGrid();
|
||||||
int taskCount = getTaskViewCount();
|
int taskCount = getTaskViewCount();
|
||||||
int dismissedIndex = indexOfChild(dismissedTaskView);
|
int dismissedIndex = indexOfChild(dismissedTaskView);
|
||||||
int dismissedTaskId = dismissedTaskView.getTaskIds()[0];
|
|
||||||
int dismissedTaskViewId = dismissedTaskView.getTaskViewId();
|
int dismissedTaskViewId = dismissedTaskView.getTaskViewId();
|
||||||
|
|
||||||
// Grid specific properties.
|
// Grid specific properties.
|
||||||
|
@ -2585,9 +2699,14 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
&& child instanceof TaskView
|
&& child instanceof TaskView
|
||||||
&& ((TaskView) child).isRunningTask()) {
|
&& ((TaskView) child).isRunningTask()) {
|
||||||
anim.addOnFrameCallback(() -> {
|
anim.addOnFrameCallback(() -> {
|
||||||
mLiveTileTaskViewSimulator.taskPrimaryTranslation.value =
|
runActionOnRemoteHandles(
|
||||||
mOrientationHandler.getPrimaryValue(child.getTranslationX(),
|
remoteTargetHandle ->
|
||||||
child.getTranslationY());
|
remoteTargetHandle.mTaskViewSimulator
|
||||||
|
.taskPrimaryTranslation.value =
|
||||||
|
mOrientationHandler.getPrimaryValue(
|
||||||
|
child.getTranslationX(),
|
||||||
|
child.getTranslationY()
|
||||||
|
));
|
||||||
redrawLiveTile();
|
redrawLiveTile();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2669,9 +2788,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get()
|
||||||
&& dismissedTaskView.isRunningTask()) {
|
&& dismissedTaskView.isRunningTask()) {
|
||||||
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
|
finishRecentsAnimation(true /* toRecents */, false /* shouldPip */,
|
||||||
() -> removeTaskInternal(dismissedTaskId));
|
() -> removeTaskInternal(dismissedTaskViewId));
|
||||||
} else {
|
} else {
|
||||||
removeTaskInternal(dismissedTaskId);
|
removeTaskInternal(dismissedTaskViewId);
|
||||||
}
|
}
|
||||||
mActivity.getStatsLogManager().logger()
|
mActivity.getStatsLogManager().logger()
|
||||||
.withItemInfo(dismissedTaskView.getItemInfo())
|
.withItemInfo(dismissedTaskView.getItemInfo())
|
||||||
|
@ -2801,9 +2920,17 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
return lastVisibleIndex;
|
return lastVisibleIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeTaskInternal(int dismissedTaskId) {
|
private void removeTaskInternal(int dismissedTaskViewId) {
|
||||||
|
int[] taskIds = getTaskIdsForTaskViewId(dismissedTaskViewId);
|
||||||
|
int primaryTaskId = taskIds[0];
|
||||||
|
int secondaryTaskId = taskIds[1];
|
||||||
UI_HELPER_EXECUTOR.getHandler().postDelayed(
|
UI_HELPER_EXECUTOR.getHandler().postDelayed(
|
||||||
() -> ActivityManagerWrapper.getInstance().removeTask(dismissedTaskId),
|
() -> {
|
||||||
|
ActivityManagerWrapper.getInstance().removeTask(primaryTaskId);
|
||||||
|
if (secondaryTaskId != -1) {
|
||||||
|
ActivityManagerWrapper.getInstance().removeTask(secondaryTaskId);
|
||||||
|
}
|
||||||
|
},
|
||||||
REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
|
REMOVE_TASK_WAIT_FOR_APP_STOP_MS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3136,7 +3263,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
mLastComputedTaskStartPushOutDistance = null;
|
mLastComputedTaskStartPushOutDistance = null;
|
||||||
mLastComputedTaskEndPushOutDistance = null;
|
mLastComputedTaskEndPushOutDistance = null;
|
||||||
updatePageOffsets();
|
updatePageOffsets();
|
||||||
mLiveTileTaskViewSimulator.setScroll(getScrollOffset());
|
runActionOnRemoteHandles(
|
||||||
|
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||||
|
.setScroll(getScrollOffset()));
|
||||||
setImportantForAccessibility(isModal() ? IMPORTANT_FOR_ACCESSIBILITY_NO
|
setImportantForAccessibility(isModal() ? IMPORTANT_FOR_ACCESSIBILITY_NO
|
||||||
: IMPORTANT_FOR_ACCESSIBILITY_AUTO);
|
: IMPORTANT_FOR_ACCESSIBILITY_AUTO);
|
||||||
}
|
}
|
||||||
|
@ -3200,7 +3329,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
translationProperty.set(child, totalTranslation);
|
translationProperty.set(child, totalTranslation);
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile
|
||||||
&& i == getRunningTaskIndex()) {
|
&& i == getRunningTaskIndex()) {
|
||||||
mLiveTileTaskViewSimulator.taskPrimaryTranslation.value = totalTranslation;
|
runActionOnRemoteHandles(
|
||||||
|
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||||
|
.taskPrimaryTranslation.value = totalTranslation);
|
||||||
redrawLiveTile();
|
redrawLiveTile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3303,7 +3434,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
TaskView task = getTaskViewAt(i);
|
TaskView task = getTaskViewAt(i);
|
||||||
task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY());
|
task.getTaskResistanceTranslationProperty().set(task, translation / getScaleY());
|
||||||
}
|
}
|
||||||
mLiveTileTaskViewSimulator.recentsViewSecondaryTranslation.value = translation;
|
runActionOnRemoteHandles(
|
||||||
|
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||||
|
.recentsViewSecondaryTranslation.value = translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setTaskViewsPrimarySplitTranslation(float translation) {
|
protected void setTaskViewsPrimarySplitTranslation(float translation) {
|
||||||
|
@ -3505,8 +3638,6 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
resetTaskVisuals();
|
resetTaskVisuals();
|
||||||
mSplitHiddenTaskView.setVisibility(VISIBLE);
|
mSplitHiddenTaskView.setVisibility(VISIBLE);
|
||||||
mSplitHiddenTaskView = null;
|
mSplitHiddenTaskView = null;
|
||||||
mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
|
|
||||||
mSecondSplitHiddenTaskView = null;
|
|
||||||
mSplitHiddenTaskViewIndex = -1;
|
mSplitHiddenTaskViewIndex = -1;
|
||||||
if (mFirstFloatingTaskView != null) {
|
if (mFirstFloatingTaskView != null) {
|
||||||
mActivity.getRootView().removeView(mFirstFloatingTaskView);
|
mActivity.getRootView().removeView(mFirstFloatingTaskView);
|
||||||
|
@ -3515,6 +3646,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
if (mSecondFloatingTaskView != null) {
|
if (mSecondFloatingTaskView != null) {
|
||||||
mActivity.getRootView().removeView(mSecondFloatingTaskView);
|
mActivity.getRootView().removeView(mSecondFloatingTaskView);
|
||||||
mSecondFloatingTaskView = null;
|
mSecondFloatingTaskView = null;
|
||||||
|
mSecondSplitHiddenTaskView.setVisibility(VISIBLE);
|
||||||
|
mSecondSplitHiddenTaskView = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3610,10 +3743,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
int runningTaskIndex = recentsView.getRunningTaskIndex();
|
int runningTaskIndex = recentsView.getRunningTaskIndex();
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && runningTaskIndex != -1
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get() && runningTaskIndex != -1
|
||||||
&& runningTaskIndex != taskIndex) {
|
&& runningTaskIndex != taskIndex) {
|
||||||
anim.play(ObjectAnimator.ofFloat(
|
for (RemoteTargetHandle remoteHandle : recentsView.getRemoteTargetHandles()) {
|
||||||
recentsView.getLiveTileTaskViewSimulator().taskPrimaryTranslation,
|
anim.play(ObjectAnimator.ofFloat(
|
||||||
AnimatedFloat.VALUE,
|
remoteHandle.mTaskViewSimulator.taskPrimaryTranslation,
|
||||||
primaryTranslation));
|
AnimatedFloat.VALUE,
|
||||||
|
primaryTranslation));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - taskIndex);
|
int otherAdjacentTaskIndex = centerTaskIndex + (centerTaskIndex - taskIndex);
|
||||||
|
@ -3693,7 +3828,9 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
mPendingAnimation = new PendingAnimation(duration);
|
mPendingAnimation = new PendingAnimation(duration);
|
||||||
mPendingAnimation.add(anim);
|
mPendingAnimation.add(anim);
|
||||||
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
|
||||||
mLiveTileTaskViewSimulator.addOverviewToAppAnim(mPendingAnimation, interpolator);
|
runActionOnRemoteHandles(
|
||||||
|
remoteTargetHandle -> remoteTargetHandle.mTaskViewSimulator
|
||||||
|
.addOverviewToAppAnim(mPendingAnimation, interpolator));
|
||||||
mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
|
mPendingAnimation.addOnFrameCallback(this::redrawLiveTile);
|
||||||
}
|
}
|
||||||
mPendingAnimation.addEndListener(isSuccess -> {
|
mPendingAnimation.addEndListener(isSuccess -> {
|
||||||
|
@ -3784,31 +3921,87 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
}
|
}
|
||||||
|
|
||||||
public void redrawLiveTile() {
|
public void redrawLiveTile() {
|
||||||
if (mLiveTileParams.getTargetSet() != null) {
|
runActionOnRemoteHandles(remoteTargetHandle -> {
|
||||||
mLiveTileTaskViewSimulator.apply(mLiveTileParams);
|
TransformParams params = remoteTargetHandle.mTransformParams;
|
||||||
}
|
if (params.getTargetSet() != null) {
|
||||||
|
remoteTargetHandle.mTaskViewSimulator.apply(params);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskViewSimulator getLiveTileTaskViewSimulator() {
|
public RemoteTargetHandle[] getRemoteTargetHandles() {
|
||||||
return mLiveTileTaskViewSimulator;
|
return mRemoteTargetHandles;
|
||||||
}
|
|
||||||
|
|
||||||
public TransformParams getLiveTileParams() {
|
|
||||||
return mLiveTileParams;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: To be removed in a follow up CL
|
// TODO: To be removed in a follow up CL
|
||||||
public void setRecentsAnimationTargets(RecentsAnimationController recentsAnimationController,
|
public void setRecentsAnimationTargets(RecentsAnimationController recentsAnimationController,
|
||||||
RecentsAnimationTargets recentsAnimationTargets) {
|
RecentsAnimationTargets recentsAnimationTargets) {
|
||||||
mRecentsAnimationController = recentsAnimationController;
|
mRecentsAnimationController = recentsAnimationController;
|
||||||
if (recentsAnimationTargets != null && recentsAnimationTargets.apps.length > 0) {
|
if (recentsAnimationTargets == null || recentsAnimationTargets.apps.length == 0) {
|
||||||
if (mSyncTransactionApplier != null) {
|
return;
|
||||||
recentsAnimationTargets.addReleaseCheck(mSyncTransactionApplier);
|
|
||||||
}
|
|
||||||
mLiveTileTaskViewSimulator.setPreview(
|
|
||||||
recentsAnimationTargets.apps[recentsAnimationTargets.apps.length - 1]);
|
|
||||||
mLiveTileParams.setTargetSet(recentsAnimationTargets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mSyncTransactionApplier != null) {
|
||||||
|
recentsAnimationTargets.addReleaseCheck(mSyncTransactionApplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO Consolidate this shared code with SwipeUpAnimationLogic (or mabe just reuse
|
||||||
|
// what that class has and pass it into here
|
||||||
|
mRemoteTargetHandles = new RemoteTargetHandle[recentsAnimationTargets.apps.length];
|
||||||
|
TaskViewSimulator primaryTvs = createTaskViewSimulator();
|
||||||
|
mRemoteTargetHandles[0] = new RemoteTargetHandle(primaryTvs, new TransformParams());
|
||||||
|
if (recentsAnimationTargets.apps.length == 1) {
|
||||||
|
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 dividerTarget =
|
||||||
|
recentsAnimationTargets.getNonAppTargetOfType(TYPE_DOCK_DIVIDER);
|
||||||
|
RemoteAnimationTargetCompat primaryTaskTarget = recentsAnimationTargets.apps[0];
|
||||||
|
RemoteAnimationTargetCompat secondaryTaskTarget = recentsAnimationTargets.apps[1];
|
||||||
|
SplitConfigurationOptions.StagedSplitBounds
|
||||||
|
info = new SplitConfigurationOptions.StagedSplitBounds(
|
||||||
|
primaryTaskTarget.screenSpaceBounds,
|
||||||
|
secondaryTaskTarget.screenSpaceBounds, dividerTarget.screenSpaceBounds);
|
||||||
|
mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(primaryTaskTarget, info);
|
||||||
|
mRemoteTargetHandles[1].mTaskViewSimulator.setPreview(secondaryTaskTarget, info);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper to avoid writing some for-loops to iterate over {@link #mRemoteTargetHandles} */
|
||||||
|
private void runActionOnRemoteHandles(Consumer<RemoteTargetHandle> consumer) {
|
||||||
|
if (mRemoteTargetHandles == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (RemoteTargetHandle handle : mRemoteTargetHandles) {
|
||||||
|
consumer.accept(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
public void finishRecentsAnimation(boolean toRecents, Runnable onFinishComplete) {
|
||||||
|
@ -4114,14 +4307,42 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
|
||||||
switchToScreenshot(mRunningTaskViewId == -1 ? null
|
switchToScreenshotInternal(onFinishRunnable);
|
||||||
: mRecentsAnimationController.screenshotTask(runningTaskId), onFinishRunnable);
|
}
|
||||||
|
|
||||||
|
private void switchToScreenshotInternal(Runnable onFinishRunnable) {
|
||||||
|
TaskView taskView = getRunningTaskView();
|
||||||
|
if (taskView == null) {
|
||||||
|
onFinishRunnable.run();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
taskView.setShowScreenshot(true);
|
||||||
|
for (TaskView.TaskIdAttributeContainer container :
|
||||||
|
taskView.getTaskIdAttributeContainers()) {
|
||||||
|
if (container == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ThumbnailData td =
|
||||||
|
mRecentsAnimationController.screenshotTask(container.getTask().key.id);
|
||||||
|
TaskThumbnailView thumbnailView = container.getThumbnailView();
|
||||||
|
if (td != null) {
|
||||||
|
thumbnailView.setThumbnail(container.getTask(), td);
|
||||||
|
} else {
|
||||||
|
thumbnailView.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ViewUtils.postFrameDrawn(taskView, onFinishRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch the current running task view to static snapshot mode, using the
|
* Switch the current running task view to static snapshot mode, using the
|
||||||
* provided thumbnail data as the snapshot.
|
* provided thumbnail data as the snapshot.
|
||||||
|
* TODO(b/195609063) Consolidate this method w/ the one above, except this thumbnail data comes
|
||||||
|
* from gesture state, which is a larger change of it having to keep track of multiple tasks.
|
||||||
|
* OR. Maybe it doesn't need to pass in a thumbnail and we can use the exact same flow as above
|
||||||
*/
|
*/
|
||||||
public void switchToScreenshot(ThumbnailData thumbnailData, Runnable onFinishRunnable) {
|
public void switchToScreenshot(ThumbnailData thumbnailData, Runnable onFinishRunnable) {
|
||||||
TaskView taskView = getRunningTaskView();
|
TaskView taskView = getRunningTaskView();
|
||||||
|
@ -4274,7 +4495,8 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dispatchScrollChanged() {
|
private void dispatchScrollChanged() {
|
||||||
mLiveTileTaskViewSimulator.setScroll(getScrollOffset());
|
runActionOnRemoteHandles(remoteTargetHandle ->
|
||||||
|
remoteTargetHandle.mTaskViewSimulator.setScroll(getScrollOffset()));
|
||||||
for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
|
for (int i = mScrollListeners.size() - 1; i >= 0; i--) {
|
||||||
mScrollListeners.get(i).onScrollChanged();
|
mScrollListeners.get(i).onScrollChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,7 @@ import com.android.launcher3.util.TransformingTouchDelegate;
|
||||||
import com.android.launcher3.util.ViewPool.Reusable;
|
import com.android.launcher3.util.ViewPool.Reusable;
|
||||||
import com.android.quickstep.RecentsModel;
|
import com.android.quickstep.RecentsModel;
|
||||||
import com.android.quickstep.RemoteAnimationTargets;
|
import com.android.quickstep.RemoteAnimationTargets;
|
||||||
|
import com.android.quickstep.SwipeUpAnimationLogic.RemoteTargetHandle;
|
||||||
import com.android.quickstep.SystemUiProxy;
|
import com.android.quickstep.SystemUiProxy;
|
||||||
import com.android.quickstep.TaskIconCache;
|
import com.android.quickstep.TaskIconCache;
|
||||||
import com.android.quickstep.TaskOverlayFactory;
|
import com.android.quickstep.TaskOverlayFactory;
|
||||||
|
@ -100,16 +101,20 @@ import com.android.quickstep.TaskViewUtils;
|
||||||
import com.android.quickstep.util.CancellableTask;
|
import com.android.quickstep.util.CancellableTask;
|
||||||
import com.android.quickstep.util.RecentsOrientedState;
|
import com.android.quickstep.util.RecentsOrientedState;
|
||||||
import com.android.quickstep.util.TaskCornerRadius;
|
import com.android.quickstep.util.TaskCornerRadius;
|
||||||
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
|
import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper;
|
||||||
import com.android.systemui.shared.recents.model.Task;
|
import com.android.systemui.shared.recents.model.Task;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||||
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
import com.android.systemui.shared.system.ActivityOptionsCompat;
|
||||||
import com.android.systemui.shared.system.QuickStepContract;
|
import com.android.systemui.shared.system.QuickStepContract;
|
||||||
|
import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A task in the Recents view.
|
* A task in the Recents view.
|
||||||
|
@ -329,8 +334,8 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||||
|
|
||||||
private final TaskOutlineProvider mOutlineProvider;
|
private final TaskOutlineProvider mOutlineProvider;
|
||||||
|
|
||||||
private Task mTask;
|
protected Task mTask;
|
||||||
private TaskThumbnailView mSnapshotView;
|
protected TaskThumbnailView mSnapshotView;
|
||||||
private IconView mIconView;
|
private IconView mIconView;
|
||||||
private final DigitalWellBeingToast mDigitalWellBeingToast;
|
private final DigitalWellBeingToast mDigitalWellBeingToast;
|
||||||
private float mFullscreenProgress;
|
private float mFullscreenProgress;
|
||||||
|
@ -338,7 +343,7 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||||
private float mNonGridScale = 1;
|
private float mNonGridScale = 1;
|
||||||
private float mDismissScale = 1;
|
private float mDismissScale = 1;
|
||||||
private final FullscreenDrawParams mCurrentFullscreenParams;
|
private final FullscreenDrawParams mCurrentFullscreenParams;
|
||||||
private final StatefulActivity mActivity;
|
protected final StatefulActivity mActivity;
|
||||||
|
|
||||||
// Various causes of changing primary translation, which we aggregate to setTranslationX/Y().
|
// Various causes of changing primary translation, which we aggregate to setTranslationX/Y().
|
||||||
private float mDismissTranslationX;
|
private float mDismissTranslationX;
|
||||||
|
@ -367,7 +372,12 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||||
private float mStableAlpha = 1;
|
private float mStableAlpha = 1;
|
||||||
|
|
||||||
private int mTaskViewId = -1;
|
private int mTaskViewId = -1;
|
||||||
private final int[] mTaskIdContainer = new int[]{-1, -1};
|
/**
|
||||||
|
* Index 0 will contain taskID of left/top task, index 1 will contain taskId of bottom/right
|
||||||
|
*/
|
||||||
|
protected final int[] mTaskIdContainer = new int[]{-1, -1};
|
||||||
|
protected final TaskIdAttributeContainer[] mTaskIdAttributeContainer =
|
||||||
|
new TaskIdAttributeContainer[2];
|
||||||
|
|
||||||
private boolean mShowScreenshot;
|
private boolean mShowScreenshot;
|
||||||
|
|
||||||
|
@ -518,10 +528,15 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||||
cancelPendingLoadTasks();
|
cancelPendingLoadTasks();
|
||||||
mTask = task;
|
mTask = task;
|
||||||
mTaskIdContainer[0] = mTask.key.id;
|
mTaskIdContainer[0] = mTask.key.id;
|
||||||
|
mTaskIdAttributeContainer[0] = new TaskIdAttributeContainer(task, mSnapshotView);
|
||||||
mSnapshotView.bind(task);
|
mSnapshotView.bind(task);
|
||||||
setOrientationState(orientedState);
|
setOrientationState(orientedState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TaskIdAttributeContainer[] getTaskIdAttributeContainers() {
|
||||||
|
return mTaskIdAttributeContainer;
|
||||||
|
}
|
||||||
|
|
||||||
public Task getTask() {
|
public Task getTask() {
|
||||||
return mTask;
|
return mTask;
|
||||||
}
|
}
|
||||||
|
@ -563,7 +578,29 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||||
|
|
||||||
mIsClickableAsLiveTile = false;
|
mIsClickableAsLiveTile = false;
|
||||||
RecentsView recentsView = getRecentsView();
|
RecentsView recentsView = getRecentsView();
|
||||||
final RemoteAnimationTargets targets = recentsView.getLiveTileParams().getTargetSet();
|
RemoteAnimationTargets targets;
|
||||||
|
RemoteTargetHandle[] remoteTargetHandles =
|
||||||
|
recentsView.mRemoteTargetHandles;
|
||||||
|
if (remoteTargetHandles.length == 1) {
|
||||||
|
targets = remoteTargetHandles[0].mTransformParams.getTargetSet();
|
||||||
|
} else {
|
||||||
|
TransformParams topLeftParams = remoteTargetHandles[0].mTransformParams;
|
||||||
|
TransformParams rightBottomParams = remoteTargetHandles[1].mTransformParams;
|
||||||
|
RemoteAnimationTargetCompat[] apps = Stream.concat(
|
||||||
|
Arrays.stream(topLeftParams.getTargetSet().apps),
|
||||||
|
Arrays.stream(rightBottomParams.getTargetSet().apps))
|
||||||
|
.toArray(RemoteAnimationTargetCompat[]::new);
|
||||||
|
RemoteAnimationTargetCompat[] wallpapers = Stream.concat(
|
||||||
|
Arrays.stream(topLeftParams.getTargetSet().wallpapers),
|
||||||
|
Arrays.stream(rightBottomParams.getTargetSet().wallpapers))
|
||||||
|
.toArray(RemoteAnimationTargetCompat[]::new);
|
||||||
|
RemoteAnimationTargetCompat[] nonApps = Stream.concat(
|
||||||
|
Arrays.stream(topLeftParams.getTargetSet().nonApps),
|
||||||
|
Arrays.stream(rightBottomParams.getTargetSet().nonApps))
|
||||||
|
.toArray(RemoteAnimationTargetCompat[]::new);
|
||||||
|
targets = new RemoteAnimationTargets(apps, wallpapers, nonApps,
|
||||||
|
topLeftParams.getTargetSet().targetMode);
|
||||||
|
}
|
||||||
if (targets == null) {
|
if (targets == null) {
|
||||||
// If the recents animation is cancelled somehow between the parent if block and
|
// If the recents animation is cancelled somehow between the parent if block and
|
||||||
// here, try to launch the task as a non live tile task.
|
// here, try to launch the task as a non live tile task.
|
||||||
|
@ -723,11 +760,11 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) {
|
protected boolean needsUpdate(@TaskDataChanges int dataChange, @TaskDataChanges int flag) {
|
||||||
return (dataChange & flag) == flag;
|
return (dataChange & flag) == flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cancelPendingLoadTasks() {
|
protected void cancelPendingLoadTasks() {
|
||||||
if (mThumbnailLoadRequest != null) {
|
if (mThumbnailLoadRequest != null) {
|
||||||
mThumbnailLoadRequest.cancel();
|
mThumbnailLoadRequest.cancel();
|
||||||
mThumbnailLoadRequest = null;
|
mThumbnailLoadRequest = null;
|
||||||
|
@ -1509,4 +1546,22 @@ public class TaskView extends FrameLayout implements Reusable {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class TaskIdAttributeContainer {
|
||||||
|
private final TaskThumbnailView thumbnailView;
|
||||||
|
private final Task task;
|
||||||
|
|
||||||
|
public TaskIdAttributeContainer(Task task, TaskThumbnailView thumbnailView) {
|
||||||
|
this.task = task;
|
||||||
|
this.thumbnailView = thumbnailView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskThumbnailView getThumbnailView() {
|
||||||
|
return thumbnailView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task getTask() {
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,6 +221,7 @@ public class DeviceProfile {
|
||||||
// DragController
|
// DragController
|
||||||
public int flingToDeleteThresholdVelocity;
|
public int flingToDeleteThresholdVelocity;
|
||||||
|
|
||||||
|
/** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
|
||||||
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
|
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
|
||||||
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
|
boolean isMultiWindowMode, boolean transposeLayoutWithOrientation,
|
||||||
boolean useTwoPanels) {
|
boolean useTwoPanels) {
|
||||||
|
|
|
@ -18,6 +18,8 @@ package com.android.launcher3.util;
|
||||||
|
|
||||||
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
import static java.lang.annotation.RetentionPolicy.SOURCE;
|
||||||
|
|
||||||
|
import android.graphics.Rect;
|
||||||
|
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
|
@ -82,4 +84,25 @@ public final class SplitConfigurationOptions {
|
||||||
mStageType = stageType;
|
mStageType = stageType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class StagedSplitBounds {
|
||||||
|
public final Rect mLeftTopBounds;
|
||||||
|
public final Rect mRightBottomBounds;
|
||||||
|
public final Rect mDividerBounds;
|
||||||
|
|
||||||
|
|
||||||
|
public StagedSplitBounds(Rect leftTopBounds, Rect rightBottomBounds, Rect dividerBounds) {
|
||||||
|
mLeftTopBounds = leftTopBounds;
|
||||||
|
mRightBottomBounds = rightBottomBounds;
|
||||||
|
mDividerBounds = dividerBounds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class StagedSplitTaskPosition {
|
||||||
|
public int taskId = -1;
|
||||||
|
@StagePosition
|
||||||
|
public int stagePosition = STAGE_POSITION_UNDEFINED;
|
||||||
|
@StageType
|
||||||
|
public int stageType = STAGE_TYPE_UNDEFINED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue