Adding clear-all button.
Change-Id: Ife637438b191c4a5004f3c6551bc75691e8e426b
diff --git a/packages/SystemUI/res/layout/recents_stack_action_button.xml b/packages/SystemUI/res/layout/recents_stack_action_button.xml
index 8783261..2b2ce4e 100644
--- a/packages/SystemUI/res/layout/recents_stack_action_button.xml
+++ b/packages/SystemUI/res/layout/recents_stack_action_button.xml
@@ -27,8 +27,6 @@
android:textSize="14sp"
android:textColor="#FFFFFF"
android:textAllCaps="true"
- android:drawableStart="@drawable/ic_history"
- android:drawablePadding="6dp"
android:shadowColor="#99000000"
android:shadowDx="0"
android:shadowDy="2"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 622ae71..fd051b1 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -153,6 +153,9 @@
<!-- The animation duration for animating the removal of a task view. -->
<integer name="recents_animate_task_view_remove_duration">175</integer>
+ <!-- The base animation duration for animating the removal of all task views. -->
+ <integer name="recents_animate_task_views_remove_all_duration">300</integer>
+
<!-- The animation duration for scrolling the stack to a particular item. -->
<integer name="recents_animate_task_stack_scroll_duration">200</integer>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index d1faa4a..c094da9 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -574,10 +574,12 @@
<dimen name="recents_layout_bottom_margin">16dp</dimen>
<dimen name="recents_layout_side_margin_phone">16dp</dimen>
<dimen name="recents_layout_side_margin_tablet">48dp</dimen>
+ <dimen name="recents_layout_side_margin_tablet_docked">16dp</dimen>
<dimen name="recents_layout_side_margin_tablet_xlarge">64dp</dimen>
+ <dimen name="recents_layout_side_margin_tablet_xlarge_docked">16dp</dimen>
<!-- The height between the top margin and the top of the focused task. -->
- <dimen name="recents_layout_top_peek_size">56dp</dimen>
+ <dimen name="recents_layout_top_peek_size">48dp</dimen>
<!-- The height between the bottom margin and the top of task in front of the focused task. -->
<dimen name="recents_layout_bottom_peek_size">56dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/Interpolators.java b/packages/SystemUI/src/com/android/systemui/Interpolators.java
index 5e33a9f..17f4dab 100644
--- a/packages/SystemUI/src/com/android/systemui/Interpolators.java
+++ b/packages/SystemUI/src/com/android/systemui/Interpolators.java
@@ -17,6 +17,7 @@
package com.android.systemui;
import android.view.animation.AccelerateDecelerateInterpolator;
+import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
@@ -32,6 +33,7 @@
public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
public static final Interpolator LINEAR = new LinearInterpolator();
+ public static final Interpolator ACCELERATE = new AccelerateInterpolator();
public static final Interpolator ACCELERATE_DECELERATE = new AccelerateDecelerateInterpolator();
public static final Interpolator DECELERATE_QUINT = new DecelerateInterpolator(2.5f);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
index 043510e..1715356 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsDebugFlags.java
@@ -36,7 +36,7 @@
// Enables the task affiliations
public static final boolean EnableAffiliatedTaskGroups = false;
// TODO: To be repurposed
- public static final boolean EnableStackActionButton = false;
+ public static final boolean EnableStackActionButton = true;
// Overrides the Tuner flags and enables the timeout
private static final boolean EnableFastToggleTimeout = false;
// Overrides the Tuner flags and enables the paging via the Recents button
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissAllTaskViewsEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissAllTaskViewsEvent.java
new file mode 100644
index 0000000..f8b59c7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissAllTaskViewsEvent.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.recents.events.ui;
+
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.views.TaskView;
+
+/**
+ * This event is sent to request that all the {@link TaskView}s are dismissed.
+ */
+public class DismissAllTaskViewsEvent extends EventBus.AnimatedEvent {
+ // Simple event
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissTaskViewEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissTaskViewEvent.java
index 1165f4e..1f8c644 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissTaskViewEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/DismissTaskViewEvent.java
@@ -17,7 +17,6 @@
package com.android.systemui.recents.events.ui;
import com.android.systemui.recents.events.EventBus;
-import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.views.TaskView;
/**
@@ -26,10 +25,8 @@
public class DismissTaskViewEvent extends EventBus.AnimatedEvent {
public final TaskView taskView;
- public final Task task;
- public DismissTaskViewEvent(TaskView taskView, Task task) {
+ public DismissTaskViewEvent(TaskView taskView) {
this.taskView = taskView;
- this.task = task;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 5a2507d..df3f56c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -222,6 +222,11 @@
Task newFrontMostTask, AnimationProps animation, boolean fromDockGesture);
/**
+ * Notifies when all tasks have been removed from the stack.
+ */
+ void onStackTasksRemoved(TaskStack stack);
+
+ /**
* Notifies when tasks in the stack have been updated.
*/
void onStackTasksUpdated(TaskStack stack);
@@ -510,6 +515,22 @@
}
/**
+ * Removes all tasks from the stack.
+ */
+ public void removeAllTasks() {
+ ArrayList<Task> tasks = mStackTaskList.getTasks();
+ for (int i = tasks.size() - 1; i >= 0; i--) {
+ Task t = tasks.get(i);
+ removeTaskImpl(mStackTaskList, t);
+ mRawTaskList.remove(t);
+ }
+ if (mCb != null) {
+ // Notify that all tasks have been removed
+ mCb.onStackTasksRemoved(this);
+ }
+ }
+
+ /**
* Sets a few tasks in one go, without calling any callbacks.
*
* @param tasks the new set of tasks to replace the current set.
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
index 3d0e75a..5eb9fda 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java
@@ -158,6 +158,11 @@
}
@Override
+ public void onStackTasksRemoved(TaskStack stack) {
+ // Do nothing
+ }
+
+ @Override
public void onStackTasksUpdated(TaskStack stack) {
// Do nothing
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index b23b01f..e9ce637 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -58,6 +58,9 @@
import com.android.systemui.recents.events.activity.HideStackActionButtonEvent;
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
+import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
+import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
+import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
import com.android.systemui.recents.events.ui.ResetBackgroundScrimEvent;
@@ -87,6 +90,9 @@
private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200;
private static final float DEFAULT_SCRIM_ALPHA = 0.33f;
+ private static final int SHOW_STACK_ACTION_BUTTON_DURATION = 150;
+ private static final int HIDE_STACK_ACTION_BUTTON_DURATION = 100;
+
private TaskStack mStack;
private TaskStackView mTaskStackView;
private TextView mStackActionButton;
@@ -135,10 +141,11 @@
R.dimen.recents_task_view_rounded_corners_radius);
mStackActionButton = (TextView) inflater.inflate(R.layout.recents_stack_action_button,
this, false);
+ mStackActionButton.forceHasOverlappingRendering(false);
mStackActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
- // TODO: To be implemented
+ EventBus.getDefault().send(new DismissAllTaskViewsEvent());
}
});
addView(mStackActionButton);
@@ -579,12 +586,24 @@
animateBackgroundScrim(DEFAULT_SCRIM_ALPHA, DEFAULT_UPDATE_SCRIM_DURATION);
}
+ public final void onBusEvent(AllTaskViewsDismissedEvent event) {
+ hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
+ }
+
+ public final void onBusEvent(DismissAllTaskViewsEvent event) {
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ if (!ssp.hasDockedTask()) {
+ // Animate the background away only if we are dismissing Recents to home
+ animateBackgroundScrim(0f, DEFAULT_UPDATE_SCRIM_DURATION);
+ }
+ }
+
public final void onBusEvent(ShowStackActionButtonEvent event) {
if (!RecentsDebugFlags.Static.EnableStackActionButton) {
return;
}
- showStackActionButton(150, event.translate);
+ showStackActionButton(SHOW_STACK_ACTION_BUTTON_DURATION, event.translate);
}
public final void onBusEvent(HideStackActionButtonEvent event) {
@@ -592,7 +611,7 @@
return;
}
- hideStackActionButton(100, true /* translate */);
+ hideStackActionButton(HIDE_STACK_ACTION_BUTTON_DURATION, true /* translate */);
}
/**
@@ -623,7 +642,6 @@
.alpha(1f)
.setDuration(duration)
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
- .withLayer()
.start();
}
});
@@ -669,7 +687,6 @@
postAnimationTrigger.decrement();
}
})
- .withLayer()
.start();
postAnimationTrigger.increment();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
index 9c8189a..13ad9a5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SystemBarScrimViews.java
@@ -24,6 +24,7 @@
import com.android.systemui.R;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
import com.android.systemui.recents.events.activity.EnterRecentsWindowAnimationCompletedEvent;
+import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
/** Manages the scrims for the various system bars. */
public class SystemBarScrimViews {
@@ -107,4 +108,14 @@
animateNavBarScrimVisibility(false, animation);
}
}
+
+ public final void onBusEvent(DismissAllTaskViewsEvent event) {
+ if (mHasNavBarScrim) {
+ AnimationProps animation = new AnimationProps()
+ .setDuration(AnimationProps.BOUNDS,
+ TaskStackAnimationHelper.EXIT_TO_HOME_TRANSLATION_DURATION)
+ .setInterpolator(AnimationProps.BOUNDS, Interpolators.FAST_OUT_SLOW_IN);
+ animateNavBarScrimVisibility(false, animation);
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index 8db81f7..1c433d8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -31,6 +31,7 @@
import com.android.systemui.recents.RecentsActivityLaunchState;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.ReferenceCountedTrigger;
+import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
@@ -277,7 +278,6 @@
public void startExitToHomeAnimation(boolean animated,
ReferenceCountedTrigger postAnimationTrigger) {
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
- TaskStackViewScroller stackScroller = mStackView.getScroller();
TaskStack stack = mStackView.getStack();
// Break early if there are no tasks
@@ -313,8 +313,7 @@
taskAnimation = AnimationProps.IMMEDIATE;
}
- stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
- null);
+ mTmpTransform.fillIn(tv);
mTmpTransform.alpha = 0f;
mTmpTransform.rect.offset(0, offscreenYOffset);
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
@@ -328,8 +327,6 @@
public void startLaunchTaskAnimation(TaskView launchingTaskView, boolean screenPinningRequested,
final ReferenceCountedTrigger postAnimationTrigger) {
Resources res = mStackView.getResources();
- TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
- TaskStackViewScroller stackScroller = mStackView.getScroller();
int taskViewExitToAppDuration = res.getInteger(
R.integer.recents_task_exit_to_app_duration);
@@ -362,8 +359,7 @@
postAnimationTrigger.decrementOnAnimationEnd());
postAnimationTrigger.increment();
- stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform,
- null);
+ mTmpTransform.fillIn(tv);
mTmpTransform.alpha = 0f;
mTmpTransform.rect.offset(0, taskViewAffiliateGroupEnterOffset);
mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
@@ -374,16 +370,14 @@
/**
* Starts the delete animation for the specified {@link TaskView}.
*/
- public void startDeleteTaskAnimation(Task deleteTask, final TaskView deleteTaskView,
+ public void startDeleteTaskAnimation(final TaskView deleteTaskView,
final ReferenceCountedTrigger postAnimationTrigger) {
Resources res = mStackView.getResources();
TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
- TaskStackViewScroller stackScroller = mStackView.getScroller();
int taskViewRemoveAnimDuration = res.getInteger(
R.integer.recents_animate_task_view_remove_duration);
- int taskViewRemoveAnimTranslationXPx = res.getDimensionPixelSize(
- R.dimen.recents_task_view_remove_anim_translation_x);
+ int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
// Disabling clipping with the stack while the view is animating away, this will get
// restored when the task is next picked up from the view pool
@@ -399,14 +393,58 @@
});
postAnimationTrigger.increment();
- stackLayout.getStackTransform(deleteTask, stackScroller.getStackScroll(), mTmpTransform,
- null);
+ mTmpTransform.fillIn(deleteTaskView);
mTmpTransform.alpha = 0f;
- mTmpTransform.rect.offset(taskViewRemoveAnimTranslationXPx, 0);
+ mTmpTransform.rect.offset(offscreenXOffset, 0);
mStackView.updateTaskViewToTransform(deleteTaskView, mTmpTransform, taskAnimation);
}
/**
+ * Starts the delete animation for all the {@link TaskView}s.
+ */
+ public void startDeleteAllTasksAnimation(final List<TaskView> taskViews,
+ final ReferenceCountedTrigger postAnimationTrigger) {
+ Resources res = mStackView.getResources();
+ TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
+
+ int taskViewRemoveAnimDuration = res.getInteger(
+ R.integer.recents_animate_task_views_remove_all_duration);
+ int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
+
+ int taskViewCount = taskViews.size();
+ int startDelayMax = 125;
+
+ for (int i = taskViewCount - 1; i >= 0; i--) {
+ TaskView tv = taskViews.get(i);
+ int indexFromFront = taskViewCount - i - 1;
+ float x = Interpolators.ACCELERATE.getInterpolation((float) indexFromFront /
+ taskViewCount);
+ int startDelay = (int) Utilities.mapRange(x, 0, startDelayMax);
+
+ // Disabling clipping with the stack while the view is animating away
+ tv.setClipViewInStack(false);
+
+ // Compose the new animation and transform and star the animation
+ AnimationProps taskAnimation = new AnimationProps(startDelay,
+ taskViewRemoveAnimDuration, Interpolators.FAST_OUT_LINEAR_IN,
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ postAnimationTrigger.decrement();
+
+ // Re-enable clipping with the stack (we will reuse this view)
+ tv.setClipViewInStack(true);
+ }
+ });
+ postAnimationTrigger.increment();
+
+ mTmpTransform.fillIn(tv);
+ mTmpTransform.rect.offset(offscreenXOffset, 0);
+ mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation);
+ }
+ }
+
+ /**
* Starts the animation to focus the next {@link TaskView} when paging through recents.
*
* @return whether or not this will trigger a scroll in the stack
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 4b1faf3..2508304 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -557,15 +557,17 @@
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
mInitialNormX = null;
} else {
- float normX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
- mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2)) -
- Math.max(0, mUnfocusedRange.getAbsoluteX(normX)));
+ // We are overriding the initial two task positions, so set the initial scroll
+ // position to match the second task (aka focused task) position
+ float initialTopNormX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
+ mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2))
+ - Math.max(0, mUnfocusedRange.getAbsoluteX(initialTopNormX)));
// Set the initial scroll to the predefined state (which differs from the stack)
mInitialNormX = new float[] {
getNormalizedXFromUnfocusedY(mSystemInsets.bottom + mInitialBottomOffset,
FROM_BOTTOM),
- normX
+ initialTopNormX
};
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 04f153f..58998c6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -72,6 +72,7 @@
import com.android.systemui.recents.events.activity.ShowStackActionButtonEvent;
import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent;
import com.android.systemui.recents.events.ui.DeleteTaskDataEvent;
+import com.android.systemui.recents.events.ui.DismissAllTaskViewsEvent;
import com.android.systemui.recents.events.ui.DismissTaskViewEvent;
import com.android.systemui.recents.events.ui.TaskViewDismissedEvent;
import com.android.systemui.recents.events.ui.UpdateFreeformTaskViewVisibilityEvent;
@@ -1322,7 +1323,8 @@
}
// Update the stack action button visibility
- if (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
+ if (mStackScroller.getStackScroll() < SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
+ mStack.getTaskCount() > 0) {
EventBus.getDefault().send(new ShowStackActionButtonEvent(false /* translate */));
} else {
EventBus.getDefault().send(new HideStackActionButtonEvent());
@@ -1447,6 +1449,26 @@
}
@Override
+ public void onStackTasksRemoved(TaskStack stack) {
+ // Reset the focused task
+ resetFocusedTask(getFocusedTask());
+
+ // Return all the views to the pool
+ List<TaskView> taskViews = new ArrayList<>();
+ taskViews.addAll(getTaskViews());
+ for (int i = taskViews.size() - 1; i >= 0; i--) {
+ mViewPool.returnViewToPool(taskViews.get(i));
+ }
+
+ // Remove all the ignore tasks
+ mIgnoreTasks.clear();
+
+ // If there are no remaining tasks, then just close recents
+ EventBus.getDefault().send(new AllTaskViewsDismissedEvent(
+ R.string.recents_empty_message_dismissed_all));
+ }
+
+ @Override
public void onStackTasksUpdated(TaskStack stack) {
// Update the layout and immediately layout
updateLayoutAlgorithm(false /* boundScroll */);
@@ -1597,7 +1619,8 @@
if (mEnterAnimationComplete) {
if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
- curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
+ curScroll <= SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
+ mStack.getTaskCount() > 0) {
EventBus.getDefault().send(new ShowStackActionButtonEvent(true /* translate */));
} else if (prevScroll < HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD &&
curScroll >= HIDE_STACK_ACTION_BUTTON_SCROLL_THRESHOLD) {
@@ -1705,14 +1728,42 @@
}
}
- public final void onBusEvent(final DismissTaskViewEvent event) {
+ public final void onBusEvent(DismissTaskViewEvent event) {
// For visible children, defer removing the task until after the animation
- mAnimationHelper.startDeleteTaskAnimation(event.task, event.taskView,
- event.getAnimationTrigger());
+ mAnimationHelper.startDeleteTaskAnimation(event.taskView, event.getAnimationTrigger());
+ }
+
+ public final void onBusEvent(final DismissAllTaskViewsEvent event) {
+ // Keep track of the tasks which will have their data removed
+ ArrayList<Task> tasks = new ArrayList<>(mStack.getStackTasks());
+ mAnimationHelper.startDeleteAllTasksAnimation(getTaskViews(), event.getAnimationTrigger());
+ event.addPostAnimationCallback(new Runnable() {
+ @Override
+ public void run() {
+ // Announce for accessibility
+ announceForAccessibility(getContext().getString(
+ R.string.accessibility_recents_all_items_dismissed));
+
+ // Remove all tasks and delete the task data for all tasks
+ mStack.removeAllTasks();
+ for (int i = tasks.size() - 1; i >= 0; i--) {
+ EventBus.getDefault().send(new DeleteTaskDataEvent(tasks.get(i)));
+ }
+
+ MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS_ALL);
+ }
+ });
+
}
public final void onBusEvent(TaskViewDismissedEvent event) {
- removeTaskViewFromStack(event.taskView, event.task);
+ // Announce for accessibility
+ announceForAccessibility(getContext().getString(
+ R.string.accessibility_recents_item_dismissed, event.task.title));
+
+ // Remove the task from the stack
+ mStack.removeTask(event.task, new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
+ Interpolators.FAST_OUT_SLOW_IN), false /* fromDockGesture */);
EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
@@ -1956,20 +2007,6 @@
}
/**
- * Removes the task from the stack, and updates the focus to the next task in the stack if the
- * removed TaskView was focused.
- */
- private void removeTaskViewFromStack(TaskView tv, Task task) {
- // Announce for accessibility
- tv.announceForAccessibility(getContext().getString(
- R.string.accessibility_recents_item_dismissed, task.title));
-
- // Remove the task from the stack
- mStack.removeTask(task, new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
- Interpolators.FAST_OUT_SLOW_IN), false /* fromDockGesture */);
- }
-
- /**
* Starts an alpha animation on the freeform workspace background.
*/
private void animateFreeformWorkspaceBackgroundAlpha(int targetAlpha,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index aed19c3..ee0de1a 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -356,6 +356,11 @@
return;
}
+ // Disallow tapping above and below the stack to dismiss recents
+ if (x > mSv.mLayoutAlgorithm.mStackRect.left && x < mSv.mLayoutAlgorithm.mStackRect.right) {
+ return;
+ }
+
// If tapping on the freeform workspace background, just launch the first freeform task
SystemServicesProxy ssp = Recents.getSystemServices();
if (ssp.hasFreeformWorkspaceSupport()) {
@@ -507,13 +512,13 @@
tv.setClipViewInStack(true);
// Re-enable touch events from this task view
tv.setTouchEnabled(true);
+ // Remove the task view from the stack
+ EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
// Update the scroll to the final scroll position from onBeginDrag()
mSv.getScroller().setStackScroll(mTargetStackScroll, null);
// Update the focus state to the final focus state
mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
mSv.getStackAlgorithm().clearUnfocusedTaskOverrides();
- // Remove the task view from the stack
- EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
// Stop tracking this deletion animation
mSwipeHelperAnimations.remove(v);
// Keep track of deletions by keyboard
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index c085d80..f8ed700 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -384,7 +384,7 @@
void dismissTask() {
// Animate out the view and call the callback
final TaskView tv = this;
- DismissTaskViewEvent dismissEvent = new DismissTaskViewEvent(tv, mTask);
+ DismissTaskViewEvent dismissEvent = new DismissTaskViewEvent(tv);
dismissEvent.addPostAnimationCallback(new Runnable() {
@Override
public void run() {
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index d6f1499..a2cfae9 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2017,6 +2017,9 @@
// action pass package name of calling package.
ACTION_SCOPED_DIRECTORY_ACCESS_DENIED_AND_PERSIST_BY_PACKAGE = 356;
+ // Logged when a user dismisses all task in overview
+ OVERVIEW_DISMISS_ALL = 357;
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}