TaskStack.java revision 8b1871d74137d7e36ba0fed5608772f51f62015b
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 19882072baacaee4ecd43f0209b691a9af746462f2Winsonimport android.animation.ObjectAnimator; 20e7f138c7f0a190c86cec10fb32fa106aacae4093Winsonimport android.content.ComponentName; 2135f3050959e43bf378f9a0adcaef13729206c7e4Winsonimport android.content.Context; 22ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chungimport android.graphics.Color; 23be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport android.graphics.Rect; 24be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport android.graphics.RectF; 25882072baacaee4ecd43f0209b691a9af746462f2Winsonimport android.graphics.drawable.ColorDrawable; 262536c7ed446203ea12b38cf05a88e603f8d1b768Winsonimport com.android.systemui.R; 27e7f138c7f0a190c86cec10fb32fa106aacae4093Winsonimport com.android.systemui.recents.Recents; 28c742f973b1e506732911c156c5869fd377afc5bfWinsonimport com.android.systemui.recents.RecentsDebugFlags; 29ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.NamedCounter; 30e7f138c7f0a190c86cec10fb32fa106aacae4093Winsonimport com.android.systemui.recents.misc.SystemServicesProxy; 31a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chungimport com.android.systemui.recents.misc.Utilities; 32eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport com.android.systemui.recents.views.DropTarget; 33303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 34303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList; 35ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.Collections; 36ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.Comparator; 37ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport java.util.HashMap; 38e7f138c7f0a190c86cec10fb32fa106aacae4093Winsonimport java.util.HashSet; 39303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.List; 40a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chungimport java.util.Random; 41303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 42be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT; 43be7607af8875236b9cf7bdb5f5aa089c207529afWinsonimport static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; 44eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; 45eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winsonimport static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; 46be7607af8875236b9cf7bdb5f5aa089c207529afWinson 47303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 48303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 49303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * An interface for a task filter to query whether a particular task should show in a stack. 50303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 51303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chunginterface TaskFilter { 52303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether the filter accepts the specified task */ 53303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public boolean acceptTask(Task t, int index); 54303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 55303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 56303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 57303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * A list of filtered tasks. 58303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 59303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungclass FilteredTaskList { 60eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 61eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson private static final String TAG = "FilteredTaskList"; 628b1871d74137d7e36ba0fed5608772f51f62015bWinson private static final boolean DEBUG = false; 63eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 64eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson ArrayList<Task> mTasks = new ArrayList<>(); 65eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson ArrayList<Task> mFilteredTasks = new ArrayList<>(); 66eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson HashMap<Task.TaskKey, Integer> mTaskIndices = new HashMap<>(); 67303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung TaskFilter mFilter; 68303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 69303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the task filter, saving the current touch state */ 70c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung boolean setFilter(TaskFilter filter) { 71c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> prevFilteredTasks = new ArrayList<Task>(mFilteredTasks); 72303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilter = filter; 73303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 74b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung if (!prevFilteredTasks.equals(mFilteredTasks)) { 75b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung return true; 76b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung } else { 77b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung // If the tasks are exactly the same pre/post filter, then just reset it 78b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung mFilter = null; 79b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung return false; 80b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung } 81303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 82303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 83bc571a980704dc767838935e83c6aed231c406e9Winson Chung /** Resets this FilteredTaskList. */ 84bc571a980704dc767838935e83c6aed231c406e9Winson Chung void reset() { 85bc571a980704dc767838935e83c6aed231c406e9Winson Chung mTasks.clear(); 86bc571a980704dc767838935e83c6aed231c406e9Winson Chung mFilteredTasks.clear(); 87bc571a980704dc767838935e83c6aed231c406e9Winson Chung mTaskIndices.clear(); 88bc571a980704dc767838935e83c6aed231c406e9Winson Chung mFilter = null; 89bc571a980704dc767838935e83c6aed231c406e9Winson Chung } 90bc571a980704dc767838935e83c6aed231c406e9Winson Chung 91303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes the task filter and returns the previous touch state */ 92303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void removeFilter() { 93303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilter = null; 94303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 95303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 96303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 97303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task to the task list */ 98303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void add(Task t) { 99303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.add(t); 100303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 101303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 102303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 103eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson /** 104eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson * Moves the given task. 105eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson */ 106eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson public void moveTaskToStack(Task task, int insertIndex, int newStackId) { 107eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson int taskIndex = indexOf(task); 108eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson if (taskIndex != insertIndex) { 109eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mTasks.remove(taskIndex); 110eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson if (taskIndex < insertIndex) { 111eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson insertIndex--; 112eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 113eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mTasks.add(insertIndex, task); 114eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 115eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 116eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson // Update the stack id now, after we've moved the task, and before we update the 117eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson // filtered tasks 118eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson task.setStackId(newStackId); 119eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson updateFilteredTasks(); 120eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 121eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 122303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets the list of tasks */ 123303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung void set(List<Task> tasks) { 124303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.clear(); 125303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTasks.addAll(tasks); 126303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 127303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 128303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 129303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task from the base list only if it is in the filtered list */ 130303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean remove(Task t) { 131303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilteredTasks.contains(t)) { 132303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean removed = mTasks.remove(t); 133303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung updateFilteredTasks(); 134303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return removed; 135303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 136303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return false; 137303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 138303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 139303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in the list of filtered tasks */ 140303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int indexOf(Task t) { 141a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung if (mTaskIndices.containsKey(t.key)) { 142a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung return mTaskIndices.get(t.key); 143a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung } 144a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung return -1; 145303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 146303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 147303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the size of the list of filtered tasks */ 148303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int size() { 149303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks.size(); 150303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 151303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 152303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether the filtered list contains this task */ 153303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean contains(Task t) { 154ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskIndices.containsKey(t.key); 155303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 156303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 157303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Updates the list of filtered tasks whenever the base task list changes */ 158303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung private void updateFilteredTasks() { 159303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.clear(); 160303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter != null) { 161303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung int taskCount = mTasks.size(); 162303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (int i = 0; i < taskCount; i++) { 163303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung Task t = mTasks.get(i); 164303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mFilter.acceptTask(t, i)) { 165303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.add(t); 166303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 167303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 168303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } else { 169303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mFilteredTasks.addAll(mTasks); 170303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 171ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung updateFilteredTaskIndices(); 172ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 173ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 174ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Updates the mapping of tasks to indices. */ 175ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung private void updateFilteredTaskIndices() { 176ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.clear(); 177ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = mFilteredTasks.size(); 178ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 179ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = mFilteredTasks.get(i); 180ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskIndices.put(t.key, i); 181ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 182303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 183303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 184303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether this task list is filtered */ 185303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung boolean hasFilter() { 186303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return (mFilter != null); 187303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 188303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 189303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the list of filtered tasks */ 190303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung ArrayList<Task> getTasks() { 191303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mFilteredTasks; 192303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 193303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung} 194303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 195303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/** 196303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * The task stack contains a list of multiple tasks. 197303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */ 198303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpublic class TaskStack { 199ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 200ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Task stack callbacks */ 20104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public interface TaskStackCallbacks { 20204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been added to the stack */ 20304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung public void onStackTaskAdded(TaskStack stack, Task t); 20404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /* Notifies when a task has been removed from the stack */ 20542be431c3d129871d257768e185334d49c071ec5Winson public void onStackTaskRemoved(TaskStack stack, Task removedTask, boolean wasFrontMostTask, 20642be431c3d129871d257768e185334d49c071ec5Winson Task newFrontMostTask); 2076ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung /* Notifies when all task has been removed from the stack */ 2086ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung public void onStackAllTasksRemoved(TaskStack stack, ArrayList<Task> removedTasks); 20904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was filtered */ 21011ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackFiltered(TaskStack newStack, ArrayList<Task> curTasks, Task t); 21104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung /** Notifies when the stack was un-filtered */ 21211ca76a53c60a1898956614315ae929668c523d6Winson Chung public void onStackUnfiltered(TaskStack newStack, ArrayList<Task> curTasks); 21304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung } 21404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung 215be7607af8875236b9cf7bdb5f5aa089c207529afWinson 216eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson public enum DockState implements DropTarget { 217eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson NONE(-1, 96, null, null), 2184165d336b6cd69715eda7fbdfd272a878097170eWinson LEFT(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, 192, 219eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson new RectF(0, 0, 0.25f, 1), new RectF(0, 0, 0.25f, 1)), 2204165d336b6cd69715eda7fbdfd272a878097170eWinson TOP(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, 192, 221eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson new RectF(0, 0, 1, 0.25f), new RectF(0, 0, 1, 0.25f)), 2224165d336b6cd69715eda7fbdfd272a878097170eWinson RIGHT(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, 192, 223eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson new RectF(0.75f, 0, 1, 1), new RectF(0.75f, 0, 1, 1)), 2244165d336b6cd69715eda7fbdfd272a878097170eWinson BOTTOM(DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT, 192, 225eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson new RectF(0, 0.75f, 1, 1), new RectF(0, 0.75f, 1, 1)); 226eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 227eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson @Override 228eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson public boolean acceptsDrop(int x, int y, int width, int height) { 229eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson return touchAreaContainsPoint(width, height, x, y); 230eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 231be7607af8875236b9cf7bdb5f5aa089c207529afWinson 232882072baacaee4ecd43f0209b691a9af746462f2Winson // Represents the view state of this dock state 233882072baacaee4ecd43f0209b691a9af746462f2Winson public class ViewState { 234882072baacaee4ecd43f0209b691a9af746462f2Winson public final int dockAreaAlpha; 235882072baacaee4ecd43f0209b691a9af746462f2Winson public final ColorDrawable dockAreaOverlay; 236882072baacaee4ecd43f0209b691a9af746462f2Winson private ObjectAnimator dockAreaOverlayAnimator; 237882072baacaee4ecd43f0209b691a9af746462f2Winson 238882072baacaee4ecd43f0209b691a9af746462f2Winson private ViewState(int alpha) { 239882072baacaee4ecd43f0209b691a9af746462f2Winson dockAreaAlpha = alpha; 240882072baacaee4ecd43f0209b691a9af746462f2Winson dockAreaOverlay = new ColorDrawable(0xFFffffff); 241882072baacaee4ecd43f0209b691a9af746462f2Winson dockAreaOverlay.setAlpha(0); 242882072baacaee4ecd43f0209b691a9af746462f2Winson } 243882072baacaee4ecd43f0209b691a9af746462f2Winson 244882072baacaee4ecd43f0209b691a9af746462f2Winson /** 245882072baacaee4ecd43f0209b691a9af746462f2Winson * Creates a new alpha animation. 246882072baacaee4ecd43f0209b691a9af746462f2Winson */ 247882072baacaee4ecd43f0209b691a9af746462f2Winson public void startAlphaAnimation(int alpha, int duration) { 248882072baacaee4ecd43f0209b691a9af746462f2Winson if (dockAreaOverlay.getAlpha() != alpha) { 249882072baacaee4ecd43f0209b691a9af746462f2Winson if (dockAreaOverlayAnimator != null) { 250882072baacaee4ecd43f0209b691a9af746462f2Winson dockAreaOverlayAnimator.cancel(); 251882072baacaee4ecd43f0209b691a9af746462f2Winson } 252882072baacaee4ecd43f0209b691a9af746462f2Winson dockAreaOverlayAnimator = ObjectAnimator.ofInt(dockAreaOverlay, "alpha", alpha); 253882072baacaee4ecd43f0209b691a9af746462f2Winson dockAreaOverlayAnimator.setDuration(duration); 254882072baacaee4ecd43f0209b691a9af746462f2Winson dockAreaOverlayAnimator.start(); 255882072baacaee4ecd43f0209b691a9af746462f2Winson } 256882072baacaee4ecd43f0209b691a9af746462f2Winson } 257882072baacaee4ecd43f0209b691a9af746462f2Winson } 258882072baacaee4ecd43f0209b691a9af746462f2Winson 259be7607af8875236b9cf7bdb5f5aa089c207529afWinson public final int createMode; 260882072baacaee4ecd43f0209b691a9af746462f2Winson public final ViewState viewState; 261be7607af8875236b9cf7bdb5f5aa089c207529afWinson private final RectF dockArea; 262882072baacaee4ecd43f0209b691a9af746462f2Winson private final RectF touchArea; 263be7607af8875236b9cf7bdb5f5aa089c207529afWinson 264be7607af8875236b9cf7bdb5f5aa089c207529afWinson /** 265be7607af8875236b9cf7bdb5f5aa089c207529afWinson * @param createMode used to pass to ActivityManager to dock the task 266be7607af8875236b9cf7bdb5f5aa089c207529afWinson * @param touchArea the area in which touch will initiate this dock state 267eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson * @param dockArea the visible dock area 268be7607af8875236b9cf7bdb5f5aa089c207529afWinson */ 269eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson DockState(int createMode, int dockAreaAlpha, RectF touchArea, RectF dockArea) { 270be7607af8875236b9cf7bdb5f5aa089c207529afWinson this.createMode = createMode; 271882072baacaee4ecd43f0209b691a9af746462f2Winson this.viewState = new ViewState(dockAreaAlpha); 272be7607af8875236b9cf7bdb5f5aa089c207529afWinson this.dockArea = dockArea; 273882072baacaee4ecd43f0209b691a9af746462f2Winson this.touchArea = touchArea; 274be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 275be7607af8875236b9cf7bdb5f5aa089c207529afWinson 276be7607af8875236b9cf7bdb5f5aa089c207529afWinson /** 277be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Returns whether {@param x} and {@param y} are contained in the touch area scaled to the 278be7607af8875236b9cf7bdb5f5aa089c207529afWinson * given {@param width} and {@param height}. 279be7607af8875236b9cf7bdb5f5aa089c207529afWinson */ 280be7607af8875236b9cf7bdb5f5aa089c207529afWinson public boolean touchAreaContainsPoint(int width, int height, float x, float y) { 281be7607af8875236b9cf7bdb5f5aa089c207529afWinson int left = (int) (touchArea.left * width); 282be7607af8875236b9cf7bdb5f5aa089c207529afWinson int top = (int) (touchArea.top * height); 283be7607af8875236b9cf7bdb5f5aa089c207529afWinson int right = (int) (touchArea.right * width); 284be7607af8875236b9cf7bdb5f5aa089c207529afWinson int bottom = (int) (touchArea.bottom * height); 285be7607af8875236b9cf7bdb5f5aa089c207529afWinson return x >= left && y >= top && x <= right && y <= bottom; 286be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 287be7607af8875236b9cf7bdb5f5aa089c207529afWinson 288be7607af8875236b9cf7bdb5f5aa089c207529afWinson /** 289be7607af8875236b9cf7bdb5f5aa089c207529afWinson * Returns the docked task bounds with the given {@param width} and {@param height}. 290be7607af8875236b9cf7bdb5f5aa089c207529afWinson */ 291be7607af8875236b9cf7bdb5f5aa089c207529afWinson public Rect getDockedBounds(int width, int height) { 292be7607af8875236b9cf7bdb5f5aa089c207529afWinson return new Rect((int) (dockArea.left * width), (int) (dockArea.top * height), 293be7607af8875236b9cf7bdb5f5aa089c207529afWinson (int) (dockArea.right * width), (int) (dockArea.bottom * height)); 294be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 295be7607af8875236b9cf7bdb5f5aa089c207529afWinson } 296be7607af8875236b9cf7bdb5f5aa089c207529afWinson 297083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // The task offset to apply to a task id as a group affiliation 298083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung static final int IndividualTaskIdOffset = 1 << 16; 299083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung 300303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung FilteredTaskList mTaskList = new FilteredTaskList(); 301303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung TaskStackCallbacks mCb; 302303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 303ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<TaskGrouping> mGroups = new ArrayList<TaskGrouping>(); 304083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung HashMap<Integer, TaskGrouping> mAffinitiesGroups = new HashMap<Integer, TaskGrouping>(); 305303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 306d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung /** Sets the callbacks for this task stack. */ 307303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setCallbacks(TaskStackCallbacks cb) { 308303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb = cb; 309303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 310303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 311bc571a980704dc767838935e83c6aed231c406e9Winson Chung /** Resets this TaskStack. */ 312bc571a980704dc767838935e83c6aed231c406e9Winson Chung public void reset() { 313bc571a980704dc767838935e83c6aed231c406e9Winson Chung mCb = null; 314bc571a980704dc767838935e83c6aed231c406e9Winson Chung mTaskList.reset(); 315bc571a980704dc767838935e83c6aed231c406e9Winson Chung mGroups.clear(); 316bc571a980704dc767838935e83c6aed231c406e9Winson Chung mAffinitiesGroups.clear(); 317bc571a980704dc767838935e83c6aed231c406e9Winson Chung } 318bc571a980704dc767838935e83c6aed231c406e9Winson Chung 319303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Adds a new task */ 320303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void addTask(Task t) { 321303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.add(t); 322303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 323303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 324303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 325303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 326303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 327eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson /** 328eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson * Moves the given task to either the front of the freeform workspace or the stack. 329eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson */ 330eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson public void moveTaskToStack(Task task, int newStackId) { 331eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson // Find the index to insert into 332eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson ArrayList<Task> taskList = mTaskList.getTasks(); 333eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson int taskCount = taskList.size(); 334eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson if (!task.isFreeformTask() && (newStackId == FREEFORM_WORKSPACE_STACK_ID)) { 335eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson // Insert freeform tasks at the front 336eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mTaskList.moveTaskToStack(task, taskCount, newStackId); 337eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } else if (task.isFreeformTask() && (newStackId == FULLSCREEN_WORKSPACE_STACK_ID)) { 338eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson // Insert after the first stacked task 339eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson int insertIndex = 0; 340eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson for (int i = taskCount - 1; i >= 0; i--) { 341eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson if (!taskList.get(i).isFreeformTask()) { 342eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson insertIndex = i + 1; 343eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson break; 344eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 345eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 346eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson mTaskList.moveTaskToStack(task, insertIndex, newStackId); 347eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 348eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson } 349eca4ab6e99bcb2a7b31b8b4b1c3b5474297b6b25Winson 3506ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung /** Does the actual work associated with removing the task. */ 3516ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung void removeTaskImpl(Task t) { 3526ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung // Remove the task from the list 3536ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung mTaskList.remove(t); 3546ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung // Remove it from the group as well, and if it is empty, remove the group 3556ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung TaskGrouping group = t.group; 3566ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung group.removeTask(t); 3576ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung if (group.getTaskCount() == 0) { 3586ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung removeGroup(group); 3596ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung } 3606ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung // Update the lock-to-app state 3616ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung t.lockToThisTask = false; 3626ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung } 3636ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung 364303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Removes a task */ 365303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void removeTask(Task t) { 366303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mTaskList.contains(t)) { 36742be431c3d129871d257768e185334d49c071ec5Winson boolean wasFrontMostTask = (getFrontMostTask() == t); 3686ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung removeTaskImpl(t); 36982c8c5e9872b984ba6f43b01da0c7731fd5bf762Winson Chung Task newFrontMostTask = getFrontMostTask(); 37056e09b42a0f1670970872bef611a8036904ad6bfJason Monk if (newFrontMostTask != null && newFrontMostTask.lockToTaskEnabled) { 37156e09b42a0f1670970872bef611a8036904ad6bfJason Monk newFrontMostTask.lockToThisTask = true; 3721f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung } 373303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 374ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 37542be431c3d129871d257768e185334d49c071ec5Winson mCb.onStackTaskRemoved(this, t, wasFrontMostTask, newFrontMostTask); 376303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 377303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 378303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 379303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 3806ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung /** Removes all tasks */ 3816ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung public void removeAllTasks() { 3826ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung ArrayList<Task> taskList = new ArrayList<Task>(mTaskList.getTasks()); 3836ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung int taskCount = taskList.size(); 3846ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung for (int i = taskCount - 1; i >= 0; i--) { 3856ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung Task t = taskList.get(i); 3866ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung removeTaskImpl(t); 3876ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung } 3886ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung if (mCb != null) { 3896ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung // Notify that all tasks have been removed 3906ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung mCb.onStackAllTasksRemoved(this, taskList); 3916ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung } 3926ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung } 3936ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung 394303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Sets a few tasks in one go */ 395303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void setTasks(List<Task> tasks) { 396ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> taskList = mTaskList.getTasks(); 397ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = taskList.size(); 3986ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung for (int i = taskCount - 1; i >= 0; i--) { 399ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = taskList.get(i); 4006ac8bd6198f67b64aea2258bdb5f8ed371b5bec1Winson Chung removeTaskImpl(t); 401303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 402ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Notify that a task has been removed 40342be431c3d129871d257768e185334d49c071ec5Winson mCb.onStackTaskRemoved(this, t, false, null); 404303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 405303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 406303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.set(tasks); 407303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : tasks) { 408303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 409303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mCb.onStackTaskAdded(this, t); 410303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 411303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 412303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 413303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 414ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Gets the front task */ 415ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public Task getFrontMostTask() { 4161f24c7e37bc794057a156a730c7e4b53b01212edWinson Chung if (mTaskList.size() == 0) return null; 417ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mTaskList.getTasks().get(mTaskList.size() - 1); 418ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 419ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 42004400672962d2e12132f9465928cbf7615c147c4Winson Chung /** Gets the task keys */ 42104400672962d2e12132f9465928cbf7615c147c4Winson Chung public ArrayList<Task.TaskKey> getTaskKeys() { 42204400672962d2e12132f9465928cbf7615c147c4Winson Chung ArrayList<Task.TaskKey> taskKeys = new ArrayList<Task.TaskKey>(); 42304400672962d2e12132f9465928cbf7615c147c4Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 42404400672962d2e12132f9465928cbf7615c147c4Winson Chung int taskCount = tasks.size(); 42504400672962d2e12132f9465928cbf7615c147c4Winson Chung for (int i = 0; i < taskCount; i++) { 42604400672962d2e12132f9465928cbf7615c147c4Winson Chung taskKeys.add(tasks.get(i).key); 42704400672962d2e12132f9465928cbf7615c147c4Winson Chung } 42804400672962d2e12132f9465928cbf7615c147c4Winson Chung return taskKeys; 42904400672962d2e12132f9465928cbf7615c147c4Winson Chung } 43004400672962d2e12132f9465928cbf7615c147c4Winson Chung 431303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the tasks */ 432303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public ArrayList<Task> getTasks() { 433303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.getTasks(); 434303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 435303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 436303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Gets the number of tasks */ 437303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int getTaskCount() { 438303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.size(); 439303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 440303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 44136a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson /** 44236a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson * Returns the task in this stack which is the launch target. 44336a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson */ 44436a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson public Task getLaunchTarget() { 44536a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson ArrayList<Task> tasks = mTaskList.getTasks(); 44636a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson int taskCount = tasks.size(); 44736a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson for (int i = 0; i < taskCount; i++) { 44836a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson Task task = tasks.get(i); 44936a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson if (task.isLaunchTarget) { 45036a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson return task; 45136a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson } 45236a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson } 45336a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson return null; 45436a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson } 45536a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson 456303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns the index of this task in this current task stack */ 457303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public int indexOfTask(Task t) { 458303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.indexOf(t); 459303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 460303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 461b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung /** Finds the task with the specified task id. */ 462b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung public Task findTaskWithId(int taskId) { 463b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 464b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung int taskCount = tasks.size(); 465b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung for (int i = 0; i < taskCount; i++) { 466b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung Task task = tasks.get(i); 467b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung if (task.key.id == taskId) { 468b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung return task; 469b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 470b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 471b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung return null; 472b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung } 473b1f749906f5c27114d02ea0c3f8ce0dcea08fd3fWinson Chung 47436a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson /** 47536a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson * Returns whether this stack has freeform tasks. 47636a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson */ 47736a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson public boolean hasFreeformTasks() { 47836a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson ArrayList<Task> tasks = mTaskList.getTasks(); 47936a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson int taskCount = tasks.size(); 48036a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson for (int i = 0; i < taskCount; i++) { 48136a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson Task task = tasks.get(i); 48236a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson if (task.isFreeformTask()) { 48336a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson return true; 48436a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson } 48536a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson } 48636a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson return false; 48736a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson } 48836a5a2c7003ef8157f276b411c3fda47ad2f75e3Winson 489ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Filtering ********/ 490303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 491303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Filters the stack into tasks similar to the one specified */ 492c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public void filterTasks(final Task t) { 493c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 494c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 495303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Set the task list filter 496c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung boolean filtered = mTaskList.setFilter(new TaskFilter() { 497303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 498c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung public boolean acceptTask(Task at, int i) { 499e7f138c7f0a190c86cec10fb32fa106aacae4093Winson return t.key.getComponent().getPackageName().equals( 500e7f138c7f0a190c86cec10fb32fa106aacae4093Winson at.key.getComponent().getPackageName()); 501303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 502303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung }); 503c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung if (filtered && mCb != null) { 504c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackFiltered(this, oldStack, t); 505303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 506303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 507303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 508303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Unfilters the current stack */ 509303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public void unfilterTasks() { 510c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks()); 511c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung 512303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung // Unset the filter, then update the virtual scroll 513303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung mTaskList.removeFilter(); 514303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung if (mCb != null) { 515c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung mCb.onStackUnfiltered(this, oldStack); 516303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 517303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 518303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 519303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung /** Returns whether tasks are currently filtered */ 520303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public boolean hasFilteredTasks() { 521303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return mTaskList.hasFilter(); 522303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 523303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung 524ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /******** Grouping ********/ 525ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 526ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Adds a group to the set */ 527ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void addGroup(TaskGrouping group) { 528ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.add(group); 529ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.put(group.affiliation, group); 530ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 531ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 532ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public void removeGroup(TaskGrouping group) { 533ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mGroups.remove(group); 534ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mAffinitiesGroups.remove(group.affiliation); 535ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 536ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 537ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** Returns the group with the specified affiliation. */ 538083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung public TaskGrouping getGroupWithAffiliation(int affiliation) { 539ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return mAffinitiesGroups.get(affiliation); 540ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 541ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 542ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung /** 543ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung * Temporary: This method will simulate affiliation groups by 544ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung */ 54535f3050959e43bf378f9a0adcaef13729206c7e4Winson public void createAffiliatedGroupings(Context context) { 546c742f973b1e506732911c156c5869fd377afc5bfWinson if (RecentsDebugFlags.Static.EnableSimulatedTaskGroups) { 547ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung HashMap<Task.TaskKey, Task> taskMap = new HashMap<Task.TaskKey, Task>(); 548ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort all tasks by increasing firstActiveTime of the task 549ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 550ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(tasks, new Comparator<Task>() { 551ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 552ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task task, Task task2) { 553ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (task.key.firstActiveTime - task2.key.firstActiveTime); 554ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 555ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 556ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Create groups when sequential packages are the same 557ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung NamedCounter counter = new NamedCounter("task-group", ""); 558ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 559ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung String prevPackage = ""; 560083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int prevAffiliation = -1; 561a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung Random r = new Random(); 562c742f973b1e506732911c156c5869fd377afc5bfWinson int groupCountDown = RecentsDebugFlags.Static.TaskAffiliationsGroupCount; 563ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 564ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 565e7f138c7f0a190c86cec10fb32fa106aacae4093Winson String packageName = t.key.getComponent().getPackageName(); 566a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung packageName = "pkg"; 567ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group; 568a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung if (packageName.equals(prevPackage) && groupCountDown > 0) { 569ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = getGroupWithAffiliation(prevAffiliation); 570a433fa9c17772f563163ff7db177d091d6aebd5bWinson Chung groupCountDown--; 571ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 572083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int affiliation = IndividualTaskIdOffset + t.key.id; 573ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group = new TaskGrouping(affiliation); 574ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung addGroup(group); 575ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevAffiliation = affiliation; 576ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung prevPackage = packageName; 577c742f973b1e506732911c156c5869fd377afc5bfWinson groupCountDown = RecentsDebugFlags.Static.TaskAffiliationsGroupCount; 578ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 579ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 580ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskMap.put(t.key, t); 581ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 582ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort groups by increasing latestActiveTime of the group 583ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Collections.sort(mGroups, new Comparator<TaskGrouping>() { 584ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 585ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(TaskGrouping taskGrouping, TaskGrouping taskGrouping2) { 586ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskGrouping.latestActiveTimeInGroup - 587ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskGrouping2.latestActiveTimeInGroup); 588ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 589ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 590ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // Sort group tasks by increasing firstActiveTime of the task, and also build a new list of 591ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung // tasks 592ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskIndex = 0; 593ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupCount = mGroups.size(); 594ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < groupCount; i++) { 595ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung TaskGrouping group = mGroups.get(i); 596083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung Collections.sort(group.mTaskKeys, new Comparator<Task.TaskKey>() { 597ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung @Override 598ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung public int compare(Task.TaskKey taskKey, Task.TaskKey taskKey2) { 599ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung return (int) (taskKey.firstActiveTime - taskKey2.firstActiveTime); 600ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 601ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung }); 602083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung ArrayList<Task.TaskKey> groupTasks = group.mTaskKeys; 603ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int groupTaskCount = groupTasks.size(); 604ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int j = 0; j < groupTaskCount; j++) { 605ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung tasks.set(taskIndex, taskMap.get(groupTasks.get(j))); 606ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung taskIndex++; 607ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 608ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 609ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung mTaskList.set(tasks); 610ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } else { 611083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung // Create the task groups 612ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung HashMap<Task.TaskKey, Task> tasksMap = new HashMap<Task.TaskKey, Task>(); 613ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung ArrayList<Task> tasks = mTaskList.getTasks(); 614ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung int taskCount = tasks.size(); 615ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung for (int i = 0; i < taskCount; i++) { 616ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung Task t = tasks.get(i); 617083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung TaskGrouping group; 618083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung int affiliation = t.taskAffiliation > 0 ? t.taskAffiliation : 619083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung IndividualTaskIdOffset + t.key.id; 620083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung if (mAffinitiesGroups.containsKey(affiliation)) { 621083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung group = getGroupWithAffiliation(affiliation); 622083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } else { 623083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung group = new TaskGrouping(affiliation); 624083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung addGroup(group); 625083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung } 626ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung group.addTask(t); 627ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung tasksMap.put(t.key, t); 628ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung } 629ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Update the task colors for each of the groups 63035f3050959e43bf378f9a0adcaef13729206c7e4Winson float minAlpha = context.getResources().getFloat( 63135f3050959e43bf378f9a0adcaef13729206c7e4Winson R.dimen.recents_task_affiliation_color_min_alpha_percentage); 632ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung int taskGroupCount = mGroups.size(); 633ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung for (int i = 0; i < taskGroupCount; i++) { 634ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung TaskGrouping group = mGroups.get(i); 635ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung taskCount = group.getTaskCount(); 636ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Ignore the groups that only have one task 637ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung if (taskCount <= 1) continue; 638ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung // Calculate the group color distribution 639ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung int affiliationColor = tasksMap.get(group.mTaskKeys.get(0)).taskAffiliationColor; 640ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float alphaStep = (1f - minAlpha) / taskCount; 641ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung float alpha = 1f; 642ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung for (int j = 0; j < taskCount; j++) { 643ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung Task t = tasksMap.get(group.mTaskKeys.get(j)); 644a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung t.colorPrimary = Utilities.getColorWithOverlay(affiliationColor, Color.WHITE, 645a0e88b5013d708ac6ed6518817d83c64c87ae4b1Winson Chung alpha); 646ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung alpha -= alphaStep; 647ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung } 648ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 649ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 650ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung } 651ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung 652e7f138c7f0a190c86cec10fb32fa106aacae4093Winson /** 653e7f138c7f0a190c86cec10fb32fa106aacae4093Winson * Computes the components of tasks in this stack that have been removed as a result of a change 654e7f138c7f0a190c86cec10fb32fa106aacae4093Winson * in the specified package. 655e7f138c7f0a190c86cec10fb32fa106aacae4093Winson */ 656e7f138c7f0a190c86cec10fb32fa106aacae4093Winson public HashSet<ComponentName> computeComponentsRemoved(String packageName, int userId) { 657e7f138c7f0a190c86cec10fb32fa106aacae4093Winson // Identify all the tasks that should be removed as a result of the package being removed. 658e7f138c7f0a190c86cec10fb32fa106aacae4093Winson // Using a set to ensure that we callback once per unique component. 659e7f138c7f0a190c86cec10fb32fa106aacae4093Winson SystemServicesProxy ssp = Recents.getSystemServices(); 660e7f138c7f0a190c86cec10fb32fa106aacae4093Winson HashSet<ComponentName> existingComponents = new HashSet<>(); 661e7f138c7f0a190c86cec10fb32fa106aacae4093Winson HashSet<ComponentName> removedComponents = new HashSet<>(); 662e7f138c7f0a190c86cec10fb32fa106aacae4093Winson ArrayList<Task.TaskKey> taskKeys = getTaskKeys(); 663e7f138c7f0a190c86cec10fb32fa106aacae4093Winson for (Task.TaskKey t : taskKeys) { 664e7f138c7f0a190c86cec10fb32fa106aacae4093Winson // Skip if this doesn't apply to the current user 665e7f138c7f0a190c86cec10fb32fa106aacae4093Winson if (t.userId != userId) continue; 666e7f138c7f0a190c86cec10fb32fa106aacae4093Winson 667e7f138c7f0a190c86cec10fb32fa106aacae4093Winson ComponentName cn = t.getComponent(); 668e7f138c7f0a190c86cec10fb32fa106aacae4093Winson if (cn.getPackageName().equals(packageName)) { 669e7f138c7f0a190c86cec10fb32fa106aacae4093Winson if (existingComponents.contains(cn)) { 670e7f138c7f0a190c86cec10fb32fa106aacae4093Winson // If we know that the component still exists in the package, then skip 671e7f138c7f0a190c86cec10fb32fa106aacae4093Winson continue; 672e7f138c7f0a190c86cec10fb32fa106aacae4093Winson } 673e7f138c7f0a190c86cec10fb32fa106aacae4093Winson if (ssp.getActivityInfo(cn, userId) != null) { 674e7f138c7f0a190c86cec10fb32fa106aacae4093Winson existingComponents.add(cn); 675e7f138c7f0a190c86cec10fb32fa106aacae4093Winson } else { 676e7f138c7f0a190c86cec10fb32fa106aacae4093Winson removedComponents.add(cn); 677e7f138c7f0a190c86cec10fb32fa106aacae4093Winson } 678e7f138c7f0a190c86cec10fb32fa106aacae4093Winson } 679e7f138c7f0a190c86cec10fb32fa106aacae4093Winson } 680e7f138c7f0a190c86cec10fb32fa106aacae4093Winson return removedComponents; 681e7f138c7f0a190c86cec10fb32fa106aacae4093Winson } 682e7f138c7f0a190c86cec10fb32fa106aacae4093Winson 683303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung @Override 684303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung public String toString() { 685303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung String str = "Tasks:\n"; 686303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung for (Task t : mTaskList.getTasks()) { 687303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung str += " " + t.toString() + "\n"; 688303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 689303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung return str; 690303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung } 691303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}