Merge "Fix issue with task snapshots being taken too late" into udc-dev

This commit is contained in:
Winson Chung
2023-05-23 17:05:51 +00:00
committed by Android (Google) Code Review
11 changed files with 90 additions and 25 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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