TaskSnapshotPersisterLoaderTest.java revision f9084ecae2e0f042730ab32b9c94204a0e21bb2a
1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.wm;
18
19import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
20import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY;
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertFalse;
23import static org.junit.Assert.assertNotNull;
24import static org.junit.Assert.assertTrue;
25import static org.junit.Assert.fail;
26
27import android.app.ActivityManager.TaskSnapshot;
28import android.content.pm.UserInfo;
29import android.content.res.Configuration;
30import android.graphics.Bitmap;
31import android.graphics.Canvas;
32import android.graphics.Color;
33import android.graphics.GraphicBuffer;
34import android.graphics.PixelFormat;
35import android.graphics.Rect;
36import android.os.SystemClock;
37import android.os.UserManager;
38import android.platform.test.annotations.Presubmit;
39import android.support.test.InstrumentationRegistry;
40import android.support.test.filters.MediumTest;
41import android.support.test.runner.AndroidJUnit4;
42import android.util.ArraySet;
43
44import com.android.internal.util.Predicate;
45import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem;
46
47import org.junit.After;
48import org.junit.AfterClass;
49import org.junit.Assert;
50import org.junit.Before;
51import org.junit.BeforeClass;
52import org.junit.Test;
53import org.junit.runner.RunWith;
54
55import java.io.File;
56
57/**
58 * Test class for {@link TaskSnapshotPersister} and {@link TaskSnapshotLoader}
59 *
60 * runtest frameworks-services -c com.android.server.wm.TaskSnapshotPersisterLoaderTest
61 */
62@MediumTest
63@Presubmit
64@RunWith(AndroidJUnit4.class)
65public class TaskSnapshotPersisterLoaderTest {
66
67    private static final String TEST_USER_NAME = "TaskSnapshotPersisterTest User";
68    private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
69
70    private TaskSnapshotPersister mPersister;
71    private TaskSnapshotLoader mLoader;
72    private static int sTestUserId;
73    private static File sFilesDir;
74    private static UserManager sUserManager;
75
76    @BeforeClass
77    public static void setUpUser() {
78        sUserManager = UserManager.get(InstrumentationRegistry.getContext());
79        sTestUserId = createUser(TEST_USER_NAME, 0);
80        sFilesDir = InstrumentationRegistry.getContext().getFilesDir();
81    }
82
83    @AfterClass
84    public static void tearDownUser() {
85        removeUser(sTestUserId);
86    }
87
88    @Before
89    public void setUp() throws Exception {
90        mPersister = new TaskSnapshotPersister(
91                userId -> sFilesDir);
92        mLoader = new TaskSnapshotLoader(mPersister);
93        mPersister.start();
94    }
95
96    @After
97    public void tearDown() throws Exception {
98        cleanDirectory();
99    }
100
101    @Test
102    public void testPersistAndLoadSnapshot() {
103        mPersister.persistSnapshot(1 , sTestUserId, createSnapshot());
104        mPersister.waitForQueueEmpty();
105        final File[] files = new File[] { new File(sFilesDir.getPath() + "/snapshots/1.proto"),
106                new File(sFilesDir.getPath() + "/snapshots/1.png") };
107        assertTrueForFiles(files, File::exists, " must exist");
108        final TaskSnapshot snapshot = mLoader.loadTask(1, sTestUserId);
109        assertNotNull(snapshot);
110        assertEquals(TEST_INSETS, snapshot.getContentInsets());
111        assertNotNull(snapshot.getSnapshot());
112        assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
113    }
114
115    private void assertTrueForFiles(File[] files, Predicate<File> predicate, String message) {
116        for (File file : files) {
117            assertTrue(file.getName() + message, predicate.apply(file));
118        }
119    }
120
121    @Test
122    public void testTaskRemovedFromRecents() {
123        mPersister.persistSnapshot(1, sTestUserId, createSnapshot());
124        mPersister.onTaskRemovedFromRecents(1, sTestUserId);
125        mPersister.waitForQueueEmpty();
126        assertFalse(new File(sFilesDir.getPath() + "/snapshots/1.proto").exists());
127        assertFalse(new File(sFilesDir.getPath() + "/snapshots/1.png").exists());
128    }
129
130    /**
131     * Tests that persisting a couple of snapshots is being throttled.
132     */
133    @Test
134    public void testThrottling() {
135        long ms = SystemClock.elapsedRealtime();
136        mPersister.persistSnapshot(1, sTestUserId, createSnapshot());
137        mPersister.persistSnapshot(2, sTestUserId, createSnapshot());
138        mPersister.persistSnapshot(3, sTestUserId, createSnapshot());
139        mPersister.persistSnapshot(4, sTestUserId, createSnapshot());
140        mPersister.persistSnapshot(5, sTestUserId, createSnapshot());
141        mPersister.persistSnapshot(6, sTestUserId, createSnapshot());
142        mPersister.waitForQueueEmpty();
143        assertTrue(SystemClock.elapsedRealtime() - ms > 500);
144    }
145
146    @Test
147    public void testGetTaskId() {
148        RemoveObsoleteFilesQueueItem removeObsoleteFilesQueueItem =
149                mPersister.new RemoveObsoleteFilesQueueItem(new ArraySet<>(), new int[] {});
150        assertEquals(-1, removeObsoleteFilesQueueItem.getTaskId("blablablulp"));
151        assertEquals(-1, removeObsoleteFilesQueueItem.getTaskId("nothing.err"));
152        assertEquals(-1, removeObsoleteFilesQueueItem.getTaskId("/invalid/"));
153        assertEquals(12, removeObsoleteFilesQueueItem.getTaskId("12.png"));
154        assertEquals(12, removeObsoleteFilesQueueItem.getTaskId("12.proto"));
155        assertEquals(1, removeObsoleteFilesQueueItem.getTaskId("1.png"));
156    }
157
158    @Test
159    public void testRemoveObsoleteFiles() {
160        mPersister.persistSnapshot(1, sTestUserId, createSnapshot());
161        mPersister.persistSnapshot(2, sTestUserId, createSnapshot());
162        final ArraySet<Integer> taskIds = new ArraySet<>();
163        taskIds.add(1);
164        mPersister.removeObsoleteFiles(taskIds, new int[] { sTestUserId });
165        mPersister.waitForQueueEmpty();
166        final File[] existsFiles = new File[] {
167                new File(sFilesDir.getPath() + "/snapshots/1.proto"),
168                new File(sFilesDir.getPath() + "/snapshots/1.png") };
169        final File[] nonExistsFiles = new File[] {
170                new File(sFilesDir.getPath() + "/snapshots/2.proto"),
171                new File(sFilesDir.getPath() + "/snapshots/2.png") };
172        assertTrueForFiles(existsFiles, File::exists, " must exist");
173        assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
174    }
175
176    @Test
177    public void testRemoveObsoleteFiles_addedOneInTheMeantime() {
178        mPersister.persistSnapshot(1, sTestUserId, createSnapshot());
179        final ArraySet<Integer> taskIds = new ArraySet<>();
180        taskIds.add(1);
181        mPersister.removeObsoleteFiles(taskIds, new int[] { sTestUserId });
182        mPersister.persistSnapshot(2, sTestUserId, createSnapshot());
183        mPersister.waitForQueueEmpty();
184        final File[] existsFiles = new File[] {
185                new File(sFilesDir.getPath() + "/snapshots/1.proto"),
186                new File(sFilesDir.getPath() + "/snapshots/1.png"),
187                new File(sFilesDir.getPath() + "/snapshots/2.proto"),
188                new File(sFilesDir.getPath() + "/snapshots/2.png") };
189        assertTrueForFiles(existsFiles, File::exists, " must exist");
190    }
191
192    private TaskSnapshot createSnapshot() {
193        GraphicBuffer buffer = GraphicBuffer.create(100, 100, PixelFormat.RGBA_8888,
194                USAGE_HW_TEXTURE | USAGE_SW_READ_RARELY | USAGE_SW_READ_RARELY);
195        Canvas c = buffer.lockCanvas();
196        c.drawColor(Color.RED);
197        buffer.unlockCanvasAndPost(c);
198        return new TaskSnapshot(buffer, Configuration.ORIENTATION_PORTRAIT, TEST_INSETS);
199    }
200
201    private static int createUser(String name, int flags) {
202        UserInfo user = sUserManager.createUser(name, flags);
203        if (user == null) {
204            Assert.fail("Error while creating the test user: " + TEST_USER_NAME);
205        }
206        return user.id;
207    }
208
209    private static void removeUser(int userId) {
210        if (!sUserManager.removeUser(userId)) {
211            Assert.fail("Error while removing the test user: " + TEST_USER_NAME);
212        }
213    }
214
215    private void cleanDirectory() {
216        for (File file : new File(sFilesDir, "snapshots").listFiles()) {
217            if (!file.isDirectory()) {
218                file.delete();
219            }
220        }
221    }
222}
223