Ensuring that the undocked task is visible in Overview.

Bug: 26043233
Change-Id: I2186bdfc64af161b8e828061a8e064f90c5cae24
This commit is contained in:
Winson Chung
2015-12-11 10:24:21 -05:00
parent 636e71c326
commit 062667710e
6 changed files with 153 additions and 8 deletions

View File

@@ -51,6 +51,7 @@ import com.android.systemui.recents.events.activity.IterateRecentsEvent;
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;
@@ -525,6 +526,22 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
}
}
@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) {

View File

@@ -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;
}
}

View File

@@ -200,7 +200,7 @@ public class RecentsTaskLoadPlan {
allTasks.addAll(stackTasks);
allTasks.addAll(freeformTasks);
mStack = new TaskStack();
mStack.setTasks(allTasks);
mStack.setTasks(allTasks, false /* notifyStackChanges */);
mStack.createAffiliatedGroupings(mContext);
}

View File

@@ -206,11 +206,20 @@ public class TaskStack {
/** 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 @@ public class TaskStack {
// 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 @@ public class TaskStack {
/**
* 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 @@ public class TaskStack {
}
return str;
}
}
/**
* 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;
}
}

View File

@@ -50,6 +50,7 @@ import com.android.systemui.recents.events.activity.HideHistoryEvent;
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 @@ public class RecentsView extends FrameLayout {
hideHistoryButton(100);
}
public final void onBusEvent(TaskStackUpdatedEvent event) {
mStack.setTasks(event.stack.computeAllTasksList(), true /* notifyStackChanges */);
}
/**
* Shows the history button.
*/

View File

@@ -103,6 +103,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
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
@@ -1198,6 +1200,15 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
/**** 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) {
@@ -1244,7 +1255,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
// 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 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
updateLayout(true);
// Animate all the tasks into place
requestSynchronizeStackViewsWithModel(200);
requestSynchronizeStackViewsWithModel(DEFAULT_SYNC_STACK_DURATION);
}
// Update the new front most task