use of com.android.systemui.recents.model.TaskStack in project platform_frameworks_base by android.
the class RecentsImpl method getThumbnailTransitionTransform.
/**
* Returns the transition rect for the given task id.
*/
private TaskViewTransform getThumbnailTransitionTransform(TaskStackView stackView, Task runningTaskOut, Rect windowOverrideRect) {
// Find the running task in the TaskStack
TaskStack stack = stackView.getStack();
Task launchTask = stack.getLaunchTarget();
if (launchTask != null) {
runningTaskOut.copyFrom(launchTask);
} else {
// If no task is specified or we can not find the task just use the front most one
launchTask = stack.getStackFrontMostTask(true);
runningTaskOut.copyFrom(launchTask);
}
// Get the transform for the running task
stackView.updateLayoutAlgorithm(true);
stackView.updateToInitialState();
stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask, stackView.getScroller().getStackScroll(), mTmpTransform, null, windowOverrideRect);
return mTmpTransform;
}
use of com.android.systemui.recents.model.TaskStack in project platform_frameworks_base by android.
the class RecentsView method launchPreviousTask.
/** Launches the task that recents was launched from if possible */
public boolean launchPreviousTask() {
if (mTaskStackView != null) {
TaskStack stack = mTaskStackView.getStack();
Task task = stack.getLaunchTarget();
if (task != null) {
TaskView taskView = mTaskStackView.getChildViewForTask(task);
EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null, INVALID_STACK_ID, false));
return true;
}
}
return false;
}
use of com.android.systemui.recents.model.TaskStack in project platform_frameworks_base by android.
the class TaskStackAnimationHelper method startEnterAnimation.
/**
* Starts the in-app enter animation, which animates the {@link TaskView}s to their final places
* depending on how Recents was triggered.
*/
public void startEnterAnimation(final ReferenceCountedTrigger postAnimationTrigger) {
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
Resources res = mStackView.getResources();
Resources appRes = mStackView.getContext().getApplicationContext().getResources();
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
TaskStackViewScroller stackScroller = mStackView.getScroller();
TaskStack stack = mStackView.getStack();
Task launchTargetTask = stack.getLaunchTarget();
// Break early if there are no tasks
if (stack.getTaskCount() == 0) {
return;
}
int taskViewEnterFromAppDuration = res.getInteger(R.integer.recents_task_enter_from_app_duration);
int taskViewEnterFromAffiliatedAppDuration = res.getInteger(R.integer.recents_task_enter_from_affiliated_app_duration);
int dockGestureAnimDuration = appRes.getInteger(R.integer.long_press_dock_anim_duration);
// Create enter animations for each of the views from front to back
List<TaskView> taskViews = mStackView.getTaskViews();
int taskViewCount = taskViews.size();
for (int i = taskViewCount - 1; i >= 0; i--) {
int taskIndexFromFront = taskViewCount - i - 1;
int taskIndexFromBack = i;
final TaskView tv = taskViews.get(i);
Task task = tv.getTask();
boolean currentTaskOccludesLaunchTarget = launchTargetTask != null && launchTargetTask.group != null && launchTargetTask.group.isTaskAboveTask(task, launchTargetTask);
// Get the current transform for the task, which will be updated to the final transform
// to animate to depending on how recents was invoked
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform, null);
if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
if (task.isLaunchTarget) {
tv.onStartLaunchTargetEnterAnimation(mTmpTransform, taskViewEnterFromAppDuration, mStackView.mScreenPinningEnabled, postAnimationTrigger);
} else {
// Animate the task up if it was occluding the launch target
if (currentTaskOccludesLaunchTarget) {
AnimationProps taskAnimation = new AnimationProps(taskViewEnterFromAffiliatedAppDuration, Interpolators.ALPHA_IN, new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
tv.setClipViewInStack(true);
}
});
postAnimationTrigger.increment();
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
}
}
} else if (launchState.launchedFromHome) {
// Animate the tasks up, but offset the animations to be relative to the front-most
// task animation
AnimationProps taskAnimation = new AnimationProps().setInitialPlayTime(AnimationProps.BOUNDS, Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS, taskIndexFromFront) * DOUBLE_FRAME_OFFSET_MS).setStartDelay(AnimationProps.ALPHA, Math.min(ENTER_EXIT_NUM_ANIMATING_TASKS, taskIndexFromFront) * FRAME_OFFSET_MS).setDuration(AnimationProps.BOUNDS, ENTER_FROM_HOME_TRANSLATION_DURATION).setDuration(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_DURATION).setInterpolator(AnimationProps.BOUNDS, ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR).setInterpolator(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_INTERPOLATOR).setListener(postAnimationTrigger.decrementOnAnimationEnd());
postAnimationTrigger.increment();
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
if (i == taskViewCount - 1) {
tv.onStartFrontTaskEnterAnimation(mStackView.mScreenPinningEnabled);
}
} else if (launchState.launchedViaDockGesture) {
// Animate the tasks up - add some delay to match the divider animation
AnimationProps taskAnimation = new AnimationProps().setDuration(AnimationProps.BOUNDS, dockGestureAnimDuration + (taskIndexFromBack * DOUBLE_FRAME_OFFSET_MS)).setInterpolator(AnimationProps.BOUNDS, ENTER_WHILE_DOCKING_INTERPOLATOR).setStartDelay(AnimationProps.BOUNDS, 48).setListener(postAnimationTrigger.decrementOnAnimationEnd());
postAnimationTrigger.increment();
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
}
}
}
use of com.android.systemui.recents.model.TaskStack in project platform_frameworks_base by android.
the class TaskStackAnimationHelper method prepareForEnterAnimation.
/**
* Prepares the stack views and puts them in their initial animation state while visible, before
* the in-app enter animations start (after the window-transition completes).
*/
public void prepareForEnterAnimation() {
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
Resources res = mStackView.getResources();
Resources appResources = mStackView.getContext().getApplicationContext().getResources();
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
TaskStackViewScroller stackScroller = mStackView.getScroller();
TaskStack stack = mStackView.getStack();
Task launchTargetTask = stack.getLaunchTarget();
// Break early if there are no tasks
if (stack.getTaskCount() == 0) {
return;
}
int offscreenYOffset = stackLayout.mStackRect.height();
int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize(R.dimen.recents_task_stack_animation_affiliate_enter_offset);
int launchedWhileDockingOffset = res.getDimensionPixelSize(R.dimen.recents_task_stack_animation_launched_while_docking_offset);
boolean isLandscape = appResources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
// Prepare each of the task views for their enter animation from front to back
List<TaskView> taskViews = mStackView.getTaskViews();
for (int i = taskViews.size() - 1; i >= 0; i--) {
TaskView tv = taskViews.get(i);
Task task = tv.getTask();
boolean currentTaskOccludesLaunchTarget = launchTargetTask != null && launchTargetTask.group != null && launchTargetTask.group.isTaskAboveTask(task, launchTargetTask);
boolean hideTask = launchTargetTask != null && launchTargetTask.isFreeformTask() && task.isFreeformTask();
// Get the current transform for the task, which will be used to position it offscreen
stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform, null);
if (hideTask) {
tv.setVisibility(View.INVISIBLE);
} else if (launchState.launchedFromApp && !launchState.launchedViaDockGesture) {
if (task.isLaunchTarget) {
tv.onPrepareLaunchTargetForEnterAnimation();
} else if (currentTaskOccludesLaunchTarget) {
// Move the task view slightly lower so we can animate it in
mTmpTransform.rect.offset(0, taskViewAffiliateGroupEnterOffset);
mTmpTransform.alpha = 0f;
mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
tv.setClipViewInStack(false);
}
} else if (launchState.launchedFromHome) {
// Move the task view off screen (below) so we can animate it in
mTmpTransform.rect.offset(0, offscreenYOffset);
mTmpTransform.alpha = 0f;
mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
} else if (launchState.launchedViaDockGesture) {
int offset = isLandscape ? launchedWhileDockingOffset : (int) (offscreenYOffset * 0.9f);
mTmpTransform.rect.offset(0, offset);
mTmpTransform.alpha = 0f;
mStackView.updateTaskViewToTransform(tv, mTmpTransform, AnimationProps.IMMEDIATE);
}
}
}
use of com.android.systemui.recents.model.TaskStack in project platform_frameworks_base by android.
the class RecentsTransitionHelper method composeAnimationSpecs.
/**
* Composes the animation specs for all the tasks in the target stack.
*/
private List<AppTransitionAnimationSpec> composeAnimationSpecs(final Task task, final TaskStackView stackView, final int destinationStack) {
// Ensure we have a valid target stack id
final int targetStackId = destinationStack != INVALID_STACK_ID ? destinationStack : task.key.stackId;
if (!StackId.useAnimationSpecForAppTransition(targetStackId)) {
return null;
}
// Calculate the offscreen task rect (for tasks that are not backed by views)
TaskView taskView = stackView.getChildViewForTask(task);
TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm();
Rect offscreenTaskRect = new Rect();
stackLayout.getFrontOfStackTransform().rect.round(offscreenTaskRect);
// If this is a full screen stack, the transition will be towards the single, full screen
// task. We only need the transition spec for this task.
List<AppTransitionAnimationSpec> specs = new ArrayList<>();
// check for INVALID_STACK_ID
if (targetStackId == FULLSCREEN_WORKSPACE_STACK_ID || targetStackId == DOCKED_STACK_ID || targetStackId == INVALID_STACK_ID) {
if (taskView == null) {
specs.add(composeOffscreenAnimationSpec(task, offscreenTaskRect));
} else {
mTmpTransform.fillIn(taskView);
stackLayout.transformToScreenCoordinates(mTmpTransform, null);
AppTransitionAnimationSpec spec = composeAnimationSpec(stackView, taskView, mTmpTransform, true);
if (spec != null) {
specs.add(spec);
}
}
return specs;
}
// Otherwise, for freeform tasks, create a new animation spec for each task we have to
// launch
TaskStack stack = stackView.getStack();
ArrayList<Task> tasks = stack.getStackTasks();
int taskCount = tasks.size();
for (int i = taskCount - 1; i >= 0; i--) {
Task t = tasks.get(i);
if (t.isFreeformTask() || targetStackId == FREEFORM_WORKSPACE_STACK_ID) {
TaskView tv = stackView.getChildViewForTask(t);
if (tv == null) {
// TODO: Create a different animation task rect for this case (though it should
// never happen)
specs.add(composeOffscreenAnimationSpec(t, offscreenTaskRect));
} else {
mTmpTransform.fillIn(taskView);
stackLayout.transformToScreenCoordinates(mTmpTransform, null);
AppTransitionAnimationSpec spec = composeAnimationSpec(stackView, tv, mTmpTransform, true);
if (spec != null) {
specs.add(spec);
}
}
}
}
return specs;
}
Aggregations