Task.java revision bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8
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();
3904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    }
4004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
41a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy    /** The ComponentNameKey represents the unique primary key for a component
42a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy     * belonging to a specified user. */
43a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy    public static class ComponentNameKey {
44a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        final ComponentName component;
45a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        final int userId;
46a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
47a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public ComponentNameKey(ComponentName cn, int user) {
48a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            component = cn;
49a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            userId = user;
50a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
51a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
52a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        @Override
53a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public int hashCode() {
54a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            return Objects.hash(component, userId);
55a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
56a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
57a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        @Override
58a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public boolean equals(Object o) {
59a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            if (!(o instanceof ComponentNameKey)) {
60a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy                return false;
61a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            }
62a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            return component.equals(((ComponentNameKey) o).component) &&
63a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy                    userId == ((ComponentNameKey) o).userId;
64a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
65a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy    }
66a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
6704dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    /* The Task Key represents the unique primary key for the task */
6804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    public static class TaskKey {
69a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        final ComponentNameKey mComponentNameKey;
7004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public final int id;
71c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung        public final Intent baseIntent;
724f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani        public final int userId;
73ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        public long firstActiveTime;
74f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung        public long lastActiveTime;
7504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
76ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        public TaskKey(int id, Intent intent, int userId, long firstActiveTime, long lastActiveTime) {
77a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            mComponentNameKey = new ComponentNameKey(intent.getComponent(), userId);
7804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung            this.id = id;
79c6a1623cc48581380b698ae87b43bfafb9c935baWinson Chung            this.baseIntent = intent;
804f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            this.userId = userId;
81ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            this.firstActiveTime = firstActiveTime;
82f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung            this.lastActiveTime = lastActiveTime;
83f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung        }
84f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung
85a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        /** Returns the component name key for this task. */
86a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        public ComponentNameKey getComponentNameKey() {
87a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy            return mComponentNameKey;
88a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy        }
89a734fc1ecedb316fdf6deddc169b8b0bddab76bfKenny Guy
9004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        @Override
9104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public boolean equals(Object o) {
924f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            if (!(o instanceof TaskKey)) {
934f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani                return false;
944f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            }
954f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            return id == ((TaskKey) o).id
964f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani                    && userId == ((TaskKey) o).userId;
9704dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        }
9804dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
9904dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        @Override
10004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public int hashCode() {
1014f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            return (id << 5) + userId;
10204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        }
10304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
10404dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        @Override
10504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        public String toString() {
1064f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani            return "Task.Key: " + id + ", "
107f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung                    + "u: " + userId + ", "
108f1fbd77cf057e43926f9a0347692611386d09f40Winson Chung                    + "lat: " + lastActiveTime + ", "
1094f0a49e6b9ad1b00972dbe8a751263aa6c482538Amith Yamasani                    + baseIntent.getComponent().getPackageName();
11004dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        }
11104dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    }
11204dfe0d26b944324ee920001f40d74cff47281d6Winson Chung
11304dfe0d26b944324ee920001f40d74cff47281d6Winson Chung    public TaskKey key;
114ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    public TaskGrouping group;
115083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung    public int taskAffiliation;
116ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung    public int taskAffiliationColor;
117dcfa7976fa836ae90bb4a579892a18a0abf35b3cWinson Chung    public boolean isLaunchTarget;
1185e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung    public Drawable applicationIcon;
11911e41baac63a42d7ddb7ba2cab40ee55443d262fWinson Chung    public Drawable activityIcon;
1205e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung    public String activityLabel;
121f5e22e71cb5f8699a4312c797af068f655cbe629Winson Chung    public int colorPrimary;
12293748a11cba1b44edbc2e888c997533461355594Winson Chung    public boolean useLightOnPrimaryColor;
123303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public Bitmap thumbnail;
1244be0445c66f19ed985aecbc2a572f5d8c6e2553aWinson Chung    public boolean isActive;
12556e09b42a0f1670970872bef611a8036904ad6bfJason Monk    public boolean lockToThisTask;
12656e09b42a0f1670970872bef611a8036904ad6bfJason Monk    public boolean lockToTaskEnabled;
127bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi    public Bitmap icon;
128bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi    public String iconFilename;
129303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    TaskCallbacks mCb;
130303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
1310d767551c55d9e594a0b944bd1926c21a344b5aeWinson Chung    public Task() {
1320d767551c55d9e594a0b944bd1926c21a344b5aeWinson Chung        // Only used by RecentsService for task rect calculations.
1330d767551c55d9e594a0b944bd1926c21a344b5aeWinson Chung    }
1340d767551c55d9e594a0b944bd1926c21a344b5aeWinson Chung
135a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    public Task(TaskKey key, boolean isActive, int taskAffiliation, int taskAffiliationColor,
136a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung                String activityTitle, Drawable activityIcon, int colorPrimary,
137bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi                boolean lockToThisTask, boolean lockToTaskEnabled, Bitmap icon,
138bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi                String iconFilename) {
139a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        boolean isInAffiliationGroup = (taskAffiliation != key.id);
140ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        boolean hasAffiliationGroupColor = isInAffiliationGroup && (taskAffiliationColor != 0);
141a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.key = key;
142083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung        this.taskAffiliation = taskAffiliation;
143ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        this.taskAffiliationColor = taskAffiliationColor;
1445e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        this.activityLabel = activityTitle;
1455e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        this.activityIcon = activityIcon;
146ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        this.colorPrimary = hasAffiliationGroupColor ? taskAffiliationColor : colorPrimary;
147ec396d6399c5c31d697d81e94aff459e9771b0c6Winson Chung        this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary,
14893748a11cba1b44edbc2e888c997533461355594Winson Chung                Color.WHITE) > 3f;
1494be0445c66f19ed985aecbc2a572f5d8c6e2553aWinson Chung        this.isActive = isActive;
15056e09b42a0f1670970872bef611a8036904ad6bfJason Monk        this.lockToThisTask = lockToTaskEnabled && lockToThisTask;
15156e09b42a0f1670970872bef611a8036904ad6bfJason Monk        this.lockToTaskEnabled = lockToTaskEnabled;
152bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi        this.icon = icon;
153bdd4b201e45ffa82dcd3b09fb9724d243c86c8d8Jorim Jaggi        this.iconFilename = iconFilename;
154a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    }
155a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung
156a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    /** Copies the other task. */
157a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung    public void copyFrom(Task o) {
158a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.key = o.key;
159a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.taskAffiliation = o.taskAffiliation;
160a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.taskAffiliationColor = o.taskAffiliationColor;
161a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.activityLabel = o.activityLabel;
162a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.activityIcon = o.activityIcon;
163a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.colorPrimary = o.colorPrimary;
164a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.useLightOnPrimaryColor = o.useLightOnPrimaryColor;
165a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.isActive = o.isActive;
166a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.lockToThisTask = o.lockToThisTask;
167a4ccb86ddc8f9f486aee25fb836f4aff97bf7679Winson Chung        this.lockToTaskEnabled = o.lockToTaskEnabled;
168303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
169303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
170303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    /** Set the callbacks */
171303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public void setCallbacks(TaskCallbacks cb) {
172303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        mCb = cb;
173303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
174303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
175ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    /** Set the grouping */
176ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    public void setGroup(TaskGrouping group) {
177ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        if (group != null && this.group != null) {
178ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung            throw new RuntimeException("This task is already assigned to a group.");
179ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        }
180ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        this.group = group;
181ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung    }
182ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung
1834d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    /** Notifies the callback listeners that this task has been loaded */
1848eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon) {
1855e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        this.applicationIcon = applicationIcon;
1864d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        this.thumbnail = thumbnail;
1874d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        if (mCb != null) {
1888eaeb7dc93ed71b768a2ea8d45021cca010e8263Winson Chung            mCb.onTaskDataLoaded();
1894d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        }
1904d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    }
1914d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung
1924d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    /** Notifies the callback listeners that this task has been unloaded */
1935e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung    public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultApplicationIcon) {
1945e3e5d8945249cfeb8bd59de112be88954ba62bfWinson Chung        applicationIcon = defaultApplicationIcon;
1954d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        thumbnail = defaultThumbnail;
1964d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        if (mCb != null) {
19704dfe0d26b944324ee920001f40d74cff47281d6Winson Chung            mCb.onTaskDataUnloaded();
1984d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung        }
1994d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung    }
2004d7b092a866d2fce3e11b5a12cda2b87a83af52dWinson Chung
201303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
202303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public boolean equals(Object o) {
203a10370fc2eb8eb95631592160c5f6281b9d75722Winson Chung        // Check that the id matches
204303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung        Task t = (Task) o;
20504dfe0d26b944324ee920001f40d74cff47281d6Winson Chung        return key.equals(t.key);
206303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
207303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung
208303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    @Override
209303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    public String toString() {
210ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        String groupAffiliation = "no group";
211ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        if (group != null) {
212083baf99ff1228e96ede96aac88c8200c4fdc2b2Winson Chung            groupAffiliation = Integer.toString(group.affiliation);
213ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        }
214ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung        return "Task (" + groupAffiliation + "): " + key.baseIntent.getComponent().getPackageName() +
215ffa2ec664479bff6b4b61d4c349d9db2cb37ca16Winson Chung                " [" + super.toString() + "]";
216303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung    }
217303e1ff1fec8b240b587bb18b981247a99833aa8Winson Chung}
218