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)
This commit is contained in:
@@ -21,15 +21,16 @@ import android.util.LruCache;
|
||||
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) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.recents.model;
|
||||
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.HashSet;
|
||||
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 @@ public class RecentsPackageMonitor extends PackageMonitor {
|
||||
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 @@ public class RecentsPackageMonitor extends PackageMonitor {
|
||||
}
|
||||
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 class RecentsPackageMonitor extends PackageMonitor {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -420,10 +420,6 @@ public class RecentsTaskLoader {
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ public class Task {
|
||||
TaskCallbacks mCb;
|
||||
|
||||
public Task() {
|
||||
// Only used by RecentsService for task rect calculations.
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public Task(TaskKey key, boolean isActive, int taskAffiliation, int taskAffiliationColor,
|
||||
|
||||
@@ -255,6 +255,17 @@ public class TaskStack {
|
||||
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();
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.recents.views;
|
||||
|
||||
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.Task;
|
||||
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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
||||
/**** 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1081,12 +1081,16 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
||||
/**** 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
|
||||
|
||||
Reference in New Issue
Block a user