TaskStack.java revision 11ca76a53c60a1898956614315ae929668c523d6
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
19303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.content.Context;
20303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
21303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.ArrayList;
22303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport java.util.List;
23303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
24303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
25303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/**
26303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * An interface for a task filter to query whether a particular task should show in a stack.
27303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */
28303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chunginterface TaskFilter {
29303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns whether the filter accepts the specified task */
30303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public boolean acceptTask(Task t, int index);
31303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}
32303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
33303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/**
34303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * A list of filtered tasks.
35303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */
36303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungclass FilteredTaskList {
37303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    ArrayList<Task> mTasks = new ArrayList<Task>();
38303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    ArrayList<Task> mFilteredTasks = new ArrayList<Task>();
39303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    TaskFilter mFilter;
40303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
41303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Sets the task filter, saving the current touch state */
42c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung    boolean setFilter(TaskFilter filter) {
43c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung        ArrayList<Task> prevFilteredTasks = new ArrayList<Task>(mFilteredTasks);
44303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mFilter = filter;
45303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        updateFilteredTasks();
46b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        if (!prevFilteredTasks.equals(mFilteredTasks)) {
47b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung            return true;
48b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        } else {
49b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung            // If the tasks are exactly the same pre/post filter, then just reset it
50b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung            mFilter = null;
51b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung            return false;
52b44c24fb50845dfbc1f49e78085cf5e01a32067fWinson Chung        }
53303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
54303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
55303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Removes the task filter and returns the previous touch state */
56303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    void removeFilter() {
57303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mFilter = null;
58303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        updateFilteredTasks();
59303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
60303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
61303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Adds a new task to the task list */
62303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    void add(Task t) {
63303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mTasks.add(t);
64303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        updateFilteredTasks();
65303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
66303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
67303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Sets the list of tasks */
68303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    void set(List<Task> tasks) {
69303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mTasks.clear();
70303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mTasks.addAll(tasks);
71303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        updateFilteredTasks();
72303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
73303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
74303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Removes a task from the base list only if it is in the filtered list */
75303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    boolean remove(Task t) {
76303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        if (mFilteredTasks.contains(t)) {
77303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            boolean removed = mTasks.remove(t);
78303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            updateFilteredTasks();
79303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            return removed;
80303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
81303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return false;
82303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
83303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
84303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns the index of this task in the list of filtered tasks */
85303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    int indexOf(Task t) {
86303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mFilteredTasks.indexOf(t);
87303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
88303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
89303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns the size of the list of filtered tasks */
90303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    int size() {
91303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mFilteredTasks.size();
92303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
93303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
94303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns whether the filtered list contains this task */
95303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    boolean contains(Task t) {
96303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mFilteredTasks.contains(t);
97303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
98303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
99303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Updates the list of filtered tasks whenever the base task list changes */
100303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    private void updateFilteredTasks() {
101303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mFilteredTasks.clear();
102303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        if (mFilter != null) {
103303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            int taskCount = mTasks.size();
104303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            for (int i = 0; i < taskCount; i++) {
105303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                Task t = mTasks.get(i);
106303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                if (mFilter.acceptTask(t, i)) {
107303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                    mFilteredTasks.add(t);
108303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                }
109303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
110303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        } else {
111303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mFilteredTasks.addAll(mTasks);
112303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
113303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
114303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
115303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns whether this task list is filtered */
116303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    boolean hasFilter() {
117303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return (mFilter != null);
118303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
119303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
120303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns the list of filtered tasks */
121303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    ArrayList<Task> getTasks() {
122303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mFilteredTasks;
123303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
124303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}
125303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
126303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/**
127303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * The task stack contains a list of multiple tasks.
128303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */
129303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpublic class TaskStack {
13004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    /* Task stack callbacks */
13104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    public interface TaskStackCallbacks {
13204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        /* Notifies when a task has been added to the stack */
13304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public void onStackTaskAdded(TaskStack stack, Task t);
13404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        /* Notifies when a task has been removed from the stack */
13504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public void onStackTaskRemoved(TaskStack stack, Task t);
13604dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        /** Notifies when the stack was filtered */
13711ca76a53c60a1898956614315ae929668c523d6Winson Chung        public void onStackFiltered(TaskStack newStack, ArrayList<Task> curTasks, Task t);
13804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        /** Notifies when the stack was un-filtered */
13911ca76a53c60a1898956614315ae929668c523d6Winson Chung        public void onStackUnfiltered(TaskStack newStack, ArrayList<Task> curTasks);
14004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    }
14104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
142303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    Context mContext;
143303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
144303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    FilteredTaskList mTaskList = new FilteredTaskList();
145303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    TaskStackCallbacks mCb;
146303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
147303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public TaskStack(Context context) {
148303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mContext = context;
149303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
150303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
151303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Sets the callbacks for this task stack */
152303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void setCallbacks(TaskStackCallbacks cb) {
153303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mCb = cb;
154303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
155303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
156303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Adds a new task */
157303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void addTask(Task t) {
158303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mTaskList.add(t);
159303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        if (mCb != null) {
160303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mCb.onStackTaskAdded(this, t);
161303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
162303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
163303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
164303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Removes a task */
165303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void removeTask(Task t) {
166303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        if (mTaskList.contains(t)) {
167303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            mTaskList.remove(t);
168303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            if (mCb != null) {
169303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                mCb.onStackTaskRemoved(this, t);
170303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
171303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
172303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
173303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
174303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Sets a few tasks in one go */
175303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void setTasks(List<Task> tasks) {
176303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        int taskCount = mTaskList.getTasks().size();
177303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        for (int i = 0; i < taskCount; i++) {
178303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            Task t = mTaskList.getTasks().get(i);
179303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            if (mCb != null) {
180303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                mCb.onStackTaskRemoved(this, t);
181303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
182303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
183303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mTaskList.set(tasks);
184303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        for (Task t : tasks) {
185303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            if (mCb != null) {
186303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung                mCb.onStackTaskAdded(this, t);
187303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
188303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
189303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
190303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
191303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Gets the tasks */
192303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public ArrayList<Task> getTasks() {
193303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mTaskList.getTasks();
194303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
195303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
196303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Gets the number of tasks */
197303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public int getTaskCount() {
198303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mTaskList.size();
199303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
200303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
201303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns the index of this task in this current task stack */
202303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public int indexOfTask(Task t) {
203303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mTaskList.indexOf(t);
204303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
205303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
206303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Tests whether a task is in this current task stack */
207303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public boolean containsTask(Task t) {
208303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mTaskList.contains(t);
209303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
210303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
211303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Filters the stack into tasks similar to the one specified */
212c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung    public void filterTasks(final Task t) {
213c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung        ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks());
214c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung
215303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Set the task list filter
216c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung        boolean filtered = mTaskList.setFilter(new TaskFilter() {
217303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            @Override
218c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung            public boolean acceptTask(Task at, int i) {
219c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                return t.key.baseIntent.getComponent().getPackageName().equals(
220c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung                        at.key.baseIntent.getComponent().getPackageName());
221303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            }
222303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        });
223c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung        if (filtered && mCb != null) {
224c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung            mCb.onStackFiltered(this, oldStack, t);
225303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
226303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
227303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
228303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Unfilters the current stack */
229303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void unfilterTasks() {
230c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung        ArrayList<Task> oldStack = new ArrayList<Task>(mTaskList.getTasks());
231c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung
232303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        // Unset the filter, then update the virtual scroll
233303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mTaskList.removeFilter();
234303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        if (mCb != null) {
235c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung            mCb.onStackUnfiltered(this, oldStack);
236303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
237303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
238303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
239303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Returns whether tasks are currently filtered */
240303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public boolean hasFilteredTasks() {
241303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return mTaskList.hasFilter();
242303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
243303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
244303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
245303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public String toString() {
246303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        String str = "Tasks:\n";
247303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        for (Task t : mTaskList.getTasks()) {
248303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung            str += "  " + t.toString() + "\n";
249303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        }
250303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        return str;
251303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
252303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}