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

Commit b7f67503 authored by Wei Sheng Shih's avatar Wei Sheng Shih Committed by Android (Google) Code Review
Browse files

Merge "Fixes multiple activity snapshots can stay in cache." into main

parents 7ea9db1a 9b2f7b6b
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.server.wm;

import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;

import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -343,6 +345,11 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord
        if (DEBUG) {
            Slog.d(TAG, "ActivitySnapshotController#recordSnapshot " + activity);
        }
        if (mPersister.mSnapshotPersistQueue.peekWriteQueueSize() >= MAX_STORE_QUEUE_DEPTH
                || mPersister.mSnapshotPersistQueue.peekQueueSize() > MAX_PERSIST_SNAPSHOT_COUNT) {
            Slog.w(TAG, "Skipping recording activity snapshot, too many requests!");
            return;
        }
        final int size = activity.size();
        final int[] mixedCode = new int[size];
        if (size == 1) {
@@ -432,7 +439,7 @@ class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord
            addBelowActivityIfExist(ar, mPendingLoadActivity, false, "load-snapshot");
        } else {
            // remove the snapshot for the one below close
            addBelowActivityIfExist(ar, mPendingRemoveActivity, true, "remove-snapshot");
            addBelowActivityIfExist(ar, mPendingRemoveActivity, false, "remove-snapshot");
        }
    }

+7 −2
Original line number Diff line number Diff line
@@ -50,7 +50,7 @@ import java.util.ArrayDeque;
class SnapshotPersistQueue {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskSnapshotPersister" : TAG_WM;
    private static final long DELAY_MS = 100;
    private static final int MAX_STORE_QUEUE_DEPTH = 2;
    static final int MAX_STORE_QUEUE_DEPTH = 2;
    private static final int COMPRESS_QUALITY = 95;

    @GuardedBy("mLock")
@@ -154,7 +154,12 @@ class SnapshotPersistQueue {
        }
    }

    @VisibleForTesting
    int peekWriteQueueSize() {
        synchronized (mLock) {
            return mStoreQueueItems.size();
        }
    }

    int peekQueueSize() {
        synchronized (mLock) {
            return mWriteQueue.size();
+36 −25
Original line number Diff line number Diff line
@@ -17,30 +17,23 @@
package com.android.server.wm;

import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;

import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.server.wm.SnapshotPersistQueue.MAX_STORE_QUEUE_DEPTH;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;

import android.content.ComponentName;
import android.graphics.ColorSpace;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
import android.view.Surface;
import android.window.TaskSnapshot;

import androidx.test.filters.SmallTest;
@@ -61,14 +54,20 @@ import java.util.Arrays;
@SmallTest
@Presubmit
@RunWith(WindowTestRunner.class)
public class ActivitySnapshotControllerTests extends WindowTestsBase {
public class ActivitySnapshotControllerTests extends TaskSnapshotPersisterTestBase {

    private ActivitySnapshotController mActivitySnapshotController;

    public ActivitySnapshotControllerTests() {
        super(0.8f /* highResScale */, 0.5f /* lowResScale */);
    }

    @Override
    @Before
    public void setUp() throws Exception {
        spyOn(mWm.mSnapshotController.mActivitySnapshotController);
        mActivitySnapshotController = mWm.mSnapshotController.mActivitySnapshotController;
    public void setUp() {
        super.setUp();
        mActivitySnapshotController = new ActivitySnapshotController(mWm, mSnapshotPersistQueue);
        spyOn(mActivitySnapshotController);
        doReturn(false).when(mActivitySnapshotController).shouldDisableSnapshots();
        mActivitySnapshotController.resetTmpFields();
    }
@@ -92,12 +91,11 @@ public class ActivitySnapshotControllerTests extends WindowTestsBase {
        assertEquals(0, mActivitySnapshotController.mPendingRemoveActivity.size());
        mActivitySnapshotController.resetTmpFields();

        // simulate three activity
        // simulate three activity, the bottom activity won't participate in transition
        final WindowState belowClose = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
                "belowClose");
        belowClose.mActivityRecord.commitVisibility(
                false /* visible */, true /* performLayout */);
        windows.add(belowClose.mActivityRecord);
        mActivitySnapshotController.handleTransitionFinish(windows);
        assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
        assertEquals(belowClose.mActivityRecord,
@@ -249,15 +247,28 @@ public class ActivitySnapshotControllerTests extends WindowTestsBase {
        assertEquals(taskSnapshot, mActivitySnapshotController.getSnapshot(activities));
    }

    private TaskSnapshot createSnapshot() {
        HardwareBuffer buffer = mock(HardwareBuffer.class);
        doReturn(100).when(buffer).getWidth();
        doReturn(100).when(buffer).getHeight();
        return new TaskSnapshot(1, 0 /* captureTime */, new ComponentName("", ""), buffer,
                ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
                Surface.ROTATION_0, new Point(100, 100), new Rect() /* contentInsets */,
                new Rect() /* letterboxInsets*/, false /* isLowResolution */,
                true /* isRealSnapshot */, WINDOWING_MODE_FULLSCREEN, 0 /* mSystemUiVisibility */,
                false /* isTranslucent */, false /* hasImeSurface */, 0 /* uiMode */);
    /**
     * Verifies that activity snapshot is skipped if the persister queue has too many pending write
     * items.
     */
    @Test
    public void testSkipRecordActivity() {
        doReturn(createSnapshot()).when(mActivitySnapshotController).recordSnapshotInner(any());
        final Task task = createTask(mDisplayContent);

        mSnapshotPersistQueue.setPaused(true);
        final ArrayList<ActivityRecord> tmpList = new ArrayList<>();
        for (int i = 0; i < MAX_STORE_QUEUE_DEPTH; ++i) {
            tmpList.clear();
            final ActivityRecord activity = createActivityRecord(task);
            tmpList.add(activity);
            mActivitySnapshotController.recordSnapshot(tmpList);
            assertNotNull(mActivitySnapshotController.findSavedFile(activity));
        }
        tmpList.clear();
        final ActivityRecord activity = createActivityRecord(task);
        tmpList.add(activity);
        mActivitySnapshotController.recordSnapshot(tmpList);
        assertNull(mActivitySnapshotController.findSavedFile(activity));
    }
}