• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.server.wm;
18 
19 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
20 import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
21 import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
22 import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY;
23 
24 import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
25 
26 import static org.junit.Assert.assertTrue;
27 import static org.mockito.Mockito.mock;
28 import static org.mockito.Mockito.spy;
29 import static org.mockito.Mockito.when;
30 
31 import android.app.ActivityManager.TaskSnapshot;
32 import android.content.ComponentName;
33 import android.content.ContextWrapper;
34 import android.content.res.Resources;
35 import android.graphics.Canvas;
36 import android.graphics.Color;
37 import android.graphics.ColorSpace;
38 import android.graphics.GraphicBuffer;
39 import android.graphics.PixelFormat;
40 import android.graphics.Point;
41 import android.graphics.Rect;
42 import android.os.UserManager;
43 import android.os.UserManagerInternal;
44 import android.view.Surface;
45 
46 import com.android.server.LocalServices;
47 
48 import org.junit.After;
49 import org.junit.AfterClass;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 
53 import java.io.File;
54 import java.util.function.Predicate;
55 
56 /**
57  * Base class for tests that use a {@link TaskSnapshotPersister}.
58  */
59 class TaskSnapshotPersisterTestBase extends WindowTestsBase {
60 
61     private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
62     static final File FILES_DIR = getInstrumentation().getTargetContext().getFilesDir();
63     static final long MOCK_SNAPSHOT_ID = 12345678;
64 
65     private ContextWrapper mContextSpy;
66     private Resources mResourcesSpy;
67     TaskSnapshotPersister mPersister;
68     TaskSnapshotLoader mLoader;
69     int mTestUserId;
70     float mHighResScale;
71     float mLowResScale;
72 
TaskSnapshotPersisterTestBase(float highResScale, float lowResScale)73     TaskSnapshotPersisterTestBase(float highResScale, float lowResScale) {
74         super();
75         mHighResScale = highResScale;
76         mLowResScale = lowResScale;
77     }
78 
79     @BeforeClass
setUpOnce()80     public static void setUpOnce() {
81         final UserManagerInternal userManager = mock(UserManagerInternal.class);
82         LocalServices.addService(UserManagerInternal.class, userManager);
83     }
84 
85     @AfterClass
tearDownOnce()86     public static void tearDownOnce() {
87         LocalServices.removeServiceForTest(UserManagerInternal.class);
88     }
89 
90     @Before
setUp()91     public void setUp() {
92         final UserManager um = UserManager.get(getInstrumentation().getTargetContext());
93         mTestUserId = um.getUserHandle();
94 
95         final UserManagerInternal userManagerInternal =
96                 LocalServices.getService(UserManagerInternal.class);
97         when(userManagerInternal.isUserUnlocked(mTestUserId)).thenReturn(true);
98 
99         mContextSpy = spy(new ContextWrapper(mWm.mContext));
100         mResourcesSpy = spy(mContextSpy.getResources());
101         when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
102         when(mResourcesSpy.getFloat(
103                 com.android.internal.R.dimen.config_highResTaskSnapshotScale))
104                 .thenReturn(mHighResScale);
105         when(mResourcesSpy.getFloat(
106                 com.android.internal.R.dimen.config_lowResTaskSnapshotScale))
107                 .thenReturn(mLowResScale);
108 
109         mPersister = new TaskSnapshotPersister(mWm, userId -> FILES_DIR);
110         mLoader = new TaskSnapshotLoader(mPersister);
111         mPersister.start();
112     }
113 
114     @After
tearDown()115     public void tearDown() {
116         cleanDirectory();
117     }
118 
cleanDirectory()119     private void cleanDirectory() {
120         final File[] files = new File(FILES_DIR, "snapshots").listFiles();
121         if (files == null) {
122             return;
123         }
124         for (File file : files) {
125             if (!file.isDirectory()) {
126                 file.delete();
127             }
128         }
129     }
130 
createSnapshot()131     TaskSnapshot createSnapshot() {
132         return new TaskSnapshotBuilder()
133                 .build();
134     }
135 
assertTrueForFiles(File[] files, Predicate<File> predicate, String message)136     protected static void assertTrueForFiles(File[] files, Predicate<File> predicate,
137             String message) {
138         for (File file : files) {
139             assertTrue(file.getName() + message, predicate.test(file));
140         }
141     }
142 
143     /**
144      * Builds a TaskSnapshot.
145      */
146     static class TaskSnapshotBuilder {
147         private static final int SNAPSHOT_WIDTH = 100;
148         private static final int SNAPSHOT_HEIGHT = 100;
149 
150         private float mScaleFraction = 1f;
151         private boolean mIsRealSnapshot = true;
152         private boolean mIsTranslucent = false;
153         private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
154         private int mSystemUiVisibility = 0;
155         private int mRotation = Surface.ROTATION_0;
156 
TaskSnapshotBuilder()157         TaskSnapshotBuilder() {
158         }
159 
setScaleFraction(float scale)160         TaskSnapshotBuilder setScaleFraction(float scale) {
161             mScaleFraction = scale;
162             return this;
163         }
164 
setIsRealSnapshot(boolean isRealSnapshot)165         TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) {
166             mIsRealSnapshot = isRealSnapshot;
167             return this;
168         }
169 
setIsTranslucent(boolean isTranslucent)170         TaskSnapshotBuilder setIsTranslucent(boolean isTranslucent) {
171             mIsTranslucent = isTranslucent;
172             return this;
173         }
174 
setWindowingMode(int windowingMode)175         TaskSnapshotBuilder setWindowingMode(int windowingMode) {
176             mWindowingMode = windowingMode;
177             return this;
178         }
179 
setSystemUiVisibility(int systemUiVisibility)180         TaskSnapshotBuilder setSystemUiVisibility(int systemUiVisibility) {
181             mSystemUiVisibility = systemUiVisibility;
182             return this;
183         }
184 
setRotation(int rotation)185         TaskSnapshotBuilder setRotation(int rotation) {
186             mRotation = rotation;
187             return this;
188         }
189 
build()190         TaskSnapshot build() {
191             // To satisfy existing tests, ensure the graphics buffer is always 100x100, and
192             // compute the ize of the task according to mScaleFraction.
193             Point taskSize = new Point((int) (SNAPSHOT_WIDTH / mScaleFraction),
194                     (int) (SNAPSHOT_HEIGHT / mScaleFraction));
195             final GraphicBuffer buffer = GraphicBuffer.create(SNAPSHOT_WIDTH, SNAPSHOT_HEIGHT,
196                     PixelFormat.RGBA_8888,
197                     USAGE_HW_TEXTURE | USAGE_SW_READ_RARELY | USAGE_SW_READ_RARELY);
198             Canvas c = buffer.lockCanvas();
199             c.drawColor(Color.RED);
200             buffer.unlockCanvasAndPost(c);
201             return new TaskSnapshot(MOCK_SNAPSHOT_ID, new ComponentName("", ""), buffer,
202                     ColorSpace.get(ColorSpace.Named.SRGB), ORIENTATION_PORTRAIT,
203                     mRotation, taskSize, TEST_INSETS,
204                     // When building a TaskSnapshot with the Builder class, isLowResolution
205                     // is always false. Low-res snapshots are only created when loading from
206                     // disk.
207                     false /* isLowResolution */,
208                     mIsRealSnapshot, mWindowingMode, mSystemUiVisibility, mIsTranslucent);
209         }
210     }
211 }
212