Merge "Switch to showing top-most thumbnail of recent apps." into jb-mr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
09ad0832e0
@@ -864,7 +864,17 @@ public class ActivityManager {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @hide */
|
||||
public Bitmap getTaskTopThumbnail(int id) throws SecurityException {
|
||||
try {
|
||||
return ActivityManagerNative.getDefault().getTaskTopThumbnail(id);
|
||||
} catch (RemoteException e) {
|
||||
// System dead, we will be dead too soon!
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag for {@link #moveTaskToFront(int, int)}: also move the "home"
|
||||
* activity along with the task, so it is positioned immediately behind
|
||||
|
||||
@@ -498,7 +498,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
reply.writeTypedList(list);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
case GET_TASK_THUMBNAILS_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
int id = data.readInt();
|
||||
@@ -512,7 +512,21 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
case GET_TASK_TOP_THUMBNAIL_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
int id = data.readInt();
|
||||
Bitmap bm = getTaskTopThumbnail(id);
|
||||
reply.writeNoException();
|
||||
if (bm != null) {
|
||||
reply.writeInt(1);
|
||||
bm.writeToParcel(reply, 0);
|
||||
} else {
|
||||
reply.writeInt(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case GET_SERVICES_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
int maxNum = data.readInt();
|
||||
@@ -2307,6 +2321,21 @@ class ActivityManagerProxy implements IActivityManager
|
||||
reply.recycle();
|
||||
return bm;
|
||||
}
|
||||
public Bitmap getTaskTopThumbnail(int id) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
data.writeInt(id);
|
||||
mRemote.transact(GET_TASK_TOP_THUMBNAIL_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
Bitmap bm = null;
|
||||
if (reply.readInt() != 0) {
|
||||
bm = Bitmap.CREATOR.createFromParcel(reply);
|
||||
}
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
return bm;
|
||||
}
|
||||
public List getServices(int maxNum, int flags) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
|
||||
@@ -104,6 +104,7 @@ public interface IActivityManager extends IInterface {
|
||||
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
|
||||
int flags, int userId) throws RemoteException;
|
||||
public ActivityManager.TaskThumbnails getTaskThumbnails(int taskId) throws RemoteException;
|
||||
public Bitmap getTaskTopThumbnail(int taskId) throws RemoteException;
|
||||
public List getServices(int maxNum, int flags) throws RemoteException;
|
||||
public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState()
|
||||
throws RemoteException;
|
||||
@@ -548,7 +549,7 @@ public interface IActivityManager extends IInterface {
|
||||
int UNBIND_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+91;
|
||||
int GET_UID_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+92;
|
||||
int HANDLE_INCOMING_USER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+93;
|
||||
|
||||
int GET_TASK_TOP_THUMBNAIL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94;
|
||||
int KILL_APPLICATION_WITH_APPID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95;
|
||||
int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96;
|
||||
int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97;
|
||||
|
||||
@@ -193,14 +193,14 @@ public class RecentTasksLoader implements View.OnTouchListener {
|
||||
final ActivityManager am = (ActivityManager)
|
||||
mContext.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
final PackageManager pm = mContext.getPackageManager();
|
||||
ActivityManager.TaskThumbnails thumbs = am.getTaskThumbnails(td.persistentTaskId);
|
||||
Bitmap thumbnail = am.getTaskTopThumbnail(td.persistentTaskId);
|
||||
Drawable icon = getFullResIcon(td.resolveInfo, pm);
|
||||
|
||||
if (DEBUG) Log.v(TAG, "Loaded bitmap for task "
|
||||
+ td + ": " + thumbs.mainThumbnail);
|
||||
+ td + ": " + thumbnail);
|
||||
synchronized (td) {
|
||||
if (thumbs != null && thumbs.mainThumbnail != null) {
|
||||
td.setThumbnail(thumbs.mainThumbnail);
|
||||
if (thumbnail != null) {
|
||||
td.setThumbnail(thumbnail);
|
||||
} else {
|
||||
td.setThumbnail(mDefaultThumbnailBackground);
|
||||
}
|
||||
|
||||
@@ -168,6 +168,7 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
static final boolean localLOGV = DEBUG;
|
||||
static final boolean DEBUG_SWITCH = localLOGV || false;
|
||||
static final boolean DEBUG_TASKS = localLOGV || false;
|
||||
static final boolean DEBUG_THUMBNAILS = localLOGV || false;
|
||||
static final boolean DEBUG_PAUSE = localLOGV || false;
|
||||
static final boolean DEBUG_OOM_ADJ = localLOGV || false;
|
||||
static final boolean DEBUG_TRANSITION = localLOGV || false;
|
||||
@@ -5849,6 +5850,18 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
return null;
|
||||
}
|
||||
|
||||
public Bitmap getTaskTopThumbnail(int id) {
|
||||
synchronized (this) {
|
||||
enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
|
||||
"getTaskTopThumbnail()");
|
||||
TaskRecord tr = taskForIdLocked(id);
|
||||
if (tr != null) {
|
||||
return mMainStack.getTaskTopThumbnailLocked(tr);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean removeSubTask(int taskId, int subTaskIndex) {
|
||||
synchronized (this) {
|
||||
enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
|
||||
|
||||
@@ -219,7 +219,13 @@ final class ActivityRecord {
|
||||
pw.print(prefix); pw.print("frozenBeforeDestroy="); pw.print(frozenBeforeDestroy);
|
||||
pw.print(" thumbnailNeeded="); pw.print(thumbnailNeeded);
|
||||
pw.print(" forceNewConfig="); pw.println(forceNewConfig);
|
||||
pw.print(prefix); pw.print("thumbHolder="); pw.println(thumbHolder);
|
||||
pw.print(prefix); pw.print("thumbHolder: ");
|
||||
pw.print(Integer.toHexString(System.identityHashCode(thumbHolder)));
|
||||
if (thumbHolder != null) {
|
||||
pw.print(" bm="); pw.print(thumbHolder.lastThumbnail);
|
||||
pw.print(" desc="); pw.print(thumbHolder.lastDescription);
|
||||
}
|
||||
pw.println();
|
||||
if (launchTime != 0 || startTime != 0) {
|
||||
pw.print(prefix); pw.print("launchTime=");
|
||||
if (launchTime == 0) pw.print("0");
|
||||
@@ -674,19 +680,15 @@ final class ActivityRecord {
|
||||
}
|
||||
if (thumbHolder != null) {
|
||||
if (newThumbnail != null) {
|
||||
if (ActivityManagerService.DEBUG_THUMBNAILS) Slog.i(ActivityManagerService.TAG,
|
||||
"Setting thumbnail of " + this + " holder " + thumbHolder
|
||||
+ " to " + newThumbnail);
|
||||
thumbHolder.lastThumbnail = newThumbnail;
|
||||
}
|
||||
thumbHolder.lastDescription = description;
|
||||
}
|
||||
}
|
||||
|
||||
void clearThumbnail() {
|
||||
if (thumbHolder != null) {
|
||||
thumbHolder.lastThumbnail = null;
|
||||
thumbHolder.lastDescription = null;
|
||||
}
|
||||
}
|
||||
|
||||
void startLaunchTickingLocked() {
|
||||
if (ActivityManagerService.IS_USER_BUILD) {
|
||||
return;
|
||||
|
||||
@@ -1203,8 +1203,7 @@ final class ActivityStack {
|
||||
if (mMainStack) {
|
||||
mService.reportResumedActivityLocked(next);
|
||||
}
|
||||
|
||||
next.clearThumbnail();
|
||||
|
||||
if (mMainStack) {
|
||||
mService.setFocusedActivityLocked(next);
|
||||
}
|
||||
@@ -4328,18 +4327,33 @@ final class ActivityStack {
|
||||
finishTaskMoveLocked(task);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public ActivityManager.TaskThumbnails getTaskThumbnailsLocked(TaskRecord tr) {
|
||||
TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true);
|
||||
ActivityRecord resumed = mResumedActivity;
|
||||
if (resumed != null && resumed.thumbHolder == tr) {
|
||||
info.mainThumbnail = resumed.stack.screenshotActivities(resumed);
|
||||
} else {
|
||||
info.mainThumbnail = tr.lastThumbnail;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public Bitmap getTaskTopThumbnailLocked(TaskRecord tr) {
|
||||
ActivityRecord resumed = mResumedActivity;
|
||||
if (resumed != null && resumed.task == tr) {
|
||||
// This task is the current resumed task, we just need to take
|
||||
// a screenshot of it and return that.
|
||||
return resumed.stack.screenshotActivities(resumed);
|
||||
}
|
||||
// Return the information about the task, to figure out the top
|
||||
// thumbnail to return.
|
||||
TaskAccessInfo info = getTaskAccessInfoLocked(tr.taskId, true);
|
||||
if (info.numSubThumbbails <= 0) {
|
||||
return info.mainThumbnail;
|
||||
} else {
|
||||
return info.subtasks.get(info.numSubThumbbails-1).holder.lastThumbnail;
|
||||
}
|
||||
}
|
||||
|
||||
public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex,
|
||||
boolean taskRequired) {
|
||||
TaskAccessInfo info = getTaskAccessInfoLocked(taskId, false);
|
||||
@@ -4370,7 +4384,6 @@ final class ActivityStack {
|
||||
}
|
||||
|
||||
public TaskAccessInfo getTaskAccessInfoLocked(int taskId, boolean inclThumbs) {
|
||||
ActivityRecord resumed = mResumedActivity;
|
||||
final TaskAccessInfo thumbs = new TaskAccessInfo();
|
||||
// How many different sub-thumbnails?
|
||||
final int NA = mHistory.size();
|
||||
@@ -4380,6 +4393,10 @@ final class ActivityStack {
|
||||
ActivityRecord ar = mHistory.get(j);
|
||||
if (!ar.finishing && ar.task.taskId == taskId) {
|
||||
holder = ar.thumbHolder;
|
||||
if (holder != null) {
|
||||
thumbs.mainThumbnail = holder.lastThumbnail;
|
||||
}
|
||||
j++;
|
||||
break;
|
||||
}
|
||||
j++;
|
||||
@@ -4394,7 +4411,6 @@ final class ActivityStack {
|
||||
|
||||
ArrayList<TaskAccessInfo.SubTask> subtasks = new ArrayList<TaskAccessInfo.SubTask>();
|
||||
thumbs.subtasks = subtasks;
|
||||
ActivityRecord lastActivity = null;
|
||||
while (j < NA) {
|
||||
ActivityRecord ar = mHistory.get(j);
|
||||
j++;
|
||||
@@ -4404,30 +4420,28 @@ final class ActivityStack {
|
||||
if (ar.task.taskId != taskId) {
|
||||
break;
|
||||
}
|
||||
lastActivity = ar;
|
||||
if (ar.thumbHolder != holder && holder != null) {
|
||||
thumbs.numSubThumbbails++;
|
||||
holder = ar.thumbHolder;
|
||||
TaskAccessInfo.SubTask sub = new TaskAccessInfo.SubTask();
|
||||
sub.thumbnail = holder.lastThumbnail;
|
||||
sub.holder = holder;
|
||||
sub.activity = ar;
|
||||
sub.index = j-1;
|
||||
subtasks.add(sub);
|
||||
}
|
||||
}
|
||||
if (lastActivity != null && subtasks.size() > 0) {
|
||||
if (resumed == lastActivity) {
|
||||
TaskAccessInfo.SubTask sub = subtasks.get(subtasks.size()-1);
|
||||
sub.thumbnail = lastActivity.stack.screenshotActivities(lastActivity);
|
||||
}
|
||||
}
|
||||
if (thumbs.numSubThumbbails > 0) {
|
||||
thumbs.retriever = new IThumbnailRetriever.Stub() {
|
||||
public Bitmap getThumbnail(int index) {
|
||||
if (index < 0 || index >= thumbs.subtasks.size()) {
|
||||
return null;
|
||||
}
|
||||
return thumbs.subtasks.get(index).thumbnail;
|
||||
TaskAccessInfo.SubTask sub = thumbs.subtasks.get(index);
|
||||
ActivityRecord resumed = mResumedActivity;
|
||||
if (resumed != null && resumed.thumbHolder == sub.holder) {
|
||||
return resumed.stack.screenshotActivities(resumed);
|
||||
}
|
||||
return sub.holder.lastThumbnail;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -19,11 +19,10 @@ package com.android.server.am;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import android.app.ActivityManager.TaskThumbnails;
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
final class TaskAccessInfo extends TaskThumbnails {
|
||||
final static class SubTask {
|
||||
Bitmap thumbnail;
|
||||
ThumbnailHolder holder;
|
||||
ActivityRecord activity;
|
||||
int index;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user