Ensuring that the ActivityInfo cache accounts for the task's user id. (Bug 17314317)
Change-Id: I10bcb60abe3450f2ecfb3ee305be505e13e0be3b
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index a93e244..f7ad35b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -18,7 +18,6 @@
import android.app.ActivityManager;
import android.content.ComponentCallbacks2;
-import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Resources;
@@ -28,6 +27,8 @@
import android.os.Handler;
import android.os.HandlerThread;
import android.os.UserHandle;
+import android.util.Log;
+
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -232,6 +233,8 @@
/* Recents task loader
* NOTE: We should not hold any references to a Context from a static instance */
public class RecentsTaskLoader {
+ private static final String TAG = "RecentsTaskLoader";
+
static RecentsTaskLoader sInstance;
SystemServicesProxy mSystemServicesProxy;
@@ -335,11 +338,15 @@
infoHandle.info = ssp.getActivityInfo(taskKey.baseIntent.getComponent(),
taskKey.userId);
}
- icon = ssp.getActivityIcon(infoHandle.info, taskKey.userId);
- mApplicationIconCache.put(taskKey, icon);
- return icon;
+ if (infoHandle.info != null) {
+ icon = ssp.getActivityIcon(infoHandle.info, taskKey.userId);
+ if (icon != null) {
+ mApplicationIconCache.put(taskKey, icon);
+ return icon;
+ }
+ }
}
- // If we are not preloading, return the default icon to show
+ // If we couldn't load any icon, return null
return null;
}
@@ -361,8 +368,13 @@
infoHandle.info = ssp.getActivityInfo(taskKey.baseIntent.getComponent(),
taskKey.userId);
}
- label = ssp.getActivityLabel(infoHandle.info);
- mActivityLabelCache.put(taskKey, label);
+ if (infoHandle.info != null) {
+ label = ssp.getActivityLabel(infoHandle.info);
+ mActivityLabelCache.put(taskKey, label);
+ } else {
+ Log.w(TAG, "Missing ActivityInfo for " + taskKey.baseIntent.getComponent()
+ + " u=" + taskKey.userId);
+ }
return label;
}
@@ -401,8 +413,8 @@
List<Task> tasksToLoadOut) {
RecentsConfiguration config = RecentsConfiguration.getInstance();
List<ActivityManager.RecentTaskInfo> tasks = getRecentTasks(ssp);
- HashMap<ComponentName, ActivityInfoHandle> activityInfoCache =
- new HashMap<ComponentName, ActivityInfoHandle>();
+ HashMap<Task.ComponentNameKey, ActivityInfoHandle> activityInfoCache =
+ new HashMap<Task.ComponentNameKey, ActivityInfoHandle>();
ArrayList<Task> tasksToAdd = new ArrayList<Task>();
TaskStack stack = new TaskStack();
@@ -410,19 +422,21 @@
for (int i = 0; i < taskCount; i++) {
ActivityManager.RecentTaskInfo t = tasks.get(i);
- // Get an existing activity info handle if possible
- ComponentName cn = t.baseIntent.getComponent();
- ActivityInfoHandle infoHandle = new ActivityInfoHandle();
- boolean hasCachedActivityInfo = false;
- if (activityInfoCache.containsKey(cn)) {
- infoHandle = activityInfoCache.get(cn);
- hasCachedActivityInfo = true;
- }
-
// Compose the task key
Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.baseIntent, t.userId,
t.firstActiveTime, t.lastActiveTime);
+ // Get an existing activity info handle if possible
+ Task.ComponentNameKey cnKey = taskKey.getComponentNameKey();
+ ActivityInfoHandle infoHandle;
+ boolean hasCachedActivityInfo = false;
+ if (activityInfoCache.containsKey(cnKey)) {
+ infoHandle = activityInfoCache.get(cnKey);
+ hasCachedActivityInfo = true;
+ } else {
+ infoHandle = new ActivityInfoHandle();
+ }
+
// Determine whether to preload this task
boolean preloadTask = false;
if (preloadTaskId > 0) {
@@ -440,7 +454,7 @@
// Update the activity info cache
if (!hasCachedActivityInfo && infoHandle.info != null) {
- activityInfoCache.put(cn, infoHandle);
+ activityInfoCache.put(cnKey, infoHandle);
}
// Add the task to the stack
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
index 977db60..406e03f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -16,12 +16,15 @@
package com.android.systemui.recents.model;
+import android.content.ComponentName;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import com.android.systemui.recents.misc.Utilities;
+import java.util.Objects;
+
/**
* A task represents the top most task in the system's task stack.
@@ -35,8 +38,35 @@
public void onTaskDataUnloaded();
}
+ /** The ComponentNameKey represents the unique primary key for a component
+ * belonging to a specified user. */
+ public static class ComponentNameKey {
+ final ComponentName component;
+ final int userId;
+
+ public ComponentNameKey(ComponentName cn, int user) {
+ component = cn;
+ userId = user;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(component, userId);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof ComponentNameKey)) {
+ return false;
+ }
+ return component.equals(((ComponentNameKey) o).component) &&
+ userId == ((ComponentNameKey) o).userId;
+ }
+ }
+
/* The Task Key represents the unique primary key for the task */
public static class TaskKey {
+ final ComponentNameKey mComponentNameKey;
public final int id;
public final Intent baseIntent;
public final int userId;
@@ -44,6 +74,7 @@
public long lastActiveTime;
public TaskKey(int id, Intent intent, int userId, long firstActiveTime, long lastActiveTime) {
+ mComponentNameKey = new ComponentNameKey(intent.getComponent(), userId);
this.id = id;
this.baseIntent = intent;
this.userId = userId;
@@ -51,6 +82,11 @@
this.lastActiveTime = lastActiveTime;
}
+ /** Returns the component name key for this task. */
+ public ComponentNameKey getComponentNameKey() {
+ return mComponentNameKey;
+ }
+
@Override
public boolean equals(Object o) {
if (!(o instanceof TaskKey)) {