Ensuring that the undocked task is visible in Overview.
Bug: 26043233
Change-Id: I2186bdfc64af161b8e828061a8e064f90c5cae24
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index 9f0ac35..ec963da 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -51,6 +51,7 @@
import com.android.systemui.recents.events.activity.LaunchTaskFailedEvent;
import com.android.systemui.recents.events.activity.LaunchTaskSucceededEvent;
import com.android.systemui.recents.events.activity.ShowHistoryEvent;
+import com.android.systemui.recents.events.activity.TaskStackUpdatedEvent;
import com.android.systemui.recents.events.activity.ToggleRecentsEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.component.ScreenPinningRequestEvent;
@@ -526,6 +527,22 @@
}
@Override
+ public void onMultiWindowModeChanged(boolean multiWindowMode) {
+ super.onMultiWindowModeChanged(multiWindowMode);
+ if (!multiWindowMode) {
+ RecentsTaskLoader loader = Recents.getTaskLoader();
+ RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
+ launchOpts.loadIcons = false;
+ launchOpts.loadThumbnails = false;
+ launchOpts.onlyLoadForCache = true;
+ RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
+ loader.preloadTasks(loadPlan, false);
+ loader.loadTasks(this, loadPlan, launchOpts);
+ EventBus.getDefault().send(new TaskStackUpdatedEvent(loadPlan.getTaskStack()));
+ }
+ }
+
+ @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_TAB: {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/TaskStackUpdatedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/TaskStackUpdatedEvent.java
new file mode 100644
index 0000000..b94ed7b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/TaskStackUpdatedEvent.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2015 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.activity;
+
+import com.android.systemui.recents.RecentsAppWidgetHost;
+import com.android.systemui.recents.events.EventBus;
+import com.android.systemui.recents.model.TaskStack;
+
+/**
+ * This is sent by the activity whenever the task stach has changed.
+ */
+public class TaskStackUpdatedEvent extends EventBus.Event {
+
+ /**
+ * A new TaskStack instance representing the latest stack state.
+ */
+ public final TaskStack stack;
+
+ public TaskStackUpdatedEvent(TaskStack stack) {
+ this.stack = stack;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index dae6e94..0884695d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -200,7 +200,7 @@
allTasks.addAll(stackTasks);
allTasks.addAll(freeformTasks);
mStack = new TaskStack();
- mStack.setTasks(allTasks);
+ mStack.setTasks(allTasks, false /* notifyStackChanges */);
mStack.createAffiliatedGroupings(mContext);
}
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 5d07b10..69a94fe 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -206,11 +206,20 @@
/** Task stack callbacks */
public interface TaskStackCallbacks {
- /* Notifies when a task has been removed from the stack */
+ /**
+ * Notifies when a new task has been added to the stack.
+ */
+ void onStackTaskAdded(TaskStack stack, Task newTask);
+
+ /**
+ * Notifies when a task has been removed from the stack.
+ */
void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
Task newFrontMostTask);
- /* Notifies when a task has been removed from the history */
+ /**
+ * Notifies when a task has been removed from the history.
+ */
void onHistoryTaskRemoved(TaskStack stack, Task removedTask);
}
@@ -315,6 +324,7 @@
// The task offset to apply to a task id as a group affiliation
static final int IndividualTaskIdOffset = 1 << 16;
+ ArrayList<Task> mRawTaskList = new ArrayList<>();
FilteredTaskList mStackTaskList = new FilteredTaskList();
FilteredTaskList mHistoryTaskList = new FilteredTaskList();
TaskStackCallbacks mCb;
@@ -430,19 +440,72 @@
/**
* Sets a few tasks in one go, without calling any callbacks.
+ *
+ * @param tasks the new set of tasks to replace the current set.
+ * @param notifyStackChanges whether or not to callback on specific changes to the list of tasks.
*/
- public void setTasks(List<Task> tasks) {
+ public void setTasks(List<Task> tasks, boolean notifyStackChanges) {
+ // Compute a has set for each of the tasks
+ HashMap<Task.TaskKey, Task> currentTasksMap = createTaskKeyMapFromList(mRawTaskList);
+ HashMap<Task.TaskKey, Task> newTasksMap = createTaskKeyMapFromList(tasks);
+
+ ArrayList<Task> newTasks = new ArrayList<>();
+
+ // Disable notifications if there are no callbacks
+ if (mCb == null) {
+ notifyStackChanges = false;
+ }
+
+ // Remove any tasks that no longer exist
+ int taskCount = mRawTaskList.size();
+ for (int i = 0; i < taskCount; i++) {
+ Task task = mRawTaskList.get(i);
+ if (!newTasksMap.containsKey(task.key)) {
+ if (notifyStackChanges) {
+ mCb.onStackTaskRemoved(this, task, i == (taskCount - 1), null);
+ }
+ } else {
+ newTasks.add(task);
+ }
+ }
+
+ // Add any new tasks
+ taskCount = tasks.size();
+ for (int i = 0; i < taskCount; i++) {
+ Task task = tasks.get(i);
+ if (!currentTasksMap.containsKey(task.key)) {
+ if (notifyStackChanges) {
+ mCb.onStackTaskAdded(this, task);
+ }
+ newTasks.add(task);
+ } else {
+ newTasks.add(currentTasksMap.get(task.key));
+ }
+ }
+
+ // Sort all the tasks to ensure they are ordered correctly
+ Collections.sort(newTasks, LAST_ACTIVE_TIME_COMPARATOR);
+
+ // TODO: Update screen pinning for the new front-most task post refactoring lockToTask out
+ // of the Task
+
+ // Filter out the historical tasks from this new list
ArrayList<Task> stackTasks = new ArrayList<>();
ArrayList<Task> historyTasks = new ArrayList<>();
- for (Task task : tasks) {
+ int newTaskCount = newTasks.size();
+ for (int i = 0; i < newTaskCount; i++) {
+ Task task = newTasks.get(i);
if (task.isHistorical) {
historyTasks.add(task);
} else {
stackTasks.add(task);
}
}
+
mStackTaskList.set(stackTasks);
mHistoryTaskList.set(historyTasks);
+ mRawTaskList.clear();
+ mRawTaskList.addAll(newTasks);
}
/** Gets the front task */
@@ -714,4 +777,17 @@
}
return str;
}
-}
\ No newline at end of file
+
+ /**
+ * Given a list of tasks, returns a map of each task's key to the task.
+ */
+ private HashMap<Task.TaskKey, Task> createTaskKeyMapFromList(List<Task> tasks) {
+ HashMap<Task.TaskKey, Task> map = new HashMap<>();
+ int taskCount = tasks.size();
+ for (int i = 0; i < taskCount; i++) {
+ Task task = tasks.get(i);
+ map.put(task.key, task);
+ }
+ return map;
+ }
+}
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 21c08d1..5b6fdd1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -50,6 +50,7 @@
import com.android.systemui.recents.events.activity.LaunchTaskEvent;
import com.android.systemui.recents.events.activity.ShowHistoryButtonEvent;
import com.android.systemui.recents.events.activity.ShowHistoryEvent;
+import com.android.systemui.recents.events.activity.TaskStackUpdatedEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.events.ui.DraggingInRecentsEndedEvent;
import com.android.systemui.recents.events.ui.DraggingInRecentsEvent;
@@ -599,6 +600,10 @@
hideHistoryButton(100);
}
+ public final void onBusEvent(TaskStackUpdatedEvent event) {
+ mStack.setTasks(event.stack.computeAllTasksList(), true /* notifyStackChanges */);
+ }
+
/**
* Shows the history button.
*/
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 4e75d5a..4140fb5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -103,6 +103,8 @@
private static final float SHOW_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
private static final float HIDE_HISTORY_BUTTON_SCROLL_THRESHOLD = 0.3f;
+ private static final int DEFAULT_SYNC_STACK_DURATION = 200;
+
public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
new IntProperty<Drawable>("drawableAlpha") {
@Override
@@ -1199,6 +1201,15 @@
/**** TaskStackCallbacks Implementation ****/
@Override
+ public void onStackTaskAdded(TaskStack stack, Task newTask) {
+ // Update the min/max scroll and animate other task views into their new positions
+ updateLayout(true);
+
+ // Animate all the tasks into place
+ requestSynchronizeStackViewsWithModel(DEFAULT_SYNC_STACK_DURATION);
+ }
+
+ @Override
public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask,
Task newFrontMostTask) {
if (mFocusedTask == removedTask) {
@@ -1244,7 +1255,7 @@
}
// Animate all the tasks into place
- requestSynchronizeStackViewsWithModel(200);
+ requestSynchronizeStackViewsWithModel(DEFAULT_SYNC_STACK_DURATION);
} else {
// 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
@@ -1257,7 +1268,7 @@
updateLayout(true);
// Animate all the tasks into place
- requestSynchronizeStackViewsWithModel(200);
+ requestSynchronizeStackViewsWithModel(DEFAULT_SYNC_STACK_DURATION);
}
// Update the new front most task