Merge "Switch to showing top-most thumbnail of recent apps." into jb-mr1-dev

This commit is contained in:
Dianne Hackborn
2012-09-19 11:40:17 -07:00
committed by Android (Google) Code Review
8 changed files with 102 additions and 34 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;
}
};
}

View File

@@ -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;
}