TaskStack.java revision a4ccb86ddc8f9f486aee25fb836f4aff97bf7679
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 64303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes the task filter and returns the previous touch state */ 65303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void removeFilter() { 66303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilter = null; 67303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 68303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 69303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 70303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task to the task list */ 71303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void add(Task t) { 72303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.add(t); 73303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 74303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 75303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 76303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the list of tasks */ 77303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void set(List<Task> tasks) { 78303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.clear(); 79303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.addAll(tasks); 80303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 81303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 82303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 83303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task from the base list only if it is in the filtered list */ 84303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean remove(Task t) { 85303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilteredTasks.contains(t)) { 86303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean removed = mTasks.remove(t); 87303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 88303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return removed; 89303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 90303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return false; 91303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 92303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 93303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in the list of filtered tasks */ 94303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int indexOf(Task t) { 95a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung if (mTaskIndices.containsKey(t.key)) { 96a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung return mTaskIndices.get(t.key); 97a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung } 98a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung return -1; 99303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 100303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 101303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the size of the list of filtered tasks */ 102303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int size() { 103303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks.size(); 104303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 105303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 106303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether the filtered list contains this task */ 107303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean contains(Task t) { 108ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskIndices.containsKey(t.key); 109303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 110303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 111303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Updates the list of filtered tasks whenever the base task list changes */ 112303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung private void updateFilteredTasks() { 113303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.clear(); 114303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter != null) { 115303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int taskCount = mTasks.size(); 116303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (int i = 0; i < taskCount; i++) { 117303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung Task t = mTasks.get(i); 118303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter.acceptTask(t, i)) { 119303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.add(t); 120303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 121303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 122303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } else { 123303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.addAll(mTasks); 124303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 125ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung updateFilteredTaskIndices(); 126ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 127ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 128ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Updates the mapping of tasks to indices. */ 129ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung private void updateFilteredTaskIndices() { 130ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.clear(); 131ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = mFilteredTasks.size(); 132ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 133ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = mFilteredTasks.get(i); 134ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.put(t.key, i); 135ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 136303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 137303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 138303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether this task list is filtered */ 139303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean hasFilter() { 140303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return (mFilter != null); 141303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 142303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 143303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the list of filtered tasks */ 144303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> getTasks() { 145303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks; 146303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 147303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 148303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 149303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 150303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * The task stack contains a list of multiple tasks. 151303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 152303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpublic class TaskStack { 153ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 154ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Task stack callbacks */ 15504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public interface TaskStackCallbacks { 15604dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been added to the stack */ 15704dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public void onStackTaskAdded(TaskStack stack, Task t); 15804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been removed from the stack */ 1591f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung public void onStackTaskRemoved(TaskStack stack, Task removedTask, Task newFrontMostTask); 16004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was filtered */ 16111ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackFiltered(TaskStack newStack, ArrayList<Task> curTasks, Task t); 16204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was un-filtered */ 16311ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackUnfiltered(TaskStack newStack, ArrayList<Task> curTasks); 16404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung } 16504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung 166ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** A pair of indices representing the group and task positions in the stack and group. */ 167ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public static class GroupTaskIndex { 168ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int groupIndex; // Index in the stack 169ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int taskIndex; // Index in the group 170ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 171ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public GroupTaskIndex() {} 172ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 173ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public GroupTaskIndex(int gi, int ti) { 174ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung groupIndex = gi; 175ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskIndex = ti; 176ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 177ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 178ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 179083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // The task offset to apply to a task id as a group affiliation 180083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung static final int IndividualTaskIdOffset = 1 << 16; 181083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung 182303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung FilteredTaskList mTaskList = new FilteredTaskList(); 183303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung TaskStackCallbacks mCb; 184303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 185ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<TaskGrouping> mGroups = new ArrayList<TaskGrouping>(); 186083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung HashMap<Integer, TaskGrouping> mAffinitiesGroups = new HashMap<Integer, TaskGrouping>(); 187303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 188303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the callbacks for this task stack */ 189303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setCallbacks(TaskStackCallbacks cb) { 190303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb = cb; 191303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 192303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 193303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task */ 194303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void addTask(Task t) { 195303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.add(t); 196303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 197303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 198303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 199303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 200303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 201303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task */ 202303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void removeTask(Task t) { 203303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mTaskList.contains(t)) { 204ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove the task from the list 205303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.remove(t); 206ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove it from the group as well, and if it is empty, remove the group 207ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = t.group; 208ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.removeTask(t); 209ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (group.getTaskCount() == 0) { 210ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung removeGroup(group); 211ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 2121f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung // Update the lock-to-app state 21356e09b42a0f1670970872bef611a8036904ad6bfJason Monk t.lockToThisTask = false; 21482c8c5e9872b984ba6f43b01da0c7731fd5bf762Winson Chung Task newFrontMostTask = getFrontMostTask(); 21556e09b42a0f1670970872bef611a8036904ad6bfJason Monk if (newFrontMostTask != null && newFrontMostTask.lockToTaskEnabled) { 21656e09b42a0f1670970872bef611a8036904ad6bfJason Monk newFrontMostTask.lockToThisTask = true; 2171f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung } 218303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 219ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 2201f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung mCb.onStackTaskRemoved(this, t, newFrontMostTask); 221303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 222303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 223303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 224303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 225303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets a few tasks in one go */ 226303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setTasks(List<Task> tasks) { 227ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> taskList = mTaskList.getTasks(); 228ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = taskList.size(); 229303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (int i = 0; i < taskCount; i++) { 230ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = taskList.get(i); 231ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove the task from the list 232ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskList.remove(t); 233ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Remove it from the group as well, and if it is empty, remove the group 234ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = t.group; 235ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.removeTask(t); 236ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (group.getTaskCount() == 0) { 237ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung removeGroup(group); 238ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 239303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 240ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 2411f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung mCb.onStackTaskRemoved(this, t, null); 242303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 243303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 244303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.set(tasks); 245303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : tasks) { 246303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 247303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 248303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 249303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 250303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 251303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 252ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Gets the front task */ 253ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public Task getFrontMostTask() { 2541f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung if (mTaskList.size() == 0) return null; 255ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskList.getTasks().get(mTaskList.size() - 1); 256ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 257ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 258303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the tasks */ 259303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public ArrayList<Task> getTasks() { 260303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.getTasks(); 261303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 262303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 263303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the number of tasks */ 264303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int getTaskCount() { 265303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.size(); 266303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 267303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 268303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in this current task stack */ 269303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int indexOfTask(Task t) { 270303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.indexOf(t); 271303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 272303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 273b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung /** Finds the task with the specified task id. */ 274b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung public Task findTaskWithId(int taskId) { 275b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 276b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung int taskCount = tasks.size(); 277b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung for (int i = 0; i < taskCount; i++) { 278b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung Task task = tasks.get(i); 279b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung if (task.key.id == taskId) { 280b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung return task; 281b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 282b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 283b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung return null; 284b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 285b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung 286ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Filtering ********/ 287303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 288303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Filters the stack into tasks similar to the one specified */ 289c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public void filterTasks(final Task t) { 290c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 291c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 292303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Set the task list filter 293c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung boolean filtered = mTaskList.setFilter(new TaskFilter() { 294303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 295c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public boolean acceptTask(Task at, int i) { 296c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung return t.key.baseIntent.getComponent().getPackageName().equals( 297c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung at.key.baseIntent.getComponent().getPackageName()); 298303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 299303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung }); 300c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung if (filtered && mCb != null) { 301c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackFiltered(this, oldStack, t); 302303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 303303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 304303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 305303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Unfilters the current stack */ 306303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void unfilterTasks() { 307c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 308c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 309303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Unset the filter, then update the virtual scroll 310303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.removeFilter(); 311303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 312c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackUnfiltered(this, oldStack); 313303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 314303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 315303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 316303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether tasks are currently filtered */ 317303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public boolean hasFilteredTasks() { 318303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.hasFilter(); 319303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 320303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 321ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Grouping ********/ 322ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 323ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Adds a group to the set */ 324ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void addGroup(TaskGrouping group) { 325ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.add(group); 326ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.put(group.affiliation, group); 327ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 328ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 329ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void removeGroup(TaskGrouping group) { 330ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.remove(group); 331ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.remove(group.affiliation); 332ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 333ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 334ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Returns the group with the specified affiliation. */ 335083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung public TaskGrouping getGroupWithAffiliation(int affiliation) { 336ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mAffinitiesGroups.get(affiliation); 337ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 338ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 339ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 340ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Temporary: This method will simulate affiliation groups by 341ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 342ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung public void createAffiliatedGroupings(RecentsConfiguration config) { 343ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung if (Constants.DebugFlags.App.EnableSimulatedTaskGroups) { 344ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung HashMap<Task.TaskKey, Task> taskMap = new HashMap<Task.TaskKey, Task>(); 345ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort all tasks by increasing firstActiveTime of the task 346ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 347ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(tasks, new Comparator<Task>() { 348ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 349ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task task, Task task2) { 350ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (task.key.firstActiveTime - task2.key.firstActiveTime); 351ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 352ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 353ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Create groups when sequential packages are the same 354ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung NamedCounter counter = new NamedCounter("task-group", ""); 355ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 356ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String prevPackage = ""; 357083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int prevAffiliation = -1; 358a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung Random r = new Random(); 359012ef36a6c5e9745d112c734aed916cab052558cWinson Chung int groupCountDown = Constants.DebugFlags.App.TaskAffiliationsGroupCount; 360ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 361ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 362ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String packageName = t.key.baseIntent.getComponent().getPackageName(); 363a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung packageName = "pkg"; 364ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group; 365a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung if (packageName.equals(prevPackage) && groupCountDown > 0) { 366ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = getGroupWithAffiliation(prevAffiliation); 367a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung groupCountDown--; 368ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 369083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int affiliation = IndividualTaskIdOffset + t.key.id; 370ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = new TaskGrouping(affiliation); 371ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung addGroup(group); 372ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevAffiliation = affiliation; 373ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevPackage = packageName; 374012ef36a6c5e9745d112c734aed916cab052558cWinson Chung groupCountDown = Constants.DebugFlags.App.TaskAffiliationsGroupCount; 375ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 376ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 377ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskMap.put(t.key, t); 378ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 379ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort groups by increasing latestActiveTime of the group 380ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(mGroups, new Comparator<TaskGrouping>() { 381ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 382ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(TaskGrouping taskGrouping, TaskGrouping taskGrouping2) { 383ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskGrouping.latestActiveTimeInGroup - 384ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskGrouping2.latestActiveTimeInGroup); 385ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 386ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 387ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort group tasks by increasing firstActiveTime of the task, and also build a new list of 388ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // tasks 389ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskIndex = 0; 390ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupCount = mGroups.size(); 391ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < groupCount; i++) { 392ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = mGroups.get(i); 393083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung Collections.sort(group.mTaskKeys, new Comparator<Task.TaskKey>() { 394ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 395ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task.TaskKey taskKey, Task.TaskKey taskKey2) { 396ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskKey.firstActiveTime - taskKey2.firstActiveTime); 397ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 398ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 399083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung ArrayList<Task.TaskKey> groupTasks = group.mTaskKeys; 400ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupTaskCount = groupTasks.size(); 401ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int j = 0; j < groupTaskCount; j++) { 402ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung tasks.set(taskIndex, taskMap.get(groupTasks.get(j))); 403ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskIndex++; 404ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 405ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 406ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskList.set(tasks); 407ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 408083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // Create the task groups 409ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung HashMap<Task.TaskKey, Task> tasksMap = new HashMap<Task.TaskKey, Task>(); 410ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 411ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 412ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 413ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 414083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung TaskGrouping group; 415083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int affiliation = t.taskAffiliation > 0 ? t.taskAffiliation : 416083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung IndividualTaskIdOffset + t.key.id; 417083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung if (mAffinitiesGroups.containsKey(affiliation)) { 418083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung group = getGroupWithAffiliation(affiliation); 419083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } else { 420083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung group = new TaskGrouping(affiliation); 421083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung addGroup(group); 422083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } 423ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 424ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung tasksMap.put(t.key, t); 425ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung } 426ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Update the task colors for each of the groups 427ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float minAlpha = config.taskBarViewAffiliationColorMinAlpha; 428ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung int taskGroupCount = mGroups.size(); 429ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung for (int i = 0; i < taskGroupCount; i++) { 430ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung TaskGrouping group = mGroups.get(i); 431ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung taskCount = group.getTaskCount(); 432ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Ignore the groups that only have one task 433ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung if (taskCount <= 1) continue; 434ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Calculate the group color distribution 435ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung int affiliationColor = tasksMap.get(group.mTaskKeys.get(0)).taskAffiliationColor; 436ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float alphaStep = (1f - minAlpha) / taskCount; 437ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float alpha = 1f; 438ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung for (int j = 0; j < taskCount; j++) { 439ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung Task t = tasksMap.get(group.mTaskKeys.get(j)); 440a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung t.colorPrimary = Utilities.getColorWithOverlay(affiliationColor, Color.WHITE, 441a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung alpha); 442ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung alpha -= alphaStep; 443ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung } 444ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 445ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 446ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 447ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 448303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 449303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public String toString() { 450303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung String str = "Tasks:\n"; 451303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : mTaskList.getTasks()) { 452303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung str += " " + t.toString() + "\n"; 453303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 454303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return str; 455303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 456303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}