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

Commit 23aa7b11 authored by Winson Chung's avatar Winson Chung
Browse files

Update the cache with the snapshot requested during recents animation

- When a screenshot is requested by the recents animation runner, update
  the task snapshot cache to ensure that the same snapshot is used for the
  next starting animation. In doing so, we also need to prevent the default
  logic from taking a new snapshot when the app is hidden at the end of the
  recents animation.

Bug: 70180552
Test: atest TaskSnapshotControllerTest
Change-Id: Ib081ba324587b0719edb370e3c253c86f5e6c1b6
parent 759148c6
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -24,15 +24,15 @@ import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_W
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.app.ActivityManager;
import android.app.ActivityManager.TaskSnapshot;
import android.app.WindowConfiguration;
import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.view.IRecentsAnimationController;
@@ -41,6 +41,7 @@ import android.view.RemoteAnimationTarget;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import com.google.android.collect.Sets;
import java.io.PrintWriter;
import java.util.ArrayList;

@@ -99,17 +100,13 @@ public class RecentsAnimationController {
                        final TaskAnimationAdapter adapter = mPendingAnimations.get(i);
                        final Task task = adapter.mTask;
                        if (task.mTaskId == taskId) {
                            // TODO: Save this screenshot as the task snapshot?
                            final Rect taskFrame = new Rect();
                            task.getBounds(taskFrame);
                            final GraphicBuffer buffer = SurfaceControl.captureLayers(
                                    task.getSurfaceControl().getHandle(), taskFrame, 1f);
                            final AppWindowToken topChild = task.getTopChild();
                            final WindowState mainWindow = topChild.findMainWindow();
                            return new TaskSnapshot(buffer, topChild.getConfiguration().orientation,
                                    mainWindow.mContentInsets,
                                    ActivityManager.isLowRamDeviceStatic() /* reduced */,
                                    1.0f /* scale */);
                            final TaskSnapshotController snapshotController =
                                    mService.mTaskSnapshotController;
                            final ArraySet<Task> tasks = Sets.newArraySet(task);
                            snapshotController.snapshotTasks(tasks);
                            snapshotController.addSkipClosingAppSnapshotTasks(tasks);
                            return snapshotController.getSnapshot(taskId, 0 /* userId */,
                                    false /* restoreFromDisk */, false /* reducedResolution */);
                        }
                    }
                    return null;
+13 −2
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@ class TaskSnapshotController {
    private final TaskSnapshotPersister mPersister = new TaskSnapshotPersister(
            Environment::getDataSystemCeDirectory);
    private final TaskSnapshotLoader mLoader = new TaskSnapshotLoader(mPersister);
    private final ArraySet<Task> mSkipClosingAppSnapshotTasks = new ArraySet<>();
    private final ArraySet<Task> mTmpTasks = new ArraySet<>();
    private final Handler mHandler = new Handler();

@@ -149,10 +150,20 @@ class TaskSnapshotController {
        // either closing or hidden.
        getClosingTasks(closingApps, mTmpTasks);
        snapshotTasks(mTmpTasks);
        mSkipClosingAppSnapshotTasks.clear();
    }

    /**
     * Adds the given {@param tasks} to the list of tasks which should not have their snapshots
     * taken upon the next processing of the set of closing apps. The caller is responsible for
     * calling {@link #snapshotTasks} to ensure that the task has an up-to-date snapshot.
     */
    @VisibleForTesting
    void addSkipClosingAppSnapshotTasks(ArraySet<Task> tasks) {
        mSkipClosingAppSnapshotTasks.addAll(tasks);
    }

    private void snapshotTasks(ArraySet<Task> tasks) {
    void snapshotTasks(ArraySet<Task> tasks) {
        for (int i = tasks.size() - 1; i >= 0; i--) {
            final Task task = tasks.valueAt(i);
            final int mode = getSnapshotMode(task);
@@ -295,7 +306,7 @@ class TaskSnapshotController {

            // If the task of the app is not visible anymore, it means no other app in that task
            // is opening. Thus, the task is closing.
            if (task != null && !task.isVisible()) {
            if (task != null && !task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) {
                outClosingTasks.add(task);
            }
        }
+16 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
import android.util.ArraySet;

import com.google.android.collect.Sets;
import org.junit.Test;
import org.junit.runner.RunWith;

@@ -73,6 +74,21 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
        assertEquals(0, closingTasks.size());
    }

    @Test
    public void testGetClosingApps_skipClosingAppsSnapshotTasks() throws Exception {
        final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
                "closingWindow");
        closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET,
                true /* performLayout */, false /* isVoiceInteraction */);
        final ArraySet<AppWindowToken> closingApps = new ArraySet<>();
        closingApps.add(closingWindow.mAppToken);
        final ArraySet<Task> closingTasks = new ArraySet<>();
        sWm.mTaskSnapshotController.addSkipClosingAppSnapshotTasks(
                Sets.newArraySet(closingWindow.mAppToken.getTask()));
        sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
        assertEquals(0, closingTasks.size());
    }

    @Test
    public void testGetSnapshotMode() throws Exception {
        final WindowState disabledWindow = createWindow(null,