summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml42
-rw-r--r--core/java/android/app/ActivityManager.java42
-rw-r--r--core/java/android/app/BackStackRecord.java18
-rw-r--r--core/java/android/app/Fragment.java11
-rw-r--r--core/java/android/app/FragmentManager.java4
-rw-r--r--core/java/android/view/IWindowManager.aidl2
-rw-r--r--core/java/android/view/Surface.java14
-rw-r--r--core/jni/android_view_Surface.cpp25
-rw-r--r--packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java47
-rw-r--r--services/java/com/android/server/WindowManagerService.java13
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java31
-rw-r--r--services/java/com/android/server/am/ActivityStack.java9
-rw-r--r--services/java/com/android/server/am/TaskRecord.java4
14 files changed, 197 insertions, 71 deletions
diff --git a/api/current.xml b/api/current.xml
index 5bdb3b1..2c971ec 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -24439,6 +24439,17 @@
visibility="public"
>
</field>
+<field name="RECENT_IGNORE_UNAVAILABLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="RECENT_WITH_EXCLUDED"
type="int"
transient="false"
@@ -24450,6 +24461,17 @@
visibility="public"
>
</field>
+<field name="TASKS_GET_THUMBNAILS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4096"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="ActivityManager.MemoryInfo"
extends="java.lang.Object"
@@ -24818,6 +24840,16 @@
visibility="public"
>
</field>
+<field name="description"
+ type="java.lang.CharSequence"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="id"
type="int"
transient="false"
@@ -24838,6 +24870,16 @@
visibility="public"
>
</field>
+<field name="thumbnail"
+ type="android.graphics.Bitmap"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="ActivityManager.RunningAppProcessInfo"
extends="java.lang.Object"
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index e168034..ebdc7fd 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -93,6 +93,17 @@ public class ActivityManager {
* implementation that the alias referred to. Otherwise, this is null.
*/
public ComponentName origActivity;
+
+ /**
+ * Thumbnail representation of the task's last state. Must
+ * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
+ */
+ public Bitmap thumbnail;
+
+ /**
+ * Description of the task's last state.
+ */
+ public CharSequence description;
public RecentTaskInfo() {
}
@@ -110,6 +121,14 @@ public class ActivityManager {
dest.writeInt(0);
}
ComponentName.writeToParcel(origActivity, dest);
+ if (thumbnail != null) {
+ dest.writeInt(1);
+ thumbnail.writeToParcel(dest, 0);
+ } else {
+ dest.writeInt(0);
+ }
+ TextUtils.writeToParcel(description, dest,
+ Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
}
public void readFromParcel(Parcel source) {
@@ -120,6 +139,12 @@ public class ActivityManager {
baseIntent = null;
}
origActivity = ComponentName.readFromParcel(source);
+ if (source.readInt() != 0) {
+ thumbnail = Bitmap.CREATOR.createFromParcel(source);
+ } else {
+ thumbnail = null;
+ }
+ description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
}
public static final Creator<RecentTaskInfo> CREATOR
@@ -145,11 +170,16 @@ public class ActivityManager {
public static final int RECENT_WITH_EXCLUDED = 0x0001;
/**
- * @hide
- * TODO: Make this public. Provides a list that does not contain any
+ * Provides a list that does not contain any
* recent tasks that currently are not available to the user.
*/
public static final int RECENT_IGNORE_UNAVAILABLE = 0x0002;
+
+ /**
+ * Flag for use with {@link #getRecentTasks}: also return the thumbnail
+ * bitmap (if available) for each recent task.
+ */
+ public static final int TASKS_GET_THUMBNAILS = 0x0001000;
/**
* Return a list of the tasks that the user has recently launched, with
@@ -158,6 +188,9 @@ public class ActivityManager {
* @param maxNum The maximum number of entries to return in the list. The
* actual number returned may be smaller, depending on how many tasks the
* user has started and the maximum number the system can remember.
+ * @param flags Information about what to return. May be any combination
+ * of {@link #RECENT_WITH_EXCLUDED}, {@link #RECENT_IGNORE_UNAVAILABLE},
+ * and {@link #TASKS_GET_THUMBNAILS}.
*
* @return Returns a list of RecentTaskInfo records describing each of
* the recent tasks.
@@ -203,7 +236,8 @@ public class ActivityManager {
public ComponentName topActivity;
/**
- * Thumbnail representation of the task's current state.
+ * Thumbnail representation of the task's current state. Must
+ * use {@link ActivityManager#TASKS_GET_THUMBNAILS} to have this set.
*/
public Bitmap thumbnail;
@@ -273,7 +307,7 @@ public class ActivityManager {
readFromParcel(source);
}
}
-
+
/**
* Return a list of the tasks that are currently running, with
* the most recent being first and older ones after in order. Note that
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index b47aefd..33b747c 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -233,19 +233,25 @@ final class BackStackRecord extends FragmentTransaction implements
Op op = mHead;
int num = 0;
while (op != null) {
- writer.print(prefix); writer.print(" #"); writer.print(num);
- writer.print(" "); writer.print(op); writer.println(":");
+ writer.print(prefix); writer.print(" Op #"); writer.print(num);
+ writer.println(":");
writer.print(innerPrefix); writer.print("cmd="); writer.print(op.cmd);
- writer.println("fragment="); writer.println(op.fragment);
+ writer.print(" fragment="); writer.println(op.fragment);
if (op.enterAnim != 0 || op.exitAnim != 0) {
writer.print(prefix); writer.print("enterAnim="); writer.print(op.enterAnim);
writer.print(" exitAnim="); writer.println(op.exitAnim);
}
if (op.removed != null && op.removed.size() > 0) {
for (int i=0; i<op.removed.size(); i++) {
- writer.print(innerPrefix); writer.println("Removed:");
- writer.print(innerPrefix); writer.print(" #"); writer.print(num);
- writer.print(": "); writer.println(op.removed.get(i));
+ writer.print(innerPrefix);
+ if (op.removed.size() == 1) {
+ writer.print("Removed: ");
+ } else {
+ writer.println("Removed:");
+ writer.print(innerPrefix); writer.print(" #"); writer.print(num);
+ writer.print(": ");
+ }
+ writer.println(op.removed.get(i));
}
}
op = op.next;
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index eaa1e05..348149e 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -526,7 +526,16 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
@Override
public String toString() {
StringBuilder sb = new StringBuilder(128);
- sb.append("Fragment{");
+ String simpleName = getClass().getSimpleName();
+ if (simpleName == null || simpleName.isEmpty()) {
+ simpleName = getClass().getName();
+ int end = simpleName.lastIndexOf('.');
+ if (end > 0) {
+ simpleName = simpleName.substring(end+1);
+ }
+ }
+ sb.append(simpleName);
+ sb.append("{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
if (mIndex >= 0) {
sb.append(" #");
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 196e7b2..488b673 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -293,7 +293,7 @@ final class FragmentManagerState implements Parcelable {
* Container for fragments associated with an activity.
*/
final class FragmentManagerImpl extends FragmentManager {
- static final boolean DEBUG = true;
+ static final boolean DEBUG = false;
static final String TAG = "FragmentManager";
static final String TARGET_REQUEST_CODE_STATE_TAG = "android:target_req_state";
@@ -562,6 +562,7 @@ final class FragmentManagerImpl extends FragmentManager {
}
}
f.mActivity = mActivity;
+ f.mFragmentManager = mActivity.mFragments;
f.mCalled = false;
f.onAttach(mActivity);
if (!f.mCalled) {
@@ -737,6 +738,7 @@ final class FragmentManagerImpl extends FragmentManager {
}
f.mImmediateActivity = null;
f.mActivity = null;
+ f.mFragmentManager = null;
}
}
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 2c8ca8b..8bdc1f8 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -186,5 +186,5 @@ interface IWindowManager
/**
* Create a screenshot of the applications currently displayed.
*/
- Bitmap screenshotApplications(int maxWidth, int maxHeight);
+ Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight);
}
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 86cd3b0..b8d72a6 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -377,17 +377,29 @@ public class Surface implements Parcelable {
}
/**
+ * Like {@link #screenshot(int, int, int, int)} but includes all
+ * Surfaces in the screenshot.
+ *
+ * @hide
+ */
+ public static native Bitmap screenshot(int width, int height);
+
+ /**
* Copy the current screen contents into a bitmap and return it.
*
* @param width The desired width of the returned bitmap; the raw
* screen will be scaled down to this size.
* @param height The desired height of the returned bitmap; the raw
* screen will be scaled down to this size.
+ * @param minLayer The lowest (bottom-most Z order) surface layer to
+ * include in the screenshot.
+ * @param maxLayer The highest (top-most Z order) surface layer to
+ * include in the screenshot.
* @return Returns a Bitmap containing the screen contents.
*
* @hide
*/
- public static native Bitmap screenshot(int width, int height);
+ public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer);
/**
* set surface parameters.
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 206e320..8c30987 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -449,9 +449,11 @@ public:
SkSafeUnref(fCTable);
}
- status_t update(int width, int height) {
+ status_t update(int width, int height, int minLayer, int maxLayer, bool allLayers) {
status_t res = (width > 0 && height > 0)
- ? mScreenshot.update(width, height)
+ ? (allLayers
+ ? mScreenshot.update(width, height)
+ : mScreenshot.update(width, height, minLayer, maxLayer))
: mScreenshot.update();
if (res != NO_ERROR) {
return res;
@@ -493,10 +495,11 @@ private:
typedef SkPixelRef INHERITED;
};
-static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height)
+static jobject doScreenshot(JNIEnv* env, jobject clazz, jint width, jint height,
+ jint minLayer, jint maxLayer, bool allLayers)
{
ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
- if (pixels->update(width, height) != NO_ERROR) {
+ if (pixels->update(width, height, minLayer, maxLayer, allLayers) != NO_ERROR) {
delete pixels;
return 0;
}
@@ -525,6 +528,17 @@ static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint h
return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
}
+static jobject Surface_screenshotAll(JNIEnv* env, jobject clazz, jint width, jint height)
+{
+ return doScreenshot(env, clazz, width, height, 0, 0, true);
+}
+
+static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height,
+ jint minLayer, jint maxLayer, bool allLayers)
+{
+ return doScreenshot(env, clazz, width, height, minLayer, maxLayer, false);
+}
+
static void Surface_setLayer(
JNIEnv* env, jobject clazz, jint zorder)
{
@@ -750,7 +764,8 @@ static JNINativeMethod gSurfaceMethods[] = {
{"setOrientation", "(III)V", (void*)Surface_setOrientation },
{"freezeDisplay", "(I)V", (void*)Surface_freezeDisplay },
{"unfreezeDisplay", "(I)V", (void*)Surface_unfreezeDisplay },
- {"screenshot", "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
+ {"screenshot", "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll },
+ {"screenshot", "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
{"setLayer", "(I)V", (void*)Surface_setLayer },
{"setPosition", "(II)V",(void*)Surface_setPosition },
{"setSize", "(II)V",(void*)Surface_setSize },
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
index a98ef0b..8c6eefb 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java
@@ -409,7 +409,8 @@ public class RecentApplicationsActivity extends Activity {
}
void updateRunningTasks() {
- mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS, 0, mThumbnailReceiver);
+ mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS,
+ ActivityManager.TASKS_GET_THUMBNAILS, mThumbnailReceiver);
if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode);
for (RunningTaskInfo r : mRunningTaskList) {
if (r.thumbnail != null) {
@@ -440,7 +441,8 @@ public class RecentApplicationsActivity extends Activity {
final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RecentTaskInfo> recentTasks =
- am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+ am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+ | ActivityManager.TASKS_GET_THUMBNAILS);
ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
.resolveActivityInfo(pm, 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
index 87d73ad..1301329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java
@@ -58,7 +58,7 @@ public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnC
private static final boolean DEBUG = TabletStatusBar.DEBUG;
private static final int DISPLAY_TASKS_PORTRAIT = 8;
private static final int DISPLAY_TASKS_LANDSCAPE = 5; // number of recent tasks to display
- private static final int MAX_TASKS = 2 * DISPLAY_TASKS_PORTRAIT; // allow extra for non-apps
+ private static final int MAX_TASKS = DISPLAY_TASKS_PORTRAIT + 2; // allow extra for non-apps
private TabletStatusBar mBar;
private TextView mNoRecents;
private LinearLayout mRecentsContainer;
@@ -80,8 +80,8 @@ public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnC
int position; // position in list
public ActivityDescription(Bitmap _thumbnail,
- Drawable _icon, String _label, String _desc, Intent _intent, int _id, int _pos,
- String _packageName)
+ Drawable _icon, String _label, CharSequence _desc, Intent _intent,
+ int _id, int _pos, String _packageName)
{
thumbnail = _thumbnail;
icon = _icon;
@@ -94,21 +94,6 @@ public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnC
}
};
- private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() {
-
- public void finished() throws RemoteException {
- }
-
- public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description)
- throws RemoteException {
- ActivityDescription info = findActivityDescription(id);
- if (info != null) {
- info.thumbnail = bitmap;
- info.description = description;
- }
- }
- };
-
public boolean isInContentArea(int x, int y) {
final int l = mRecentsContainer.getPaddingLeft();
final int r = mRecentsContainer.getWidth() - mRecentsContainer.getPaddingRight();
@@ -201,7 +186,8 @@ public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnC
mContext.getSystemService(Context.ACTIVITY_SERVICE);
final List<ActivityManager.RecentTaskInfo> recentTasks =
- am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE);
+ am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE
+ | ActivityManager.TASKS_GET_THUMBNAILS);
ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME)
.resolveActivityInfo(pm, 0);
@@ -234,7 +220,8 @@ public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnC
if (title != null && title.length() > 0 && icon != null) {
if (DEBUG) Log.v(TAG, "creating activity desc for id=" + id + ", label=" + title);
ActivityDescription item = new ActivityDescription(
- null, icon, title, null, intent, id, index, info.packageName);
+ crop(recentInfo.thumbnail), icon, title, recentInfo.description,
+ intent, id, index, info.packageName);
activityDescriptions.add(item);
++index;
} else {
@@ -258,28 +245,8 @@ public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnC
return desc;
}
- private void getThumbnails(ArrayList<ActivityDescription> tasks) {
- ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- List<RunningTaskInfo> runningTasks = am.getRunningTasks(MAX_TASKS, 0, mThumbnailReceiver);
- for (RunningTaskInfo runningTaskInfo : runningTasks) {
- // Find the activity description associted with the given id
- ActivityDescription desc = findActivityDescription(runningTaskInfo.id);
- if (desc != null) {
- if (runningTaskInfo.thumbnail != null) {
- desc.thumbnail = crop(runningTaskInfo.thumbnail);
- desc.description = runningTaskInfo.description;
- } else {
- if (DEBUG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***");
- }
- } else {
- if (DEBUG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + runningTaskInfo.id);
- }
- }
- }
-
private void refreshApplicationList() {
mActivityDescriptions = getRecentTasks();
- getThumbnails(mActivityDescriptions);
updateUiElements(getResources().getConfiguration(), true);
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 8e33011..ba7692d 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -4908,7 +4908,7 @@ public class WindowManagerService extends IWindowManager.Stub
SystemProperties.set(StrictMode.VISUAL_PROPERTY, value);
}
- public Bitmap screenshotApplications(int maxWidth, int maxHeight) {
+ public Bitmap screenshotApplications(IBinder appToken, int maxWidth, int maxHeight) {
if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
"screenshotApplications()")) {
throw new SecurityException("Requires READ_FRAME_BUFFER permission");
@@ -4916,6 +4916,8 @@ public class WindowManagerService extends IWindowManager.Stub
Bitmap rawss;
+ int maxLayer = 0;
+ boolean foundApp;
final Rect frame = new Rect();
float scale;
@@ -4939,6 +4941,13 @@ public class WindowManagerService extends IWindowManager.Stub
if (ws.mLayer >= aboveAppLayer) {
break;
}
+ if (appToken != null && (ws.mAppToken == null
+ || ws.mAppToken.token != appToken)) {
+ continue;
+ }
+ if (maxLayer < ws.mAnimLayer) {
+ maxLayer = ws.mAnimLayer;
+ }
final Rect wf = ws.mFrame;
final Rect cr = ws.mContentInsets;
int left = wf.left + cr.left;
@@ -4978,7 +4987,7 @@ public class WindowManagerService extends IWindowManager.Stub
dh = tmp;
rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
}
- rawss = Surface.screenshot(dw, dh);
+ rawss = Surface.screenshot(dw, dh, 0, maxLayer);
}
Bitmap bm = Bitmap.createBitmap(sw, sh, rawss.getConfig());
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 44029cd..a26fe5f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -3808,8 +3808,14 @@ public final class ActivityManagerService extends ActivityManagerNative
r.haveState = true;
if (thumbnail != null) {
r.thumbnail = thumbnail;
+ if (r.task != null) {
+ r.task.lastThumbnail = r.thumbnail;
+ }
}
r.description = description;
+ if (r.task != null) {
+ r.task.lastDescription = r.description;
+ }
r.stopped = true;
r.state = ActivityState.STOPPED;
if (!r.finishing) {
@@ -4826,9 +4832,10 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException(msg);
}
- final boolean canReadFb = checkCallingPermission(
- android.Manifest.permission.READ_FRAME_BUFFER)
- == PackageManager.PERMISSION_GRANTED;
+ final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
+ && checkCallingPermission(
+ android.Manifest.permission.READ_FRAME_BUFFER)
+ == PackageManager.PERMISSION_GRANTED;
int pos = mMainStack.mHistory.size()-1;
ActivityRecord next =
@@ -4878,7 +4885,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (top.thumbnail != null) {
ci.thumbnail = top.thumbnail;
} else if (top.state == ActivityState.RESUMED) {
- ci.thumbnail = top.stack.screenshotActivities();
+ ci.thumbnail = top.stack.screenshotActivities(top);
}
}
ci.description = topDescription;
@@ -4949,8 +4956,15 @@ public final class ActivityManagerService extends ActivityManagerNative
enforceCallingPermission(android.Manifest.permission.GET_TASKS,
"getRecentTasks()");
+ final boolean canReadFb = (flags&ActivityManager.TASKS_GET_THUMBNAILS) != 0
+ && checkCallingPermission(
+ android.Manifest.permission.READ_FRAME_BUFFER)
+ == PackageManager.PERMISSION_GRANTED;
+
IPackageManager pm = AppGlobals.getPackageManager();
+ ActivityRecord resumed = mMainStack.mResumedActivity;
+
final int N = mRecentTasks.size();
ArrayList<ActivityManager.RecentTaskInfo> res
= new ArrayList<ActivityManager.RecentTaskInfo>(
@@ -4968,6 +4982,15 @@ public final class ActivityManagerService extends ActivityManagerNative
tr.intent != null ? tr.intent : tr.affinityIntent);
rti.origActivity = tr.origActivity;
+ if (canReadFb) {
+ if (resumed != null && resumed.task == tr) {
+ rti.thumbnail = resumed.stack.screenshotActivities(resumed);
+ } else {
+ rti.thumbnail = tr.lastThumbnail;
+ }
+ }
+ rti.description = tr.lastDescription;
+
if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
// Check whether this activity is currently available.
try {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index d92695c..920bbc9 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -650,7 +650,7 @@ public class ActivityStack {
}
}
- public final Bitmap screenshotActivities() {
+ public final Bitmap screenshotActivities(ActivityRecord who) {
Resources res = mService.mContext.getResources();
int w = mThumbnailWidth;
int h = mThumbnailHeight;
@@ -662,7 +662,7 @@ public class ActivityStack {
}
if (w > 0) {
- //return mService.mWindowManager.screenshotApplications(w, h);
+ //return mService.mWindowManager.screenshotApplications(who, w, h);
}
return null;
}
@@ -686,7 +686,10 @@ public class ActivityStack {
mLastPausedActivity = prev;
prev.state = ActivityState.PAUSING;
prev.task.touchActiveTime();
- prev.thumbnail = screenshotActivities();
+ prev.thumbnail = screenshotActivities(prev);
+ if (prev.task != null) {
+ prev.task.lastThumbnail = prev.thumbnail;
+ }
mService.updateCpuStats();
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 09d9c3b6..86cec42 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -19,7 +19,7 @@ package com.android.server.am;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.ActivityInfo;
-import android.os.SystemClock;
+import android.graphics.Bitmap;
import java.io.PrintWriter;
@@ -34,6 +34,8 @@ class TaskRecord {
long lastActiveTime; // Last time this task was active, including sleep.
boolean rootWasReset; // True if the intent at the root of the task had
// the FLAG_ACTIVITY_RESET_TASK_IF_NEEDED flag.
+ Bitmap lastThumbnail; // Last thumbnail captured for this task.
+ CharSequence lastDescription; // Last description captured for this task.
String stringName; // caching of toString() result.