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
19a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guyimport android.content.ComponentName;
20303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.content.Intent;
21303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.graphics.Bitmap;
2293748a11cba1b44edbc2e888c997533461355594Winson Chungimport android.graphics.Color;
23303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungimport android.graphics.drawable.Drawable;
24ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chungimport com.android.systemui.recents.misc.Utilities;
25303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
26a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guyimport java.util.Objects;
27a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
28303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
29303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung/**
30303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung * A task represents the top most task in the system's task stack.
31303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung */
32303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chungpublic class Task {
3304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    /* Task callbacks */
3404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    public interface TaskCallbacks {
3504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        /* Notifies when a task has been bound */
368eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung        public void onTaskDataLoaded();
3704dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        /* Notifies when a task has been unbound */
3804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public void onTaskDataUnloaded();
39d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung
40d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung        /* Notifies when a task's stack id has changed. */
41d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung        public void onMultiStackDebugTaskStackIdChanged();
4204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    }
4304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
44a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy    /** The ComponentNameKey represents the unique primary key for a component
45a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy     * belonging to a specified user. */
46a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy    public static class ComponentNameKey {
47a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        final ComponentName component;
48a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        final int userId;
49a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
50a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public ComponentNameKey(ComponentName cn, int user) {
51a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            component = cn;
52a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            userId = user;
53a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
54a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
55a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        @Override
56a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public int hashCode() {
57a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            return Objects.hash(component, userId);
58a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
59a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
60a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        @Override
61a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public boolean equals(Object o) {
62a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            if (!(o instanceof ComponentNameKey)) {
63a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy                return false;
64a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            }
65a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            return component.equals(((ComponentNameKey) o).component) &&
66a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy                    userId == ((ComponentNameKey) o).userId;
67a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
68a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy    }
69a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
7004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    /* The Task Key represents the unique primary key for the task */
7104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    public static class TaskKey {
72a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        final ComponentNameKey mComponentNameKey;
7304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public final int id;
74d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung        public int stackId;
75c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung        public final Intent baseIntent;
764f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        public final int userId;
77ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        public long firstActiveTime;
78f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung        public long lastActiveTime;
7904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
80d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung        public TaskKey(int id, int stackId, Intent intent, int userId, long firstActiveTime,
81d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung                long lastActiveTime) {
82a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            mComponentNameKey = new ComponentNameKey(intent.getComponent(), userId);
8304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung            this.id = id;
84d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung            this.stackId = stackId;
85c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung            this.baseIntent = intent;
864f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            this.userId = userId;
87ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            this.firstActiveTime = firstActiveTime;
88f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung            this.lastActiveTime = lastActiveTime;
89f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung        }
90f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung
91a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        /** Returns the component name key for this task. */
92a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public ComponentNameKey getComponentNameKey() {
93a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            return mComponentNameKey;
94a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
95a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
9604dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        @Override
9704dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public boolean equals(Object o) {
984f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            if (!(o instanceof TaskKey)) {
994f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani                return false;
1004f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            }
101d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung            TaskKey otherKey = (TaskKey) o;
102d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung            return id == otherKey.id && stackId == otherKey.stackId && userId == otherKey.userId;
10304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        }
10404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
10504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        @Override
10604dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public int hashCode() {
107d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung            return Objects.hash(id, stackId, userId);
10804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        }
10904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
11004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        @Override
11104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public String toString() {
1124f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            return "Task.Key: " + id + ", "
113d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung                    + "s: " + stackId + ", "
114f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung                    + "u: " + userId + ", "
115f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung                    + "lat: " + lastActiveTime + ", "
1164f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani                    + baseIntent.getComponent().getPackageName();
11704dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        }
11804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    }
11904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
12004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    public TaskKey key;
121ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    public TaskGrouping group;
122083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung    public int taskAffiliation;
123ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung    public int taskAffiliationColor;
124dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung    public boolean isLaunchTarget;
1255e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung    public Drawable applicationIcon;
12611e41baac63a42d7ddb7ba2cab40ee55443d262fWinson Chung    public Drawable activityIcon;
127b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz    public String contentDescription;
1285e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung    public String activityLabel;
129f5e22e71cb5f8699a4312c797af068f655cbe629Winson Chung    public int colorPrimary;
13093748a11cba1b44edbc2e888c997533461355594Winson Chung    public boolean useLightOnPrimaryColor;
131303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public Bitmap thumbnail;
1324be0445c66f19ed985aecbc2a572f5d8c6e2553aWinson Chung    public boolean isActive;
13356e09b42a0f1670970872bef611a8036904ad6bfJason Monk    public boolean lockToThisTask;
13456e09b42a0f1670970872bef611a8036904ad6bfJason Monk    public boolean lockToTaskEnabled;
135bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi    public Bitmap icon;
136bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi    public String iconFilename;
137303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    TaskCallbacks mCb;
138303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
1390d767551c55d9e594a0b944bd1926c21a344b5aeWinson Chung    public Task() {
14004400672962d2e12132f9465928cbf7615c147c4Winson Chung        // Do nothing
1410d767551c55d9e594a0b944bd1926c21a344b5aeWinson Chung    }
1420d767551c55d9e594a0b944bd1926c21a344b5aeWinson Chung
143a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    public Task(TaskKey key, boolean isActive, int taskAffiliation, int taskAffiliationColor,
144b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz                String activityTitle, String contentDescription, Drawable activityIcon,
145b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz                int colorPrimary, boolean lockToThisTask, boolean lockToTaskEnabled, Bitmap icon,
146bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi                String iconFilename) {
147a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        boolean isInAffiliationGroup = (taskAffiliation != key.id);
148ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        boolean hasAffiliationGroupColor = isInAffiliationGroup && (taskAffiliationColor != 0);
149a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.key = key;
150083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung        this.taskAffiliation = taskAffiliation;
151ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        this.taskAffiliationColor = taskAffiliationColor;
1525e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        this.activityLabel = activityTitle;
153b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz        this.contentDescription = contentDescription;
1545e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        this.activityIcon = activityIcon;
155ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        this.colorPrimary = hasAffiliationGroupColor ? taskAffiliationColor : colorPrimary;
156ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary,
15793748a11cba1b44edbc2e888c997533461355594Winson Chung                Color.WHITE) > 3f;
1584be0445c66f19ed985aecbc2a572f5d8c6e2553aWinson Chung        this.isActive = isActive;
15956e09b42a0f1670970872bef611a8036904ad6bfJason Monk        this.lockToThisTask = lockToTaskEnabled && lockToThisTask;
16056e09b42a0f1670970872bef611a8036904ad6bfJason Monk        this.lockToTaskEnabled = lockToTaskEnabled;
161bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi        this.icon = icon;
162bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi        this.iconFilename = iconFilename;
163a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    }
164a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
165a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    /** Copies the other task. */
166a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    public void copyFrom(Task o) {
167a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.key = o.key;
168a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.taskAffiliation = o.taskAffiliation;
169a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.taskAffiliationColor = o.taskAffiliationColor;
170a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.activityLabel = o.activityLabel;
171b7a42fda313b6e5d5e82591ea9fb5d1b30acfc55Benjamin Franz        this.contentDescription = o.contentDescription;
172a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.activityIcon = o.activityIcon;
173a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.colorPrimary = o.colorPrimary;
174a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
175a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.isActive = o.isActive;
176a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.lockToThisTask = o.lockToThisTask;
177a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.lockToTaskEnabled = o.lockToTaskEnabled;
178303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
179303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
180303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Set the callbacks */
181303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void setCallbacks(TaskCallbacks cb) {
182303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mCb = cb;
183303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
184303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
185ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    /** Set the grouping */
186ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    public void setGroup(TaskGrouping group) {
187ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        if (group != null && this.group != null) {
188ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            throw new RuntimeException("This task is already assigned to a group.");
189ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        }
190ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        this.group = group;
191ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    }
192ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung
193d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung    /** Updates the stack id of this task. */
194d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung    public void setStackId(int stackId) {
195d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung        key.stackId = stackId;
196d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung        if (mCb != null) {
197d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung            mCb.onMultiStackDebugTaskStackIdChanged();
198d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung        }
199d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung    }
200d16c565a607de754379fe699a4def21bd0e3de2fWinson Chung
2014d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    /** Notifies the callback listeners that this task has been loaded */
2028eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon) {
2035e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        this.applicationIcon = applicationIcon;
2044d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        this.thumbnail = thumbnail;
2054d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        if (mCb != null) {
2068eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            mCb.onTaskDataLoaded();
2074d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        }
2084d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    }
2094d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung
2104d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    /** Notifies the callback listeners that this task has been unloaded */
2115e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung    public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultApplicationIcon) {
2125e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        applicationIcon = defaultApplicationIcon;
2134d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        thumbnail = defaultThumbnail;
2144d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        if (mCb != null) {
21504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung            mCb.onTaskDataUnloaded();
2164d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        }
2174d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    }
2184d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung
219303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
220303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public boolean equals(Object o) {
221a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        // Check that the id matches
222303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        Task t = (Task) o;
22304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        return key.equals(t.key);
224303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
225303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
226303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
227303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public String toString() {
228ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        String groupAffiliation = "no group";
229ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        if (group != null) {
230083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung            groupAffiliation = Integer.toString(group.affiliation);
231ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        }
232ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        return "Task (" + groupAffiliation + "): " + key.baseIntent.getComponent().getPackageName() +
233ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung                " [" + super.toString() + "]";
234303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
235303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}
236