TaskStack.java revision a433fa9c17772f563163ff7db177d091d6aebd5b
1303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/* 2303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Copyright (C) 2014 The Android Open Source Project 3303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * 4303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Licensed under the Apache License, Version 2.0 (the "License"); 5303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * you may not use this file except in compliance with the License. 6303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * You may obtain a copy of the License at 7303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * 8303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * http://www.apache.org/licenses/LICENSE-2.0 9303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * 10303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * Unless required by applicable law or agreed to in writing, software 11303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * distributed under the License is distributed on an "AS IS" BASIS, 12303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * See the License for the specific language governing permissions and 14303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * limitations under the License. 15303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 16303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 17303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpackage com.android.systemui.recents.model; 18303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 19ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.Constants; 20ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.NamedCounter; 21303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 22303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList; 23ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.Collections; 24ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.Comparator; 25ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.HashMap; 26303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.List; 27a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chungimport java.util.Random; 28303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 29303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 30303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 31303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * An interface for a task filter to query whether a particular task should show in a stack. 32303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 33303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chunginterface TaskFilter { 34303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether the filter accepts the specified task */ 35303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public boolean acceptTask(Task t, int index); 36303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 37303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 38303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 39303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * A list of filtered tasks. 40303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 41303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungclass FilteredTaskList { 42303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> mTasks = new ArrayList<Task>(); 43303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> mFilteredTasks = new ArrayList<Task>(); 44ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung HashMap<Task.TaskKey, Integer> mTaskIndices = new HashMap<Task.TaskKey, Integer>(); 45303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung TaskFilter mFilter; 46303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 47303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the task filter, saving the current touch state */ 48c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung boolean setFilter(TaskFilter filter) { 49c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> prevFilteredTasks = new ArrayList<Task>(mFilteredTasks); 50303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilter = filter; 51303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 52b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung if (!prevFilteredTasks.equals(mFilteredTasks)) { 53b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung return true; 54b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung } else { 55b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung // If the tasks are exactly the same pre/post filter, then just reset it 56b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung mFilter = null; 57b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung return false; 58b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung } 59303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 60303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 61303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes the task filter and returns the previous touch state */ 62303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void removeFilter() { 63303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilter = null; 64303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 65303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 66303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 67303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task to the task list */ 68303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void add(Task t) { 69303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.add(t); 70303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 71303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 72303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 73303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the list of tasks */ 74303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void set(List<Task> tasks) { 75303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.clear(); 76303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.addAll(tasks); 77303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 78303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 79303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 80303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task from the base list only if it is in the filtered list */ 81303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean remove(Task t) { 82303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilteredTasks.contains(t)) { 83303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean removed = mTasks.remove(t); 84303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 85303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return removed; 86303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 87303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return false; 88303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 89303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 90303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in the list of filtered tasks */ 91303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int indexOf(Task t) { 92ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskIndices.get(t.key); 93303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 94303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 95303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the size of the list of filtered tasks */ 96303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int size() { 97303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks.size(); 98303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 99303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 100303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether the filtered list contains this task */ 101303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean contains(Task t) { 102ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskIndices.containsKey(t.key); 103303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 104303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 105303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Updates the list of filtered tasks whenever the base task list changes */ 106303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung private void updateFilteredTasks() { 107303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.clear(); 108303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter != null) { 109303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int taskCount = mTasks.size(); 110303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (int i = 0; i < taskCount; i++) { 111303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung Task t = mTasks.get(i); 112303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter.acceptTask(t, i)) { 113303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.add(t); 114303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 115303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 116303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } else { 117303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.addAll(mTasks); 118303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 119ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung updateFilteredTaskIndices(); 120ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 121ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 122ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Updates the mapping of tasks to indices. */ 123ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung private void updateFilteredTaskIndices() { 124ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.clear(); 125ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = mFilteredTasks.size(); 126ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 127ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = mFilteredTasks.get(i); 128ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.put(t.key, i); 129ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 130303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 131303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 132303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether this task list is filtered */ 133303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean hasFilter() { 134303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return (mFilter != null); 135303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 136303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 137303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the list of filtered tasks */ 138303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> getTasks() { 139303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks; 140303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 141303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 142303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 143303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 144303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * The task stack contains a list of multiple tasks. 145303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 146303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpublic class TaskStack { 147ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 148ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Task stack callbacks */ 14904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public interface TaskStackCallbacks { 15004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been added to the stack */ 15104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public void onStackTaskAdded(TaskStack stack, Task t); 15204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been removed from the stack */ 15304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public void onStackTaskRemoved(TaskStack stack, Task t); 15404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was filtered */ 15511ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackFiltered(TaskStack newStack, ArrayList<Task> curTasks, Task t); 15604dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was un-filtered */ 15711ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackUnfiltered(TaskStack newStack, ArrayList<Task> curTasks); 15804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung } 15904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung 160ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** A pair of indices representing the group and task positions in the stack and group. */ 161ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public static class GroupTaskIndex { 162ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int groupIndex; // Index in the stack 163ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int taskIndex; // Index in the group 164ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 165ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public GroupTaskIndex() {} 166ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 167ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public GroupTaskIndex(int gi, int ti) { 168ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung groupIndex = gi; 169ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskIndex = ti; 170ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 171ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 172ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 173303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung FilteredTaskList mTaskList = new FilteredTaskList(); 174303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung TaskStackCallbacks mCb; 175303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 176ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<TaskGrouping> mGroups = new ArrayList<TaskGrouping>(); 177ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung HashMap<String, TaskGrouping> mAffinitiesGroups = new HashMap<String, TaskGrouping>(); 178303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 179303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the callbacks for this task stack */ 180303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setCallbacks(TaskStackCallbacks cb) { 181303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb = cb; 182303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 183303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 184303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task */ 185303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void addTask(Task t) { 186303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.add(t); 187303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 188303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 189303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 190303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 191303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 192303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task */ 193303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void removeTask(Task t) { 194303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mTaskList.contains(t)) { 195ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove the task from the list 196303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.remove(t); 197ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove it from the group as well, and if it is empty, remove the group 198ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = t.group; 199ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.removeTask(t); 200ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (group.getTaskCount() == 0) { 201ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung removeGroup(group); 202ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 203303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 204ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 205303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskRemoved(this, t); 206303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 207303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 208303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 209303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 210303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets a few tasks in one go */ 211303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setTasks(List<Task> tasks) { 212ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> taskList = mTaskList.getTasks(); 213ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = taskList.size(); 214303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (int i = 0; i < taskCount; i++) { 215ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = taskList.get(i); 216ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove the task from the list 217ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskList.remove(t); 218ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove it from the group as well, and if it is empty, remove the group 219ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = t.group; 220ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.removeTask(t); 221ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (group.getTaskCount() == 0) { 222ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung removeGroup(group); 223ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 224303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 225ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 226303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskRemoved(this, t); 227303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 228303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 229303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.set(tasks); 230303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : tasks) { 231303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 232303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 233303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 234303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 235303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 236303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 237ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Gets the front task */ 238ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public Task getFrontMostTask() { 239ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskList.getTasks().get(mTaskList.size() - 1); 240ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 241ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 242303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the tasks */ 243303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public ArrayList<Task> getTasks() { 244303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.getTasks(); 245303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 246303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 247303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the number of tasks */ 248303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int getTaskCount() { 249303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.size(); 250303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 251303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 252303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in this current task stack */ 253303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int indexOfTask(Task t) { 254303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.indexOf(t); 255303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 256303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 257ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Filtering ********/ 258303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 259303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Filters the stack into tasks similar to the one specified */ 260c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public void filterTasks(final Task t) { 261c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 262c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 263303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Set the task list filter 264c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung boolean filtered = mTaskList.setFilter(new TaskFilter() { 265303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 266c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public boolean acceptTask(Task at, int i) { 267c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung return t.key.baseIntent.getComponent().getPackageName().equals( 268c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung at.key.baseIntent.getComponent().getPackageName()); 269303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 270303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung }); 271c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung if (filtered && mCb != null) { 272c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackFiltered(this, oldStack, t); 273303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 274303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 275303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 276303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Unfilters the current stack */ 277303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void unfilterTasks() { 278c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 279c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 280303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Unset the filter, then update the virtual scroll 281303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.removeFilter(); 282303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 283c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackUnfiltered(this, oldStack); 284303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 285303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 286303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 287303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether tasks are currently filtered */ 288303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public boolean hasFilteredTasks() { 289303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.hasFilter(); 290303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 291303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 292ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Grouping ********/ 293ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 294ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Adds a group to the set */ 295ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void addGroup(TaskGrouping group) { 296ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.add(group); 297ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.put(group.affiliation, group); 298ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 299ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 300ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void removeGroup(TaskGrouping group) { 301ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.remove(group); 302ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.remove(group.affiliation); 303ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 304ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 305ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Returns the group with the specified affiliation. */ 306ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public TaskGrouping getGroupWithAffiliation(String affiliation) { 307ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mAffinitiesGroups.get(affiliation); 308ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 309ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 310ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 311ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Temporary: This method will simulate affiliation groups by 312ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 313ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void createSimulatedAffiliatedGroupings() { 314ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (Constants.DebugFlags.App.EnableSimulatedTaskGroups) { 315ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung HashMap<Task.TaskKey, Task> taskMap = new HashMap<Task.TaskKey, Task>(); 316ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort all tasks by increasing firstActiveTime of the task 317ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 318ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(tasks, new Comparator<Task>() { 319ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 320ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task task, Task task2) { 321ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (task.key.firstActiveTime - task2.key.firstActiveTime); 322ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 323ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 324ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Create groups when sequential packages are the same 325ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung NamedCounter counter = new NamedCounter("task-group", ""); 326ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 327ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String prevPackage = ""; 328ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String prevAffiliation = ""; 329a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung Random r = new Random(); 330a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung int groupCountDown = 1000; 331ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 332ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 333ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String packageName = t.key.baseIntent.getComponent().getPackageName(); 334a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung packageName = "pkg"; 335ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group; 336a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung if (packageName.equals(prevPackage) && groupCountDown > 0) { 337ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = getGroupWithAffiliation(prevAffiliation); 338a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung groupCountDown--; 339ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 340ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String affiliation = counter.nextName(); 341ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = new TaskGrouping(affiliation); 342ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung addGroup(group); 343ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevAffiliation = affiliation; 344ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevPackage = packageName; 345a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung groupCountDown = 1000; 346ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 347ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 348ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskMap.put(t.key, t); 349ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 350ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort groups by increasing latestActiveTime of the group 351ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(mGroups, new Comparator<TaskGrouping>() { 352ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 353ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(TaskGrouping taskGrouping, TaskGrouping taskGrouping2) { 354ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskGrouping.latestActiveTimeInGroup - 355ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskGrouping2.latestActiveTimeInGroup); 356ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 357ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 358ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort group tasks by increasing firstActiveTime of the task, and also build a new list of 359ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // tasks 360ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskIndex = 0; 361ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupCount = mGroups.size(); 362ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < groupCount; i++) { 363ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = mGroups.get(i); 364ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(group.mTasks, new Comparator<Task.TaskKey>() { 365ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 366ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task.TaskKey taskKey, Task.TaskKey taskKey2) { 367ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskKey.firstActiveTime - taskKey2.firstActiveTime); 368ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 369ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 370ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task.TaskKey> groupTasks = group.mTasks; 371ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupTaskCount = groupTasks.size(); 372ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int j = 0; j < groupTaskCount; j++) { 373ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung tasks.set(taskIndex, taskMap.get(groupTasks.get(j))); 374ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskIndex++; 375ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 376ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 377ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskList.set(tasks); 378ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 379ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Create a group per task 380ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung NamedCounter counter = new NamedCounter("task-group", ""); 381ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 382ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 383ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 384ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 385ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = new TaskGrouping(counter.nextName()); 386ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung addGroup(group); 387ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 388ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 389ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 390ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 391ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 392303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 393303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public String toString() { 394303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung String str = "Tasks:\n"; 395303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : mTaskList.getTasks()) { 396303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung str += " " + t.toString() + "\n"; 397303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 398303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return str; 399303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 400303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}