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