OSDN Git Service

Handle content insets for snapshots
authorJorim Jaggi <jjaggi@google.com>
Thu, 29 Dec 2016 13:57:22 +0000 (14:57 +0100)
committerJorim Jaggi <jjaggi@google.com>
Thu, 12 Jan 2017 15:28:19 +0000 (16:28 +0100)
Pass information about content insets of a snapshotted task to
SystemUI and use it there to correctly offset the snapshot
when drawing.

Test: Open app, go to recents, make sure app aligns before
and after the animation.
Bug: 31339431
Change-Id: I2ff9bd44534bd8f66b591385da1e1e3aec40b6c5

21 files changed:
core/java/android/app/ActivityManager.aidl
core/java/android/app/ActivityManager.java
core/java/android/app/IActivityManager.aidl
core/java/android/view/IWindowManager.aidl
core/java/android/view/WindowManager.aidl
core/java/android/view/WindowManager.java
packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
packages/SystemUI/src/com/android/systemui/recents/model/Task.java
packages/SystemUI/src/com/android/systemui/recents/model/ThumbnailData.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
packages/SystemUI/src/com/android/systemui/recents/views/grid/GridTaskView.java
services/core/java/com/android/server/am/ActivityManagerService.java
services/core/java/com/android/server/am/TaskRecord.java
services/core/java/com/android/server/wm/AppWindowContainerController.java
services/core/java/com/android/server/wm/TaskSnapshotCache.java
services/core/java/com/android/server/wm/TaskSnapshotController.java
services/core/java/com/android/server/wm/TaskWindowContainerController.java
services/core/java/com/android/server/wm/WindowManagerService.java
tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java

index 5672f6b..29260e9 100644 (file)
@@ -26,4 +26,6 @@ parcelable ActivityManager.RunningTaskInfo;
 /** @hide */
 parcelable ActivityManager.StackInfo;
 /** @hide */
-parcelable ActivityManager.TaskThumbnail;
\ No newline at end of file
+parcelable ActivityManager.TaskThumbnail;
+/** @hide */
+parcelable ActivityManager.TaskSnapshot;
\ No newline at end of file
index 2f8089d..3170d0d 100644 (file)
@@ -26,6 +26,7 @@ import android.annotation.TestApi;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
+import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.Point;
 import android.os.BatteryStats;
@@ -2125,6 +2126,62 @@ public class ActivityManager {
         };
     }
 
+    /**
+     * Represents a task snapshot.
+     * @hide
+     */
+    public static class TaskSnapshot implements Parcelable {
+
+        private final GraphicBuffer mSnapshot;
+        private final int mOrientation;
+        private final Rect mContentInsets;
+
+        public TaskSnapshot(GraphicBuffer snapshot, int orientation, Rect contentInsets) {
+            mSnapshot = snapshot;
+            mOrientation = orientation;
+            mContentInsets = new Rect(contentInsets);
+        }
+
+        private TaskSnapshot(Parcel source) {
+            mSnapshot = source.readParcelable(null /* classLoader */);
+            mOrientation = source.readInt();
+            mContentInsets = source.readParcelable(null /* classLoader */);
+        }
+
+        public GraphicBuffer getSnapshot() {
+            return mSnapshot;
+        }
+
+        public int getOrientation() {
+            return mOrientation;
+        }
+
+        public Rect getContentInsets() {
+            return mContentInsets;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeParcelable(mSnapshot, 0);
+            dest.writeInt(mOrientation);
+            dest.writeParcelable(mContentInsets, 0);
+        }
+
+        public static final Creator<TaskSnapshot> CREATOR = new Creator<TaskSnapshot>() {
+            public TaskSnapshot createFromParcel(Parcel source) {
+                return new TaskSnapshot(source);
+            }
+            public TaskSnapshot[] newArray(int size) {
+                return new TaskSnapshot[size];
+            }
+        };
+    }
+
     /** @hide */
     public TaskThumbnail getTaskThumbnail(int id) throws SecurityException {
         try {
index a4c80b8..21ae853 100644 (file)
@@ -600,7 +600,7 @@ interface IActivityManager {
     /**
      * @return a graphic buffer representing a screenshot of a task
      */
-    GraphicBuffer getTaskSnapshot(int taskId);
+    ActivityManager.TaskSnapshot getTaskSnapshot(int taskId);
 
     // WARNING: when these transactions are updated, check if they are any callers on the native
     // side. If so, make sure they are using the correct transaction ids and arguments.
index c0ebd2c..19edb5c 100644 (file)
@@ -48,6 +48,7 @@ import android.view.InputDevice;
 import android.view.IInputFilter;
 import android.view.AppTransitionAnimationSpec;
 import android.view.WindowContentFrameStats;
+import android.view.WindowManager;
 
 /**
  * System private interface to the window manager.
index 556dc72..1363f05 100644 (file)
@@ -18,4 +18,5 @@
 package android.view;
 
 parcelable WindowManager.LayoutParams;
-
+/** @hide */
+parcelable WindowManager.TaskSnapshot;
index aac3c18..e5a6ebd 100644 (file)
@@ -22,6 +22,7 @@ import android.app.KeyguardManager;
 import android.app.Presentation;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
+import android.graphics.GraphicBuffer;
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.os.IBinder;
index 08970e4..3587b89 100644 (file)
@@ -22,11 +22,9 @@ import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
 
 import android.app.ActivityManager;
-import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityOptions;
 import android.app.AppGlobals;
 import android.app.IActivityManager;
@@ -47,7 +45,6 @@ import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.GraphicBuffer;
 import android.graphics.Paint;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
@@ -83,7 +80,6 @@ import com.android.internal.os.BackgroundThread;
 import com.android.systemui.R;
 import com.android.systemui.pip.tv.PipMenuActivity;
 import com.android.systemui.pip.tv.PipOnboardingActivity;
-import com.android.systemui.recents.Constants;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recents.RecentsDebugFlags;
 import com.android.systemui.recents.RecentsImpl;
@@ -631,21 +627,19 @@ public class SystemServicesProxy {
         }
 
         if (ActivityManager.ENABLE_TASK_SNAPSHOTS) {
-            GraphicBuffer graphicBuffer = null;
+            ActivityManager.TaskSnapshot snapshot = null;
             try {
-                graphicBuffer = ActivityManager.getService().getTaskSnapshot(taskId);
+                snapshot = ActivityManager.getService().getTaskSnapshot(taskId);
             } catch (RemoteException e) {
                 Log.w(TAG, "Failed to retrieve snapshot", e);
             }
-            if (graphicBuffer != null) {
-                thumbnailDataOut.thumbnail = Bitmap.createHardwareBitmap(graphicBuffer);
+            if (snapshot != null) {
+                thumbnailDataOut.thumbnail = Bitmap.createHardwareBitmap(snapshot.getSnapshot());
+                thumbnailDataOut.orientation = snapshot.getOrientation();
+                thumbnailDataOut.insets.set(snapshot.getContentInsets());
             } else {
                 thumbnailDataOut.thumbnail = null;
             }
-
-            // TODO: Retrieve screen orientation.
-            thumbnailDataOut.thumbnailInfo = new TaskThumbnailInfo();
-            thumbnailDataOut.thumbnailInfo.screenOrientation = ORIENTATION_PORTRAIT;
         } else {
             ActivityManager.TaskThumbnail taskThumbnail = mAm.getTaskThumbnail(taskId);
             if (taskThumbnail == null) {
@@ -665,7 +659,8 @@ public class SystemServicesProxy {
                 }
             }
             thumbnailDataOut.thumbnail = thumbnail;
-            thumbnailDataOut.thumbnailInfo = taskThumbnail.thumbnailInfo;
+            thumbnailDataOut.orientation = taskThumbnail.thumbnailInfo.screenOrientation;
+            thumbnailDataOut.insets.setEmpty();
         }
     }
 
index ba31e3e..6ea51e5 100644 (file)
@@ -220,8 +220,7 @@ class BackgroundTaskLoader implements Runnable {
                             mMainThreadHandler.post(new Runnable() {
                                 @Override
                                 public void run() {
-                                    t.notifyTaskDataLoaded(newThumbnailData.thumbnail, newIcon,
-                                            newThumbnailData.thumbnailInfo);
+                                    t.notifyTaskDataLoaded(newThumbnailData, newIcon);
                                 }
                             });
                         }
@@ -364,11 +363,9 @@ public class RecentsTaskLoader {
     public void loadTaskData(Task t) {
         Drawable icon = mIconCache.getAndInvalidateIfModified(t.key);
         Bitmap thumbnail = null;
-        ActivityManager.TaskThumbnailInfo thumbnailInfo = null;
         ThumbnailData thumbnailData = mThumbnailCache.getAndInvalidateIfModified(t.key);
         if (thumbnailData != null) {
             thumbnail = thumbnailData.thumbnail;
-            thumbnailInfo = thumbnailData.thumbnailInfo;
         }
 
         // Grab the thumbnail/icon from the cache, if either don't exist, then trigger a reload and
@@ -378,8 +375,7 @@ public class RecentsTaskLoader {
         if (requiresLoad) {
             mLoadQueue.addTask(t);
         }
-        t.notifyTaskDataLoaded(thumbnail == mDefaultThumbnail ? null : thumbnail, icon,
-                thumbnailInfo);
+        t.notifyTaskDataLoaded(thumbnail == mDefaultThumbnail ? null : thumbnailData, icon);
     }
 
     /** Releases the task resource data back into the pool. */
index 53f713a..2f2e866 100644 (file)
@@ -45,7 +45,7 @@ public class Task {
     /* Task callbacks */
     public interface TaskCallbacks {
         /* Notifies when a task has been bound */
-        public void onTaskDataLoaded(Task task, ActivityManager.TaskThumbnailInfo thumbnailInfo);
+        public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData);
         /* Notifies when a task has been unbound */
         public void onTaskDataUnloaded();
         /* Notifies when a task's stack id has changed. */
@@ -299,13 +299,12 @@ public class Task {
     }
 
     /** Notifies the callback listeners that this task has been loaded */
-    public void notifyTaskDataLoaded(Bitmap thumbnail, Drawable applicationIcon,
-            ActivityManager.TaskThumbnailInfo thumbnailInfo) {
+    public void notifyTaskDataLoaded(ThumbnailData thumbnailData, Drawable applicationIcon) {
         this.icon = applicationIcon;
-        this.thumbnail = thumbnail;
+        this.thumbnail = thumbnailData != null ? thumbnailData.thumbnail : null;
         int callbackCount = mCallbacks.size();
         for (int i = 0; i < callbackCount; i++) {
-            mCallbacks.get(i).onTaskDataLoaded(this, thumbnailInfo);
+            mCallbacks.get(i).onTaskDataLoaded(this, thumbnailData);
         }
     }
 
index d0cdae5..18735ac 100644 (file)
 
 package com.android.systemui.recents.model;
 
-import android.app.ActivityManager;
 import android.graphics.Bitmap;
+import android.graphics.Rect;
 
 /**
  * Data for a single thumbnail.
  */
 public class ThumbnailData {
     public Bitmap thumbnail;
-    public ActivityManager.TaskThumbnailInfo thumbnailInfo;
+    public int orientation;
+    public final Rect insets = new Rect();
 }
index 36d5f83..5f37349 100644 (file)
@@ -57,6 +57,7 @@ import com.android.systemui.recents.misc.SystemServicesProxy;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
 import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.model.ThumbnailData;
 
 import java.io.PrintWriter;
 import java.util.ArrayList;
@@ -620,9 +621,9 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
     }
 
     @Override
-    public void onTaskDataLoaded(Task task, ActivityManager.TaskThumbnailInfo thumbnailInfo) {
+    public void onTaskDataLoaded(Task task, ThumbnailData thumbnailData) {
         // Update each of the views to the new task data
-        mThumbnailView.onTaskDataLoaded(thumbnailInfo);
+        mThumbnailView.onTaskDataLoaded(thumbnailData);
         mHeaderView.onTaskDataLoaded();
     }
 
index 1a81446..3ae51b0 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.android.systemui.recents.views;
 
-import android.app.ActivityManager;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
@@ -37,7 +36,7 @@ import android.view.ViewDebug;
 import com.android.systemui.R;
 import com.android.systemui.recents.misc.Utilities;
 import com.android.systemui.recents.model.Task;
-
+import com.android.systemui.recents.model.ThumbnailData;
 import java.io.PrintWriter;
 
 
@@ -65,12 +64,12 @@ public class TaskViewThumbnail extends View {
     private float mFullscreenThumbnailScale;
     private boolean mSizeToFit = false;
     private boolean mOverlayHeaderOnThumbnailActionBar = true;
-    private ActivityManager.TaskThumbnailInfo mThumbnailInfo;
+    private ThumbnailData mThumbnailData;
 
     private int mCornerRadius;
     @ViewDebug.ExportedProperty(category="recents")
     private float mDimAlpha;
-    private Matrix mScaleMatrix = new Matrix();
+    private Matrix mMatrix = new Matrix();
     private Paint mDrawPaint = new Paint();
     private Paint mLockedPaint = new Paint();
     private Paint mBgFillPaint = new Paint();
@@ -125,7 +124,7 @@ public class TaskViewThumbnail extends View {
 
         mTaskViewRect.set(0, 0, width, height);
         setLeftTopRightBottom(0, 0, width, height);
-        updateThumbnailScale();
+        updateThumbnailMatrix();
     }
 
     @Override
@@ -174,19 +173,22 @@ public class TaskViewThumbnail extends View {
     }
 
     /** Sets the thumbnail to a given bitmap. */
-    void setThumbnail(Bitmap bm, ActivityManager.TaskThumbnailInfo thumbnailInfo) {
-        if (bm != null) {
+    void setThumbnail(ThumbnailData thumbnailData) {
+        if (thumbnailData != null && thumbnailData.thumbnail != null) {
+            Bitmap bm = thumbnailData.thumbnail;
             bm.prepareToDraw();
             mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
             mDrawPaint.setShader(mBitmapShader);
-            mThumbnailRect.set(0, 0, bm.getWidth(), bm.getHeight());
-            mThumbnailInfo = thumbnailInfo;
-            updateThumbnailScale();
+            mThumbnailRect.set(0, 0,
+                    bm.getWidth() - thumbnailData.insets.left - thumbnailData.insets.right,
+                    bm.getHeight() - thumbnailData.insets.top - thumbnailData.insets.bottom);
+            mThumbnailData = thumbnailData;
+            updateThumbnailMatrix();
         } else {
             mBitmapShader = null;
             mDrawPaint.setShader(null);
             mThumbnailRect.setEmpty();
-            mThumbnailInfo = null;
+            mThumbnailData = null;
         }
     }
 
@@ -233,20 +235,21 @@ public class TaskViewThumbnail extends View {
     /**
      * Updates the scale of the bitmap relative to this view.
      */
-    public void updateThumbnailScale() {
+    public void updateThumbnailMatrix() {
         mThumbnailScale = 1f;
-        if (mBitmapShader != null) {
+        if (mBitmapShader != null && mThumbnailData != null) {
             // We consider this a stack task if it is not freeform (ie. has no bounds) or has been
             // dragged into the stack from the freeform workspace
             boolean isStackTask = !mTask.isFreeformTask() || mTask.bounds == null;
-            if (mTaskViewRect.isEmpty() || mThumbnailInfo == null) {
-                // If we haven't measured or the thumbnail is invalid, skip the thumbnail drawing
-                // and only draw the background color
+            int xOffset, yOffset = 0;
+            if (mTaskViewRect.isEmpty()) {
+                // If we haven't measured , skip the thumbnail drawing and only draw the background
+                // color
                 mThumbnailScale = 0f;
             } else if (isStackTask && !mSizeToFit) {
                 float invThumbnailScale = 1f / mFullscreenThumbnailScale;
                 if (mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT) {
-                    if (mThumbnailInfo.screenOrientation == Configuration.ORIENTATION_PORTRAIT) {
+                    if (mThumbnailData.orientation == Configuration.ORIENTATION_PORTRAIT) {
                         // If we are in the same orientation as the screenshot, just scale it to the
                         // width of the task view
                         mThumbnailScale = (float) mTaskViewRect.width() / mThumbnailRect.width();
@@ -267,8 +270,9 @@ public class TaskViewThumbnail extends View {
                         (float) mTaskViewRect.width() / mThumbnailRect.width(),
                         (float) mTaskViewRect.height() / mThumbnailRect.height());
             }
-            mScaleMatrix.setScale(mThumbnailScale, mThumbnailScale);
-            mBitmapShader.setLocalMatrix(mScaleMatrix);
+            mMatrix.setTranslate(-mThumbnailData.insets.left, -mThumbnailData.insets.top);
+            mMatrix.postScale(mThumbnailScale, mThumbnailScale);
+            mBitmapShader.setLocalMatrix(mMatrix);
         }
         if (!mInvisible) {
             invalidate();
@@ -332,18 +336,14 @@ public class TaskViewThumbnail extends View {
      * Called when the bound task's data has loaded and this view should update to reflect the
      * changes.
      */
-    void onTaskDataLoaded(ActivityManager.TaskThumbnailInfo thumbnailInfo) {
-        if (mTask.thumbnail != null) {
-            setThumbnail(mTask.thumbnail, thumbnailInfo);
-        } else {
-            setThumbnail(null, null);
-        }
+    void onTaskDataLoaded(ThumbnailData thumbnailData) {
+        setThumbnail(thumbnailData);
     }
 
     /** Unbinds the thumbnail view from the task */
     void unbindFromTask() {
         mTask = null;
-        setThumbnail(null, null);
+        setThumbnail(null);
     }
 
     public void dump(String prefix, PrintWriter writer) {
index 6300400..a86abf6 100644 (file)
@@ -51,7 +51,7 @@ public class GridTaskView extends TaskView {
         // Show the full thumbnail and don't overlap with the header.
         mThumbnailView.setSizeToFit(true);
         mThumbnailView.setOverlayHeaderOnThumbnailActionBar(false);
-        mThumbnailView.updateThumbnailScale();
+        mThumbnailView.updateThumbnailMatrix();
         mThumbnailView.setTranslationY(mHeaderHeight);
     }
 
index 5437ad2..74304f0 100644 (file)
@@ -148,6 +148,7 @@ import android.app.ActivityManager;
 import android.app.ActivityManager.RunningTaskInfo;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.StackInfo;
+import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityManagerInternal;
 import android.app.ActivityManagerInternal.PictureInPictureArguments;
@@ -9654,7 +9655,7 @@ public class ActivityManagerService extends IActivityManager.Stub
     }
 
     @Override
-    public GraphicBuffer getTaskSnapshot(int taskId) {
+    public TaskSnapshot getTaskSnapshot(int taskId) {
         enforceCallingPermission(READ_FRAME_BUFFER, "getTaskSnapshot()");
         final long ident = Binder.clearCallingIdentity();
         try {
index 4e44c5f..9e22c50 100644 (file)
@@ -21,6 +21,7 @@ import android.app.Activity;
 import android.app.ActivityManager;
 import android.app.ActivityManager.StackId;
 import android.app.ActivityManager.TaskDescription;
+import android.app.ActivityManager.TaskSnapshot;
 import android.app.ActivityManager.TaskThumbnail;
 import android.app.ActivityManager.TaskThumbnailInfo;
 import android.app.ActivityOptions;
@@ -546,7 +547,7 @@ final class TaskRecord extends ConfigurationContainer {
         mWindowContainerController.cancelThumbnailTransition();
     }
 
-    public GraphicBuffer getSnapshot() {
+    public TaskSnapshot getSnapshot() {
         if (mWindowContainerController == null) {
             return null;
         }
index 4dbe35f..1eb74fa 100644 (file)
@@ -28,10 +28,10 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TOKEN_MOVEMEN
 import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
+import android.app.ActivityManager.TaskSnapshot;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
-import android.graphics.GraphicBuffer;
 import android.os.Debug;
 import android.os.Handler;
 import android.os.IBinder;
@@ -489,14 +489,15 @@ public class AppWindowContainerController
     }
 
     private boolean createSnapshot() {
-        final GraphicBuffer snapshot = mService.mTaskSnapshotController.getSnapshot(
+        final TaskSnapshot snapshot = mService.mTaskSnapshotController.getSnapshot(
                 mContainer.mTask);
 
         if (snapshot == null) {
             return false;
         }
 
-        mContainer.startingData = new SnapshotStartingData(mService, mContainer, snapshot);
+        mContainer.startingData = new SnapshotStartingData(mService, mContainer,
+                snapshot.getSnapshot());
         scheduleAddStartingWindow();
         return true;
     }
index b4fa5a5..994a155 100644 (file)
@@ -17,7 +17,7 @@
 package com.android.server.wm;
 
 import android.annotation.Nullable;
-import android.graphics.GraphicBuffer;
+import android.app.ActivityManager.TaskSnapshot;
 import android.util.ArrayMap;
 
 /**
@@ -27,13 +27,13 @@ import android.util.ArrayMap;
  */
 class TaskSnapshotCache {
 
-    private final ArrayMap<Task, GraphicBuffer> mCache = new ArrayMap<>();
+    private final ArrayMap<Task, TaskSnapshot> mCache = new ArrayMap<>();
 
-    void putSnapshot(Task task, GraphicBuffer snapshot) {
+    void putSnapshot(Task task, TaskSnapshot snapshot) {
         mCache.put(task, snapshot);
     }
 
-    @Nullable GraphicBuffer getSnapshot(Task task) {
+    @Nullable TaskSnapshot getSnapshot(Task task) {
         return mCache.get(task);
     }
 }
index d08c744..4421d61 100644 (file)
@@ -25,6 +25,7 @@ import static android.graphics.PixelFormat.RGBA_8888;
 
 import android.annotation.Nullable;
 import android.app.ActivityManager.StackId;
+import android.app.ActivityManager.TaskSnapshot;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.GraphicBuffer;
@@ -70,14 +71,14 @@ class TaskSnapshotController {
             if (!canSnapshotTask(task)) {
                 continue;
             }
-            final GraphicBuffer graphicBuffer = snapshotTask(task);
-            if (graphicBuffer != null) {
-                mCache.putSnapshot(task, graphicBuffer);
+            final TaskSnapshot snapshot = snapshotTask(task);
+            if (snapshot != null) {
+                mCache.putSnapshot(task, snapshot);
             }
         }
     }
 
-    @Nullable GraphicBuffer getSnapshot(Task task) {
+    @Nullable TaskSnapshot getSnapshot(Task task) {
         return mCache.getSnapshot(task);
     }
 
@@ -90,7 +91,7 @@ class TaskSnapshotController {
         return TaskSnapshotSurface.create(mService, token, snapshot);
     }
 
-    private GraphicBuffer snapshotTask(Task task) {
+    private TaskSnapshot snapshotTask(Task task) {
         final AppWindowToken top = (AppWindowToken) task.getTop();
         if (top == null) {
             return null;
@@ -106,7 +107,8 @@ class TaskSnapshotController {
         final Canvas c = buffer.lockCanvas();
         c.drawBitmap(bmp, 0, 0, null);
         buffer.unlockCanvasAndPost(c);
-        return buffer;
+        return new TaskSnapshot(buffer, top.getConfiguration().orientation,
+                top.findMainWindow().mStableInsets);
     }
 
     /**
index 1d598e7..0e4d048 100644 (file)
@@ -16,6 +16,7 @@
 
 package com.android.server.wm;
 
+import android.app.ActivityManager.TaskSnapshot;
 import android.content.res.Configuration;
 import android.graphics.GraphicBuffer;
 import android.graphics.Rect;
@@ -242,7 +243,7 @@ public class TaskWindowContainerController
     /**
      * @return a graphic buffer representing a screenshot of a task
      */
-    public GraphicBuffer getSnapshot() {
+    public TaskSnapshot getSnapshot() {
         synchronized (mWindowMap) {
             if (mContainer == null) {
                 Slog.w(TAG_WM, "getSnapshot: taskId " + mTaskId + " not found.");
index 3639fb0..195d4c3 100644 (file)
 
 package com.android.server.wm;
 
+import static android.Manifest.permission.MANAGE_APP_TOKENS;
+import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
+import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
+import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
+import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.StatusBarManager.DISABLE_MASK;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.WindowManager.DOCKED_INVALID;
+import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
+import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
+import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
+import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
+import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
+import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
+import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
+import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
+import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
+import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
+import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
+import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
+import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
+import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
+import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
+import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
+import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
+import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
+import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
+import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
+
 import android.Manifest;
 import android.Manifest.permission;
 import android.animation.ValueAnimator;
@@ -39,9 +113,8 @@ import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.database.ContentObserver;
 import android.graphics.Bitmap;
-import android.graphics.GraphicBuffer;
-import android.graphics.PixelFormat;
 import android.graphics.Matrix;
+import android.graphics.PixelFormat;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
@@ -89,7 +162,6 @@ import android.view.Choreographer;
 import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.Gravity;
-import android.view.PointerIcon;
 import android.view.IAppTransitionAnimationSpecsFuture;
 import android.view.IDockedStackListener;
 import android.view.IInputFilter;
@@ -108,6 +180,7 @@ import android.view.InputEventReceiver;
 import android.view.KeyEvent;
 import android.view.MagnificationSpec;
 import android.view.MotionEvent;
+import android.view.PointerIcon;
 import android.view.Surface;
 import android.view.Surface.OutOfResourcesException;
 import android.view.SurfaceControl;
@@ -162,84 +235,6 @@ import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 
-import static android.Manifest.permission.MANAGE_APP_TOKENS;
-import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
-import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
-import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
-import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
-import static android.app.StatusBarManager.DISABLE_MASK;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.WindowManager.DOCKED_INVALID;
-import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
-import static android.view.WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD;
-import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
-import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
-import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
-import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
-import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
-import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
-import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
-import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
-import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
-import static android.view.WindowManager.LayoutParams.TYPE_DRAG;
-import static android.view.WindowManager.LayoutParams.TYPE_DREAM;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
-import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION;
-import static android.view.WindowManager.LayoutParams.TYPE_QS_DIALOG;
-import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
-import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
-import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
-import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
-import static android.view.WindowManagerGlobal.RELAYOUT_DEFER_SURFACE_DESTROY;
-import static android.view.WindowManagerGlobal.RELAYOUT_RES_SURFACE_CHANGED;
-import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
-import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
-import static com.android.server.EventLogTags.WM_TASK_CREATED;
-import static com.android.server.wm.AppTransition.TRANSIT_UNSET;
-import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
-import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
-import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
-import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
-import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
-import static com.android.server.wm.WindowContainer.POSITION_TOP;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_CONFIGURATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_FOCUS_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_KEEP_SCREEN_ON;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_LAYOUT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ORIENTATION;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREEN_ON;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STARTING_WINDOW;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_VISIBILITY;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_MOVEMENT;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WINDOW_TRACE;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_STACK_CRAWLS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.SHOW_VERBOSE_TRANSACTIONS;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_KEEP_SCREEN_ON;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
-
 /** {@hide} */
 public class WindowManagerService extends IWindowManager.Stub
         implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs {
index 33f1476..5ed5460 100644 (file)
 
 package android.view;
 
-import android.graphics.GraphicBuffer;
-import android.graphics.Point;
-import android.graphics.Rect;
-import com.android.internal.app.IAssistScreenshotReceiver;
-import com.android.internal.os.IResultReceiver;
-import com.android.internal.policy.IKeyguardDismissCallback;
-import com.android.internal.policy.IShortcutService;
-import com.android.internal.view.IInputContext;
-import com.android.internal.view.IInputMethodClient;
-
-import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Point;
+import android.graphics.Rect;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.IRemoteCallback;
@@ -36,7 +27,12 @@ import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.util.DisplayMetrics;
 
-import java.lang.Override;
+import com.android.internal.app.IAssistScreenshotReceiver;
+import com.android.internal.os.IResultReceiver;
+import com.android.internal.policy.IKeyguardDismissCallback;
+import com.android.internal.policy.IShortcutService;
+import com.android.internal.view.IInputContext;
+import com.android.internal.view.IInputMethodClient;
 
 /**
  * Basic implementation of {@link IWindowManager} so that {@link Display} (and