Merge "Fixing crash when trying to reset focused task after removing task."
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 34353bc..063bb3e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -284,6 +284,20 @@
}
/**
+ * Dismisses recents back to the launch target task.
+ */
+ boolean dismissRecentsToLaunchTargetTaskOrHome() {
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ if (ssp.isRecentsTopMost(ssp.getTopMostTask(), null)) {
+ // If we have a focused Task, launch that Task now
+ if (mRecentsView.launchPreviousTask()) return true;
+ // If none of the other cases apply, then just go Home
+ dismissRecentsToHome(true);
+ }
+ return false;
+ }
+
+ /**
* Dismisses recents if we are already visible and the intent is to toggle the recents view.
*/
boolean dismissRecentsToFocusedTaskOrHome() {
@@ -566,9 +580,8 @@
@Override
public void onBackPressed() {
- if (!dismissHistory()) {
- dismissRecentsToFocusedTaskOrHome();
- }
+ // Back behaves like the recents button so just trigger a toggle event
+ EventBus.getDefault().send(new ToggleRecentsEvent());
}
/**** RecentsResizeTaskDialog ****/
@@ -584,7 +597,12 @@
public final void onBusEvent(ToggleRecentsEvent event) {
if (!dismissHistory()) {
- dismissRecentsToFocusedTaskOrHome();
+ RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
+ if (launchState.launchedFromHome) {
+ dismissRecentsToHome(true);
+ } else {
+ dismissRecentsToLaunchTargetTaskOrHome();
+ }
}
}
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 381ffc9..530cd2d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -199,8 +199,11 @@
/** Task stack callbacks */
public interface TaskStackCallbacks {
/* Notifies when a task has been removed from the stack */
- void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
- Task newFrontMostTask);
+ void onStackTaskRemoved(TaskStack stack, Task removedTask, int removedTaskIndex,
+ boolean wasFrontMostTask, Task newFrontMostTask);
+
+ /* Notifies when a task has been removed from the history */
+ void onHistoryTaskRemoved(TaskStack stack, Task removedTask);
}
/**
@@ -382,6 +385,7 @@
public void removeTask(Task t) {
if (mStackTaskList.contains(t)) {
boolean wasFrontMostTask = (getStackFrontMostTask() == t);
+ int removedTaskIndex = indexOfStackTask(t);
removeTaskImpl(mStackTaskList, t);
Task newFrontMostTask = getStackFrontMostTask();
if (newFrontMostTask != null && newFrontMostTask.lockToTaskEnabled) {
@@ -389,13 +393,14 @@
}
if (mCb != null) {
// Notify that a task has been removed
- mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask);
+ mCb.onStackTaskRemoved(this, t, removedTaskIndex, wasFrontMostTask,
+ newFrontMostTask);
}
} else if (mHistoryTaskList.contains(t)) {
removeTaskImpl(mHistoryTaskList, t);
if (mCb != null) {
// Notify that a task has been removed
- mCb.onStackTaskRemoved(this, t, false, null);
+ mCb.onHistoryTaskRemoved(this, t);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
index a3a9e5a..96b1a41 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
@@ -308,12 +308,6 @@
*/
private static AppTransitionAnimationSpec composeAnimationSpec(TaskView taskView,
TaskViewTransform transform, boolean addHeaderBitmap) {
- // Disable any focused state before we draw the header
- // Upfront the processing of the thumbnail
- if (taskView.isFocusedTask()) {
- taskView.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
- }
-
Bitmap b = null;
if (addHeaderBitmap) {
float scale = transform.scale;
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 551f067..0911578 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -213,6 +213,21 @@
return false;
}
+ /** 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);
+ onTaskViewClicked(mTaskStackView, taskView, stack, task, false, null,
+ INVALID_STACK_ID);
+ return true;
+ }
+ }
+ return false;
+ }
+
/** Launches a given task. */
public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
if (mTaskStackView != null) {
@@ -471,9 +486,6 @@
final TaskStack.DockState dockState = (TaskStack.DockState) event.dropTarget;
// Remove the task after it is docked
- if (event.taskView.isFocusedTask()) {
- mTaskStackView.resetFocusedTask();
- }
event.taskView.animate()
.alpha(0f)
.setDuration(150)
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 d9e352d..6dc380c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -658,7 +658,8 @@
transformOut.rect.set(mTaskRect);
transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
- transformOut.visible = true;
+ transformOut.visible = (transformOut.rect.top < mStackRect.bottom) &&
+ (frontTransform == null || transformOut.rect.top != frontTransform.rect.top);
transformOut.clipBottom = 0;
transformOut.clipRight = 0;
transformOut.thumbnailScale = 1f;
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 ae6cc46..d45fba2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -280,7 +280,7 @@
/** Resets this TaskStackView for reuse. */
void reset() {
// Reset the focused task
- resetFocusedTask();
+ resetFocusedTask(getFocusedTask());
// Return all the views to the pool
List<TaskView> taskViews = getTaskViews();
@@ -426,7 +426,6 @@
// Return all the invisible children to the pool
mTmpTaskViewMap.clear();
List<TaskView> taskViews = getTaskViews();
- boolean wasLastFocusedTaskAnimated = false;
int lastFocusedTaskIndex = -1;
int taskViewCount = taskViews.size();
for (int i = taskViewCount - 1; i >= 0; i--) {
@@ -437,10 +436,9 @@
visibleStackRange[1] <= taskIndex && taskIndex <= visibleStackRange[0]) {
mTmpTaskViewMap.put(task, tv);
} else {
- if (mTouchExplorationEnabled && tv.isFocusedTask()) {
- wasLastFocusedTaskAnimated = tv.isFocusAnimated();
+ if (mTouchExplorationEnabled) {
lastFocusedTaskIndex = taskIndex;
- resetFocusedTask();
+ resetFocusedTask(task);
}
if (DEBUG) {
Log.d(TAG, "returning to pool: " + task.key);
@@ -467,6 +465,21 @@
if (mLayersDisabled) {
tv.disableLayersForOneFrame();
}
+ } else {
+ // Reattach it in the right z order
+ detachViewFromParent(tv);
+ int insertIndex = -1;
+ int taskIndex = mStack.indexOfStackTask(task);
+ taskViews = getTaskViews();
+ taskViewCount = taskViews.size();
+ for (int j = 0; j < taskViewCount; j++) {
+ Task tvTask = taskViews.get(j).getTask();
+ if (taskIndex <= mStack.indexOfStackTask(tvTask)) {
+ insertIndex = j;
+ break;
+ }
+ }
+ attachViewToParent(tv, insertIndex, tv.getLayoutParams());
}
// Animate the task into place
@@ -474,21 +487,6 @@
mStackViewsAnimationDuration, mFastOutSlowInInterpolator,
mRequestUpdateClippingListener);
- // Reattach it in the right z order
- detachViewFromParent(tv);
- int insertIndex = -1;
- int taskIndex = mStack.indexOfStackTask(task);
- taskViews = getTaskViews();
- taskViewCount = taskViews.size();
- for (int j = 0; j < taskViewCount; j++) {
- Task tvTask = taskViews.get(j).getTask();
- if (taskIndex < mStack.indexOfStackTask(tvTask)) {
- insertIndex = j;
- break;
- }
- }
- attachViewToParent(tv, insertIndex, tv.getLayoutParams());
-
// Update the task views list after adding the new task view
updateTaskViewsList();
}
@@ -538,9 +536,11 @@
// Update the focus if the previous focused task was returned to the view pool
if (lastFocusedTaskIndex != -1) {
if (lastFocusedTaskIndex < visibleStackRange[1]) {
- setFocusedTask(visibleStackRange[1], false, wasLastFocusedTaskAnimated);
+ setFocusedTask(visibleStackRange[1], false /* animated */,
+ true /* requestViewFocus */);
} else {
- setFocusedTask(visibleStackRange[0], false, wasLastFocusedTaskAnimated);
+ setFocusedTask(visibleStackRange[0], false /* animated */,
+ true /* requestViewFocus */);
}
}
@@ -653,7 +653,7 @@
if (mFocusedTaskIndex != -1) {
Task focusedTask = mStack.getStackTasks().get(mFocusedTaskIndex);
if (focusedTask != newFocusedTask) {
- resetFocusedTask();
+ resetFocusedTask(focusedTask);
}
}
@@ -777,10 +777,9 @@
/**
* Resets the focused task.
*/
- void resetFocusedTask() {
- if (mFocusedTaskIndex != -1) {
- Task t = mStack.getStackTasks().get(mFocusedTaskIndex);
- TaskView tv = getChildViewForTask(t);
+ void resetFocusedTask(Task task) {
+ if (task != null) {
+ TaskView tv = getChildViewForTask(task);
if (tv != null) {
tv.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
}
@@ -1183,8 +1182,12 @@
/**** TaskStackCallbacks Implementation ****/
@Override
- public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
- Task newFrontMostTask) {
+ public void onStackTaskRemoved(TaskStack stack, Task removedTask, int removedTaskIndex,
+ boolean wasFrontMostTask, Task newFrontMostTask) {
+ if (mFocusedTaskIndex == removedTaskIndex) {
+ resetFocusedTask(removedTask);
+ }
+
if (!removedTask.isFreeformTask()) {
// Remove the view associated with this task, we can't rely on updateTransforms
// to work here because the task is no longer in the list
@@ -1260,6 +1263,11 @@
}
}
+ @Override
+ public void onHistoryTaskRemoved(TaskStack stack, Task removedTask) {
+ // To be implemented
+ }
+
/**** ViewPoolConsumer Implementation ****/
@Override
@@ -1282,6 +1290,9 @@
// Reset the view properties
tv.resetViewProperties();
+ // Reset the focused view state
+ tv.setFocusedState(false, false /* animated */, false /* requestViewFocus */);
+
// Reset the clip state of the task view
tv.setClipViewInStack(false);
}
@@ -1332,6 +1343,9 @@
tv.setCallbacks(this);
tv.setTouchEnabled(true);
tv.setClipViewInStack(true);
+ if (mFocusedTaskIndex == taskIndex) {
+ tv.setFocusedState(true, false /* animated */, false /* requestViewFocus */);
+ }
}
@Override
@@ -1553,11 +1567,6 @@
private void removeTaskViewFromStack(TaskView tv) {
Task task = tv.getTask();
- // Reset the previously focused task before it is removed from the stack
- if (tv.isFocusedTask()) {
- resetFocusedTask();
- }
-
// Announce for accessibility
tv.announceForAccessibility(getContext().getString(
R.string.accessibility_recents_item_dismissed, tv.getTask().activityLabel));
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 6fdfe62..1baa1a3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -78,8 +78,6 @@
Task mTask;
boolean mTaskDataLoaded;
- boolean mIsFocused;
- boolean mIsFocusAnimated;
boolean mClipViewInStack;
AnimateableViewBounds mViewBounds;
private AnimatorSet mClipAnimation;
@@ -640,14 +638,12 @@
public void setFocusedState(boolean isFocused, boolean animated, boolean requestViewFocus) {
if (DEBUG) {
Log.d(TAG, "setFocusedState: " + mTask.activityLabel + " focused: " + isFocused +
- " mIsFocused: " + mIsFocused + " animated: " + animated +
- " requestViewFocus: " + requestViewFocus + " isFocused(): " + isFocused() +
+ " animated: " + animated + " requestViewFocus: " + requestViewFocus +
+ " isFocused(): " + isFocused() +
" isAccessibilityFocused(): " + isAccessibilityFocused());
}
SystemServicesProxy ssp = Recents.getSystemServices();
- mIsFocused = isFocused;
- mIsFocusAnimated = animated;
mHeaderView.onTaskViewFocusChanged(isFocused, animated);
if (isFocused) {
if (requestViewFocus && !isFocused()) {
@@ -663,20 +659,6 @@
}
}
- /**
- * Returns whether we have explicitly been focused.
- */
- public boolean isFocusedTask() {
- return mIsFocused;
- }
-
- /**
- * Returns whether this focused task is animated.
- */
- public boolean isFocusAnimated() {
- return mIsFocusAnimated;
- }
-
public void disableLayersForOneFrame() {
mHeaderView.disableLayersForOneFrame();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
index 85b4b9b..ec59f31 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java
@@ -55,6 +55,8 @@
public class TaskViewHeader extends FrameLayout
implements View.OnClickListener, View.OnLongClickListener {
+ private static final float FOCUS_TRANSLATION_Z = 4f;
+
Task mTask;
// Header views
@@ -367,13 +369,14 @@
Utilities.cancelAnimationWithoutCallbacks(mFocusAnimator);
if (focused) {
- // If we are not animating the visible state, just return
- if (!animateFocusedState) return;
-
- // Bump up the translation
- mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", 8f);
- mFocusAnimator.setDuration(200);
- mFocusAnimator.start();
+ if (animateFocusedState) {
+ // Bump up the translation
+ mFocusAnimator = ObjectAnimator.ofFloat(this, "translationZ", FOCUS_TRANSLATION_Z);
+ mFocusAnimator.setDuration(200);
+ mFocusAnimator.start();
+ } else {
+ setTranslationZ(FOCUS_TRANSLATION_Z);
+ }
} else {
if (isRunning) {
// Restore the translation