Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 08e20939 authored by Evan Rosky's avatar Evan Rosky
Browse files

Take snapshot directly during change transition

Using the tasksnapshotcontroller here is actually wrong... the
snapshot being created is already out-of-date and could have
scaling/other things applied to it. Additionally, it can clash
with things listening for task-snapshot changes which is also
wrong.

This changes to getting a snapshot directly which is more
correct and faster (since it doesn't go through the snapshot
controller's caching thing).

Bug: 132783168
Test: Manual, change transitions still work. android on chrome
      doesn't crash on tablet-mode switch

Change-Id: I726ed174765ac64bedb7cd130719190a06ad42ab
parent 26fdabb9
Loading
Loading
Loading
Loading
+7 −11
Original line number Diff line number Diff line
@@ -1733,17 +1733,13 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
            return;
        }

        if (mThumbnail == null && getTask() != null) {
            final TaskSnapshotController snapshotCtrl = mWmService.mTaskSnapshotController;
            final ArraySet<Task> tasks = new ArraySet<>();
            tasks.add(getTask());
            snapshotCtrl.snapshotTasks(tasks);
            snapshotCtrl.addSkipClosingAppSnapshotTasks(tasks);
            final ActivityManager.TaskSnapshot snapshot = snapshotCtrl.getSnapshot(
                    getTask().mTaskId, getTask().mUserId, false /* restoreFromDisk */,
                    false /* reducedResolution */);
        Task task = getTask();
        if (mThumbnail == null && task != null && !hasCommittedReparentToAnimationLeash()) {
            SurfaceControl.ScreenshotGraphicBuffer snapshot =
                    mWmService.mTaskSnapshotController.createTaskSnapshot(
                            task, 1 /* scaleFraction */);
            if (snapshot != null) {
                mThumbnail = new AppWindowThumbnail(t, this, snapshot.getSnapshot(),
                mThumbnail = new AppWindowThumbnail(t, this, snapshot.getGraphicBuffer(),
                        true /* relative */);
            }
        }
@@ -2858,7 +2854,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
            }
        }
        t.hide(mTransitChangeLeash);
        t.reparent(mTransitChangeLeash, null);
        t.remove(mTransitChangeLeash);
        mTransitChangeLeash = null;
        if (cancel) {
            onAnimationLeashLost(t);
+27 −13
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
@@ -241,16 +242,32 @@ class TaskSnapshotController {
        return null;
    }

    @Nullable private TaskSnapshot snapshotTask(Task task) {
        if (!mService.mPolicy.isScreenOn()) {
    @Nullable
    SurfaceControl.ScreenshotGraphicBuffer createTaskSnapshot(@NonNull Task task,
            float scaleFraction) {
        if (task.getSurfaceControl() == null) {
            if (DEBUG_SCREENSHOT) {
                Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
                Slog.w(TAG_WM, "Failed to take screenshot. No surface control for " + task);
            }
            return null;
        }
        if (task.getSurfaceControl() == null) {
        task.getBounds(mTmpRect);
        mTmpRect.offsetTo(0, 0);
        final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
                SurfaceControl.captureLayers(
                        task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
        final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
                : null;
        if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
            return null;
        }
        return screenshotBuffer;
    }

    @Nullable private TaskSnapshot snapshotTask(Task task) {
        if (!mService.mPolicy.isScreenOn()) {
            if (DEBUG_SCREENSHOT) {
                Slog.w(TAG_WM, "Failed to take screenshot. No surface control for " + task);
                Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
            }
            return null;
        }
@@ -271,8 +288,6 @@ class TaskSnapshotController {

        final boolean isLowRamDevice = ActivityManager.isLowRamDeviceStatic();
        final float scaleFraction = isLowRamDevice ? mPersister.getReducedScale() : 1f;
        task.getBounds(mTmpRect);
        mTmpRect.offsetTo(0, 0);

        final WindowState mainWindow = appWindowToken.findMainWindow();
        if (mainWindow == null) {
@@ -280,18 +295,17 @@ class TaskSnapshotController {
            return null;
        }
        final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
                SurfaceControl.captureLayers(
                        task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
        final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
                : null;
        if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
                createTaskSnapshot(task, scaleFraction);

        if (screenshotBuffer == null) {
            if (DEBUG_SCREENSHOT) {
                Slog.w(TAG_WM, "Failed to take screenshot for " + task);
            }
            return null;
        }
        final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
        return new TaskSnapshot(appWindowToken.mActivityComponent, buffer,
        return new TaskSnapshot(
                appWindowToken.mActivityComponent, screenshotBuffer.getGraphicBuffer(),
                screenshotBuffer.getColorSpace(), appWindowToken.getConfiguration().orientation,
                getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */,
                true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),