am 623484d2: Merge "Ensuring that user-specific Recent tasks are removed. (Bug 18036610)" into lmp-mr1-dev
* commit '623484d231436ee209089adaa6b88b68f0ebf534':
Ensuring that user-specific Recent tasks are removed. (Bug 18036610)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
index 7ccefc6..97e0916 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java
@@ -21,15 +21,16 @@
import java.util.HashMap;
/**
- * An LRU cache that support querying the keys as well as values. By using the Task's key, we can
- * prevent holding onto a reference to the Task resource data, while keeping the cache data in
- * memory where necessary.
+ * An LRU cache that internally support querying the keys as well as values. We use this to keep
+ * track of the task metadata to determine when to invalidate the cache when tasks have been
+ * updated. Generally, this cache will return the last known cache value for the requested task
+ * key.
*/
public class KeyStoreLruCache<V> {
// We keep a set of keys that are associated with the LRU cache, so that we can find out
// information about the Task that was previously in the cache.
HashMap<Integer, Task.TaskKey> mTaskKeys = new HashMap<Integer, Task.TaskKey>();
- // The cache implementation
+ // The cache implementation, mapping task id -> value
LruCache<Integer, V> mCache;
public KeyStoreLruCache(int cacheSize) {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
index 60e89bf..e48e5f0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java
@@ -19,6 +19,7 @@
import android.content.ComponentName;
import android.content.Context;
import android.os.Looper;
+import android.os.UserHandle;
import com.android.internal.content.PackageMonitor;
import com.android.systemui.recents.misc.SystemServicesProxy;
@@ -26,16 +27,16 @@
import java.util.List;
/**
- * The package monitor listens for changes from PackageManager to update the contents of the Recents
- * list.
+ * The package monitor listens for changes from PackageManager to update the contents of the
+ * Recents list.
*/
public class RecentsPackageMonitor extends PackageMonitor {
public interface PackageCallbacks {
- public void onComponentRemoved(HashSet<ComponentName> cns);
+ public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName,
+ int userId);
}
PackageCallbacks mCb;
- List<Task.TaskKey> mTasks;
SystemServicesProxy mSystemServicesProxy;
/** Registers the broadcast receivers with the specified callbacks. */
@@ -43,7 +44,9 @@
mSystemServicesProxy = new SystemServicesProxy(context);
mCb = cb;
try {
- register(context, Looper.getMainLooper(), true);
+ // We register for events from all users, but will cross-reference them with
+ // packages for the current user and any profiles they have
+ register(context, Looper.getMainLooper(), UserHandle.ALL, true);
} catch (IllegalStateException e) {
e.printStackTrace();
}
@@ -59,29 +62,15 @@
}
mSystemServicesProxy = null;
mCb = null;
- mTasks.clear();
- }
-
- /** Sets the list of tasks to match against package broadcast changes. */
- void setTasks(List<Task.TaskKey> tasks) {
- mTasks = tasks;
}
@Override
public void onPackageRemoved(String packageName, int uid) {
if (mCb == null) return;
- // Identify all the tasks that should be removed as a result of the package being removed.
- // Using a set to ensure that we callback once per unique component.
- HashSet<ComponentName> componentsToRemove = new HashSet<ComponentName>();
- for (Task.TaskKey t : mTasks) {
- ComponentName cn = t.baseIntent.getComponent();
- if (cn.getPackageName().equals(packageName)) {
- componentsToRemove.add(cn);
- }
- }
- // Notify our callbacks that the components no longer exist
- mCb.onComponentRemoved(componentsToRemove);
+ // Notify callbacks that a package has changed
+ final int eventUserId = getChangingUserId();
+ mCb.onPackagesChanged(this, packageName, eventUserId);
}
@Override
@@ -94,25 +83,38 @@
public void onPackageModified(String packageName) {
if (mCb == null) return;
+ // Notify callbacks that a package has changed
+ final int eventUserId = getChangingUserId();
+ mCb.onPackagesChanged(this, packageName, eventUserId);
+ }
+
+ /**
+ * Computes the components that have been removed as a result of a change in the specified
+ * package.
+ */
+ public HashSet<ComponentName> computeComponentsRemoved(List<Task.TaskKey> taskKeys,
+ String packageName, int userId) {
// Identify all the tasks that should be removed as a result of the package being removed.
// Using a set to ensure that we callback once per unique component.
- HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
- HashSet<ComponentName> componentsToRemove = new HashSet<ComponentName>();
- for (Task.TaskKey t : mTasks) {
+ HashSet<ComponentName> existingComponents = new HashSet<ComponentName>();
+ HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();
+ for (Task.TaskKey t : taskKeys) {
+ // Skip if this doesn't apply to the current user
+ if (t.userId != userId) continue;
+
ComponentName cn = t.baseIntent.getComponent();
if (cn.getPackageName().equals(packageName)) {
- if (componentsKnownToExist.contains(cn)) {
+ if (existingComponents.contains(cn)) {
// If we know that the component still exists in the package, then skip
continue;
}
- if (mSystemServicesProxy.getActivityInfo(cn) != null) {
- componentsKnownToExist.add(cn);
+ if (mSystemServicesProxy.getActivityInfo(cn, userId) != null) {
+ existingComponents.add(cn);
} else {
- componentsToRemove.add(cn);
+ removedComponents.add(cn);
}
}
}
- // Notify our callbacks that the components no longer exist
- mCb.onComponentRemoved(componentsToRemove);
+ return removedComponents;
}
}
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 d40e847..114e93f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -420,10 +420,6 @@
// Start the task loader and add all the tasks we need to load
mLoader.start(context);
mLoadQueue.addTasks(tasksToLoad);
-
- // Update the package monitor with the list of packages to listen for
- mPackageMonitor.setTasks(taskKeys);
-
return root;
}
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 a7e2b0b..55dfe45 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -129,7 +129,7 @@
TaskCallbacks mCb;
public Task() {
- // Only used by RecentsService for task rect calculations.
+ // Do nothing
}
public Task(TaskKey key, boolean isActive, int taskAffiliation, int taskAffiliationColor,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index 1e47b50..a37b9e6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -255,6 +255,17 @@
return mTaskList.getTasks().get(mTaskList.size() - 1);
}
+ /** Gets the task keys */
+ public ArrayList<Task.TaskKey> getTaskKeys() {
+ ArrayList<Task.TaskKey> taskKeys = new ArrayList<Task.TaskKey>();
+ ArrayList<Task> tasks = mTaskList.getTasks();
+ int taskCount = tasks.size();
+ for (int i = 0; i < taskCount; i++) {
+ taskKeys.add(tasks.get(i).key);
+ }
+ return taskKeys;
+ }
+
/** Gets the tasks */
public ArrayList<Task> getTasks() {
return mTaskList.getTasks();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 9dfebfe..6b0d306 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -18,7 +18,6 @@
import android.app.ActivityOptions;
import android.app.TaskStackBuilder;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -42,7 +41,6 @@
import com.android.systemui.recents.model.TaskStack;
import java.util.ArrayList;
-import java.util.HashSet;
/**
* This view is the the top level layout that contains TaskStacks (which are laid out according
@@ -564,14 +562,14 @@
/**** RecentsPackageMonitor.PackageCallbacks Implementation ****/
@Override
- public void onComponentRemoved(HashSet<ComponentName> cns) {
+ public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, int userId) {
// Propagate this event down to each task stack view
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
if (child != mSearchBar) {
TaskStackView stackView = (TaskStackView) child;
- stackView.onComponentRemoved(cns);
+ stackView.onPackagesChanged(monitor, packageName, userId);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index e479952..dee26e6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -1081,12 +1081,16 @@
/**** RecentsPackageMonitor.PackageCallbacks Implementation ****/
@Override
- public void onComponentRemoved(HashSet<ComponentName> cns) {
+ public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, int userId) {
+ // Compute which components need to be removed
+ HashSet<ComponentName> removedComponents = monitor.computeComponentsRemoved(
+ mStack.getTaskKeys(), packageName, userId);
+
// For other tasks, just remove them directly if they no longer exist
ArrayList<Task> tasks = mStack.getTasks();
for (int i = tasks.size() - 1; i >= 0; i--) {
final Task t = tasks.get(i);
- if (cns.contains(t.key.baseIntent.getComponent())) {
+ if (removedComponents.contains(t.key.baseIntent.getComponent())) {
TaskView tv = getChildViewForTask(t);
if (tv != null) {
// For visible children, defer removing the task until after the animation