| /* |
| * Copyright (C) 2014 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.systemui.shared.recents.model; |
| |
| import android.app.ActivityManager.TaskDescription; |
| import android.content.ComponentName; |
| import android.content.Intent; |
| import android.content.pm.ActivityInfo; |
| import android.graphics.Color; |
| import android.graphics.drawable.Drawable; |
| import android.view.ViewDebug; |
| |
| import com.android.systemui.shared.recents.utilities.Utilities; |
| |
| import java.io.PrintWriter; |
| import java.util.ArrayList; |
| import java.util.Objects; |
| |
| /** |
| * A task represents the top most task in the system's task stack. |
| */ |
| public class Task { |
| |
| public static final String TAG = "Task"; |
| |
| /* Task callbacks */ |
| public interface TaskCallbacks { |
| /* Notifies when a task has been bound */ |
| void onTaskDataLoaded(Task task, ThumbnailData thumbnailData); |
| /* Notifies when a task has been unbound */ |
| void onTaskDataUnloaded(); |
| /* Notifies when a task's windowing mode has changed. */ |
| void onTaskWindowingModeChanged(); |
| } |
| |
| /* The Task Key represents the unique primary key for the task */ |
| public static class TaskKey { |
| @ViewDebug.ExportedProperty(category="recents") |
| public final int id; |
| @ViewDebug.ExportedProperty(category="recents") |
| public int windowingMode; |
| @ViewDebug.ExportedProperty(category="recents") |
| public final Intent baseIntent; |
| @ViewDebug.ExportedProperty(category="recents") |
| public final int userId; |
| @ViewDebug.ExportedProperty(category="recents") |
| public long lastActiveTime; |
| |
| private int mHashCode; |
| |
| public TaskKey(int id, int windowingMode, Intent intent, int userId, long lastActiveTime) { |
| this.id = id; |
| this.windowingMode = windowingMode; |
| this.baseIntent = intent; |
| this.userId = userId; |
| this.lastActiveTime = lastActiveTime; |
| updateHashCode(); |
| } |
| |
| public void setWindowingMode(int windowingMode) { |
| this.windowingMode = windowingMode; |
| updateHashCode(); |
| } |
| |
| public ComponentName getComponent() { |
| return this.baseIntent.getComponent(); |
| } |
| |
| public String getPackageName() { |
| if (this.baseIntent.getComponent() != null) { |
| return this.baseIntent.getComponent().getPackageName(); |
| } |
| return this.baseIntent.getPackage(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (!(o instanceof TaskKey)) { |
| return false; |
| } |
| TaskKey otherKey = (TaskKey) o; |
| return id == otherKey.id |
| && windowingMode == otherKey.windowingMode |
| && userId == otherKey.userId; |
| } |
| |
| @Override |
| public int hashCode() { |
| return mHashCode; |
| } |
| |
| @Override |
| public String toString() { |
| return "id=" + id + " windowingMode=" + windowingMode + " user=" + userId |
| + " lastActiveTime=" + lastActiveTime; |
| } |
| |
| private void updateHashCode() { |
| mHashCode = Objects.hash(id, windowingMode, userId); |
| } |
| } |
| |
| @ViewDebug.ExportedProperty(deepExport=true, prefix="key_") |
| public TaskKey key; |
| |
| /** |
| * The temporary sort index in the stack, used when ordering the stack. |
| */ |
| public int temporarySortIndexInStack; |
| |
| /** |
| * The icon is the task description icon (if provided), which falls back to the activity icon, |
| * which can then fall back to the application icon. |
| */ |
| public Drawable icon; |
| public ThumbnailData thumbnail; |
| @ViewDebug.ExportedProperty(category="recents") |
| public String title; |
| @ViewDebug.ExportedProperty(category="recents") |
| public String titleDescription; |
| @ViewDebug.ExportedProperty(category="recents") |
| public int colorPrimary; |
| @ViewDebug.ExportedProperty(category="recents") |
| public int colorBackground; |
| @ViewDebug.ExportedProperty(category="recents") |
| public boolean useLightOnPrimaryColor; |
| |
| /** |
| * The task description for this task, only used to reload task icons. |
| */ |
| public TaskDescription taskDescription; |
| |
| /** |
| * The state isLaunchTarget will be set for the correct task upon launching Recents. |
| */ |
| @ViewDebug.ExportedProperty(category="recents") |
| public boolean isLaunchTarget; |
| @ViewDebug.ExportedProperty(category="recents") |
| public boolean isStackTask; |
| @ViewDebug.ExportedProperty(category="recents") |
| public boolean isSystemApp; |
| @ViewDebug.ExportedProperty(category="recents") |
| public boolean isDockable; |
| |
| /** |
| * Resize mode. See {@link ActivityInfo#resizeMode}. |
| */ |
| @ViewDebug.ExportedProperty(category="recents") |
| public int resizeMode; |
| |
| @ViewDebug.ExportedProperty(category="recents") |
| public ComponentName topActivity; |
| |
| @ViewDebug.ExportedProperty(category="recents") |
| public boolean isLocked; |
| |
| private ArrayList<TaskCallbacks> mCallbacks = new ArrayList<>(); |
| |
| public Task() { |
| // Do nothing |
| } |
| |
| public Task(TaskKey key, Drawable icon, ThumbnailData thumbnail, String title, |
| String titleDescription, int colorPrimary, int colorBackground, boolean isLaunchTarget, |
| boolean isStackTask, boolean isSystemApp, boolean isDockable, |
| TaskDescription taskDescription, int resizeMode, ComponentName topActivity, |
| boolean isLocked) { |
| this.key = key; |
| this.icon = icon; |
| this.thumbnail = thumbnail; |
| this.title = title; |
| this.titleDescription = titleDescription; |
| this.colorPrimary = colorPrimary; |
| this.colorBackground = colorBackground; |
| this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary, |
| Color.WHITE) > 3f; |
| this.taskDescription = taskDescription; |
| this.isLaunchTarget = isLaunchTarget; |
| this.isStackTask = isStackTask; |
| this.isSystemApp = isSystemApp; |
| this.isDockable = isDockable; |
| this.resizeMode = resizeMode; |
| this.topActivity = topActivity; |
| this.isLocked = isLocked; |
| } |
| |
| /** |
| * Copies the metadata from another task, but retains the current callbacks. |
| */ |
| public void copyFrom(Task o) { |
| this.key = o.key; |
| this.icon = o.icon; |
| this.thumbnail = o.thumbnail; |
| this.title = o.title; |
| this.titleDescription = o.titleDescription; |
| this.colorPrimary = o.colorPrimary; |
| this.colorBackground = o.colorBackground; |
| this.useLightOnPrimaryColor = o.useLightOnPrimaryColor; |
| this.taskDescription = o.taskDescription; |
| this.isLaunchTarget = o.isLaunchTarget; |
| this.isStackTask = o.isStackTask; |
| this.isSystemApp = o.isSystemApp; |
| this.isDockable = o.isDockable; |
| this.resizeMode = o.resizeMode; |
| this.isLocked = o.isLocked; |
| this.topActivity = o.topActivity; |
| } |
| |
| /** |
| * Add a callback. |
| */ |
| public void addCallback(TaskCallbacks cb) { |
| if (!mCallbacks.contains(cb)) { |
| mCallbacks.add(cb); |
| } |
| } |
| |
| /** |
| * Remove a callback. |
| */ |
| public void removeCallback(TaskCallbacks cb) { |
| mCallbacks.remove(cb); |
| } |
| |
| /** Updates the task's windowing mode. */ |
| public void setWindowingMode(int windowingMode) { |
| key.setWindowingMode(windowingMode); |
| int callbackCount = mCallbacks.size(); |
| for (int i = 0; i < callbackCount; i++) { |
| mCallbacks.get(i).onTaskWindowingModeChanged(); |
| } |
| } |
| |
| /** Notifies the callback listeners that this task has been loaded */ |
| public void notifyTaskDataLoaded(ThumbnailData thumbnailData, Drawable applicationIcon) { |
| this.icon = applicationIcon; |
| this.thumbnail = thumbnailData; |
| int callbackCount = mCallbacks.size(); |
| for (int i = 0; i < callbackCount; i++) { |
| mCallbacks.get(i).onTaskDataLoaded(this, thumbnailData); |
| } |
| } |
| |
| /** Notifies the callback listeners that this task has been unloaded */ |
| public void notifyTaskDataUnloaded(Drawable defaultApplicationIcon) { |
| icon = defaultApplicationIcon; |
| thumbnail = null; |
| for (int i = mCallbacks.size() - 1; i >= 0; i--) { |
| mCallbacks.get(i).onTaskDataUnloaded(); |
| } |
| } |
| |
| /** |
| * Returns the top activity component. |
| */ |
| public ComponentName getTopComponent() { |
| return topActivity != null |
| ? topActivity |
| : key.baseIntent.getComponent(); |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| // Check that the id matches |
| Task t = (Task) o; |
| return key.equals(t.key); |
| } |
| |
| @Override |
| public String toString() { |
| return "[" + key.toString() + "] " + title; |
| } |
| |
| public void dump(String prefix, PrintWriter writer) { |
| writer.print(prefix); writer.print(key); |
| if (!isDockable) { |
| writer.print(" dockable=N"); |
| } |
| if (isLaunchTarget) { |
| writer.print(" launchTarget=Y"); |
| } |
| if (isLocked) { |
| writer.print(" locked=Y"); |
| } |
| writer.print(" "); writer.print(title); |
| writer.println(); |
| } |
| } |