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 19ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chungimport android.graphics.Color; 20ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.Constants; 21ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chungimport com.android.systemui.recents.RecentsConfiguration; 22ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.NamedCounter; 23a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chungimport com.android.systemui.recents.misc.Utilities; 24303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 25303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList; 26ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.Collections; 27ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.Comparator; 28ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.HashMap; 29303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.List; 30a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chungimport java.util.Random; 31303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 32303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 33303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 34303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * An interface for a task filter to query whether a particular task should show in a stack. 35303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 36303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chunginterface TaskFilter { 37303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether the filter accepts the specified task */ 38303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public boolean acceptTask(Task t, int index); 39303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 40303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 41303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 42303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * A list of filtered tasks. 43303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 44303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungclass FilteredTaskList { 45303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> mTasks = new ArrayList<Task>(); 46303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> mFilteredTasks = new ArrayList<Task>(); 47ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung HashMap<Task.TaskKey, Integer> mTaskIndices = new HashMap<Task.TaskKey, Integer>(); 48303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung TaskFilter mFilter; 49303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 50303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the task filter, saving the current touch state */ 51c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung boolean setFilter(TaskFilter filter) { 52c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> prevFilteredTasks = new ArrayList<Task>(mFilteredTasks); 53303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilter = filter; 54303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 55b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung if (!prevFilteredTasks.equals(mFilteredTasks)) { 56b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung return true; 57b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung } else { 58b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung // If the tasks are exactly the same pre/post filter, then just reset it 59b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung mFilter = null; 60b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung return false; 61b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung } 62303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 63303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 64bc571a980704dc767838935e83c6aed231c406e9Winson Chung /** Resets this FilteredTaskList. */ 65bc571a980704dc767838935e83c6aed231c406e9Winson Chung void reset() { 66bc571a980704dc767838935e83c6aed231c406e9Winson Chung mTasks.clear(); 67bc571a980704dc767838935e83c6aed231c406e9Winson Chung mFilteredTasks.clear(); 68bc571a980704dc767838935e83c6aed231c406e9Winson Chung mTaskIndices.clear(); 69bc571a980704dc767838935e83c6aed231c406e9Winson Chung mFilter = null; 70bc571a980704dc767838935e83c6aed231c406e9Winson Chung } 71bc571a980704dc767838935e83c6aed231c406e9Winson Chung 72303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes the task filter and returns the previous touch state */ 73303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void removeFilter() { 74303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilter = null; 75303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 76303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 77303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 78303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task to the task list */ 79303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void add(Task t) { 80303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.add(t); 81303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 82303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 83303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 84303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the list of tasks */ 85303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void set(List<Task> tasks) { 86303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.clear(); 87303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.addAll(tasks); 88303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 89303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 90303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 91303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task from the base list only if it is in the filtered list */ 92303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean remove(Task t) { 93303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilteredTasks.contains(t)) { 94303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean removed = mTasks.remove(t); 95303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 96303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return removed; 97303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 98303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return false; 99303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 100303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 101303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in the list of filtered tasks */ 102303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int indexOf(Task t) { 103a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung if (mTaskIndices.containsKey(t.key)) { 104a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung return mTaskIndices.get(t.key); 105a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung } 106a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung return -1; 107303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 108303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 109303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the size of the list of filtered tasks */ 110303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int size() { 111303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks.size(); 112303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 113303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 114303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether the filtered list contains this task */ 115303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean contains(Task t) { 116ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskIndices.containsKey(t.key); 117303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 118303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 119303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Updates the list of filtered tasks whenever the base task list changes */ 120303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung private void updateFilteredTasks() { 121303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.clear(); 122303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter != null) { 123303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int taskCount = mTasks.size(); 124303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (int i = 0; i < taskCount; i++) { 125303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung Task t = mTasks.get(i); 126303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter.acceptTask(t, i)) { 127303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.add(t); 128303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 129303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 130303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } else { 131303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.addAll(mTasks); 132303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 133ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung updateFilteredTaskIndices(); 134ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 135ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 136ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Updates the mapping of tasks to indices. */ 137ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung private void updateFilteredTaskIndices() { 138ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.clear(); 139ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = mFilteredTasks.size(); 140ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 141ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = mFilteredTasks.get(i); 142ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.put(t.key, i); 143ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 144303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 145303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 146303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether this task list is filtered */ 147303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean hasFilter() { 148303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return (mFilter != null); 149303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 150303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 151303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the list of filtered tasks */ 152303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> getTasks() { 153303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks; 154303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 155303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 156303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 157303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 158303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * The task stack contains a list of multiple tasks. 159303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 160303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpublic class TaskStack { 161ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 162ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Task stack callbacks */ 16304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public interface TaskStackCallbacks { 16404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been added to the stack */ 16504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public void onStackTaskAdded(TaskStack stack, Task t); 16604dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been removed from the stack */ 1671f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung public void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask); 16804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was filtered */ 16911ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackFiltered(TaskStack newStack, ArrayList<Task> curTasks, Task t); 17004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was un-filtered */ 17111ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackUnfiltered(TaskStack newStack, ArrayList<Task> curTasks); 17204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung } 17304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung 174ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** A pair of indices representing the group and task positions in the stack and group. */ 175ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public static class GroupTaskIndex { 176ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int groupIndex; // Index in the stack 177ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int taskIndex; // Index in the group 178ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 179ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public GroupTaskIndex() {} 180ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 181ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public GroupTaskIndex(int gi, int ti) { 182ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung groupIndex = gi; 183ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskIndex = ti; 184ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 185ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 186ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 187083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // The task offset to apply to a task id as a group affiliation 188083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung static final int IndividualTaskIdOffset = 1 << 16; 189083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung 190303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung FilteredTaskList mTaskList = new FilteredTaskList(); 191303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung TaskStackCallbacks mCb; 192303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 193ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<TaskGrouping> mGroups = new ArrayList<TaskGrouping>(); 194083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung HashMap<Integer, TaskGrouping> mAffinitiesGroups = new HashMap<Integer, TaskGrouping>(); 195303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 196303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the callbacks for this task stack */ 197303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setCallbacks(TaskStackCallbacks cb) { 198303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb = cb; 199303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 200303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 201bc571a980704dc767838935e83c6aed231c406e9Winson Chung /** Resets this TaskStack. */ 202bc571a980704dc767838935e83c6aed231c406e9Winson Chung public void reset() { 203bc571a980704dc767838935e83c6aed231c406e9Winson Chung mCb = null; 204bc571a980704dc767838935e83c6aed231c406e9Winson Chung mTaskList.reset(); 205bc571a980704dc767838935e83c6aed231c406e9Winson Chung mGroups.clear(); 206bc571a980704dc767838935e83c6aed231c406e9Winson Chung mAffinitiesGroups.clear(); 207bc571a980704dc767838935e83c6aed231c406e9Winson Chung } 208bc571a980704dc767838935e83c6aed231c406e9Winson Chung 209303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task */ 210303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void addTask(Task t) { 211303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.add(t); 212303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 213303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 214303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 215303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 216303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 217303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task */ 218303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void removeTask(Task t) { 219303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mTaskList.contains(t)) { 220ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove the task from the list 221303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.remove(t); 222ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove it from the group as well, and if it is empty, remove the group 223ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = t.group; 224ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.removeTask(t); 225ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (group.getTaskCount() == 0) { 226ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung removeGroup(group); 227ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 2281f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung // Update the lock-to-app state 22956e09b42a0f1670970872bef611a8036904ad6bfJason Monk t.lockToThisTask = false; 23082c8c5e9872b984ba6f43b01da0c7731fd5bf762Winson Chung Task newFrontMostTask = getFrontMostTask(); 23156e09b42a0f1670970872bef611a8036904ad6bfJason Monk if (newFrontMostTask != null && newFrontMostTask.lockToTaskEnabled) { 23256e09b42a0f1670970872bef611a8036904ad6bfJason Monk newFrontMostTask.lockToThisTask = true; 2331f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung } 234303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 235ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 2361f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung mCb.onStackTaskRemoved(this, t, newFrontMostTask); 237303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 238303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 239303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 240303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 241303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets a few tasks in one go */ 242303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setTasks(List<Task> tasks) { 243ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> taskList = mTaskList.getTasks(); 244ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = taskList.size(); 245303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (int i = 0; i < taskCount; i++) { 246ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = taskList.get(i); 247ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove the task from the list 248ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskList.remove(t); 249ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove it from the group as well, and if it is empty, remove the group 250ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = t.group; 251ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.removeTask(t); 252ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (group.getTaskCount() == 0) { 253ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung removeGroup(group); 254ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 25598e8f7ac5e75a47abaa0061aab343b9f06770258Winson Chung // Update the lock-to-app state 25698e8f7ac5e75a47abaa0061aab343b9f06770258Winson Chung t.lockToThisTask = false; 257303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 258ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 2591f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung mCb.onStackTaskRemoved(this, t, null); 260303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 261303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 262303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.set(tasks); 263303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : tasks) { 264303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 265303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 266303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 267303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 268303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 269303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 270ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Gets the front task */ 271ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public Task getFrontMostTask() { 2721f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung if (mTaskList.size() == 0) return null; 273ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskList.getTasks().get(mTaskList.size() - 1); 274ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 275ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 27604400672962d2e12132f9465928cbf7615c147c4Winson Chung /** Gets the task keys */ 27704400672962d2e12132f9465928cbf7615c147c4Winson Chung public ArrayList<Task.TaskKey> getTaskKeys() { 27804400672962d2e12132f9465928cbf7615c147c4Winson Chung ArrayList<Task.TaskKey> taskKeys = new ArrayList<Task.TaskKey>(); 27904400672962d2e12132f9465928cbf7615c147c4Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 28004400672962d2e12132f9465928cbf7615c147c4Winson Chung int taskCount = tasks.size(); 28104400672962d2e12132f9465928cbf7615c147c4Winson Chung for (int i = 0; i < taskCount; i++) { 28204400672962d2e12132f9465928cbf7615c147c4Winson Chung taskKeys.add(tasks.get(i).key); 28304400672962d2e12132f9465928cbf7615c147c4Winson Chung } 28404400672962d2e12132f9465928cbf7615c147c4Winson Chung return taskKeys; 28504400672962d2e12132f9465928cbf7615c147c4Winson Chung } 28604400672962d2e12132f9465928cbf7615c147c4Winson Chung 287303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the tasks */ 288303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public ArrayList<Task> getTasks() { 289303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.getTasks(); 290303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 291303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 292303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the number of tasks */ 293303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int getTaskCount() { 294303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.size(); 295303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 296303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 297303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in this current task stack */ 298303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int indexOfTask(Task t) { 299303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.indexOf(t); 300303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 301303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 302b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung /** Finds the task with the specified task id. */ 303b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung public Task findTaskWithId(int taskId) { 304b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 305b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung int taskCount = tasks.size(); 306b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung for (int i = 0; i < taskCount; i++) { 307b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung Task task = tasks.get(i); 308b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung if (task.key.id == taskId) { 309b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung return task; 310b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 311b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 312b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung return null; 313b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 314b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung 315ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Filtering ********/ 316303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 317303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Filters the stack into tasks similar to the one specified */ 318c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public void filterTasks(final Task t) { 319c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 320c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 321303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Set the task list filter 322c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung boolean filtered = mTaskList.setFilter(new TaskFilter() { 323303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 324c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public boolean acceptTask(Task at, int i) { 325c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung return t.key.baseIntent.getComponent().getPackageName().equals( 326c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung at.key.baseIntent.getComponent().getPackageName()); 327303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 328303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung }); 329c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung if (filtered && mCb != null) { 330c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackFiltered(this, oldStack, t); 331303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 332303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 333303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 334303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Unfilters the current stack */ 335303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void unfilterTasks() { 336c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 337c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 338303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Unset the filter, then update the virtual scroll 339303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.removeFilter(); 340303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 341c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackUnfiltered(this, oldStack); 342303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 343303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 344303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 345303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether tasks are currently filtered */ 346303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public boolean hasFilteredTasks() { 347303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.hasFilter(); 348303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 349303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 350ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Grouping ********/ 351ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 352ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Adds a group to the set */ 353ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void addGroup(TaskGrouping group) { 354ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.add(group); 355ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.put(group.affiliation, group); 356ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 357ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 358ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void removeGroup(TaskGrouping group) { 359ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.remove(group); 360ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.remove(group.affiliation); 361ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 362ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 363ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Returns the group with the specified affiliation. */ 364083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung public TaskGrouping getGroupWithAffiliation(int affiliation) { 365ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mAffinitiesGroups.get(affiliation); 366ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 367ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 368ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 369ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Temporary: This method will simulate affiliation groups by 370ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 371ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung public void createAffiliatedGroupings(RecentsConfiguration config) { 372ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (Constants.DebugFlags.App.EnableSimulatedTaskGroups) { 373ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung HashMap<Task.TaskKey, Task> taskMap = new HashMap<Task.TaskKey, Task>(); 374ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort all tasks by increasing firstActiveTime of the task 375ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 376ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(tasks, new Comparator<Task>() { 377ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 378ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task task, Task task2) { 379ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (task.key.firstActiveTime - task2.key.firstActiveTime); 380ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 381ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 382ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Create groups when sequential packages are the same 383ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung NamedCounter counter = new NamedCounter("task-group", ""); 384ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 385ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String prevPackage = ""; 386083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int prevAffiliation = -1; 387a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung Random r = new Random(); 388012ef36a6c5e9745d112c734aed916cab052558cWinson Chung int groupCountDown = Constants.DebugFlags.App.TaskAffiliationsGroupCount; 389ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 390ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 391ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String packageName = t.key.baseIntent.getComponent().getPackageName(); 392a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung packageName = "pkg"; 393ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group; 394a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung if (packageName.equals(prevPackage) && groupCountDown > 0) { 395ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = getGroupWithAffiliation(prevAffiliation); 396a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung groupCountDown--; 397ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 398083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int affiliation = IndividualTaskIdOffset + t.key.id; 399ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = new TaskGrouping(affiliation); 400ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung addGroup(group); 401ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevAffiliation = affiliation; 402ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevPackage = packageName; 403012ef36a6c5e9745d112c734aed916cab052558cWinson Chung groupCountDown = Constants.DebugFlags.App.TaskAffiliationsGroupCount; 404ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 405ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 406ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskMap.put(t.key, t); 407ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 408ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort groups by increasing latestActiveTime of the group 409ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(mGroups, new Comparator<TaskGrouping>() { 410ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 411ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(TaskGrouping taskGrouping, TaskGrouping taskGrouping2) { 412ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskGrouping.latestActiveTimeInGroup - 413ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskGrouping2.latestActiveTimeInGroup); 414ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 415ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 416ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort group tasks by increasing firstActiveTime of the task, and also build a new list of 417ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // tasks 418ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskIndex = 0; 419ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupCount = mGroups.size(); 420ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < groupCount; i++) { 421ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = mGroups.get(i); 422083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung Collections.sort(group.mTaskKeys, new Comparator<Task.TaskKey>() { 423ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 424ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task.TaskKey taskKey, Task.TaskKey taskKey2) { 425ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskKey.firstActiveTime - taskKey2.firstActiveTime); 426ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 427ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 428083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung ArrayList<Task.TaskKey> groupTasks = group.mTaskKeys; 429ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupTaskCount = groupTasks.size(); 430ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int j = 0; j < groupTaskCount; j++) { 431ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung tasks.set(taskIndex, taskMap.get(groupTasks.get(j))); 432ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskIndex++; 433ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 434ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 435ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskList.set(tasks); 436ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 437083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // Create the task groups 438ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung HashMap<Task.TaskKey, Task> tasksMap = new HashMap<Task.TaskKey, Task>(); 439ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 440ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 441ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 442ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 443083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung TaskGrouping group; 444083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int affiliation = t.taskAffiliation > 0 ? t.taskAffiliation : 445083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung IndividualTaskIdOffset + t.key.id; 446083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung if (mAffinitiesGroups.containsKey(affiliation)) { 447083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung group = getGroupWithAffiliation(affiliation); 448083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } else { 449083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung group = new TaskGrouping(affiliation); 450083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung addGroup(group); 451083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } 452ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 453ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung tasksMap.put(t.key, t); 454ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung } 455ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Update the task colors for each of the groups 456ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float minAlpha = config.taskBarViewAffiliationColorMinAlpha; 457ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung int taskGroupCount = mGroups.size(); 458ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung for (int i = 0; i < taskGroupCount; i++) { 459ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung TaskGrouping group = mGroups.get(i); 460ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung taskCount = group.getTaskCount(); 461ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Ignore the groups that only have one task 462ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung if (taskCount <= 1) continue; 463ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Calculate the group color distribution 464ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung int affiliationColor = tasksMap.get(group.mTaskKeys.get(0)).taskAffiliationColor; 465ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float alphaStep = (1f - minAlpha) / taskCount; 466ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float alpha = 1f; 467ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung for (int j = 0; j < taskCount; j++) { 468ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung Task t = tasksMap.get(group.mTaskKeys.get(j)); 469a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung t.colorPrimary = Utilities.getColorWithOverlay(affiliationColor, Color.WHITE, 470a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung alpha); 471ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung alpha -= alphaStep; 472ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung } 473ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 474ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 475ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 476ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 477303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 478303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public String toString() { 479303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung String str = "Tasks:\n"; 480303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : mTaskList.getTasks()) { 481303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung str += " " + t.toString() + "\n"; 482303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 483303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return str; 484303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 48598e8f7ac5e75a47abaa0061aab343b9f06770258Winson Chung} 486