Merge "Fix issue with task snapshots being taken too late" into udc-dev
This commit is contained in:
@@ -28,6 +28,7 @@ import android.hardware.HardwareBuffer;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.os.SystemClock;
|
||||
import android.view.Surface;
|
||||
import android.view.WindowInsetsController;
|
||||
|
||||
@@ -38,6 +39,9 @@ import android.view.WindowInsetsController;
|
||||
public class TaskSnapshot implements Parcelable {
|
||||
// Identifier of this snapshot
|
||||
private final long mId;
|
||||
// The elapsed real time (in nanoseconds) when this snapshot was captured, not intended for use outside the
|
||||
// process in which the snapshot was taken (ie. this is not parceled)
|
||||
private final long mCaptureTime;
|
||||
// Top activity in task when snapshot was taken
|
||||
private final ComponentName mTopActivityComponent;
|
||||
private final HardwareBuffer mSnapshot;
|
||||
@@ -65,7 +69,7 @@ public class TaskSnapshot implements Parcelable {
|
||||
// Must be one of the named color spaces, otherwise, always use SRGB color space.
|
||||
private final ColorSpace mColorSpace;
|
||||
|
||||
public TaskSnapshot(long id,
|
||||
public TaskSnapshot(long id, long captureTime,
|
||||
@NonNull ComponentName topActivityComponent, HardwareBuffer snapshot,
|
||||
@NonNull ColorSpace colorSpace, int orientation, int rotation, Point taskSize,
|
||||
Rect contentInsets, Rect letterboxInsets, boolean isLowResolution,
|
||||
@@ -73,6 +77,7 @@ public class TaskSnapshot implements Parcelable {
|
||||
@WindowInsetsController.Appearance int appearance, boolean isTranslucent,
|
||||
boolean hasImeSurface) {
|
||||
mId = id;
|
||||
mCaptureTime = captureTime;
|
||||
mTopActivityComponent = topActivityComponent;
|
||||
mSnapshot = snapshot;
|
||||
mColorSpace = colorSpace.getId() < 0
|
||||
@@ -92,6 +97,7 @@ public class TaskSnapshot implements Parcelable {
|
||||
|
||||
private TaskSnapshot(Parcel source) {
|
||||
mId = source.readLong();
|
||||
mCaptureTime = SystemClock.elapsedRealtimeNanos();
|
||||
mTopActivityComponent = ComponentName.readFromParcel(source);
|
||||
mSnapshot = source.readTypedObject(HardwareBuffer.CREATOR);
|
||||
int colorSpaceId = source.readInt();
|
||||
@@ -118,6 +124,14 @@ public class TaskSnapshot implements Parcelable {
|
||||
return mId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The elapsed real time (in nanoseconds) when this snapshot was captured. This time is
|
||||
* only valid in the process where this snapshot was taken.
|
||||
*/
|
||||
public long getCaptureTime() {
|
||||
return mCaptureTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The top activity component for the task at the point this snapshot was taken.
|
||||
*/
|
||||
@@ -268,6 +282,7 @@ public class TaskSnapshot implements Parcelable {
|
||||
final int height = mSnapshot != null ? mSnapshot.getHeight() : 0;
|
||||
return "TaskSnapshot{"
|
||||
+ " mId=" + mId
|
||||
+ " mCaptureTime=" + mCaptureTime
|
||||
+ " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
|
||||
+ " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
|
||||
+ " mColorSpace=" + mColorSpace.toString()
|
||||
@@ -296,6 +311,7 @@ public class TaskSnapshot implements Parcelable {
|
||||
/** Builder for a {@link TaskSnapshot} object */
|
||||
public static final class Builder {
|
||||
private long mId;
|
||||
private long mCaptureTime;
|
||||
private ComponentName mTopActivity;
|
||||
private HardwareBuffer mSnapshot;
|
||||
private ColorSpace mColorSpace;
|
||||
@@ -317,6 +333,11 @@ public class TaskSnapshot implements Parcelable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCaptureTime(long captureTime) {
|
||||
mCaptureTime = captureTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTopActivityComponent(ComponentName name) {
|
||||
mTopActivity = name;
|
||||
return this;
|
||||
@@ -400,6 +421,7 @@ public class TaskSnapshot implements Parcelable {
|
||||
public TaskSnapshot build() {
|
||||
return new TaskSnapshot(
|
||||
mId,
|
||||
mCaptureTime,
|
||||
mTopActivity,
|
||||
mSnapshot,
|
||||
mColorSpace,
|
||||
|
||||
@@ -88,6 +88,7 @@ public class SnapshotDrawerUtilsTest {
|
||||
1, HardwareBuffer.USAGE_CPU_READ_RARELY);
|
||||
return new TaskSnapshot(
|
||||
System.currentTimeMillis(),
|
||||
0 /* captureTime */,
|
||||
new ComponentName("", ""), buffer,
|
||||
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
|
||||
Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
|
||||
|
||||
@@ -1135,6 +1135,12 @@
|
||||
"group": "WM_DEBUG_RECENTS_ANIMATIONS",
|
||||
"at": "com\/android\/server\/wm\/RecentsAnimation.java"
|
||||
},
|
||||
"-1060529098": {
|
||||
"message": " Skipping post-transition snapshot for task %d",
|
||||
"level": "VERBOSE",
|
||||
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
|
||||
"at": "com\/android\/server\/wm\/Transition.java"
|
||||
},
|
||||
"-1060365734": {
|
||||
"message": "Attempted to add QS dialog window with bad token %s. Aborting.",
|
||||
"level": "WARN",
|
||||
|
||||
@@ -264,21 +264,18 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
|
||||
void cancel(String reason) {
|
||||
// restoring (to-home = false) involves submitting more WM changes, so by default, use
|
||||
// toHome = true when canceling.
|
||||
cancel(true /* toHome */, reason);
|
||||
cancel(true /* toHome */, false /* withScreenshots */, reason);
|
||||
}
|
||||
|
||||
void cancel(boolean toHome, String reason) {
|
||||
void cancel(boolean toHome, boolean withScreenshots, String reason) {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
|
||||
"[%d] RecentsController.cancel: toHome=%b reason=%s",
|
||||
mInstanceId, toHome, reason);
|
||||
if (mListener != null) {
|
||||
try {
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
|
||||
"[%d] RecentsController.cancel: calling onAnimationCanceled",
|
||||
mInstanceId);
|
||||
mListener.onAnimationCanceled(null, null);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error canceling recents animation", e);
|
||||
if (withScreenshots) {
|
||||
sendCancelWithSnapshots();
|
||||
} else {
|
||||
sendCancel(null, null);
|
||||
}
|
||||
}
|
||||
if (mFinishCB != null) {
|
||||
@@ -300,24 +297,34 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
|
||||
snapshots = new TaskSnapshot[mPausingTasks.size()];
|
||||
try {
|
||||
for (int i = 0; i < mPausingTasks.size(); ++i) {
|
||||
TaskState state = mPausingTasks.get(0);
|
||||
snapshots[i] = ActivityTaskManager.getService().takeTaskSnapshot(
|
||||
mPausingTasks.get(0).mTaskInfo.taskId, false /* updateCache */);
|
||||
state.mTaskInfo.taskId, true /* updateCache */);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
taskIds = null;
|
||||
snapshots = null;
|
||||
}
|
||||
}
|
||||
return sendCancel(taskIds, snapshots);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a cancel message to the recents animation.
|
||||
*/
|
||||
private boolean sendCancel(@Nullable int[] taskIds,
|
||||
@Nullable TaskSnapshot[] taskSnapshots) {
|
||||
try {
|
||||
final String cancelDetails = taskSnapshots != null ? " with snapshots" : "";
|
||||
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENTS_TRANSITION,
|
||||
"[%d] RecentsController.cancel: calling onAnimationCanceled with snapshots",
|
||||
mInstanceId);
|
||||
mListener.onAnimationCanceled(taskIds, snapshots);
|
||||
"[%d] RecentsController.cancel: calling onAnimationCanceled %s",
|
||||
mInstanceId, cancelDetails);
|
||||
mListener.onAnimationCanceled(taskIds, taskSnapshots);
|
||||
return true;
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Error canceling recents animation", e);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cleanUp() {
|
||||
@@ -519,7 +526,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
|
||||
// Finish recents animation if the display is changed, so the default
|
||||
// transition handler can play the animation such as rotation effect.
|
||||
if (change.hasFlags(TransitionInfo.FLAG_IS_DISPLAY)) {
|
||||
cancel(mWillFinishToHome, "display change");
|
||||
cancel(mWillFinishToHome, true /* withScreenshots */, "display change");
|
||||
return;
|
||||
}
|
||||
// Don't consider order-only changes as changing apps.
|
||||
@@ -633,7 +640,7 @@ public class RecentsTransitionHandler implements Transitions.TransitionHandler {
|
||||
+ foundRecentsClosing);
|
||||
if (foundRecentsClosing) {
|
||||
mWillFinishToHome = false;
|
||||
cancel(false /* toHome */, "didn't merge");
|
||||
cancel(false /* toHome */, false /* withScreenshots */, "didn't merge");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -364,6 +364,7 @@ public class StartingSurfaceDrawerTests extends ShellTestCase {
|
||||
1, HardwareBuffer.USAGE_CPU_READ_RARELY);
|
||||
return new TaskSnapshot(
|
||||
System.currentTimeMillis(),
|
||||
0 /* captureTime */,
|
||||
new ComponentName("", ""), buffer,
|
||||
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
|
||||
Surface.ROTATION_0, taskSize, contentInsets, new Rect() /* letterboxInsets */,
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.graphics.RecordingCanvas;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RenderNode;
|
||||
import android.hardware.HardwareBuffer;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Trace;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
@@ -213,6 +214,7 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
|
||||
// Failed to acquire image. Has been logged.
|
||||
return null;
|
||||
}
|
||||
builder.setCaptureTime(SystemClock.elapsedRealtimeNanos());
|
||||
builder.setSnapshot(screenshotBuffer.getHardwareBuffer());
|
||||
builder.setColorSpace(screenshotBuffer.getColorSpace());
|
||||
return builder.build();
|
||||
@@ -432,6 +434,7 @@ abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
|
||||
// color above
|
||||
return new TaskSnapshot(
|
||||
System.currentTimeMillis() /* id */,
|
||||
SystemClock.elapsedRealtimeNanos() /* captureTime */,
|
||||
topActivity.mActivityComponent, hwBitmap.getHardwareBuffer(),
|
||||
hwBitmap.getColorSpace(), mainWindow.getConfiguration().orientation,
|
||||
mainWindow.getWindowConfiguration().getRotation(), new Point(taskWidth, taskHeight),
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.graphics.BitmapFactory.Options;
|
||||
import android.graphics.Point;
|
||||
import android.graphics.Rect;
|
||||
import android.hardware.HardwareBuffer;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Slog;
|
||||
import android.window.TaskSnapshot;
|
||||
|
||||
@@ -195,8 +196,9 @@ class AppSnapshotLoader {
|
||||
taskSize = new Point(proto.taskWidth, proto.taskHeight);
|
||||
}
|
||||
|
||||
return new TaskSnapshot(proto.id, topActivityComponent, buffer,
|
||||
hwBitmap.getColorSpace(), proto.orientation, proto.rotation, taskSize,
|
||||
return new TaskSnapshot(proto.id, SystemClock.elapsedRealtimeNanos(),
|
||||
topActivityComponent, buffer, hwBitmap.getColorSpace(),
|
||||
proto.orientation, proto.rotation, taskSize,
|
||||
new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
|
||||
new Rect(proto.letterboxInsetLeft, proto.letterboxInsetTop,
|
||||
proto.letterboxInsetRight, proto.letterboxInsetBottom),
|
||||
|
||||
@@ -179,6 +179,18 @@ class TaskSnapshotController extends AbsAppSnapshotController<Task, TaskSnapshot
|
||||
&& mPersistInfoProvider.enableLowResSnapshots());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the elapsed real time (in nanoseconds) at which a snapshot for the given task was
|
||||
* last taken, or -1 if no such snapshot exists for that task.
|
||||
*/
|
||||
long getSnapshotCaptureTime(int taskId) {
|
||||
final TaskSnapshot snapshot = mCache.getSnapshot(taskId);
|
||||
if (snapshot != null) {
|
||||
return snapshot.getCaptureTime();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see WindowManagerInternal#clearSnapshotCache
|
||||
*/
|
||||
|
||||
@@ -1086,12 +1086,23 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
|
||||
if (commitVisibility) {
|
||||
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
|
||||
" Commit activity becoming invisible: %s", ar);
|
||||
final SnapshotController snapController = mController.mSnapshotController;
|
||||
if (mTransientLaunches != null && !task.isVisibleRequested()) {
|
||||
final long startTimeNs = mLogger.mSendTimeNs;
|
||||
final long lastSnapshotTimeNs = snapController.mTaskSnapshotController
|
||||
.getSnapshotCaptureTime(task.mTaskId);
|
||||
// If transition is transient, then snapshots are taken at end of
|
||||
// transition.
|
||||
mController.mSnapshotController.mTaskSnapshotController
|
||||
.recordSnapshot(task, false /* allowSnapshotHome */);
|
||||
mController.mSnapshotController.mActivitySnapshotController
|
||||
// transition only if a snapshot was not already captured by request
|
||||
// during the transition
|
||||
if (lastSnapshotTimeNs < startTimeNs) {
|
||||
snapController.mTaskSnapshotController
|
||||
.recordSnapshot(task, false /* allowSnapshotHome */);
|
||||
} else {
|
||||
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS,
|
||||
" Skipping post-transition snapshot for task %d",
|
||||
task.mTaskId);
|
||||
}
|
||||
snapController.mActivitySnapshotController
|
||||
.notifyAppVisibilityChanged(ar, false /* visible */);
|
||||
}
|
||||
ar.commitVisibility(false /* visible */, false /* performLayout */,
|
||||
|
||||
@@ -1286,7 +1286,7 @@ public class RecentTasksTest extends WindowTestsBase {
|
||||
doReturn(bufferSize.x).when(buffer).getWidth();
|
||||
doReturn(bufferSize.y).when(buffer).getHeight();
|
||||
}
|
||||
return new TaskSnapshot(1, new ComponentName("", ""), buffer,
|
||||
return new TaskSnapshot(1, 0 /* captureTime */, new ComponentName("", ""), buffer,
|
||||
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
|
||||
Surface.ROTATION_0, taskSize, new Rect() /* contentInsets */,
|
||||
new Rect() /* letterboxInsets*/, false /* isLowResolution */,
|
||||
|
||||
@@ -218,7 +218,7 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
|
||||
Canvas c = buffer.lockCanvas();
|
||||
c.drawColor(Color.RED);
|
||||
buffer.unlockCanvasAndPost(c);
|
||||
return new TaskSnapshot(MOCK_SNAPSHOT_ID, mTopActivityComponent,
|
||||
return new TaskSnapshot(MOCK_SNAPSHOT_ID, 0 /* captureTime */, mTopActivityComponent,
|
||||
HardwareBuffer.createFromGraphicBuffer(buffer),
|
||||
ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
|
||||
mRotation, taskSize, TEST_CONTENT_INSETS, TEST_LETTERBOX_INSETS,
|
||||
|
||||
Reference in New Issue
Block a user