1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.recents.model; 18 19 import android.content.ComponentName; 20 import android.content.Intent; 21 import android.graphics.Bitmap; 22 import android.graphics.Color; 23 import android.graphics.drawable.Drawable; 24 import com.android.systemui.recents.misc.Utilities; 25 26 import java.util.Objects; 27 28 29 /** 30 * A task represents the top most task in the system's task stack. 31 */ 32 public class Task { 33 /* Task callbacks */ 34 public interface TaskCallbacks { 35 /* Notifies when a task has been bound */ 36 public void onTaskDataLoaded(); 37 /* Notifies when a task has been unbound */ 38 public void onTaskDataUnloaded(); 39 40 /* Notifies when a task's stack id has changed. */ 41 public void onMultiStackDebugTaskStackIdChanged(); 42 } 43 44 /** The ComponentNameKey represents the unique primary key for a component 45 * belonging to a specified user. */ 46 public static class ComponentNameKey { 47 final ComponentName component; 48 final int userId; 49 50 public ComponentNameKey(ComponentName cn, int user) { 51 component = cn; 52 userId = user; 53 } 54 55 @Override 56 public int hashCode() { 57 return Objects.hash(component, userId); 58 } 59 60 @Override 61 public boolean equals(Object o) { 62 if (!(o instanceof ComponentNameKey)) { 63 return false; 64 } 65 return component.equals(((ComponentNameKey) o).component) && 66 userId == ((ComponentNameKey) o).userId; 67 } 68 } 69 70 /* The Task Key represents the unique primary key for the task */ 71 public static class TaskKey { 72 final ComponentNameKey mComponentNameKey; 73 public final int id; 74 public int stackId; 75 public final Intent baseIntent; 76 public final int userId; 77 public long firstActiveTime; 78 public long lastActiveTime; 79 80 public TaskKey(int id, int stackId, Intent intent, int userId, long firstActiveTime, 81 long lastActiveTime) { 82 mComponentNameKey = new ComponentNameKey(intent.getComponent(), userId); 83 this.id = id; 84 this.stackId = stackId; 85 this.baseIntent = intent; 86 this.userId = userId; 87 this.firstActiveTime = firstActiveTime; 88 this.lastActiveTime = lastActiveTime; 89 } 90 91 /** Returns the component name key for this task. */ 92 public ComponentNameKey getComponentNameKey() { 93 return mComponentNameKey; 94 } 95 96 @Override 97 public boolean equals(Object o) { 98 if (!(o instanceof TaskKey)) { 99 return false; 100 } 101 TaskKey otherKey = (TaskKey) o; 102 return id == otherKey.id && stackId == otherKey.stackId && userId == otherKey.userId; 103 } 104 105 @Override 106 public int hashCode() { 107 return Objects.hash(id, stackId, userId); 108 } 109 110 @Override 111 public String toString() { 112 return "Task.Key: " + id + ", " 113 + "s: " + stackId + ", " 114 + "u: " + userId + ", " 115 + "lat: " + lastActiveTime + ", " 116 + baseIntent.getComponent().getPackageName(); 117 } 118 } 119 120 public TaskKey key; 121 public TaskGrouping group; 122 public int taskAffiliation; 123 public int taskAffiliationColor; 124 public boolean isLaunchTarget; 125 public Drawable applicationIcon; 126 public Drawable activityIcon; 127 public String contentDescription; 128 public String activityLabel; 129 public int colorPrimary; 130 public boolean useLightOnPrimaryColor; 131 public Bitmap thumbnail; 132 public boolean isActive; 133 public boolean lockToThisTask; 134 public boolean lockToTaskEnabled; 135 public Bitmap icon; 136 public String iconFilename; 137 TaskCallbacks mCb; 138 139 public Task() { 140 // Do nothing 141 } 142 143 public Task(TaskKey key, boolean isActive, int taskAffiliation, int taskAffiliationColor, 144 String activityTitle, String contentDescription, Drawable activityIcon, 145 int colorPrimary, boolean lockToThisTask, boolean lockToTaskEnabled, Bitmap icon, 146 String iconFilename) { 147 boolean isInAffiliationGroup = (taskAffiliation != key.id); 148 boolean hasAffiliationGroupColor = isInAffiliationGroup && (taskAffiliationColor != 0); 149 this.key = key; 150 this.taskAffiliation = taskAffiliation; 151 this.taskAffiliationColor = taskAffiliationColor; 152 this.activityLabel = activityTitle; 153 this.contentDescription = contentDescription; 154 this.activityIcon = activityIcon; 155 this.colorPrimary = hasAffiliationGroupColor ? taskAffiliationColor : colorPrimary; 156 this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary, 157 Color.WHITE) > 3f; 158 this.isActive = isActive; 159 this.lockToThisTask = lockToTaskEnabled && lockToThisTask; 160 this.lockToTaskEnabled = lockToTaskEnabled; 161 this.icon = icon; 162 this.iconFilename = iconFilename; 163 } 164 165 /** Copies the other task. */ 166 public void copyFrom(Task o) { 167 this.key = o.key; 168 this.taskAffiliation = o.taskAffiliation; 169 this.taskAffiliationColor = o.taskAffiliationColor; 170 this.activityLabel = o.activityLabel; 171 this.contentDescription = o.contentDescription; 172 this.activityIcon = o.activityIcon; 173 this.colorPrimary = o.colorPrimary; 174 this.useLightOnPrimaryColor = o.useLightOnPrimaryColor; 175 this.isActive = o.isActive; 176 this.lockToThisTask = o.lockToThisTask; 177 this.lockToTaskEnabled = o.lockToTaskEnabled; 178 } 179 180 /** Set the callbacks */ 181 public void setCallbacks(TaskCallbacks cb) { 182 mCb = cb; 183 } 184 185 /** Set the grouping */ 186 public void setGroup(TaskGrouping group) { 187 if (group != null && this.group != null) { 188 throw new RuntimeException("This task is already assigned to a group."); 189 } 190 this.group = group; 191 } 192 193 /** Updates the stack id of this task. */ 194 public void setStackId(int stackId) { 195 key.stackId = stackId; 196 if (mCb != null) { 197 mCb.onMultiStackDebugTaskStackIdChanged(); 198 } 199 } 200 201 /** Notifies the callback listeners that this task has been loaded */ 202 public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon) { 203 this.applicationIcon = applicationIcon; 204 this.thumbnail = thumbnail; 205 if (mCb != null) { 206 mCb.onTaskDataLoaded(); 207 } 208 } 209 210 /** Notifies the callback listeners that this task has been unloaded */ 211 public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultApplicationIcon) { 212 applicationIcon = defaultApplicationIcon; 213 thumbnail = defaultThumbnail; 214 if (mCb != null) { 215 mCb.onTaskDataUnloaded(); 216 } 217 } 218 219 @Override 220 public boolean equals(Object o) { 221 // Check that the id matches 222 Task t = (Task) o; 223 return key.equals(t.key); 224 } 225 226 @Override 227 public String toString() { 228 String groupAffiliation = "no group"; 229 if (group != null) { 230 groupAffiliation = Integer.toString(group.affiliation); 231 } 232 return "Task (" + groupAffiliation + "): " + key.baseIntent.getComponent().getPackageName() + 233 " [" + super.toString() + "]"; 234 } 235 } 236