summaryrefslogtreecommitdiffstats
path: root/go
diff options
context:
space:
mode:
authorTreeHugger Robot <treehugger-gerrit@google.com>2019-03-29 02:07:01 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-03-29 02:07:01 +0000
commit7c1d69e5154cb5845e948215dd4c3374159e1592 (patch)
tree71e0f927a0bf00072d6082c8fa8aa3d1f232112b /go
parent09b91447467ad401e994e6e215d9a5b770dbe2c3 (diff)
parentb589241fd683cda2da005093c891a89b39fc08a3 (diff)
downloadandroid_packages_apps_Trebuchet-7c1d69e5154cb5845e948215dd4c3374159e1592.tar.gz
android_packages_apps_Trebuchet-7c1d69e5154cb5845e948215dd4c3374159e1592.tar.bz2
android_packages_apps_Trebuchet-7c1d69e5154cb5845e948215dd4c3374159e1592.zip
Merge "Show ASAP for Recents Go and load content after" into ub-launcher3-master
Diffstat (limited to 'go')
-rw-r--r--go/quickstep/src/com/android/quickstep/TaskAdapter.java16
-rw-r--r--go/quickstep/src/com/android/quickstep/TaskHolder.java11
-rw-r--r--go/quickstep/src/com/android/quickstep/TaskListLoader.java116
-rw-r--r--go/quickstep/src/com/android/quickstep/views/TaskItemView.java42
4 files changed, 116 insertions, 69 deletions
diff --git a/go/quickstep/src/com/android/quickstep/TaskAdapter.java b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
index e56cc5125..c98eca622 100644
--- a/go/quickstep/src/com/android/quickstep/TaskAdapter.java
+++ b/go/quickstep/src/com/android/quickstep/TaskAdapter.java
@@ -75,8 +75,20 @@ public final class TaskAdapter extends Adapter<TaskHolder> {
// Task list has updated.
return;
}
- holder.bindTask(tasks.get(position));
-
+ Task task = tasks.get(position);
+ holder.bindTask(task);
+ mLoader.loadTaskIconAndLabel(task, () -> {
+ // Ensure holder still has the same task.
+ if (task.equals(holder.getTask())) {
+ holder.getTaskItemView().setIcon(task.icon);
+ holder.getTaskItemView().setLabel(task.titleDescription);
+ }
+ });
+ mLoader.loadTaskThumbnail(task, () -> {
+ if (task.equals(holder.getTask())) {
+ holder.getTaskItemView().setThumbnail(task.thumbnail.thumbnail);
+ }
+ });
}
@Override
diff --git a/go/quickstep/src/com/android/quickstep/TaskHolder.java b/go/quickstep/src/com/android/quickstep/TaskHolder.java
index a89229f2f..744afd766 100644
--- a/go/quickstep/src/com/android/quickstep/TaskHolder.java
+++ b/go/quickstep/src/com/android/quickstep/TaskHolder.java
@@ -35,17 +35,18 @@ public final class TaskHolder extends ViewHolder {
mTaskItemView = itemView;
}
+ public TaskItemView getTaskItemView() {
+ return mTaskItemView;
+ }
+
/**
- * Bind task content to the view. This includes the task icon and title as well as binding
- * input handlers such as which task to launch/remove.
+ * Bind a task to the holder, resetting the view and preparing it for content to load in.
*
* @param task the task to bind to the view
*/
public void bindTask(Task task) {
mTask = task;
- mTaskItemView.setLabel(task.titleDescription);
- mTaskItemView.setIcon(task.icon);
- mTaskItemView.setThumbnail(task.thumbnail.thumbnail);
+ mTaskItemView.resetTaskItemView();
}
/**
diff --git a/go/quickstep/src/com/android/quickstep/TaskListLoader.java b/go/quickstep/src/com/android/quickstep/TaskListLoader.java
index c86c24e8f..1234989d2 100644
--- a/go/quickstep/src/com/android/quickstep/TaskListLoader.java
+++ b/go/quickstep/src/com/android/quickstep/TaskListLoader.java
@@ -25,7 +25,6 @@ import com.android.systemui.shared.recents.model.Task;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
/**
@@ -39,35 +38,48 @@ public final class TaskListLoader {
private ArrayList<Task> mTaskList = new ArrayList<>();
private int mTaskListChangeId;
+ private RecentsModel.TaskThumbnailChangeListener listener = (taskId, thumbnailData) -> {
+ Task foundTask = null;
+ for (Task task : mTaskList) {
+ if (task.key.id == taskId) {
+ foundTask = task;
+ break;
+ }
+ }
+ if (foundTask != null) {
+ foundTask.thumbnail = thumbnailData;
+ }
+ return foundTask;
+ };
public TaskListLoader(Context context) {
mRecentsModel = RecentsModel.INSTANCE.get(context);
+ mRecentsModel.addThumbnailChangeListener(listener);
}
/**
- * Returns the current task list as of the last completed load (see
- * {@link #loadTaskList}) as a read-only list. This list of tasks is guaranteed to always have
- * all its task content loaded.
+ * Returns the current task list as of the last completed load (see {@link #loadTaskList}) as a
+ * read-only list. This list of tasks is not guaranteed to have all content loaded.
*
- * @return the current list of tasks w/ all content loaded
+ * @return the current list of tasks
*/
public List<Task> getCurrentTaskList() {
return Collections.unmodifiableList(mTaskList);
}
/**
- * Fetches the most recent tasks and updates the task list asynchronously. In addition it
- * loads the content for each task (icon and label). The callback and task list being updated
- * only occur when all task content is fully loaded and up-to-date.
+ * Fetches the most recent tasks and updates the task list asynchronously. This call does not
+ * provide guarantees the task content (icon, thumbnail, label) are loaded but will fill in
+ * what it has. May run the callback immediately if there have been no changes in the task
+ * list.
*
- * @param onTasksLoadedCallback callback for when the tasks are fully loaded. Done on the UI
- * thread
+ * @param onLoadedCallback callback to run when task list is loaded
*/
- public void loadTaskList(@Nullable Consumer<ArrayList<Task>> onTasksLoadedCallback) {
+ public void loadTaskList(@Nullable Consumer<ArrayList<Task>> onLoadedCallback) {
if (mRecentsModel.isTaskListValid(mTaskListChangeId)) {
// Current task list is already up to date. No need to update.
- if (onTasksLoadedCallback != null) {
- onTasksLoadedCallback.accept(mTaskList);
+ if (onLoadedCallback != null) {
+ onLoadedCallback.accept(mTaskList);
}
return;
}
@@ -76,16 +88,46 @@ public final class TaskListLoader {
// Reverse tasks to put most recent at the bottom of the view
Collections.reverse(tasks);
// Load task content
- loadTaskContents(tasks, () -> {
- mTaskList = tasks;
- if (onTasksLoadedCallback != null) {
- onTasksLoadedCallback.accept(mTaskList);
+ for (Task task : tasks) {
+ int loadedPos = mTaskList.indexOf(task);
+ if (loadedPos == -1) {
+ continue;
}
- });
+ Task loadedTask = mTaskList.get(loadedPos);
+ task.icon = loadedTask.icon;
+ task.titleDescription = loadedTask.titleDescription;
+ task.thumbnail = loadedTask.thumbnail;
+ }
+ mTaskList = tasks;
+ onLoadedCallback.accept(tasks);
});
}
/**
+ * Load task icon and label asynchronously if it is not already loaded in the task. If the task
+ * already has an icon, this calls the callback immediately.
+ *
+ * @param task task to update with icon + label
+ * @param onLoadedCallback callback to run when task has icon and label
+ */
+ public void loadTaskIconAndLabel(Task task, @Nullable Runnable onLoadedCallback) {
+ mRecentsModel.getIconCache().updateIconInBackground(task,
+ loadedTask -> onLoadedCallback.run());
+ }
+
+ /**
+ * Load thumbnail asynchronously if not already loaded in the task. If the task already has a
+ * thumbnail or if the thumbnail is cached, this calls the callback immediately.
+ *
+ * @param task task to update with the thumbnail
+ * @param onLoadedCallback callback to run when task has thumbnail
+ */
+ public void loadTaskThumbnail(Task task, @Nullable Runnable onLoadedCallback) {
+ mRecentsModel.getThumbnailCache().updateThumbnailInBackground(task,
+ thumbnail -> onLoadedCallback.run());
+ }
+
+ /**
* Removes the task from the current task list.
*/
void removeTask(Task task) {
@@ -98,42 +140,4 @@ public final class TaskListLoader {
void clearAllTasks() {
mTaskList.clear();
}
-
- /**
- * Loads task content for a list of tasks, including the label, icon, and thumbnail. For content
- * that isn't cached, load the content asynchronously in the background.
- *
- * @param tasksToLoad list of tasks that need to load their content
- * @param onFullyLoadedCallback runnable to run after all tasks have loaded their content
- */
- private void loadTaskContents(ArrayList<Task> tasksToLoad,
- @Nullable Runnable onFullyLoadedCallback) {
- // Make two load requests per task, one for the icon/title and one for the thumbnail.
- AtomicInteger loadRequestsCount = new AtomicInteger(tasksToLoad.size() * 2);
- Runnable itemLoadedRunnable = () -> {
- if (loadRequestsCount.decrementAndGet() == 0 && onFullyLoadedCallback != null) {
- onFullyLoadedCallback.run();
- }
- };
- for (Task task : tasksToLoad) {
- // Load icon and title.
- int index = mTaskList.indexOf(task);
- if (index >= 0) {
- // If we've already loaded the task and have its content then just copy it over.
- Task loadedTask = mTaskList.get(index);
- task.titleDescription = loadedTask.titleDescription;
- task.icon = loadedTask.icon;
- itemLoadedRunnable.run();
- } else {
- // Otherwise, load the content in the background.
- mRecentsModel.getIconCache().updateIconInBackground(task,
- loadedTask -> itemLoadedRunnable.run());
- }
-
- // Load the thumbnail. May return immediately and synchronously if the thumbnail is
- // cached.
- mRecentsModel.getThumbnailCache().updateThumbnailInBackground(task,
- thumbnail -> itemLoadedRunnable.run());
- }
- }
}
diff --git a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
index 373f10791..d831b206a 100644
--- a/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
+++ b/go/quickstep/src/com/android/quickstep/views/TaskItemView.java
@@ -17,6 +17,7 @@ package com.android.quickstep.views;
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
@@ -24,6 +25,8 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
+import androidx.annotation.Nullable;
+
import com.android.launcher3.R;
/**
@@ -31,12 +34,16 @@ import com.android.launcher3.R;
*/
public final class TaskItemView extends LinearLayout {
+ private static final String DEFAULT_LABEL = "...";
+ private final Drawable mDefaultIcon;
private TextView mLabelView;
private ImageView mIconView;
private ImageView mThumbnailView;
public TaskItemView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mDefaultIcon = context.getResources().getDrawable(
+ android.R.drawable.sym_def_app_icon, context.getTheme());
}
@Override
@@ -48,33 +55,56 @@ public final class TaskItemView extends LinearLayout {
}
/**
- * Set the label for the task item.
+ * Resets task item view to default values.
+ */
+ public void resetTaskItemView() {
+ setLabel(DEFAULT_LABEL);
+ setIcon(null);
+ setThumbnail(null);
+ }
+
+ /**
+ * Set the label for the task item. Sets to a default label if null.
*
* @param label task label
*/
- public void setLabel(String label) {
+ public void setLabel(@Nullable String label) {
+ if (label == null) {
+ mLabelView.setText(DEFAULT_LABEL);
+ return;
+ }
mLabelView.setText(label);
}
/**
- * Set the icon for the task item.
+ * Set the icon for the task item. Sets to a default icon if null.
*
* @param icon task icon
*/
- public void setIcon(Drawable icon) {
+ public void setIcon(@Nullable Drawable icon) {
// TODO: Scale the icon up based off the padding on the side
// The icon proper is actually smaller than the drawable and has "padding" on the side for
// the purpose of drawing the shadow, allowing the icon to pop up, so we need to scale the
// view if we want the icon to be flush with the bottom of the thumbnail.
+ if (icon == null) {
+ mIconView.setImageDrawable(mDefaultIcon);
+ return;
+ }
mIconView.setImageDrawable(icon);
}
/**
- * Set the task thumbnail for the task.
+ * Set the task thumbnail for the task. Sets to a default thumbnail if null.
*
* @param thumbnail task thumbnail for the task
*/
- public void setThumbnail(Bitmap thumbnail) {
+ public void setThumbnail(@Nullable Bitmap thumbnail) {
+ if (thumbnail == null) {
+ mThumbnailView.setImageBitmap(null);
+ mThumbnailView.setBackgroundColor(Color.GRAY);
+ return;
+ }
+ mThumbnailView.setBackgroundColor(Color.TRANSPARENT);
mThumbnailView.setImageBitmap(thumbnail);
}