summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ActivityManager.java91
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java14
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityRecord.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java5
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java2
-rw-r--r--services/core/java/com/android/server/am/TaskPersister.java14
-rw-r--r--services/core/java/com/android/server/am/TaskRecord.java66
7 files changed, 165 insertions, 29 deletions
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index ac54960b61f9..351064a2fd0d 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1531,14 +1531,90 @@ public class ActivityManager {
}
}
+ /**
+ * Metadata related to the {@link TaskThumbnail}.
+ *
+ * @hide
+ */
+ public static class TaskThumbnailInfo implements Parcelable {
+ /** @hide */
+ public static final String ATTR_TASK_THUMBNAILINFO_PREFIX = "task_thumbnailinfo_";
+ private static final String ATTR_TASK_WIDTH =
+ ATTR_TASK_THUMBNAILINFO_PREFIX + "task_width";
+ private static final String ATTR_TASK_HEIGHT =
+ ATTR_TASK_THUMBNAILINFO_PREFIX + "task_height";
+ private static final String ATTR_SCREEN_ORIENTATION =
+ ATTR_TASK_THUMBNAILINFO_PREFIX + "screen_orientation";
+
+ public int taskWidth;
+ public int taskHeight;
+ public int screenOrientation;
+
+ public TaskThumbnailInfo() {
+ // Do nothing
+ }
+
+ private TaskThumbnailInfo(Parcel source) {
+ readFromParcel(source);
+ }
+
+ /** @hide */
+ public void saveToXml(XmlSerializer out) throws IOException {
+ out.attribute(null, ATTR_TASK_WIDTH, Integer.toString(taskWidth));
+ out.attribute(null, ATTR_TASK_HEIGHT, Integer.toString(taskHeight));
+ out.attribute(null, ATTR_SCREEN_ORIENTATION, Integer.toString(screenOrientation));
+ }
+
+ /** @hide */
+ public void restoreFromXml(String attrName, String attrValue) {
+ if (ATTR_TASK_WIDTH.equals(attrName)) {
+ taskWidth = Integer.parseInt(attrValue);
+ } else if (ATTR_TASK_HEIGHT.equals(attrName)) {
+ taskHeight = Integer.parseInt(attrValue);
+ } else if (ATTR_SCREEN_ORIENTATION.equals(attrName)) {
+ screenOrientation = Integer.parseInt(attrValue);
+ }
+ }
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(taskWidth);
+ dest.writeInt(taskHeight);
+ dest.writeInt(screenOrientation);
+ }
+
+ public void readFromParcel(Parcel source) {
+ taskWidth = source.readInt();
+ taskHeight = source.readInt();
+ screenOrientation = source.readInt();
+ }
+
+ public static final Creator<TaskThumbnailInfo> CREATOR = new Creator<TaskThumbnailInfo>() {
+ public TaskThumbnailInfo createFromParcel(Parcel source) {
+ return new TaskThumbnailInfo(source);
+ }
+ public TaskThumbnailInfo[] newArray(int size) {
+ return new TaskThumbnailInfo[size];
+ }
+ };
+ }
+
/** @hide */
public static class TaskThumbnail implements Parcelable {
public Bitmap mainThumbnail;
public ParcelFileDescriptor thumbnailFileDescriptor;
+ public TaskThumbnailInfo thumbnailInfo;
public TaskThumbnail() {
}
+ private TaskThumbnail(Parcel source) {
+ readFromParcel(source);
+ }
+
public int describeContents() {
if (thumbnailFileDescriptor != null) {
return thumbnailFileDescriptor.describeContents();
@@ -1559,6 +1635,12 @@ public class ActivityManager {
} else {
dest.writeInt(0);
}
+ if (thumbnailInfo != null) {
+ dest.writeInt(1);
+ thumbnailInfo.writeToParcel(dest, flags);
+ } else {
+ dest.writeInt(0);
+ }
}
public void readFromParcel(Parcel source) {
@@ -1572,6 +1654,11 @@ public class ActivityManager {
} else {
thumbnailFileDescriptor = null;
}
+ if (source.readInt() != 0) {
+ thumbnailInfo = TaskThumbnailInfo.CREATOR.createFromParcel(source);
+ } else {
+ thumbnailInfo = null;
+ }
}
public static final Creator<TaskThumbnail> CREATOR = new Creator<TaskThumbnail>() {
@@ -1582,10 +1669,6 @@ public class ActivityManager {
return new TaskThumbnail[size];
}
};
-
- private TaskThumbnail(Parcel source) {
- readFromParcel(source);
- }
}
/** @hide */
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 99e30f3370d5..0cf58b1e95e5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -114,6 +114,7 @@ import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
import com.android.server.Watchdog;
import com.android.server.am.ActivityStack.ActivityState;
+import com.android.server.am.ActivityStackSupervisor.ActivityDisplay;
import com.android.server.firewall.IntentFirewall;
import com.android.server.pm.Installer;
import com.android.server.pm.UserManagerService;
@@ -134,6 +135,7 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManager.TaskThumbnailInfo;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal.SleepToken;
import android.app.ActivityManagerNative;
@@ -8577,8 +8579,16 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ // Use the full screen as the context for the task thumbnail
+ final Point displaySize = new Point();
+ final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
+ r.task.stack.getDisplaySize(displaySize);
+ thumbnailInfo.taskWidth = displaySize.x;
+ thumbnailInfo.taskHeight = displaySize.y;
+ thumbnailInfo.screenOrientation = mConfiguration.orientation;
+
TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
- intent, description);
+ intent, description, thumbnailInfo);
int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
if (trimIdx >= 0) {
@@ -8597,7 +8607,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mRecentTasks.add(task);
r.task.stack.addTask(task, false, false);
- task.setLastThumbnail(thumbnail);
+ task.setLastThumbnailLocked(thumbnail);
task.freeLastThumbnail();
return task.taskId;
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 9278a9074c6b..aa04bd70c714 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -932,7 +932,7 @@ final class ActivityRecord {
if (newThumbnail != null) {
if (DEBUG_THUMBNAILS) Slog.i(TAG_THUMBNAILS,
"Setting thumbnail of " + this + " to " + newThumbnail);
- boolean thumbnailUpdated = task.setLastThumbnail(newThumbnail);
+ boolean thumbnailUpdated = task.setLastThumbnailLocked(newThumbnail);
if (thumbnailUpdated && isPersistable()) {
mStackSupervisor.mService.notifyTaskPersisterLocked(task, false);
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ea0db6b44a40..400ebc68026d 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -31,6 +31,7 @@ import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStackSupervisor.MOVING;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import android.graphics.Point;
import android.graphics.Rect;
import android.util.ArraySet;
@@ -388,6 +389,10 @@ final class ActivityStack {
mWindowManager.detachStack(mStackId);
}
+ public void getDisplaySize(Point out) {
+ mActivityContainer.mActivityDisplay.mDisplay.getSize(out);
+ }
+
void setBounds(Rect bounds) {
mBounds = mFullscreen ? null : new Rect(bounds);
if (mTaskPositioner != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f62442470dd8..6acaa773b2bd 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3681,7 +3681,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
void handleLaunchTaskBehindCompleteLocked(ActivityRecord r) {
r.mLaunchTaskBehind = false;
final TaskRecord task = r.task;
- task.setLastThumbnail(task.stack.screenshotActivities(r));
+ task.setLastThumbnailLocked(task.stack.screenshotActivities(r));
mRecentTasks.addLocked(task);
mService.notifyTaskStackChangedLocked();
mWindowManager.setAppVisibility(r.appToken, false);
diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 871331b770e2..150baf0e89d5 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -16,22 +16,14 @@
package com.android.server.am;
-import android.app.ActivityManager;
-import android.app.AppGlobals;
-import android.content.ComponentName;
import android.content.pm.IPackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Debug;
-import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.UserHandle;
-import android.text.format.DateUtils;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.Slog;
-import android.util.SparseArray;
import android.util.Xml;
import android.os.Process;
@@ -51,14 +43,10 @@ import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Collections;
import java.util.Comparator;
-import java.util.List;
import libcore.io.IoUtils;
-import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
-
public class TaskPersister {
static final String TAG = "TaskPersister";
static final boolean DEBUG = false;
@@ -104,6 +92,7 @@ public class TaskPersister {
private static class WriteQueueItem {}
private static class TaskWriteQueueItem extends WriteQueueItem {
final TaskRecord mTask;
+
TaskWriteQueueItem(TaskRecord task) {
mTask = task;
}
@@ -111,6 +100,7 @@ public class TaskPersister {
private static class ImageWriteQueueItem extends WriteQueueItem {
final String mFilename;
Bitmap mImage;
+
ImageWriteQueueItem(String filename, Bitmap image) {
mFilename = filename;
mImage = image;
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 803a273652d6..22c30252bcee 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -37,6 +37,8 @@ import android.app.ActivityManager;
import android.app.ActivityManager.StackId;
import android.app.ActivityManager.TaskThumbnail;
import android.app.ActivityManager.TaskDescription;
+import android.app.ActivityManager.TaskThumbnail;
+import android.app.ActivityManager.TaskThumbnailInfo;
import android.app.ActivityOptions;
import android.app.AppGlobals;
import android.content.ComponentName;
@@ -47,6 +49,7 @@ import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Debug;
import android.os.ParcelFileDescriptor;
@@ -194,6 +197,7 @@ final class TaskRecord {
private Bitmap mLastThumbnail; // Last thumbnail captured for this item.
private final File mLastThumbnailFile; // File containing last thumbnail.
private final String mFilename;
+ private TaskThumbnailInfo mLastThumbnailInfo;
CharSequence lastDescription; // Last description captured for this item.
int mAffiliatedTaskId; // taskId of parent affiliation or self if no parent.
@@ -234,6 +238,7 @@ final class TaskRecord {
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
+ mLastThumbnailInfo = new TaskThumbnailInfo();
taskId = _taskId;
mAffiliatedTaskId = _taskId;
voiceSession = _voiceSession;
@@ -247,11 +252,12 @@ final class TaskRecord {
}
TaskRecord(ActivityManagerService service, int _taskId, ActivityInfo info, Intent _intent,
- TaskDescription _taskDescription) {
+ TaskDescription _taskDescription, TaskThumbnailInfo thumbnailInfo) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
+ mLastThumbnailInfo = thumbnailInfo;
taskId = _taskId;
mAffiliatedTaskId = _taskId;
voiceSession = null;
@@ -282,12 +288,14 @@ final class TaskRecord {
int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
long _firstActiveTime, long _lastActiveTime, long lastTimeMoved,
boolean neverRelinquishIdentity, TaskDescription _lastTaskDescription,
- int taskAffiliation, int prevTaskId, int nextTaskId, int taskAffiliationColor,
- int callingUid, String callingPackage, boolean resizeable, boolean privileged) {
+ TaskThumbnailInfo lastThumbnailInfo, int taskAffiliation, int prevTaskId,
+ int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
+ boolean resizeable, boolean privileged) {
mService = service;
mFilename = String.valueOf(_taskId) + TASK_THUMBNAIL_SUFFIX +
TaskPersister.IMAGE_EXTENSION;
mLastThumbnailFile = new File(TaskPersister.sImagesDir, mFilename);
+ mLastThumbnailInfo = lastThumbnailInfo;
taskId = _taskId;
intent = _intent;
affinityIntent = _affinityIntent;
@@ -490,12 +498,40 @@ final class TaskRecord {
}
/**
- * Sets the last thumbnail.
+ * Sets the last thumbnail with the current task bounds and the system orientation.
* @return whether the thumbnail was set
*/
- boolean setLastThumbnail(Bitmap thumbnail) {
+ boolean setLastThumbnailLocked(Bitmap thumbnail) {
+ final Configuration serviceConfig = mService.mConfiguration;
+ int taskWidth = 0;
+ int taskHeight = 0;
+ if (mBounds != null) {
+ // Non-fullscreen tasks
+ taskWidth = mBounds.width();
+ taskHeight = mBounds.height();
+ } else if (stack != null) {
+ // Fullscreen tasks
+ final Point displaySize = new Point();
+ stack.getDisplaySize(displaySize);
+ taskWidth = displaySize.x;
+ taskHeight = displaySize.y;
+ } else {
+ Slog.e(TAG, "setLastThumbnailLocked() called on Task without stack");
+ }
+ return setLastThumbnailLocked(thumbnail, taskWidth, taskHeight, serviceConfig.orientation);
+ }
+
+ /**
+ * Sets the last thumbnail with the current task bounds.
+ * @return whether the thumbnail was set
+ */
+ private boolean setLastThumbnailLocked(Bitmap thumbnail, int taskWidth, int taskHeight,
+ int screenOrientation) {
if (mLastThumbnail != thumbnail) {
mLastThumbnail = thumbnail;
+ mLastThumbnailInfo.taskWidth = taskWidth;
+ mLastThumbnailInfo.taskHeight = taskHeight;
+ mLastThumbnailInfo.screenOrientation = screenOrientation;
if (thumbnail == null) {
if (mLastThumbnailFile != null) {
mLastThumbnailFile.delete();
@@ -510,6 +546,7 @@ final class TaskRecord {
void getLastThumbnail(TaskThumbnail thumbs) {
thumbs.mainThumbnail = mLastThumbnail;
+ thumbs.thumbnailInfo = mLastThumbnailInfo;
thumbs.thumbnailFileDescriptor = null;
if (mLastThumbnail == null) {
thumbs.mainThumbnail = mService.mTaskPersister.getImageFromWriteQueue(mFilename);
@@ -524,12 +561,19 @@ final class TaskRecord {
}
}
+ /**
+ * Removes in-memory thumbnail data when the max number of in-memory task thumbnails is reached.
+ */
void freeLastThumbnail() {
mLastThumbnail = null;
}
+ /**
+ * Removes all associated thumbnail data when a task is removed or pruned from recents.
+ */
void disposeThumbnail() {
mLastThumbnail = null;
+ mLastThumbnailInfo = null;
lastDescription = null;
}
@@ -779,7 +823,7 @@ final class TaskRecord {
final ActivityRecord resumedActivity = stack.mResumedActivity;
if (resumedActivity != null && resumedActivity.task == this) {
final Bitmap thumbnail = stack.screenshotActivities(resumedActivity);
- setLastThumbnail(thumbnail);
+ setLastThumbnailLocked(thumbnail);
}
}
final TaskThumbnail taskThumbnail = new TaskThumbnail();
@@ -991,6 +1035,7 @@ final class TaskRecord {
if (lastTaskDescription != null) {
lastTaskDescription.saveToXml(out);
}
+ mLastThumbnailInfo.saveToXml(out);
out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
out.attribute(null, ATTR_PREV_AFFILIATION, String.valueOf(mPrevAffiliateTaskId));
@@ -1035,7 +1080,7 @@ final class TaskRecord {
throws IOException, XmlPullParserException {
Intent intent = null;
Intent affinityIntent = null;
- ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
+ ArrayList<ActivityRecord> activities = new ArrayList<>();
ComponentName realActivity = null;
ComponentName origActivity = null;
String affinity = null;
@@ -1055,6 +1100,7 @@ final class TaskRecord {
int taskId = INVALID_TASK_ID;
final int outerDepth = in.getDepth();
TaskDescription taskDescription = new TaskDescription();
+ TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
int taskAffiliation = INVALID_TASK_ID;
int taskAffiliationColor = 0;
int prevTaskId = INVALID_TASK_ID;
@@ -1103,6 +1149,8 @@ final class TaskRecord {
lastTimeOnTop = Long.valueOf(attrValue);
} else if (ATTR_NEVERRELINQUISH.equals(attrName)) {
neverRelinquishIdentity = Boolean.valueOf(attrValue);
+ } else if (attrName.startsWith(TaskThumbnailInfo.ATTR_TASK_THUMBNAILINFO_PREFIX)) {
+ thumbnailInfo.restoreFromXml(attrName, attrValue);
} else if (attrName.startsWith(TaskDescription.ATTR_TASKDESCRIPTION_PREFIX)) {
taskDescription.restoreFromXml(attrName, attrValue);
} else if (ATTR_TASK_AFFILIATION.equals(attrName)) {
@@ -1181,8 +1229,8 @@ final class TaskRecord {
affinityIntent, affinity, rootAffinity, realActivity, origActivity, rootHasReset,
autoRemoveRecents, askedCompatMode, taskType, userId, effectiveUid, lastDescription,
activities, firstActiveTime, lastActiveTime, lastTimeOnTop, neverRelinquishIdentity,
- taskDescription, taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor,
- callingUid, callingPackage, resizeable, privileged);
+ taskDescription, thumbnailInfo, taskAffiliation, prevTaskId, nextTaskId,
+ taskAffiliationColor, callingUid, callingPackage, resizeable, privileged);
task.updateOverrideConfiguration(bounds);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {