summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2014-03-14 14:06:29 -0700
committerWinson Chung <winsonc@google.com>2014-03-14 16:53:45 -0700
commit04dfe0d26b944324ee920001f40d74cff47281d6 (patch)
tree0c43364c6cf2cf74c45e5006a7405cb24f1b0725 /packages/SystemUI/src/com/android
parent4d7b092a866d2fce3e11b5a12cda2b87a83af52d (diff)
downloadframeworks_base-04dfe0d26b944324ee920001f40d74cff47281d6.zip
frameworks_base-04dfe0d26b944324ee920001f40d74cff47281d6.tar.gz
frameworks_base-04dfe0d26b944324ee920001f40d74cff47281d6.tar.bz2
Simplifying memory management, use Task Keys as resource cache keys.
- Attempts to load non-topmost task thumbnails from cache - Ensuring that we release all references to the activity from the bg loader - Removes background loading debug flag - Moving callbacks into their respective classes - cleaning up some callbacks when data is loaded in the bg Change-Id: Ibb968349d08084922d5b28e432b76a165bf20d6b
Diffstat (limited to 'packages/SystemUI/src/com/android')
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Constants.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java251
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/SpaceNodeCallbacks.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/Task.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/TaskStackCallbacks.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/ViewPoolConsumer.java28
14 files changed, 243 insertions, 325 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index 57ebbc2..34dd726 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -28,10 +28,10 @@ public class Constants {
public static class App {
public static final boolean EnableTaskFiltering = false;
public static final boolean EnableTaskStackClipping = false;
- public static final boolean EnableBackgroundTaskLoading = true;
- public static final boolean ForceDisableBackgroundCache = false;
+ // This disables the bitmap and icon caches to
+ public static final boolean DisableBackgroundCache = false;
- public static final boolean TaskDataLoader = false;
+ public static final boolean TaskDataLoader = true;
public static final boolean SystemUIHandshake = false;
public static final boolean TimeSystemCalls = false;
public static final boolean Memory = false;
@@ -43,7 +43,7 @@ public class Constants {
public static final boolean TouchEvents = false;
public static final boolean MeasureAndLayout = false;
public static final boolean Clipping = false;
- public static final boolean HwLayers = false;
+ public static final boolean HwLayers = true;
}
public static class TaskStack {
@@ -74,8 +74,6 @@ public class Constants {
public static class Animation {
public static final int TaskRemovedReshuffleDuration = 200;
public static final int SnapScrollBackDuration = 650;
- public static final int SwipeDismissDuration = 350;
- public static final int SwipeSnapBackDuration = 350;
}
// The padding will be applied to the smallest dimension, and then applied to all sides
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index fc4d819..e3908ff 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -45,7 +45,6 @@ public class RecentsActivity extends Activity {
SpaceNode root = loader.reload(this, Constants.Values.RecentsTaskLoader.PreloadFirstTasksCount);
ArrayList<TaskStack> stacks = root.getStacks();
if (!stacks.isEmpty()) {
- // XXX: We just replace the root every time for now, we will change this in the future
mRecentsView.setBSP(root);
}
@@ -155,7 +154,7 @@ public class RecentsActivity extends Activity {
Console.AnsiRed);
super.onPause();
- // Stop the loader when we leave Recents
+ // Stop the loader immediately when we leave Recents
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
loader.stopLoader();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
index 96efed4..c8576b2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsTaskLoader.java
@@ -36,7 +36,6 @@ import com.android.systemui.recents.model.TaskStack;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -84,7 +83,9 @@ class TaskResourceLoader implements Runnable {
TaskResourceLoadQueue mLoadQueue;
DrawableLruCache mIconCache;
BitmapLruCache mThumbnailCache;
+
boolean mCancelled;
+ boolean mWaitingOnLoadQueue;
/** Constructor, creates a new loading thread that loads task resources in the background */
public TaskResourceLoader(TaskResourceLoadQueue loadQueue, DrawableLruCache iconCache,
@@ -116,6 +117,11 @@ class TaskResourceLoader implements Runnable {
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|stop]");
// Mark as cancelled for the thread to pick up
mCancelled = true;
+ // If we are waiting for the load queue for more tasks, then we can just reset the
+ // Context now, since nothing is using it
+ if (mWaitingOnLoadQueue) {
+ mContext = null;
+ }
}
@Override
@@ -124,6 +130,8 @@ class TaskResourceLoader implements Runnable {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
"[TaskResourceLoader|run|" + Thread.currentThread().getId() + "]");
if (mCancelled) {
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
+ "[TaskResourceLoader|cancel|" + Thread.currentThread().getId() + "]");
// We have to unset the context here, since the background thread may be using it
// when we call stop()
mContext = null;
@@ -142,50 +150,52 @@ class TaskResourceLoader implements Runnable {
final Task t = mLoadQueue.nextTask();
if (t != null) {
try {
- Drawable cachedIcon = mIconCache.get(t);
- Bitmap cachedThumbnail = mThumbnailCache.get(t);
+ Drawable loadIcon = mIconCache.get(t.key);
+ Bitmap loadThumbnail = mThumbnailCache.get(t.key);
Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [TaskResourceLoader|load]",
- t + " icon: " + cachedIcon + " thumbnail: " + cachedThumbnail);
+ t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail);
// Load the icon
- if (cachedIcon == null) {
+ if (loadIcon == null) {
PackageManager pm = mContext.getPackageManager();
- ActivityInfo info = pm.getActivityInfo(t.intent.getComponent(),
+ ActivityInfo info = pm.getActivityInfo(t.key.intent.getComponent(),
PackageManager.GET_META_DATA);
Drawable icon = info.loadIcon(pm);
if (!mCancelled) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [TaskResourceLoader|loadIcon]",
icon);
- t.icon = icon;
- mIconCache.put(t, icon);
+ loadIcon = icon;
+ mIconCache.put(t.key, icon);
}
}
// Load the thumbnail
- if (cachedThumbnail == null) {
+ if (loadThumbnail == null) {
ActivityManager am = (ActivityManager)
mContext.getSystemService(Context.ACTIVITY_SERVICE);
- Bitmap thumbnail = am.getTaskTopThumbnail(t.id);
+ Bitmap thumbnail = am.getTaskTopThumbnail(t.key.id);
if (!mCancelled) {
if (thumbnail != null) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [TaskResourceLoader|loadThumbnail]",
thumbnail);
- t.thumbnail = thumbnail;
- mThumbnailCache.put(t, thumbnail);
+ loadThumbnail = thumbnail;
+ mThumbnailCache.put(t.key, thumbnail);
} else {
Console.logError(mContext,
"Failed to load task top thumbnail for: " +
- t.intent.getComponent().getPackageName());
+ t.key.intent.getComponent().getPackageName());
}
}
}
if (!mCancelled) {
// Notify that the task data has changed
+ final Drawable newIcon = loadIcon;
+ final Bitmap newThumbnail = loadThumbnail;
mMainThreadHandler.post(new Runnable() {
@Override
public void run() {
- t.notifyTaskDataChanged();
+ t.notifyTaskDataLoaded(newThumbnail, newIcon);
}
});
}
@@ -200,7 +210,9 @@ class TaskResourceLoader implements Runnable {
try {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
"[TaskResourceLoader|waitOnLoadQueue]");
+ mWaitingOnLoadQueue = true;
mLoadQueue.wait();
+ mWaitingOnLoadQueue = false;
} catch (InterruptedException ie) {
ie.printStackTrace();
}
@@ -211,14 +223,17 @@ class TaskResourceLoader implements Runnable {
}
}
-/** The drawable cache */
-class DrawableLruCache extends LruCache<Task, Drawable> {
+/**
+ * The drawable cache. 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.
+ */
+class DrawableLruCache extends LruCache<Task.TaskKey, Drawable> {
public DrawableLruCache(int cacheSize) {
super(cacheSize);
}
@Override
- protected int sizeOf(Task t, Drawable d) {
+ protected int sizeOf(Task.TaskKey t, Drawable d) {
// The cache size will be measured in kilobytes rather than number of items
// NOTE: this isn't actually correct, as the icon may be smaller
int maxBytes = (d.getIntrinsicWidth() * d.getIntrinsicHeight() * 4);
@@ -226,14 +241,17 @@ class DrawableLruCache extends LruCache<Task, Drawable> {
}
}
-/** The bitmap cache */
-class BitmapLruCache extends LruCache<Task, Bitmap> {
+/**
+ * The bitmap cache. 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.
+ */
+class BitmapLruCache extends LruCache<Task.TaskKey, Bitmap> {
public BitmapLruCache(int cacheSize) {
super(cacheSize);
}
@Override
- protected int sizeOf(Task t, Bitmap bitmap) {
+ protected int sizeOf(Task.TaskKey t, Bitmap bitmap) {
// The cache size will be measured in kilobytes rather than number of items
return bitmap.getAllocationByteCount() / 1024;
}
@@ -257,16 +275,18 @@ public class RecentsTaskLoader {
/** Private Constructor */
private RecentsTaskLoader(Context context) {
- // Calculate the cache sizes
+ // Calculate the cache sizes, we just use a reasonable number here similar to those
+ // suggested in the Android docs, 1/8th for the thumbnail cache and 1/32 of the max memory
+ // for icons.
int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
mMaxThumbnailCacheSize = maxMemory / 8;
mMaxIconCacheSize = mMaxThumbnailCacheSize / 4;
- int iconCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 :
+ int iconCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
mMaxIconCacheSize;
- int thumbnailCacheSize = Constants.DebugFlags.App.ForceDisableBackgroundCache ? 1 :
+ int thumbnailCacheSize = Constants.DebugFlags.App.DisableBackgroundCache ? 1 :
mMaxThumbnailCacheSize;
- Console.log(Constants.DebugFlags.App.EnableBackgroundTaskLoading,
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
"[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +
" iconCache: " + iconCacheSize);
@@ -351,36 +371,34 @@ public class RecentsTaskLoader {
ActivityInfo info = pm.getActivityInfo(t.baseIntent.getComponent(),
PackageManager.GET_META_DATA);
String title = info.loadLabel(pm).toString();
- Task task;
+ boolean isForemostTask = (i == (taskCount - 1));
+
// Preload the specified number of apps
- if (i >= (taskCount - preloadCount) ||
- !Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
+ if (i >= (taskCount - preloadCount)) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
"[RecentsTaskLoader|preloadTask]",
"i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
- task = new Task(t.persistentId, t.baseIntent, title, null, null);
+ Task task = new Task(t.persistentId, t.baseIntent, title);
- // Load the icon (if possible from the cache)
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- task.icon = mIconCache.get(task);
+ // Load the icon (if possible and not the foremost task, from the cache)
+ if (!isForemostTask) {
+ task.icon = mIconCache.get(task.key);
}
if (task.icon == null) {
task.icon = info.loadIcon(pm);
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- mIconCache.put(task, task.icon);
- }
+ mIconCache.put(task.key, task.icon);
}
- // Load the thumbnail (if possible from the cache)
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- task.thumbnail = mThumbnailCache.get(task);
+ // Load the thumbnail (if possible and not the foremost task, from the cache)
+ if (!isForemostTask) {
+ task.thumbnail = mThumbnailCache.get(task.key);
}
if (task.thumbnail == null) {
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
+ "[RecentsTaskLoader|loadingTaskThumbnail]");
task.thumbnail = am.getTaskTopThumbnail(t.id);
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- mThumbnailCache.put(task, task.thumbnail);
- }
+ mThumbnailCache.put(task.key, task.thumbnail);
}
// Create as many tasks a we want to multiply by
@@ -394,19 +412,9 @@ public class RecentsTaskLoader {
for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
Console.log(Constants.DebugFlags.App.TaskDataLoader,
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
- task = new Task(t.persistentId, t.baseIntent, title, null, null);
- stack.addTask(task);
+ stack.addTask(new Task(t.persistentId, t.baseIntent, title));
}
}
-
- /*
- if (stacks.containsKey(t.stackId)) {
- builder = stacks.get(t.stackId);
- } else {
- builder = new TaskStackBuilder();
- stacks.put(t.stackId, builder);
- }
- */
}
Console.log(Constants.DebugFlags.App.TimeSystemCalls,
"[RecentsTaskLoader|getAllTaskTopThumbnail]",
@@ -428,64 +436,59 @@ public class RecentsTaskLoader {
} catch (Exception e) {
e.printStackTrace();
}
+
+ // Start the task loader
mLoader.start(context);
+
return root;
}
/** Acquires the task resource data from the pool. */
public void loadTaskData(Task t) {
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- Drawable icon = mIconCache.get(t);
- Bitmap thumbnail = mThumbnailCache.get(t);
-
- Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
- t + " icon: " + icon + " thumbnail: " + thumbnail +
- " thumbnailCacheSize: " + mThumbnailCache.size());
-
- boolean requiresLoad = false;
- if (icon == null) {
- icon = mDefaultIcon;
- requiresLoad = true;
- }
- if (thumbnail == null) {
- thumbnail = mDefaultThumbnail;
- requiresLoad = true;
- }
- if (requiresLoad) {
- mLoadQueue.addTask(t);
- }
- t.notifyTaskLoaded(thumbnail, icon);
+ Drawable icon = mIconCache.get(t.key);
+ Bitmap thumbnail = mThumbnailCache.get(t.key);
+
+ Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|loadTask]",
+ t + " icon: " + icon + " thumbnail: " + thumbnail +
+ " thumbnailCacheSize: " + mThumbnailCache.size());
+
+ boolean requiresLoad = false;
+ if (icon == null) {
+ icon = mDefaultIcon;
+ requiresLoad = true;
+ }
+ if (thumbnail == null) {
+ thumbnail = mDefaultThumbnail;
+ requiresLoad = true;
}
+ if (requiresLoad) {
+ mLoadQueue.addTask(t);
+ }
+ t.notifyTaskDataLoaded(thumbnail, icon);
}
/** Releases the task resource data back into the pool. */
public void unloadTaskData(Task t) {
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- Console.log(Constants.DebugFlags.App.TaskDataLoader,
- "[RecentsTaskLoader|unloadTask]", t +
- " thumbnailCacheSize: " + mThumbnailCache.size());
- mLoadQueue.removeTask(t);
- t.notifyTaskUnloaded(mDefaultThumbnail, mDefaultIcon);
- } else {
- t.notifyTaskUnloaded(null, null);
- }
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
+ "[RecentsTaskLoader|unloadTask]", t +
+ " thumbnailCacheSize: " + mThumbnailCache.size());
+
+ mLoadQueue.removeTask(t);
+ t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
}
/** Completely removes the resource data from the pool. */
public void deleteTaskData(Task t) {
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- Console.log(Constants.DebugFlags.App.TaskDataLoader,
- "[RecentsTaskLoader|deleteTask]", t);
- mLoadQueue.removeTask(t);
- mThumbnailCache.remove(t);
- mIconCache.remove(t);
- t.notifyTaskUnloaded(mDefaultThumbnail, mDefaultIcon);
- } else {
- t.notifyTaskUnloaded(null, null);
- }
+ Console.log(Constants.DebugFlags.App.TaskDataLoader,
+ "[RecentsTaskLoader|deleteTask]", t);
+
+ mLoadQueue.removeTask(t);
+ mThumbnailCache.remove(t.key);
+ mIconCache.remove(t.key);
+ t.notifyTaskDataUnloaded(mDefaultThumbnail, mDefaultIcon);
}
- /** Stops the task loader */
+ /** Stops the task loader and clears all pending tasks */
void stopLoader() {
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stopLoader]");
mLoader.stop();
@@ -496,46 +499,30 @@ public class RecentsTaskLoader {
Console.log(Constants.DebugFlags.App.Memory, "[RecentsTaskLoader|onTrimMemory]",
Console.trimMemoryLevelToString(level));
- if (Constants.DebugFlags.App.EnableBackgroundTaskLoading) {
- // If we are hidden, then we should unload each of the task keys
- if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
- Console.log(Constants.DebugFlags.App.Memory, "[RecentsTaskLoader|unloadTasks]"
- );
- // Unload each of the keys in the thumbnail cache
- Map<Task, Bitmap> thumbnailCache = mThumbnailCache.snapshot();
- for (Task t : thumbnailCache.keySet()) {
- unloadTaskData(t);
- }
- // As well as the keys in the icon cache
- Map<Task, Drawable> iconCache = mIconCache.snapshot();
- for (Task t : iconCache.keySet()) {
- unloadTaskData(t);
- }
- }
-
- switch (level) {
- case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
- case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
- case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
- // We are leaving recents, so trim the data a bit
- mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
- mIconCache.trimToSize(mMaxIconCacheSize / 2);
- break;
- case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
- case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
- // We are going to be low on memory
- mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
- mIconCache.trimToSize(mMaxIconCacheSize / 4);
- break;
- case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
- case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
- // We are low on memory, so release everything
- mThumbnailCache.evictAll();
- mIconCache.evictAll();
- break;
- default:
- break;
- }
+ switch (level) {
+ case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
+ // Do nothing
+ break;
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE:
+ case ComponentCallbacks2.TRIM_MEMORY_BACKGROUND:
+ // We are leaving recents, so trim the data a bit
+ mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 2);
+ mIconCache.trimToSize(mMaxIconCacheSize / 2);
+ break;
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW:
+ case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+ // We are going to be low on memory
+ mThumbnailCache.trimToSize(mMaxThumbnailCacheSize / 4);
+ mIconCache.trimToSize(mMaxIconCacheSize / 4);
+ break;
+ case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL:
+ case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+ // We are low on memory, so release everything
+ mThumbnailCache.evictAll();
+ mIconCache.evictAll();
+ break;
+ default:
+ break;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
index 5893abc..1dd1be6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNode.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents.model;
import android.content.Context;
+import android.graphics.Rect;
import java.util.ArrayList;
@@ -26,6 +27,14 @@ import java.util.ArrayList;
* stacks should be placed.
*/
public class SpaceNode {
+ /* BSP node callbacks */
+ public interface SpaceNodeCallbacks {
+ /** Notifies when a node is added */
+ public void onSpaceNodeAdded(SpaceNode node);
+ /** Notifies when a node is measured */
+ public void onSpaceNodeMeasured(SpaceNode node, Rect rect);
+ }
+
Context mContext;
SpaceNode mStartNode;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNodeCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNodeCallbacks.java
deleted file mode 100644
index 31b02e7..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/SpaceNodeCallbacks.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.recents.model;
-
-import android.graphics.Rect;
-
-
-/* BSP node callbacks */
-public interface SpaceNodeCallbacks {
- /** Notifies when a node is added */
- public void onSpaceNodeAdded(SpaceNode node);
- /** Notifies when a node is measured */
- public void onSpaceNodeMeasured(SpaceNode node, Rect rect);
-} \ No newline at end of file
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 378984c..0c3c528 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java
@@ -26,17 +26,53 @@ import com.android.systemui.recents.Constants;
* A task represents the top most task in the system's task stack.
*/
public class Task {
- public final int id;
- public final Intent intent;
+ /* Task callbacks */
+ public interface TaskCallbacks {
+ /* Notifies when a task has been bound */
+ public void onTaskDataLoaded();
+ /* Notifies when a task has been unbound */
+ public void onTaskDataUnloaded();
+ }
+
+ /* The Task Key represents the unique primary key for the task */
+ public static class TaskKey {
+ public final int id;
+ public final Intent intent;
+
+ public TaskKey(int id, Intent intent) {
+ this.id = id;
+ this.intent = intent;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return hashCode() == o.hashCode();
+ }
+
+ @Override
+ public int hashCode() {
+ return id;
+ }
+
+ @Override
+ public String toString() {
+ return "Task.Key: " + id + ", " + intent.getComponent().getPackageName();
+ }
+ }
+
+ public TaskKey key;
public String title;
public Drawable icon;
public Bitmap thumbnail;
TaskCallbacks mCb;
+ public Task(int id, Intent intent, String activityTitle) {
+ this(id, intent, activityTitle, null, null);
+ }
+
public Task(int id, Intent intent, String activityTitle, Drawable icon, Bitmap thumbnail) {
- this.id = id;
- this.intent = intent;
+ this.key = new TaskKey(id, intent);
this.title = activityTitle;
this.icon = icon;
this.thumbnail = thumbnail;
@@ -47,28 +83,21 @@ public class Task {
mCb = cb;
}
- /** Notifies the callback listeners that this task's data has changed */
- public void notifyTaskDataChanged() {
- if (mCb != null) {
- mCb.onTaskDataChanged(this);
- }
- }
-
/** Notifies the callback listeners that this task has been loaded */
- public void notifyTaskLoaded(Bitmap thumbnail, Drawable icon) {
+ public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable icon) {
this.icon = icon;
this.thumbnail = thumbnail;
if (mCb != null) {
- mCb.onTaskBound();
+ mCb.onTaskDataLoaded();
}
}
/** Notifies the callback listeners that this task has been unloaded */
- public void notifyTaskUnloaded(Bitmap defaultThumbnail, Drawable defaultIcon) {
+ public void notifyTaskDataUnloaded(Bitmap defaultThumbnail, Drawable defaultIcon) {
icon = defaultIcon;
thumbnail = defaultThumbnail;
if (mCb != null) {
- mCb.onTaskUnbound();
+ mCb.onTaskDataUnloaded();
}
}
@@ -83,12 +112,11 @@ public class Task {
// Otherwise, check that the id and intent match (the other fields can be asynchronously
// loaded and is unsuitable to testing the identity of this Task)
Task t = (Task) o;
- return (id == t.id) &&
- (intent.equals(t.intent));
+ return key.equals(t.key);
}
@Override
public String toString() {
- return "Task: " + intent.getComponent().getPackageName() + " [" + super.toString() + "]";
+ return "Task: " + key.intent.getComponent().getPackageName() + " [" + super.toString() + "]";
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java
deleted file mode 100644
index 712580d..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskCallbacks.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.recents.model;
-
-/* Task callbacks */
-public interface TaskCallbacks {
- /* Notifies when a task's data has been updated */
- public void onTaskDataChanged(Task task);
- /* Notifies when a task has been bound */
- public void onTaskBound();
- /* Notifies when a task has been unbound */
- public void onTaskUnbound();
-} \ No newline at end of file
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 a5aa387..f2f89ae 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -119,6 +119,18 @@ class FilteredTaskList {
* The task stack contains a list of multiple tasks.
*/
public class TaskStack {
+ /* Task stack callbacks */
+ public interface TaskStackCallbacks {
+ /* Notifies when a task has been added to the stack */
+ public void onStackTaskAdded(TaskStack stack, Task t);
+ /* Notifies when a task has been removed from the stack */
+ public void onStackTaskRemoved(TaskStack stack, Task t);
+ /** Notifies when the stack was filtered */
+ public void onStackFiltered(TaskStack stack);
+ /** Notifies when the stack was un-filtered */
+ public void onStackUnfiltered(TaskStack stack);
+ }
+
Context mContext;
FilteredTaskList mTaskList = new FilteredTaskList();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStackCallbacks.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStackCallbacks.java
deleted file mode 100644
index 4bec655..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStackCallbacks.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.recents.model;
-
-/* Task stack callbacks */
-public interface TaskStackCallbacks {
- /* Notifies when a task has been added to the stack */
- public void onStackTaskAdded(TaskStack stack, Task t);
- /* Notifies when a task has been removed from the stack */
- public void onStackTaskRemoved(TaskStack stack, Task t);
- /** Notifies when the stack was filtered */
- public void onStackFiltered(TaskStack stack);
- /** Notifies when the stack was un-filtered */
- public void onStackUnfiltered(TaskStack stack);
-} \ No newline at end of file
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 c92041c..32110cf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -39,7 +39,7 @@ import java.util.ArrayList;
* This view is the the top level layout that contains TaskStacks (which are laid out according
* to their SpaceNode bounds.
*/
-public class RecentsView extends FrameLayout implements TaskStackViewCallbacks {
+public class RecentsView extends FrameLayout implements TaskStackView.TaskStackViewCallbacks {
// The space partitioning root of this container
SpaceNode mBSP;
@@ -52,8 +52,7 @@ public class RecentsView extends FrameLayout implements TaskStackViewCallbacks {
public void setBSP(SpaceNode n) {
mBSP = n;
- // XXX: We shouldn't be recereating new stacks every time, but for now, that is OK
- // Add all the stacks for this partition
+ // Create and add all the stacks for this partition of space.
removeAllViews();
ArrayList<TaskStack> stacks = mBSP.getStacks();
for (TaskStack stack : stacks) {
@@ -206,7 +205,7 @@ public class RecentsView extends FrameLayout implements TaskStackViewCallbacks {
}
// Launch the activity with the desired animation
- Intent i = new Intent(task.intent);
+ Intent i = new Intent(task.key.intent);
i.setFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
| Intent.FLAG_ACTIVITY_TASK_ON_HOME
| Intent.FLAG_ACTIVITY_NEW_TASK);
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 7753d69..a3ed535 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -33,7 +33,6 @@ import android.view.ViewConfiguration;
import android.view.ViewParent;
import android.widget.FrameLayout;
import android.widget.OverScroller;
-import android.widget.Toast;
import com.android.systemui.recents.Console;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
@@ -41,18 +40,20 @@ import com.android.systemui.recents.RecentsTaskLoader;
import com.android.systemui.recents.Utilities;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
-import com.android.systemui.recents.model.TaskStackCallbacks;
import java.util.ArrayList;
-/** The TaskView callbacks */
-interface TaskStackViewCallbacks {
- public void onTaskLaunched(TaskStackView stackView, TaskView tv, TaskStack stack, Task t);
-}
/* The visual representation of a task stack view */
-public class TaskStackView extends FrameLayout implements TaskStackCallbacks, TaskViewCallbacks,
- ViewPoolConsumer<TaskView, Task>, View.OnClickListener {
+public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCallbacks,
+ TaskView.TaskViewCallbacks, ViewPool.ViewPoolConsumer<TaskView, Task>,
+ View.OnClickListener {
+
+ /** The TaskView callbacks */
+ interface TaskStackViewCallbacks {
+ public void onTaskLaunched(TaskStackView stackView, TaskView tv, TaskStack stack, Task t);
+ }
+
TaskStack mStack;
TaskStackViewTouchHandler mTouchHandler;
TaskStackViewCallbacks mCb;
@@ -348,7 +349,8 @@ public class TaskStackView extends FrameLayout implements TaskStackCallbacks, Ta
tv.disableHwLayers();
}
} else if (mHwLayersRefCount < 0) {
- throw new RuntimeException("Invalid hw layers ref count");
+ new Throwable("Invalid hw layers ref count").printStackTrace();
+ Console.logError(getContext(), "Invalid HW layers ref count");
}
}
@@ -598,7 +600,7 @@ public class TaskStackView extends FrameLayout implements TaskStackCallbacks, Ta
// Setup and attach the view to the window
Task task = prepareData;
// We try and rebind the task (this MUST be done before the task filled)
- tv.bindToTask(task, this);
+ tv.onTaskBound(task);
// Request that this tasks's data be filled
RecentsTaskLoader loader = RecentsTaskLoader.getInstance();
loader.loadTaskData(task);
@@ -619,7 +621,10 @@ public class TaskStackView extends FrameLayout implements TaskStackCallbacks, Ta
"" + insertIndex);
if (isNewView) {
addView(tv, insertIndex);
+
+ // Set the callbacks and listeners for this new view
tv.setOnClickListener(this);
+ tv.setCallbacks(this);
} else {
attachViewToParent(tv, insertIndex, tv.getLayoutParams());
}
@@ -649,7 +654,7 @@ public class TaskStackView extends FrameLayout implements TaskStackCallbacks, Ta
mStack.filterTasks(tv.getTask());
}
} else {
- Toast.makeText(getContext(), "Task Filtering TBD", Toast.LENGTH_SHORT).show();
+ Console.logError(getContext(), "Task Filtering TBD");
}
}
@@ -995,7 +1000,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
final ActivityManager am = (ActivityManager)
activity.getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
- am.removeTask(tv.getTask().id,
+ am.removeTask(tv.getTask().key.id,
ActivityManager.REMOVE_TASK_KILL_PROCESS);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 9ef74ca..ace2428 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -39,13 +39,7 @@ import com.android.systemui.recents.Console;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.model.Task;
-import com.android.systemui.recents.model.TaskCallbacks;
-/** The TaskView callbacks */
-interface TaskViewCallbacks {
- public void onTaskIconClicked(TaskView tv);
- // public void onTaskViewReboundToTask(TaskView tv, Task t);
-}
/** The task thumbnail view */
class TaskThumbnailView extends ImageView {
@@ -66,7 +60,7 @@ class TaskThumbnailView extends ImageView {
// Update the bar color
if (Constants.Values.TaskView.DrawColoredTaskBars) {
int[] colors = {0xFFCC0C39, 0xFFE6781E, 0xFFC8CF02, 0xFF1693A7};
- mBarColor = colors[mTask.intent.getComponent().getPackageName().length() % colors.length];
+ mBarColor = colors[mTask.key.intent.getComponent().getPackageName().length() % colors.length];
}
setImageBitmap(t.thumbnail);
@@ -213,7 +207,13 @@ class TaskIconView extends ImageView {
}
/* A task view */
-public class TaskView extends FrameLayout implements View.OnClickListener, TaskCallbacks {
+public class TaskView extends FrameLayout implements View.OnClickListener, Task.TaskCallbacks {
+ /** The TaskView callbacks */
+ interface TaskViewCallbacks {
+ public void onTaskIconClicked(TaskView tv);
+ // public void onTaskViewReboundToTask(TaskView tv, Task t);
+ }
+
Task mTask;
TaskThumbnailView mThumbnailView;
TaskIconView mIconView;
@@ -247,26 +247,11 @@ public class TaskView extends FrameLayout implements View.OnClickListener, TaskC
((LayoutParams) mIconView.getLayoutParams()).rightMargin = offset;
}
- /** Set the task and callback */
- void bindToTask(Task t, TaskViewCallbacks cb) {
- mTask = t;
- mTask.setCallbacks(this);
+ /** Set callback */
+ void setCallbacks(TaskViewCallbacks cb) {
mCb = cb;
}
- /** Actually synchronizes the model data into the views */
- private void syncToTask() {
- mThumbnailView.rebindToTask(mTask, false);
- mIconView.rebindToTask(mTask, false);
- }
-
- /** Unset the task and callback */
- private void unbindFromTask() {
- mTask.setCallbacks(null);
- mThumbnailView.unbindFromTask();
- mIconView.unbindFromTask();
- }
-
/** Gets the task */
Task getTask() {
return mTask;
@@ -367,26 +352,25 @@ public class TaskView extends FrameLayout implements View.OnClickListener, TaskC
/**** TaskCallbacks Implementation ****/
- @Override
- public void onTaskDataChanged(Task task) {
- Console.log(Constants.DebugFlags.App.EnableBackgroundTaskLoading,
- "[TaskView|onTaskDataChanged]", task);
-
- // Only update this task view if the changed task is the same as the task for this view
- if (mTask == task) {
- mThumbnailView.rebindToTask(mTask, true);
- mIconView.rebindToTask(mTask, true);
- }
+ /** Binds this task view to the task */
+ public void onTaskBound(Task t) {
+ mTask = t;
+ mTask.setCallbacks(this);
}
@Override
- public void onTaskBound() {
- syncToTask();
+ public void onTaskDataLoaded() {
+ // Bind each of the views to the new task data
+ mThumbnailView.rebindToTask(mTask, false);
+ mIconView.rebindToTask(mTask, false);
}
@Override
- public void onTaskUnbound() {
- unbindFromTask();
+ public void onTaskDataUnloaded() {
+ // Unbind each of the views from the task data and remove the task callback
+ mTask.setCallbacks(null);
+ mThumbnailView.unbindFromTask();
+ mIconView.unbindFromTask();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
index f7d7095..af0094e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPool.java
@@ -24,6 +24,15 @@ import java.util.LinkedList;
/* A view pool to manage more views than we can visibly handle */
public class ViewPool<V, T> {
+
+ /* An interface to the consumer of a view pool */
+ public interface ViewPoolConsumer<V, T> {
+ public V createView(Context context);
+ public void prepareViewToEnterPool(V v);
+ public void prepareViewToLeavePool(V v, T prepareData, boolean isNewView);
+ public boolean hasPreferredData(V v, T preferredData);
+ }
+
Context mContext;
ViewPoolConsumer<V, T> mViewCreator;
LinkedList<V> mPool = new LinkedList<V>();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPoolConsumer.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewPoolConsumer.java
deleted file mode 100644
index 50f45bf..0000000
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewPoolConsumer.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.recents.views;
-
-import android.content.Context;
-
-
-/* An interface to the consumer of a view pool */
-public interface ViewPoolConsumer<V, T> {
- public V createView(Context context);
- public void prepareViewToEnterPool(V v);
- public void prepareViewToLeavePool(V v, T prepareData, boolean isNewView);
- public boolean hasPreferredData(V v, T preferredData);
-}