Merge "Adding system service proxy to help test UI/performance."
This commit is contained in:
@@ -23,35 +23,26 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
import android.content.pm.ActivityInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Messenger;
|
import android.os.Messenger;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemProperties;
|
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import com.android.systemui.R;
|
import com.android.systemui.R;
|
||||||
import com.android.systemui.RecentsComponent;
|
|
||||||
import com.android.systemui.SystemUI;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -113,6 +104,7 @@ public class AlternateRecentsComponent {
|
|||||||
final static String sRecentsService = "com.android.systemui.recents.RecentsService";
|
final static String sRecentsService = "com.android.systemui.recents.RecentsService";
|
||||||
|
|
||||||
Context mContext;
|
Context mContext;
|
||||||
|
SystemServicesProxy mSystemServicesProxy;
|
||||||
|
|
||||||
// Recents service binding
|
// Recents service binding
|
||||||
Messenger mService = null;
|
Messenger mService = null;
|
||||||
@@ -127,6 +119,7 @@ public class AlternateRecentsComponent {
|
|||||||
|
|
||||||
public AlternateRecentsComponent(Context context) {
|
public AlternateRecentsComponent(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
|
mSystemServicesProxy = new SystemServicesProxy(context);
|
||||||
mMessenger = new Messenger(new RecentsMessageHandler());
|
mMessenger = new Messenger(new RecentsMessageHandler());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,17 +212,16 @@ public class AlternateRecentsComponent {
|
|||||||
|
|
||||||
/** Loads the first task thumbnail */
|
/** Loads the first task thumbnail */
|
||||||
Bitmap loadFirstTaskThumbnail() {
|
Bitmap loadFirstTaskThumbnail() {
|
||||||
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
SystemServicesProxy ssp = mSystemServicesProxy;
|
||||||
List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1,
|
List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(1,
|
||||||
ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES,
|
|
||||||
UserHandle.CURRENT.getIdentifier());
|
UserHandle.CURRENT.getIdentifier());
|
||||||
for (ActivityManager.RecentTaskInfo t : tasks) {
|
for (ActivityManager.RecentTaskInfo t : tasks) {
|
||||||
// Skip tasks in the home stack
|
// Skip tasks in the home stack
|
||||||
if (am.isInHomeStack(t.persistentId)) {
|
if (ssp.isInHomeStack(t.persistentId)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap thumbnail = am.getTaskTopThumbnail(t.persistentId);
|
Bitmap thumbnail = ssp.getTaskThumbnail(t.persistentId);
|
||||||
return thumbnail;
|
return thumbnail;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -237,13 +229,12 @@ public class AlternateRecentsComponent {
|
|||||||
|
|
||||||
/** Returns whether there is a first task */
|
/** Returns whether there is a first task */
|
||||||
boolean hasFirstTask() {
|
boolean hasFirstTask() {
|
||||||
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
SystemServicesProxy ssp = mSystemServicesProxy;
|
||||||
List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(1,
|
List<ActivityManager.RecentTaskInfo> tasks = ssp.getRecentTasks(1,
|
||||||
ActivityManager.RECENT_IGNORE_UNAVAILABLE | ActivityManager.RECENT_INCLUDE_PROFILES,
|
|
||||||
UserHandle.CURRENT.getIdentifier());
|
UserHandle.CURRENT.getIdentifier());
|
||||||
for (ActivityManager.RecentTaskInfo t : tasks) {
|
for (ActivityManager.RecentTaskInfo t : tasks) {
|
||||||
// Skip tasks in the home stack
|
// Skip tasks in the home stack
|
||||||
if (am.isInHomeStack(t.persistentId)) {
|
if (ssp.isInHomeStack(t.persistentId)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,8 +285,8 @@ public class AlternateRecentsComponent {
|
|||||||
|
|
||||||
// If Recents is the front most activity, then we should just communicate with it directly
|
// If Recents is the front most activity, then we should just communicate with it directly
|
||||||
// to launch the first task or dismiss itself
|
// to launch the first task or dismiss itself
|
||||||
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
SystemServicesProxy ssp = mSystemServicesProxy;
|
||||||
List<ActivityManager.RunningTaskInfo> tasks = am.getRunningTasks(1);
|
List<ActivityManager.RunningTaskInfo> tasks = ssp.getRunningTasks(1);
|
||||||
if (!tasks.isEmpty()) {
|
if (!tasks.isEmpty()) {
|
||||||
ComponentName topActivity = tasks.get(0).topActivity;
|
ComponentName topActivity = tasks.get(0).topActivity;
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,12 @@ public class Constants {
|
|||||||
public static final boolean EnableToggleNewRecentsActivity = false;
|
public static final boolean EnableToggleNewRecentsActivity = false;
|
||||||
// This disables the bitmap and icon caches to
|
// This disables the bitmap and icon caches to
|
||||||
public static final boolean DisableBackgroundCache = false;
|
public static final boolean DisableBackgroundCache = false;
|
||||||
|
// For debugging, this enables us to create mock recents tasks
|
||||||
|
public static final boolean EnableSystemServicesProxy = false;
|
||||||
|
// For debugging, this defines the number of mock recents packages to create
|
||||||
|
public static final int SystemServicesProxyMockPackageCount = 12;
|
||||||
|
// For debugging, this defines the number of mock recents tasks to create
|
||||||
|
public static final int SystemServicesProxyMockTaskCount = 75;
|
||||||
|
|
||||||
// Timing certain paths
|
// Timing certain paths
|
||||||
public static final String TimeRecentsStartupKey = "startup";
|
public static final String TimeRecentsStartupKey = "startup";
|
||||||
@@ -73,8 +79,6 @@ public class Constants {
|
|||||||
public static class RecentsTaskLoader {
|
public static class RecentsTaskLoader {
|
||||||
// XXX: This should be calculated on the first load
|
// XXX: This should be calculated on the first load
|
||||||
public static final int PreloadFirstTasksCount = 5;
|
public static final int PreloadFirstTasksCount = 5;
|
||||||
// For debugging, this allows us to multiply the number of cards for each task
|
|
||||||
public static final int TaskEntryMultiplier = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TaskStackView {
|
public static class TaskStackView {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.SystemService;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import android.app.ActivityManager;
|
|||||||
import android.content.ComponentCallbacks2;
|
import android.content.ComponentCallbacks2;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.ActivityInfo;
|
import android.content.pm.ActivityInfo;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
@@ -109,6 +108,7 @@ class TaskResourceLoader implements Runnable {
|
|||||||
Handler mLoadThreadHandler;
|
Handler mLoadThreadHandler;
|
||||||
Handler mMainThreadHandler;
|
Handler mMainThreadHandler;
|
||||||
|
|
||||||
|
SystemServicesProxy mSystemServicesProxy;
|
||||||
TaskResourceLoadQueue mLoadQueue;
|
TaskResourceLoadQueue mLoadQueue;
|
||||||
DrawableLruCache mIconCache;
|
DrawableLruCache mIconCache;
|
||||||
BitmapLruCache mThumbnailCache;
|
BitmapLruCache mThumbnailCache;
|
||||||
@@ -135,6 +135,7 @@ class TaskResourceLoader implements Runnable {
|
|||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|start]");
|
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|start]");
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mCancelled = false;
|
mCancelled = false;
|
||||||
|
mSystemServicesProxy = new SystemServicesProxy(context);
|
||||||
// Notify the load thread to start loading
|
// Notify the load thread to start loading
|
||||||
synchronized(mLoadThread) {
|
synchronized(mLoadThread) {
|
||||||
mLoadThread.notifyAll();
|
mLoadThread.notifyAll();
|
||||||
@@ -146,6 +147,7 @@ class TaskResourceLoader implements Runnable {
|
|||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|stop]");
|
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[TaskResourceLoader|stop]");
|
||||||
// Mark as cancelled for the thread to pick up
|
// Mark as cancelled for the thread to pick up
|
||||||
mCancelled = true;
|
mCancelled = true;
|
||||||
|
mSystemServicesProxy = null;
|
||||||
// If we are waiting for the load queue for more tasks, then we can just reset the
|
// If we are waiting for the load queue for more tasks, then we can just reset the
|
||||||
// Context now, since nothing is using it
|
// Context now, since nothing is using it
|
||||||
if (mWaitingOnLoadQueue) {
|
if (mWaitingOnLoadQueue) {
|
||||||
@@ -175,66 +177,60 @@ class TaskResourceLoader implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
SystemServicesProxy ssp = mSystemServicesProxy;
|
||||||
|
|
||||||
// Load the next item from the queue
|
// Load the next item from the queue
|
||||||
Pair<Task, Boolean> nextTaskData = mLoadQueue.nextTask();
|
Pair<Task, Boolean> nextTaskData = mLoadQueue.nextTask();
|
||||||
final Task t = nextTaskData.first;
|
final Task t = nextTaskData.first;
|
||||||
final boolean forceLoadTask = nextTaskData.second;
|
final boolean forceLoadTask = nextTaskData.second;
|
||||||
if (t != null) {
|
if (t != null) {
|
||||||
try {
|
Drawable loadIcon = mIconCache.get(t.key);
|
||||||
Drawable loadIcon = mIconCache.get(t.key);
|
Bitmap loadThumbnail = mThumbnailCache.get(t.key);
|
||||||
Bitmap loadThumbnail = mThumbnailCache.get(t.key);
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
" [TaskResourceLoader|load]",
|
||||||
" [TaskResourceLoader|load]",
|
t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail +
|
||||||
t + " icon: " + loadIcon + " thumbnail: " + loadThumbnail +
|
" forceLoad: " + forceLoadTask);
|
||||||
" forceLoad: " + forceLoadTask);
|
// Load the icon
|
||||||
// Load the icon
|
if (loadIcon == null || forceLoadTask) {
|
||||||
if (loadIcon == null || forceLoadTask) {
|
ActivityInfo info = ssp.getActivityInfo(t.key.baseIntent.getComponent());
|
||||||
PackageManager pm = mContext.getPackageManager();
|
Drawable icon = ssp.getActivityIcon(info);
|
||||||
ActivityInfo info = pm.getActivityInfo(t.key.baseIntent.getComponent(),
|
|
||||||
PackageManager.GET_META_DATA);
|
|
||||||
Drawable icon = info.loadIcon(pm);
|
|
||||||
if (!mCancelled) {
|
|
||||||
if (icon != null) {
|
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
|
||||||
" [TaskResourceLoader|loadIcon]",
|
|
||||||
icon);
|
|
||||||
loadIcon = icon;
|
|
||||||
mIconCache.put(t.key, icon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Load the thumbnail
|
|
||||||
if (loadThumbnail == null || forceLoadTask) {
|
|
||||||
ActivityManager am = (ActivityManager)
|
|
||||||
mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
|
||||||
Bitmap thumbnail = am.getTaskTopThumbnail(t.key.id);
|
|
||||||
if (!mCancelled) {
|
|
||||||
if (thumbnail != null) {
|
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
|
||||||
" [TaskResourceLoader|loadThumbnail]",
|
|
||||||
thumbnail);
|
|
||||||
loadThumbnail = thumbnail;
|
|
||||||
mThumbnailCache.put(t.key, thumbnail);
|
|
||||||
} else {
|
|
||||||
Console.logError(mContext,
|
|
||||||
"Failed to load task top thumbnail for: " +
|
|
||||||
t.key.baseIntent.getComponent().getPackageName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mCancelled) {
|
if (!mCancelled) {
|
||||||
// Notify that the task data has changed
|
if (icon != null) {
|
||||||
final Drawable newIcon = loadIcon;
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
final Bitmap newThumbnail = loadThumbnail;
|
" [TaskResourceLoader|loadIcon]",
|
||||||
mMainThreadHandler.post(new Runnable() {
|
icon);
|
||||||
@Override
|
loadIcon = icon;
|
||||||
public void run() {
|
mIconCache.put(t.key, icon);
|
||||||
t.notifyTaskDataLoaded(newThumbnail, newIcon, forceLoadTask);
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (PackageManager.NameNotFoundException ne) {
|
}
|
||||||
ne.printStackTrace();
|
// Load the thumbnail
|
||||||
|
if (loadThumbnail == null || forceLoadTask) {
|
||||||
|
Bitmap thumbnail = ssp.getTaskThumbnail(t.key.id);
|
||||||
|
if (!mCancelled) {
|
||||||
|
if (thumbnail != null) {
|
||||||
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
|
" [TaskResourceLoader|loadThumbnail]",
|
||||||
|
thumbnail);
|
||||||
|
loadThumbnail = thumbnail;
|
||||||
|
mThumbnailCache.put(t.key, thumbnail);
|
||||||
|
} else {
|
||||||
|
Console.logError(mContext,
|
||||||
|
"Failed to load task top thumbnail for: " +
|
||||||
|
t.key.baseIntent.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.notifyTaskDataLoaded(newThumbnail, newIcon, forceLoadTask);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,6 +292,7 @@ class BitmapLruCache extends LruCache<Task.TaskKey, Bitmap> {
|
|||||||
public class RecentsTaskLoader {
|
public class RecentsTaskLoader {
|
||||||
static RecentsTaskLoader sInstance;
|
static RecentsTaskLoader sInstance;
|
||||||
|
|
||||||
|
SystemServicesProxy mSystemServicesProxy;
|
||||||
DrawableLruCache mIconCache;
|
DrawableLruCache mIconCache;
|
||||||
BitmapLruCache mThumbnailCache;
|
BitmapLruCache mThumbnailCache;
|
||||||
TaskResourceLoadQueue mLoadQueue;
|
TaskResourceLoadQueue mLoadQueue;
|
||||||
@@ -324,7 +321,8 @@ public class RecentsTaskLoader {
|
|||||||
"[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +
|
"[RecentsTaskLoader|init]", "thumbnailCache: " + thumbnailCacheSize +
|
||||||
" iconCache: " + iconCacheSize);
|
" iconCache: " + iconCacheSize);
|
||||||
|
|
||||||
// Initialize the cache and loaders
|
// Initialize the proxy, cache and loaders
|
||||||
|
mSystemServicesProxy = new SystemServicesProxy(context);
|
||||||
mLoadQueue = new TaskResourceLoadQueue();
|
mLoadQueue = new TaskResourceLoadQueue();
|
||||||
mIconCache = new DrawableLruCache(iconCacheSize);
|
mIconCache = new DrawableLruCache(iconCacheSize);
|
||||||
mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
|
mThumbnailCache = new BitmapLruCache(thumbnailCacheSize);
|
||||||
@@ -358,6 +356,11 @@ public class RecentsTaskLoader {
|
|||||||
return sInstance;
|
return sInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the system services proxy */
|
||||||
|
public SystemServicesProxy getSystemServicesProxy() {
|
||||||
|
return mSystemServicesProxy;
|
||||||
|
}
|
||||||
|
|
||||||
/** Reload the set of recent tasks */
|
/** Reload the set of recent tasks */
|
||||||
SpaceNode reload(Context context, int preloadCount) {
|
SpaceNode reload(Context context, int preloadCount) {
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
|
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|reload]");
|
||||||
@@ -367,141 +370,129 @@ public class RecentsTaskLoader {
|
|||||||
SpaceNode root = new SpaceNode(context);
|
SpaceNode root = new SpaceNode(context);
|
||||||
root.setStack(stack);
|
root.setStack(stack);
|
||||||
|
|
||||||
try {
|
long t1 = System.currentTimeMillis();
|
||||||
long t1 = System.currentTimeMillis();
|
|
||||||
|
|
||||||
PackageManager pm = context.getPackageManager();
|
// Get the recent tasks
|
||||||
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
SystemServicesProxy ssp = mSystemServicesProxy;
|
||||||
|
List<ActivityManager.RecentTaskInfo> tasks =
|
||||||
|
ssp.getRecentTasks(25, UserHandle.CURRENT.getIdentifier());
|
||||||
|
Collections.reverse(tasks);
|
||||||
|
Console.log(Constants.DebugFlags.App.TimeSystemCalls,
|
||||||
|
"[RecentsTaskLoader|getRecentTasks]",
|
||||||
|
"" + (System.currentTimeMillis() - t1) + "ms");
|
||||||
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
|
"[RecentsTaskLoader|tasks]", "" + tasks.size());
|
||||||
|
|
||||||
// Get the recent tasks
|
// Remove home/recents tasks
|
||||||
List<ActivityManager.RecentTaskInfo> tasks = am.getRecentTasksForUser(25,
|
Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
|
||||||
ActivityManager.RECENT_IGNORE_UNAVAILABLE |
|
while (iter.hasNext()) {
|
||||||
ActivityManager.RECENT_INCLUDE_PROFILES, UserHandle.CURRENT.getIdentifier());
|
ActivityManager.RecentTaskInfo t = iter.next();
|
||||||
Collections.reverse(tasks);
|
|
||||||
Console.log(Constants.DebugFlags.App.TimeSystemCalls,
|
|
||||||
"[RecentsTaskLoader|getRecentTasks]",
|
|
||||||
"" + (System.currentTimeMillis() - t1) + "ms");
|
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
|
||||||
"[RecentsTaskLoader|tasks]", "" + tasks.size());
|
|
||||||
|
|
||||||
// Remove home/recents tasks
|
// Skip tasks in the home stack
|
||||||
Iterator<ActivityManager.RecentTaskInfo> iter = tasks.iterator();
|
if (ssp.isInHomeStack(t.persistentId)) {
|
||||||
while (iter.hasNext()) {
|
iter.remove();
|
||||||
ActivityManager.RecentTaskInfo t = iter.next();
|
continue;
|
||||||
|
|
||||||
// Skip tasks in the home stack
|
|
||||||
if (am.isInHomeStack(t.persistentId)) {
|
|
||||||
iter.remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// Skip tasks from this Recents package
|
|
||||||
if (t.baseIntent.getComponent().getPackageName().equals(context.getPackageName())) {
|
|
||||||
iter.remove();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// Skip tasks from this Recents package
|
||||||
|
if (t.baseIntent.getComponent().getPackageName().equals(context.getPackageName())) {
|
||||||
|
iter.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add each task to the task stack
|
// Add each task to the task stack
|
||||||
t1 = System.currentTimeMillis();
|
t1 = System.currentTimeMillis();
|
||||||
int taskCount = tasks.size();
|
int taskCount = tasks.size();
|
||||||
for (int i = 0; i < taskCount; i++) {
|
for (int i = 0; i < taskCount; i++) {
|
||||||
ActivityManager.RecentTaskInfo t = tasks.get(i);
|
ActivityManager.RecentTaskInfo t = tasks.get(i);
|
||||||
ActivityInfo info = pm.getActivityInfo(t.baseIntent.getComponent(),
|
ActivityInfo info = ssp.getActivityInfo(t.baseIntent.getComponent());
|
||||||
PackageManager.GET_META_DATA);
|
String title = ssp.getActivityLabel(info);
|
||||||
String title = info.loadLabel(pm).toString();
|
boolean isForemostTask = (i == (taskCount - 1));
|
||||||
boolean isForemostTask = (i == (taskCount - 1));
|
|
||||||
|
|
||||||
// Preload the specified number of apps
|
// Preload the specified number of apps
|
||||||
if (i >= (taskCount - preloadCount)) {
|
if (i >= (taskCount - preloadCount)) {
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
"[RecentsTaskLoader|preloadTask]",
|
"[RecentsTaskLoader|preloadTask]",
|
||||||
"i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
|
"i: " + i + " task: " + t.baseIntent.getComponent().getPackageName());
|
||||||
|
|
||||||
String label = (t.activityLabel == null ? title : t.activityLabel.toString());
|
String label = (t.activityLabel == null ? title : t.activityLabel.toString());
|
||||||
BitmapDrawable bd = null;
|
BitmapDrawable bd = null;
|
||||||
if (t.activityIcon != null) {
|
if (t.activityIcon != null) {
|
||||||
bd = new BitmapDrawable(res, t.activityIcon);
|
bd = new BitmapDrawable(res, t.activityIcon);
|
||||||
}
|
}
|
||||||
Task task = new Task(t.persistentId, (t.id > -1), t.baseIntent, label, bd);
|
Task task = new Task(t.persistentId, (t.id > -1), t.baseIntent, label, bd);
|
||||||
|
|
||||||
// Load the icon (if possible and not the foremost task, from the cache)
|
// Load the icon (if possible and not the foremost task, from the cache)
|
||||||
if (task.icon != null) {
|
if (task.icon != null) {
|
||||||
mIconCache.put(task.key, task.icon);
|
mIconCache.put(task.key, task.icon);
|
||||||
} else {
|
} else {
|
||||||
if (!isForemostTask) {
|
|
||||||
task.icon = mIconCache.get(task.key);
|
|
||||||
if (task.icon != null) {
|
|
||||||
// Even though we get things from the cache, we should update them
|
|
||||||
// if they've changed in the bg
|
|
||||||
tasksToForceLoad.add(task);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (task.icon == null) {
|
|
||||||
task.icon = info.loadIcon(pm);
|
|
||||||
if (task.icon != null) {
|
|
||||||
mIconCache.put(task.key, task.icon);
|
|
||||||
} else {
|
|
||||||
task.icon = mDefaultIcon;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load the thumbnail (if possible and not the foremost task, from the cache)
|
|
||||||
if (!isForemostTask) {
|
if (!isForemostTask) {
|
||||||
task.thumbnail = mThumbnailCache.get(task.key);
|
task.icon = mIconCache.get(task.key);
|
||||||
if (task.thumbnail != null) {
|
if (task.icon != null) {
|
||||||
// Even though we get things from the cache, we should update them if
|
// Even though we get things from the cache, we should update them
|
||||||
// they've changed in the bg
|
// if they've changed in the bg
|
||||||
tasksToForceLoad.add(task);
|
tasksToForceLoad.add(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (task.thumbnail == null) {
|
if (task.icon == null) {
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
task.icon = ssp.getActivityIcon(info);
|
||||||
"[RecentsTaskLoader|loadingTaskThumbnail]");
|
if (task.icon != null) {
|
||||||
task.thumbnail = am.getTaskTopThumbnail(t.id);
|
mIconCache.put(task.key, task.icon);
|
||||||
if (task.thumbnail != null) {
|
|
||||||
mThumbnailCache.put(task.key, task.thumbnail);
|
|
||||||
} else {
|
} else {
|
||||||
task.thumbnail = mDefaultThumbnail;
|
task.icon = mDefaultIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create as many tasks a we want to multiply by
|
// Load the thumbnail (if possible and not the foremost task, from the cache)
|
||||||
for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
|
if (!isForemostTask) {
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
task.thumbnail = mThumbnailCache.get(task.key);
|
||||||
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
|
if (task.thumbnail != null) {
|
||||||
stack.addTask(task);
|
// Even though we get things from the cache, we should update them if
|
||||||
}
|
// they've changed in the bg
|
||||||
} else {
|
tasksToForceLoad.add(task);
|
||||||
// Create as many tasks a we want to multiply by
|
|
||||||
for (int j = 0; j < Constants.Values.RecentsTaskLoader.TaskEntryMultiplier; j++) {
|
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
|
||||||
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
|
|
||||||
stack.addTask(new Task(t.persistentId, (t.id > -1), t.baseIntent, title,
|
|
||||||
null, null));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (task.thumbnail == null) {
|
||||||
Console.log(Constants.DebugFlags.App.TimeSystemCalls,
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
"[RecentsTaskLoader|getAllTaskTopThumbnail]",
|
"[RecentsTaskLoader|loadingTaskThumbnail]");
|
||||||
"" + (System.currentTimeMillis() - t1) + "ms");
|
task.thumbnail = ssp.getTaskThumbnail(task.key.id);
|
||||||
|
if (task.thumbnail != null) {
|
||||||
/*
|
mThumbnailCache.put(task.key, task.thumbnail);
|
||||||
// Get all the stacks
|
} else {
|
||||||
t1 = System.currentTimeMillis();
|
task.thumbnail = mDefaultThumbnail;
|
||||||
List<ActivityManager.StackInfo> stackInfos = ams.getAllStackInfos();
|
}
|
||||||
Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getAllStackInfos]", "" + (System.currentTimeMillis() - t1) + "ms");
|
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stacks]", "" + tasks.size());
|
|
||||||
for (ActivityManager.StackInfo s : stackInfos) {
|
|
||||||
Console.log(Constants.DebugFlags.App.TaskDataLoader, " [RecentsTaskLoader|stack]", s.toString());
|
|
||||||
if (stacks.containsKey(s.stackId)) {
|
|
||||||
stacks.get(s.stackId).setRect(s.bounds);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the task to the stack
|
||||||
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
|
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
|
||||||
|
stack.addTask(task);
|
||||||
|
} else {
|
||||||
|
// Add the task to the stack
|
||||||
|
Console.log(Constants.DebugFlags.App.TaskDataLoader,
|
||||||
|
" [RecentsTaskLoader|task]", t.baseIntent.getComponent().getPackageName());
|
||||||
|
stack.addTask(new Task(t.persistentId, (t.id > -1), t.baseIntent, title,
|
||||||
|
null, null));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
Console.log(Constants.DebugFlags.App.TimeSystemCalls,
|
||||||
|
"[RecentsTaskLoader|getAllTaskTopThumbnail]",
|
||||||
|
"" + (System.currentTimeMillis() - t1) + "ms");
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Get all the stacks
|
||||||
|
t1 = System.currentTimeMillis();
|
||||||
|
List<ActivityManager.StackInfo> stackInfos = ams.getAllStackInfos();
|
||||||
|
Console.log(Constants.DebugFlags.App.TimeSystemCalls, "[RecentsTaskLoader|getAllStackInfos]", "" + (System.currentTimeMillis() - t1) + "ms");
|
||||||
|
Console.log(Constants.DebugFlags.App.TaskDataLoader, "[RecentsTaskLoader|stacks]", "" + tasks.size());
|
||||||
|
for (ActivityManager.StackInfo s : stackInfos) {
|
||||||
|
Console.log(Constants.DebugFlags.App.TaskDataLoader, " [RecentsTaskLoader|stack]", s.toString());
|
||||||
|
if (stacks.containsKey(s.stackId)) {
|
||||||
|
stacks.get(s.stackId).setRect(s.bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// Start the task loader
|
// Start the task loader
|
||||||
mLoader.start(context);
|
mLoader.start(context);
|
||||||
|
|||||||
@@ -0,0 +1,182 @@
|
|||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.app.ActivityOptions;
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ActivityInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Acts as a shim around the real system services that we need to access data from, and provides
|
||||||
|
* a point of injection when testing UI.
|
||||||
|
*/
|
||||||
|
public class SystemServicesProxy {
|
||||||
|
ActivityManager mAm;
|
||||||
|
PackageManager mPm;
|
||||||
|
String mPackage;
|
||||||
|
|
||||||
|
Bitmap mDummyIcon;
|
||||||
|
|
||||||
|
/** Private constructor */
|
||||||
|
public SystemServicesProxy(Context context) {
|
||||||
|
mAm = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||||
|
mPm = context.getPackageManager();
|
||||||
|
mPackage = context.getPackageName();
|
||||||
|
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
|
||||||
|
// Create a dummy icon
|
||||||
|
mDummyIcon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
|
||||||
|
Canvas c = new Canvas(mDummyIcon);
|
||||||
|
c.drawColor(0xFFFF0000);
|
||||||
|
c.setBitmap(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a list of the recents tasks */
|
||||||
|
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numTasks, int userId) {
|
||||||
|
if (mAm == null) return null;
|
||||||
|
|
||||||
|
// If we are mocking, then create some recent tasks
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
|
||||||
|
ArrayList<ActivityManager.RecentTaskInfo> tasks =
|
||||||
|
new ArrayList<ActivityManager.RecentTaskInfo>();
|
||||||
|
int count = Math.min(numTasks, Constants.DebugFlags.App.SystemServicesProxyMockTaskCount);
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
// Create a dummy component name
|
||||||
|
int packageIndex = i % Constants.DebugFlags.App.SystemServicesProxyMockPackageCount;
|
||||||
|
ComponentName cn = new ComponentName("com.android.test" + packageIndex,
|
||||||
|
"com.android.test" + i + ".Activity");
|
||||||
|
// Create the recent task info
|
||||||
|
ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
|
||||||
|
rti.id = rti.persistentId = i;
|
||||||
|
rti.baseIntent = new Intent();
|
||||||
|
rti.baseIntent.setComponent(cn);
|
||||||
|
rti.description = rti.activityLabel = "Recent Task";
|
||||||
|
rti.activityIcon = Bitmap.createBitmap(mDummyIcon);
|
||||||
|
tasks.add(rti);
|
||||||
|
}
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mAm.getRecentTasksForUser(numTasks,
|
||||||
|
ActivityManager.RECENT_IGNORE_UNAVAILABLE |
|
||||||
|
ActivityManager.RECENT_INCLUDE_PROFILES, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns a list of the running tasks */
|
||||||
|
public List<ActivityManager.RunningTaskInfo> getRunningTasks(int numTasks) {
|
||||||
|
if (mAm == null) return null;
|
||||||
|
return mAm.getRunningTasks(numTasks);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns whether the specified task is in the home stack */
|
||||||
|
public boolean isInHomeStack(int taskId) {
|
||||||
|
if (mAm == null) return false;
|
||||||
|
|
||||||
|
// If we are mocking, then just return false
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mAm.isInHomeStack(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the top task thumbnail for the given task id */
|
||||||
|
public Bitmap getTaskThumbnail(int taskId) {
|
||||||
|
if (mAm == null) return null;
|
||||||
|
|
||||||
|
// If we are mocking, then just return a dummy thumbnail
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
|
||||||
|
Bitmap thumbnail = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas c = new Canvas(thumbnail);
|
||||||
|
c.drawColor(0xFF00ff00);
|
||||||
|
c.setBitmap(null);
|
||||||
|
return thumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mAm.getTaskTopThumbnail(taskId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Moves a task to the front with the specified activity options */
|
||||||
|
public void moveTaskToFront(int taskId, ActivityOptions opts) {
|
||||||
|
if (mAm == null) return;
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
|
||||||
|
|
||||||
|
if (opts != null) {
|
||||||
|
mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME,
|
||||||
|
opts.toBundle());
|
||||||
|
} else {
|
||||||
|
mAm.moveTaskToFront(taskId, ActivityManager.MOVE_TASK_WITH_HOME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Removes the task and kills the process */
|
||||||
|
public void removeTask(int taskId) {
|
||||||
|
if (mAm == null) return;
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) return;
|
||||||
|
|
||||||
|
mAm.removeTask(taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the activity info for a given component name */
|
||||||
|
public ActivityInfo getActivityInfo(ComponentName cn) {
|
||||||
|
if (mPm == null) return null;
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return mPm.getActivityInfo(cn, PackageManager.GET_META_DATA);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the activity label */
|
||||||
|
public String getActivityLabel(ActivityInfo info) {
|
||||||
|
if (mPm == null) return null;
|
||||||
|
|
||||||
|
// If we are mocking, then return a mock label
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
|
||||||
|
return "Recent Task";
|
||||||
|
}
|
||||||
|
|
||||||
|
return info.loadLabel(mPm).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the activity icon */
|
||||||
|
public Drawable getActivityIcon(ActivityInfo info) {
|
||||||
|
if (mPm == null) return null;
|
||||||
|
|
||||||
|
// If we are mocking, then return a mock label
|
||||||
|
if (Constants.DebugFlags.App.EnableSystemServicesProxy) {
|
||||||
|
return new ColorDrawable(0xFFff0000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return info.loadIcon(mPm);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,7 +19,6 @@ package com.android.systemui.recents.model;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import com.android.systemui.recents.Constants;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -106,14 +105,7 @@ public class Task {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
// If we have multiple task entries for the same task, then we do the simple object
|
// Check that the id matches
|
||||||
// equality check
|
|
||||||
if (Constants.Values.RecentsTaskLoader.TaskEntryMultiplier > 1) {
|
|
||||||
return super.equals(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
Task t = (Task) o;
|
||||||
return key.equals(t.key);
|
return key.equals(t.key);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package com.android.systemui.recents.views;
|
package com.android.systemui.recents.views;
|
||||||
|
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.app.ActivityOptions;
|
import android.app.ActivityOptions;
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@@ -30,6 +29,7 @@ import android.widget.FrameLayout;
|
|||||||
import com.android.systemui.recents.Console;
|
import com.android.systemui.recents.Console;
|
||||||
import com.android.systemui.recents.Constants;
|
import com.android.systemui.recents.Constants;
|
||||||
import com.android.systemui.recents.RecentsConfiguration;
|
import com.android.systemui.recents.RecentsConfiguration;
|
||||||
|
import com.android.systemui.recents.RecentsTaskLoader;
|
||||||
import com.android.systemui.recents.model.SpaceNode;
|
import com.android.systemui.recents.model.SpaceNode;
|
||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
@@ -246,14 +246,8 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
|
|||||||
|
|
||||||
if (task.isActive) {
|
if (task.isActive) {
|
||||||
// Bring an active task to the foreground
|
// Bring an active task to the foreground
|
||||||
ActivityManager am = (ActivityManager)
|
RecentsTaskLoader.getInstance().getSystemServicesProxy()
|
||||||
stackView.getContext().getSystemService(Context.ACTIVITY_SERVICE);
|
.moveTaskToFront(task.key.id, opts);
|
||||||
if (opts != null) {
|
|
||||||
am.moveTaskToFront(task.key.id, ActivityManager.MOVE_TASK_WITH_HOME,
|
|
||||||
opts.toBundle());
|
|
||||||
} else {
|
|
||||||
am.moveTaskToFront(task.key.id, ActivityManager.MOVE_TASK_WITH_HOME);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// Launch the activity with the desired animation
|
// Launch the activity with the desired animation
|
||||||
Intent i = new Intent(task.key.baseIntent);
|
Intent i = new Intent(task.key.baseIntent);
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import android.animation.AnimatorSet;
|
|||||||
import android.animation.ObjectAnimator;
|
import android.animation.ObjectAnimator;
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
@@ -40,6 +39,7 @@ import com.android.systemui.recents.Console;
|
|||||||
import com.android.systemui.recents.Constants;
|
import com.android.systemui.recents.Constants;
|
||||||
import com.android.systemui.recents.RecentsConfiguration;
|
import com.android.systemui.recents.RecentsConfiguration;
|
||||||
import com.android.systemui.recents.RecentsTaskLoader;
|
import com.android.systemui.recents.RecentsTaskLoader;
|
||||||
|
import com.android.systemui.recents.SystemServicesProxy;
|
||||||
import com.android.systemui.recents.Utilities;
|
import com.android.systemui.recents.Utilities;
|
||||||
import com.android.systemui.recents.model.Task;
|
import com.android.systemui.recents.model.Task;
|
||||||
import com.android.systemui.recents.model.TaskStack;
|
import com.android.systemui.recents.model.TaskStack;
|
||||||
@@ -234,7 +234,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
|
|||||||
// When we are picking up a new view from the view pool, prepare it for any
|
// When we are picking up a new view from the view pool, prepare it for any
|
||||||
// following animation by putting it in a reasonable place
|
// following animation by putting it in a reasonable place
|
||||||
if (mStackViewsAnimationDuration > 0 && i != 0) {
|
if (mStackViewsAnimationDuration > 0 && i != 0) {
|
||||||
int fromIndex = (transform.t < 0) ? (i - 1) : (i + 1);
|
int fromIndex = (transform.t < 0) ? (visibleRange[0] - 1) :
|
||||||
|
(visibleRange[1] + 1);
|
||||||
tv.updateViewPropertiesToTaskTransform(null,
|
tv.updateViewPropertiesToTaskTransform(null,
|
||||||
getStackTransform(fromIndex, stackScroll), 0);
|
getStackTransform(fromIndex, stackScroll), 0);
|
||||||
}
|
}
|
||||||
@@ -1268,12 +1269,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
|
|||||||
loader.deleteTaskData(task);
|
loader.deleteTaskData(task);
|
||||||
|
|
||||||
// Remove the task from activity manager
|
// Remove the task from activity manager
|
||||||
final ActivityManager am = (ActivityManager)
|
RecentsTaskLoader.getInstance().getSystemServicesProxy().removeTask(tv.getTask().key.id);
|
||||||
activity.getSystemService(Context.ACTIVITY_SERVICE);
|
|
||||||
if (am != null) {
|
|
||||||
am.removeTask(tv.getTask().key.id,
|
|
||||||
ActivityManager.REMOVE_TASK_KILL_PROCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there are no remaining tasks, then either unfilter the current stack, or just close
|
// If there are no remaining tasks, then either unfilter the current stack, or just close
|
||||||
// the activity if there are no filtered stacks
|
// the activity if there are no filtered stacks
|
||||||
|
|||||||
Reference in New Issue
Block a user