• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 android.app.cts.wallpapers;
18 
19 import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
20 import static android.app.WallpaperManager.FLAG_LOCK;
21 import static android.app.WallpaperManager.FLAG_SYSTEM;
22 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.TWO_DIFFERENT_LIVE_WALLPAPERS;
23 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.TWO_SAME_LIVE_WALLPAPERS;
24 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.WallpaperChange;
25 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.WallpaperState;
26 import static android.app.cts.wallpapers.util.WallpaperTestUtils.isSimilar;
27 import static android.content.pm.PackageManager.FEATURE_LIVE_WALLPAPER;
28 import static android.content.pm.PackageManager.FEATURE_SECURE_LOCK_SCREEN;
29 import static android.opengl.cts.Egl14Utils.getMaxTextureSize;
30 
31 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
32 
33 import static com.google.common.truth.Truth.assertThat;
34 import static com.google.common.truth.Truth.assertWithMessage;
35 
36 import static org.junit.Assert.assertThrows;
37 import static org.junit.Assume.assumeFalse;
38 import static org.junit.Assume.assumeTrue;
39 import static org.mockito.ArgumentMatchers.any;
40 import static org.mockito.ArgumentMatchers.anyInt;
41 import static org.mockito.ArgumentMatchers.nullable;
42 import static org.mockito.Mockito.atLeast;
43 import static org.mockito.Mockito.never;
44 import static org.mockito.Mockito.spy;
45 import static org.mockito.Mockito.verify;
46 
47 import android.app.Activity;
48 import android.app.WallpaperColors;
49 import android.app.WallpaperManager;
50 import android.content.BroadcastReceiver;
51 import android.content.ComponentName;
52 import android.content.Context;
53 import android.content.Intent;
54 import android.content.IntentFilter;
55 import android.graphics.Bitmap;
56 import android.graphics.Canvas;
57 import android.graphics.Color;
58 import android.graphics.ColorSpace;
59 import android.graphics.Point;
60 import android.graphics.Rect;
61 import android.graphics.drawable.Drawable;
62 import android.os.Handler;
63 import android.os.HandlerThread;
64 import android.os.IBinder;
65 import android.os.Looper;
66 import android.server.wm.WindowManagerStateHelper;
67 import android.util.Log;
68 import android.view.Display;
69 import android.view.Window;
70 import android.view.WindowManager;
71 
72 import androidx.test.InstrumentationRegistry;
73 import androidx.test.rule.ActivityTestRule;
74 import androidx.test.runner.AndroidJUnit4;
75 
76 import com.android.compatibility.common.util.CtsTouchUtils;
77 
78 import org.junit.After;
79 import org.junit.Before;
80 import org.junit.Ignore;
81 import org.junit.Rule;
82 import org.junit.Test;
83 import org.junit.runner.RunWith;
84 import org.mockito.MockitoAnnotations;
85 
86 import java.io.IOException;
87 import java.util.ArrayList;
88 import java.util.LinkedList;
89 import java.util.List;
90 import java.util.concurrent.CountDownLatch;
91 import java.util.concurrent.TimeUnit;
92 import java.util.concurrent.atomic.AtomicBoolean;
93 
94 /**
95  * Tests for {@link WallpaperManager} and related classes.
96  * <p>
97  * Note: the wallpapers {@link TestLiveWallpaper}, {@link TestLiveWallpaperNoUnfoldTransition},
98  * {@link TestLiveWallpaperSupportingAmbientMode} draw the screen in
99  * cyan, magenta, yellow, respectively.
100  * </p>
101  */
102 @RunWith(AndroidJUnit4.class)
103 public class WallpaperManagerTest {
104 
105     private static final boolean DEBUG = false;
106     private static final String TAG = "WallpaperManagerTest";
107     private static final ComponentName DEFAULT_COMPONENT_NAME = new ComponentName(
108             TestLiveWallpaper.class.getPackageName(), TestLiveWallpaper.class.getName());
109     // Default wait time for async operations
110     private static final int SLEEP_MS = 500;
111     private static final int DIM_LISTENER_TIMEOUT_SECS = 30;
112 
113     private WallpaperManager mWallpaperManager;
114     private Context mContext;
115     private CtsTouchUtils mCtsTouchUtils;
116     private Handler mHandler;
117     private BroadcastReceiver mBroadcastReceiver;
118     private CountDownLatch mCountDownLatch;
119     private boolean mEnableWcg;
120     private static final WindowManagerStateHelper sWindowManagerStateHelper =
121             new WindowManagerStateHelper();
122 
123     @Rule
124     public ActivityTestRule<WallpaperTestActivity> mActivityTestRule = new ActivityTestRule<>(
125             WallpaperTestActivity.class,
126             false /* initialTouchMode */,
127             false /* launchActivity */);
128 
129     @Before
setUp()130     public void setUp() throws Exception {
131 
132         // grant READ_WALLPAPER_INTERNAL for all tests
133         InstrumentationRegistry.getInstrumentation().getUiAutomation()
134                 .adoptShellPermissionIdentity(READ_WALLPAPER_INTERNAL);
135 
136         mContext = InstrumentationRegistry.getTargetContext();
137         WallpaperWindowsTestUtils.setContext(mContext);
138         mCtsTouchUtils = new CtsTouchUtils(mContext);
139         mWallpaperManager = WallpaperManager.getInstance(mContext);
140         assumeTrue("Device does not support wallpapers", mWallpaperManager.isWallpaperSupported());
141 
142         MockitoAnnotations.initMocks(this);
143         final HandlerThread handlerThread = new HandlerThread("TestCallbacks");
144         handlerThread.start();
145         mHandler = new Handler(handlerThread.getLooper());
146         mCountDownLatch = new CountDownLatch(1);
147         mBroadcastReceiver = new BroadcastReceiver() {
148             @Override
149             public void onReceive(Context context, Intent intent) {
150                 mCountDownLatch.countDown();
151                 if (DEBUG) {
152                     Log.d(TAG, "broadcast state count down: " + mCountDownLatch.getCount());
153                 }
154             }
155         };
156         mContext.registerReceiver(mBroadcastReceiver,
157                 new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
158         mEnableWcg = mWallpaperManager.shouldEnableWideColorGamut();
159         mWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK);
160 
161         assertWithMessage("Home screen wallpaper must be set after setUp()").that(
162                 mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isAtLeast(0);
163         assertWithMessage("Lock screen wallpaper must be unset after setUp()").that(
164                 mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
165 
166         TestWallpaperService.Companion.resetCounts();
167     }
168 
169     @After
tearDown()170     public void tearDown() throws Exception {
171 
172         // drop READ_WALLPAPER_INTERNAL
173         InstrumentationRegistry.getInstrumentation().getUiAutomation()
174                 .dropShellPermissionIdentity();
175 
176         if (mBroadcastReceiver != null) {
177             mContext.unregisterReceiver(mBroadcastReceiver);
178         }
179         TestWallpaperService.Companion.checkAssertions();
180         TestWallpaperService.Companion.resetCounts();
181         mWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK);
182     }
183 
184     @Test
setBitmap_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome()185     public void setBitmap_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome()
186             throws IOException {
187         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
188         Canvas canvas = new Canvas(tmpWallpaper);
189         canvas.drawColor(Color.RED);
190 
191         try {
192             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
193             mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */
194                     null, /* allowBackup= */true, FLAG_SYSTEM);
195             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
196                     origHomeWallpaperId);
197             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
198         } finally {
199             tmpWallpaper.recycle();
200         }
201     }
202 
203     @Test
setBitmap_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome()204     public void setBitmap_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome()
205             throws IOException {
206         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
207         runWithShellPermissionIdentity(() -> {
208             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK);
209         });
210         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
211         Canvas canvas = new Canvas(tmpWallpaper);
212         canvas.drawColor(Color.RED);
213 
214         try {
215             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
216             mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */
217                     null, /* allowBackup= */true, FLAG_SYSTEM);
218             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
219                     origHomeWallpaperId);
220             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
221         } finally {
222             tmpWallpaper.recycle();
223         }
224     }
225 
226     @Test
setBitmap_homeScreen_lockScreenSet_singleEngine_changesHomeOnly()227     public void setBitmap_homeScreen_lockScreenSet_singleEngine_changesHomeOnly()
228             throws IOException {
229         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
230         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
231         Canvas canvas = new Canvas(tmpWallpaper);
232         canvas.drawColor(Color.GREEN);
233 
234         try {
235             mWallpaperManager.setBitmap(tmpWallpaper, null, true, FLAG_LOCK);
236             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
237             int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
238             canvas.drawColor(Color.RED);
239             mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */
240                     null, /* allowBackup= */true, FLAG_SYSTEM);
241             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
242                     origHomeWallpaperId);
243             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origLockWallpaperId);
244         } finally {
245             tmpWallpaper.recycle();
246         }
247     }
248 
249     @Test
setBitmap_lockScreen_lockScreenUnset_changesLockOnly()250     public void setBitmap_lockScreen_lockScreenUnset_changesLockOnly() throws IOException {
251         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
252         Canvas canvas = new Canvas(tmpWallpaper);
253         canvas.drawColor(Color.RED);
254 
255         try {
256             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
257             mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */
258                     null, /* allowBackup= */true, FLAG_LOCK);
259             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(
260                     origHomeWallpaperId);
261             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isAtLeast(0);
262         } finally {
263             tmpWallpaper.recycle();
264         }
265     }
266 
267     @Test
setBitmap_lockScreen_lockScreenSet_changesLockOnly()268     public void setBitmap_lockScreen_lockScreenSet_changesLockOnly() throws IOException {
269         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
270         Canvas canvas = new Canvas(tmpWallpaper);
271         canvas.drawColor(Color.GREEN);
272 
273         try {
274             mWallpaperManager.setBitmap(tmpWallpaper, null, true, FLAG_LOCK);
275             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
276             int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
277             canvas.drawColor(Color.RED);
278             mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */
279                     null, /* allowBackup= */true, FLAG_LOCK);
280             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(
281                     origHomeWallpaperId);
282             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isNotEqualTo(
283                     origLockWallpaperId);
284         } finally {
285             tmpWallpaper.recycle();
286         }
287     }
288 
289     @Test
setBitmap_both_lockScreenUnset_changesHome()290     public void setBitmap_both_lockScreenUnset_changesHome() throws IOException {
291         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
292         Canvas canvas = new Canvas(tmpWallpaper);
293         canvas.drawColor(Color.RED);
294 
295         try {
296             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
297             mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */
298                     null, /* allowBackup= */true, FLAG_SYSTEM | FLAG_LOCK);
299             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
300                     origHomeWallpaperId);
301             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
302         } finally {
303             tmpWallpaper.recycle();
304         }
305     }
306 
307     @Test
setBitmap_both_lockScreenSet_changesHomeAndClearsLock()308     public void setBitmap_both_lockScreenSet_changesHomeAndClearsLock() throws IOException {
309         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
310         Canvas canvas = new Canvas(tmpWallpaper);
311         canvas.drawColor(Color.GREEN);
312 
313         try {
314             mWallpaperManager.setBitmap(tmpWallpaper, null, true, FLAG_LOCK);
315             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
316             int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
317             canvas.drawColor(Color.RED);
318             mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */
319                     null, /* allowBackup= */true, FLAG_SYSTEM | FLAG_LOCK);
320             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
321                     origHomeWallpaperId);
322             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
323         } finally {
324             tmpWallpaper.recycle();
325         }
326     }
327 
328     @Test
setBitmap_default_lockScreenUnset_sameAsBoth()329     public void setBitmap_default_lockScreenUnset_sameAsBoth() throws IOException {
330         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
331         Canvas canvas = new Canvas(tmpWallpaper);
332         canvas.drawColor(Color.RED);
333 
334         try {
335             int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
336             mWallpaperManager.setBitmap(tmpWallpaper);
337             assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
338                     origHomeWallpaperId);
339             assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
340         } finally {
341             tmpWallpaper.recycle();
342         }
343     }
344 
345     @Test
setResource_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome()346     public void setResource_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome()
347             throws IOException {
348         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
349         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
350         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
351                 origHomeWallpaperId);
352         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
353     }
354 
355     @Test
setResource_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome()356     public void setResource_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome()
357             throws IOException {
358         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
359         runWithShellPermissionIdentity(() -> {
360             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK);
361         });
362         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
363 
364         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
365 
366         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
367                 origHomeWallpaperId);
368         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
369     }
370 
371     @Test
setResource_homeScreen_lockScreenSet_changesHomeOnly()372     public void setResource_homeScreen_lockScreenSet_changesHomeOnly() throws IOException {
373         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
374         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
375         int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
376         mWallpaperManager.setResource(R.drawable.icon_green, FLAG_SYSTEM);
377         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
378                 origHomeWallpaperId);
379         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origLockWallpaperId);
380     }
381 
382     @Test
setResource_lockScreen_lockScreenUnset_changesLockOnly()383     public void setResource_lockScreen_lockScreenUnset_changesLockOnly() throws IOException {
384         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
385         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
386         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(
387                 origHomeWallpaperId);
388         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isAtLeast(0);
389     }
390 
391     @Test
setResource_lockScreen_lockScreenSet_changesLockOnly()392     public void setResource_lockScreen_lockScreenSet_changesLockOnly() throws IOException {
393         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
394         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
395         int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
396         mWallpaperManager.setResource(R.drawable.icon_green, FLAG_LOCK);
397         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(
398                 origHomeWallpaperId);
399         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isNotEqualTo(
400                 origLockWallpaperId);
401     }
402 
403     @Test
setResource_both_lockScreenUnset_changesHome()404     public void setResource_both_lockScreenUnset_changesHome() throws IOException {
405         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
406         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM | FLAG_LOCK);
407         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
408                 origHomeWallpaperId);
409         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
410     }
411 
412     @Test
setResource_both_lockScreenSet_changesHomeAndClearsLock()413     public void setResource_both_lockScreenSet_changesHomeAndClearsLock() throws IOException {
414         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
415         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
416         mWallpaperManager.setResource(R.drawable.icon_green, FLAG_SYSTEM | FLAG_LOCK);
417         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
418                 origHomeWallpaperId);
419         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
420     }
421 
422     // This is just to be sure that setResource call the overload with `which`.
423     @Test
setResource_default_lockScreenUnset_sameAsBoth()424     public void setResource_default_lockScreenUnset_sameAsBoth() throws IOException {
425         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
426         mWallpaperManager.setResource(R.drawable.icon_red);
427         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(
428                 origHomeWallpaperId);
429         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
430     }
431 
432     @Test
setWallpaperComponent_homeScreen_homeStatic_lockScreenUnset_migratesThenSetsHome()433     public void setWallpaperComponent_homeScreen_homeStatic_lockScreenUnset_migratesThenSetsHome() {
434         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
435         runWithShellPermissionIdentity(() -> {
436             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM);
437         });
438 
439         assertWithMessage("System wallpaper must change").that(
440                 mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
441         assertWithMessage("Lock wallpaper mush not change").that(
442                 mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
443     }
444 
445     @Test
setWallpaperComponent_homeScreen_homeLive_lockScreenUnset_migratesThenSetsHome()446     public void setWallpaperComponent_homeScreen_homeLive_lockScreenUnset_migratesThenSetsHome() {
447         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
448         runWithShellPermissionIdentity(() -> {
449             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK);
450         });
451         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
452 
453         runWithShellPermissionIdentity(() -> {
454             ComponentName newComponentName = new ComponentName(
455                     TestLiveWallpaperNoUnfoldTransition.class.getPackageName(),
456                     TestLiveWallpaperNoUnfoldTransition.class.getName());
457             setWallpaperComponentAndWait(newComponentName, FLAG_SYSTEM);
458         });
459 
460         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
461         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
462     }
463 
464     @Test
setWallpaperComponent_homeScreen_lockScreenSet_changesHomeOnly()465     public void setWallpaperComponent_homeScreen_lockScreenSet_changesHomeOnly()
466             throws IOException {
467         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
468         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
469         int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
470         runWithShellPermissionIdentity(() -> {
471             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM);
472         });
473         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
474         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origLockWallpaperId);
475     }
476 
477     @Test
setWallpaperComponent_lockScreen_singleEngine_lockScreenUnset_sameAsHomeScreen()478     public void setWallpaperComponent_lockScreen_singleEngine_lockScreenUnset_sameAsHomeScreen() {
479         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
480         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
481         runWithShellPermissionIdentity(() -> {
482             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_LOCK);
483         });
484         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
485         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
486     }
487 
488     @Test
setWallpaperComponent_lockScreen_multiEngine_lockScreenUnset_changesLockOnly()489     public void setWallpaperComponent_lockScreen_multiEngine_lockScreenUnset_changesLockOnly() {
490         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
491         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
492         runWithShellPermissionIdentity(() -> {
493             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_LOCK);
494         });
495         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(origHomeWallpaperId);
496         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isAtLeast(0);
497     }
498 
499     @Test
setWallpaperComponent_lockScreen_singleEngine_lockScreenSet_behavesLikeHomeScreen()500     public void setWallpaperComponent_lockScreen_singleEngine_lockScreenSet_behavesLikeHomeScreen()
501             throws IOException {
502         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
503         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
504         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
505         int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
506         runWithShellPermissionIdentity(() -> {
507             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_LOCK);
508         });
509         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
510         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origLockWallpaperId);
511     }
512 
513     @Test
setWallpaperComponent_lockScreen_multiEngine_lockScreenSet_changeLockOnly()514     public void setWallpaperComponent_lockScreen_multiEngine_lockScreenSet_changeLockOnly()
515             throws IOException {
516         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
517         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
518         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
519         int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
520         runWithShellPermissionIdentity(() -> {
521             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_LOCK);
522         });
523         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(origHomeWallpaperId);
524         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isNotEqualTo(origLockWallpaperId);
525     }
526 
527     @Test
setWallpaperComponent_both_singleEngine_lockScreenUnset_behavesLikeHomeScreen()528     public void setWallpaperComponent_both_singleEngine_lockScreenUnset_behavesLikeHomeScreen() {
529         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
530         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
531         runWithShellPermissionIdentity(() -> {
532             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK);
533         });
534         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
535         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
536     }
537 
538     @Test
setWallpaperComponent_both_multiEngine_lockScreenUnset_setsHomeToBoth()539     public void setWallpaperComponent_both_multiEngine_lockScreenUnset_setsHomeToBoth() {
540         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
541         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
542         runWithShellPermissionIdentity(() -> {
543             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK);
544         });
545         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
546         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
547     }
548 
549     @Test
setWallpaperComponent_both_singleEngine_lockScreenSet_behavesLikeHomeScreen()550     public void setWallpaperComponent_both_singleEngine_lockScreenSet_behavesLikeHomeScreen()
551             throws IOException {
552         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
553         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
554         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
555         int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK);
556         runWithShellPermissionIdentity(() -> {
557             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK);
558         });
559         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
560         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origLockWallpaperId);
561     }
562 
563     @Test
setWallpaperComponent_both_multiEngine_lockScreenSet_changesLockOnly()564     public void setWallpaperComponent_both_multiEngine_lockScreenSet_changesLockOnly()
565             throws IOException {
566         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
567         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
568         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
569         runWithShellPermissionIdentity(() -> {
570             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK);
571         });
572         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
573         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
574     }
575 
576     @Test
setWallpaperComponent_default_singleEngine_lockScreenUnset_behavesLikeHomeScreen()577     public void setWallpaperComponent_default_singleEngine_lockScreenUnset_behavesLikeHomeScreen() {
578         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
579         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
580         runWithShellPermissionIdentity(() -> {
581             mWallpaperManager.setWallpaperComponent(DEFAULT_COMPONENT_NAME);
582         });
583         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
584         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId);
585     }
586 
587     @Test
setWallpaperComponent_default_multiEngine_lockScreenUnset_behavesLikeBoth()588     public void setWallpaperComponent_default_multiEngine_lockScreenUnset_behavesLikeBoth() {
589         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
590         int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM);
591         runWithShellPermissionIdentity(() -> {
592             mWallpaperManager.setWallpaperComponent(DEFAULT_COMPONENT_NAME);
593         });
594         assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId);
595         assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0);
596     }
597 
598     @Test
setStaticWallpaper_doesNotSetWallpaperInfo()599     public void setStaticWallpaper_doesNotSetWallpaperInfo() throws IOException {
600         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNull();
601         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull();
602 
603         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
604         mWallpaperManager.setResource(R.drawable.icon_green, FLAG_LOCK);
605 
606         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNull();
607         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull();
608     }
609 
610     @Test
setLiveWallpaper_homeScreen_setsHomeWallpaperInfo()611     public void setLiveWallpaper_homeScreen_setsHomeWallpaperInfo() {
612         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNull();
613         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull();
614 
615         runWithShellPermissionIdentity(() -> {
616             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_SYSTEM);
617         });
618 
619         assertWithMessage("Home screen").that(
620                 mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNotNull();
621         assertWithMessage("Lock screen").that(
622                 mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull();
623     }
624 
625     @Test
setLiveWallpaper_lockScreen_singleEngine_setsHomeWallpaperInfo()626     public void setLiveWallpaper_lockScreen_singleEngine_setsHomeWallpaperInfo() {
627         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
628         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNull();
629         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull();
630 
631         runWithShellPermissionIdentity(() -> {
632             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_LOCK);
633         });
634 
635         assertWithMessage("Home screen").that(
636                 mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNotNull();
637         assertWithMessage("Lock screen").that(
638                 mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull();
639     }
640 
641     @Test
setLiveWallpaper_lockScreen_multiEngine_setsLockWallpaperInfo()642     public void setLiveWallpaper_lockScreen_multiEngine_setsLockWallpaperInfo() {
643         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
644         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNull();
645         assertThat(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull();
646 
647         runWithShellPermissionIdentity(() -> {
648             setWallpaperComponentAndWait(DEFAULT_COMPONENT_NAME, FLAG_LOCK);
649         });
650 
651         assertWithMessage("Home screen").that(
652                 mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNull();
653         assertWithMessage("Lock screen").that(
654                 mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNotNull();
655     }
656 
657     @Test
getWallpaperInfo_badFlagsArgument_throwsException()658     public void getWallpaperInfo_badFlagsArgument_throwsException() {
659         assertThrows(IllegalArgumentException.class, () ->
660                 mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM | FLAG_LOCK));
661     }
662 
663     @Test
wallpaperChangedBroadcastTest()664     public void wallpaperChangedBroadcastTest() {
665         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
666         Canvas canvas = new Canvas(tmpWallpaper);
667         canvas.drawColor(Color.BLACK);
668 
669         try {
670             mWallpaperManager.setBitmap(tmpWallpaper);
671 
672             // Wait for up to 5 sec since this is an async call.
673             // Should fail if Intent.ACTION_WALLPAPER_CHANGED isn't delivered.
674             assertWithMessage("Timed out waiting for Intent").that(
675                     mCountDownLatch.await(5, TimeUnit.SECONDS)).isTrue();
676         } catch (InterruptedException | IOException e) {
677             throw new AssertionError("Intent.ACTION_WALLPAPER_CHANGED not received.");
678         } finally {
679             tmpWallpaper.recycle();
680         }
681     }
682 
683     @Test
wallpaperClearBroadcastTest()684     public void wallpaperClearBroadcastTest() {
685         try {
686             mWallpaperManager.clear(FLAG_LOCK | FLAG_SYSTEM);
687 
688             // Wait for 5 sec since this is an async call.
689             // Should fail if Intent.ACTION_WALLPAPER_CHANGED isn't delivered.
690             assertWithMessage("Timed out waiting for Intent").that(
691                     mCountDownLatch.await(5, TimeUnit.SECONDS)).isTrue();
692         } catch (InterruptedException | IOException e) {
693             throw new AssertionError(e);
694         }
695     }
696 
697     @Test
invokeOnColorsChangedListenerTest_systemOnly()698     public void invokeOnColorsChangedListenerTest_systemOnly() {
699         if (mWallpaperManager.isLockscreenLiveWallpaperEnabled()) {
700             verifyColorListenerInvoked(FLAG_SYSTEM, FLAG_SYSTEM);
701             return;
702         }
703         int both = FLAG_LOCK | FLAG_SYSTEM;
704         // Expect both since the first step is to migrate the current wallpaper
705         // to the lock screen.
706         verifyColorListenerInvoked(FLAG_SYSTEM, both);
707     }
708 
709     @Test
invokeOnColorsChangedListenerTest_lockOnly()710     public void invokeOnColorsChangedListenerTest_lockOnly() {
711         verifyColorListenerInvoked(FLAG_LOCK, FLAG_LOCK);
712     }
713 
714     @Test
invokeOnColorsChangedListenerTest_both()715     public void invokeOnColorsChangedListenerTest_both() {
716         int both = FLAG_LOCK | FLAG_SYSTEM;
717         verifyColorListenerInvoked(both, both);
718     }
719 
720     @Test
invokeOnColorsChangedListenerTest_clearLock()721     public void invokeOnColorsChangedListenerTest_clearLock() throws IOException {
722         verifyColorListenerInvokedClearing(FLAG_LOCK);
723     }
724 
725     @Test
invokeOnColorsChangedListenerTest_clearSystem()726     public void invokeOnColorsChangedListenerTest_clearSystem() throws IOException {
727         verifyColorListenerInvokedClearing(FLAG_SYSTEM);
728     }
729 
730     /**
731      * Removing a listener should not invoke it anymore
732      */
733     @Test
addRemoveOnColorsChangedListenerTest_onlyInvokeAdded()734     public void addRemoveOnColorsChangedListenerTest_onlyInvokeAdded() throws IOException {
735         ensureCleanState();
736 
737         final CountDownLatch latch = new CountDownLatch(1);
738         WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> latch.countDown();
739 
740         // Add and remove listener
741         WallpaperManager.OnColorsChangedListener listener = getTestableListener();
742         mWallpaperManager.addOnColorsChangedListener(listener, mHandler);
743         mWallpaperManager.removeOnColorsChangedListener(listener);
744 
745         // Verify that the listener is not called
746         mWallpaperManager.addOnColorsChangedListener(counter, mHandler);
747         try {
748             mWallpaperManager.setResource(R.drawable.icon_red);
749             if (!latch.await(5, TimeUnit.SECONDS)) {
750                 throw new AssertionError("Registered listener not invoked");
751             }
752         } catch (InterruptedException | IOException e) {
753             throw new RuntimeException(e);
754         }
755         verify(listener, never()).onColorsChanged(any(WallpaperColors.class), anyInt());
756         mWallpaperManager.removeOnColorsChangedListener(counter);
757     }
758 
759     /**
760      * Suggesting desired dimensions is only a hint to the system that can be ignored.
761      *
762      * Test if the desired minimum width or height the WallpaperManager returns
763      * is greater than 0. If so, then we check whether that the size is the dimension
764      * that was suggested.
765      */
766     @Test
suggestDesiredDimensionsTest()767     public void suggestDesiredDimensionsTest() {
768         final Point min = getScreenSize();
769         int w = min.x * 3;
770         int h = min.y * 2;
771 
772         // b/120847476: WallpaperManager limits at GL_MAX_TEXTURE_SIZE
773         final int max = getMaxTextureSize();
774         if (max > 0) {
775             w = Math.min(w, max);
776             h = Math.min(h, max);
777         }
778 
779         assertDesiredDimension(new Point(min.x / 2, min.y / 2), new Point(min.x / 2, min.y / 2));
780 
781         assertDesiredDimension(new Point(w, h), new Point(w, h));
782 
783         assertDesiredDimension(new Point(min.x / 2, h), new Point(min.x / 2, h));
784 
785         assertDesiredDimension(new Point(w, min.y / 2), new Point(w, min.y / 2));
786     }
787 
788     @Test
789     @Ignore("b/265007420")
wallpaperColors_primary()790     public void wallpaperColors_primary() {
791         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
792         Canvas canvas = new Canvas(tmpWallpaper);
793         canvas.drawColor(Color.RED);
794 
795         try {
796             mWallpaperManager.setBitmap(tmpWallpaper);
797             WallpaperColors colors = mWallpaperManager.getWallpaperColors(
798                     FLAG_SYSTEM);
799 
800             // Check that primary color is almost red
801             Color primary = colors.getPrimaryColor();
802             final float delta = 0.1f;
803             assertWithMessage("red").that(primary.red()).isWithin(delta).of(1f);
804             assertWithMessage("green").that(primary.green()).isWithin(delta).of(0f);
805             assertWithMessage("blue").that(primary.blue()).isWithin(delta).of(0f);
806 
807             assertThat(colors.getSecondaryColor()).isNull();
808             assertThat(colors.getTertiaryColor()).isNull();
809         } catch (IOException e) {
810             throw new RuntimeException(e);
811         } finally {
812             tmpWallpaper.recycle();
813         }
814     }
815 
816     @Test
817     @Ignore("b/265007420")
wallpaperColors_secondary()818     public void wallpaperColors_secondary() {
819         Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
820         Canvas canvas = new Canvas(tmpWallpaper);
821         canvas.drawColor(Color.RED);
822         // Make 20% of the wallpaper BLUE so that secondary color is BLUE
823         canvas.clipRect(0, 0, 100, 20);
824         canvas.drawColor(Color.BLUE);
825 
826         try {
827             mWallpaperManager.setBitmap(tmpWallpaper);
828             WallpaperColors colors = mWallpaperManager.getWallpaperColors(
829                     FLAG_SYSTEM);
830 
831             // Check that the secondary color is almost blue
832             Color secondary = colors.getSecondaryColor();
833             final float delta = 0.15f;
834             assertWithMessage("red").that(secondary.red()).isWithin(delta).of(0f);
835             assertWithMessage("green").that(secondary.green()).isWithin(delta).of(0f);
836             assertWithMessage("blue").that(secondary.blue()).isWithin(delta).of(1f);
837         } catch (IOException e) {
838             throw new RuntimeException(e);
839         } finally {
840             tmpWallpaper.recycle();
841         }
842     }
843 
844     @Test
highRatioWallpaper_largeWidth()845     public void highRatioWallpaper_largeWidth() throws Exception {
846         Bitmap highRatioWallpaper = Bitmap.createBitmap(8000, 800, Bitmap.Config.ARGB_8888);
847         Canvas canvas = new Canvas(highRatioWallpaper);
848         canvas.drawColor(Color.RED);
849 
850         try {
851             mWallpaperManager.setBitmap(highRatioWallpaper);
852             assertBitmapDimensions(mWallpaperManager.getBitmap());
853         } finally {
854             highRatioWallpaper.recycle();
855         }
856     }
857 
858     @Test
highRatioWallpaper_largeHeight()859     public void highRatioWallpaper_largeHeight() throws Exception {
860         Bitmap highRatioWallpaper = Bitmap.createBitmap(800, 8000, Bitmap.Config.ARGB_8888);
861         Canvas canvas = new Canvas(highRatioWallpaper);
862         canvas.drawColor(Color.RED);
863 
864         try {
865             mWallpaperManager.setBitmap(highRatioWallpaper);
866             assertBitmapDimensions(mWallpaperManager.getBitmap());
867         } finally {
868             highRatioWallpaper.recycle();
869         }
870     }
871 
872     @Test
highResolutionWallpaper()873     public void highResolutionWallpaper() throws Exception {
874         Bitmap highResolutionWallpaper = Bitmap.createBitmap(10000, 10000, Bitmap.Config.ARGB_8888);
875         Canvas canvas = new Canvas(highResolutionWallpaper);
876         canvas.drawColor(Color.BLUE);
877 
878         try {
879             mWallpaperManager.setBitmap(highResolutionWallpaper);
880             assertBitmapDimensions(mWallpaperManager.getBitmap());
881         } finally {
882             highResolutionWallpaper.recycle();
883         }
884     }
885 
886     @Test
testWideGamutWallpaper()887     public void testWideGamutWallpaper() throws IOException {
888         final ColorSpace srgb = ColorSpace.get(ColorSpace.Named.SRGB);
889         final ColorSpace p3 = ColorSpace.get(ColorSpace.Named.DISPLAY_P3);
890         final Bitmap.Config config = Bitmap.Config.ARGB_8888;
891         final Bitmap srgbBitmap = Bitmap.createBitmap(100, 100, config);
892         final Bitmap p3Bitmap = Bitmap.createBitmap(100, 100, config, false, p3);
893 
894         try {
895             // sRGB is the default color space
896             mWallpaperManager.setBitmap(srgbBitmap);
897             assertThat(mWallpaperManager.getBitmap().getColorSpace()).isEqualTo(srgb);
898 
899             // If wide gamut is enabled, Display-P3 should be supported.
900             mWallpaperManager.setBitmap(p3Bitmap);
901 
902             final boolean isDisplayP3 = mWallpaperManager.getBitmap().getColorSpace().equals(p3);
903             // Assert false only when device enabled WCG, but display does not support Display-P3
904             assertThat(mEnableWcg && !isDisplayP3).isFalse();
905         } finally {
906             srgbBitmap.recycle();
907             p3Bitmap.recycle();
908         }
909     }
910 
911     @Test
testWallpaperSupportsWcg()912     public void testWallpaperSupportsWcg() throws IOException {
913         final int sysWallpaper = FLAG_SYSTEM;
914 
915         final Bitmap srgbBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
916         final Bitmap p3Bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888, false,
917                 ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
918 
919         try {
920             mWallpaperManager.setBitmap(srgbBitmap);
921             assertThat(mWallpaperManager.wallpaperSupportsWcg(sysWallpaper)).isFalse();
922 
923             mWallpaperManager.setBitmap(p3Bitmap);
924             assertThat(mWallpaperManager.wallpaperSupportsWcg(sysWallpaper)).isEqualTo(mEnableWcg);
925         } finally {
926             srgbBitmap.recycle();
927             p3Bitmap.recycle();
928         }
929     }
930 
931     /**
932      * Check that all the callback methods of the wallpaper are invoked by the same thread.
933      * Also checks that the callback methods are called in a proper order.
934      * See {@link TestWallpaperService} to see the checks that are performed.
935      */
936     @Test
wallpaperCallbackMainThreadTest()937     public void wallpaperCallbackMainThreadTest() {
938 
939         // use a wallpaper supporting ambient mode, to trigger Engine.onAmbientModeChanged
940         ComponentName componentName = new ComponentName(
941                 TestLiveWallpaperSupportingAmbientMode.class.getPackageName(),
942                 TestLiveWallpaperSupportingAmbientMode.class.getName());
943         runWithShellPermissionIdentity(() ->
944                 mWallpaperManager.setWallpaperComponent(componentName));
945 
946         // trigger Engine.onDesiredDimensionsChanged
947         mWallpaperManager.suggestDesiredDimensions(1000, 1000);
948 
949         Activity activity = mActivityTestRule.launchActivity(null);
950 
951         Window window = activity.getWindow();
952         IBinder windowToken = window.getDecorView().getWindowToken();
953 
954         // send some command to trigger Engine.onCommand
955         mWallpaperManager.sendWallpaperCommand(
956                 windowToken, WallpaperManager.COMMAND_TAP, 50, 50, 0, null);
957 
958         // trigger Engine.onZoomChanged
959         mWallpaperManager.setWallpaperZoomOut(windowToken, 0.5f);
960 
961         // trigger Engine.onTouchEvent
962         mCtsTouchUtils.emulateTapOnViewCenter(
963                 InstrumentationRegistry.getInstrumentation(), null,
964                 activity.findViewById(android.R.id.content));
965 
966         mActivityTestRule.finishActivity();
967         runWithShellPermissionIdentity(() -> mWallpaperManager.clearWallpaper());
968     }
969 
970     @Test
peekWallpaperCaching_cachesWallpaper()971     public void peekWallpaperCaching_cachesWallpaper() throws IOException {
972         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
973 
974         // Get the current bitmap, and check that the second call returns the cached bitmap
975         Bitmap bitmap1 = mWallpaperManager.getBitmapAsUser(mContext.getUserId(),
976                 false /* hardware */, FLAG_SYSTEM);
977         assertThat(bitmap1).isNotNull();
978         assertThat(mWallpaperManager.getBitmapAsUser(mContext.getUserId(), false /* hardware */,
979                 FLAG_SYSTEM)).isSameInstanceAs(bitmap1);
980 
981         // Change the wallpaper to invalidate the cached bitmap
982         mWallpaperManager.setResource(R.drawable.icon_green, FLAG_SYSTEM);
983 
984         // Get the new bitmap, and check that the second call returns the newly cached bitmap
985         Bitmap bitmap2 = mWallpaperManager.getBitmapAsUser(mContext.getUserId(),
986                 false /* hardware */, FLAG_SYSTEM);
987         assertThat(bitmap2).isNotSameInstanceAs(bitmap1);
988         assertThat(mWallpaperManager.getBitmapAsUser(mContext.getUserId(), false /* hardware */,
989                 FLAG_SYSTEM)).isSameInstanceAs(bitmap2);
990     }
991 
992     @Test
peekWallpaperCaching_differentWhich_doesNotReturnCached()993     public void peekWallpaperCaching_differentWhich_doesNotReturnCached() throws IOException {
994         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
995         mWallpaperManager.setResource(R.drawable.icon_green, FLAG_LOCK);
996 
997         Bitmap bitmapSystem = mWallpaperManager.getBitmapAsUser(mContext.getUserId(),
998                 false /* hardware */, FLAG_SYSTEM);
999         Bitmap bitmapLock = mWallpaperManager.getBitmapAsUser(mContext.getUserId(),
1000                 false /* hardware */, FLAG_LOCK);
1001         assertThat(bitmapLock).isNotSameInstanceAs(bitmapSystem);
1002 
1003     }
1004 
1005     @Test
peekWallpaperCaching_bitmapRecycled_doesNotReturnCached()1006     public void peekWallpaperCaching_bitmapRecycled_doesNotReturnCached() throws IOException {
1007         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1008 
1009         Bitmap bitmap = mWallpaperManager.getBitmapAsUser(mContext.getUserId(),
1010                 false /* hardware */, FLAG_SYSTEM);
1011         assertThat(bitmap).isNotNull();
1012         bitmap.recycle();
1013         assertThat(mWallpaperManager.getBitmapAsUser(mContext.getUserId(), false /* hardware */,
1014                 FLAG_SYSTEM)).isNotSameInstanceAs(bitmap);
1015     }
1016 
1017     @Test
peekWallpaperCaching_differentUser_doesNotReturnCached()1018     public void peekWallpaperCaching_differentUser_doesNotReturnCached() throws IOException {
1019         final int bogusUserId = -1;
1020         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1021 
1022         Bitmap bitmap = mWallpaperManager.getBitmapAsUser(mContext.getUserId(),
1023                 false /* hardware */, FLAG_SYSTEM);
1024         assertThat(bitmap).isNotNull();
1025 
1026         // If the cached bitmap was determined to be invalid, this leads to a call to
1027         // WallpaperManager.Globals#getCurrentWallpaperLocked() for a different user, which
1028         // generates a security exception: the exception indicates that the cached bitmap was
1029         // invalid, which is the desired result.
1030         assertThrows(SecurityException.class,
1031                 () -> mWallpaperManager.getBitmapAsUser(bogusUserId, false /* hardware */,
1032                         FLAG_SYSTEM));
1033     }
1034 
1035     @Test
peekWallpaperDimensions_homeScreen_succeeds()1036     public void peekWallpaperDimensions_homeScreen_succeeds() throws IOException {
1037         final int width = 100;
1038         final int height = 200;
1039         final Rect expectedSize = new Rect(0, 0, width, height);
1040         Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
1041         Canvas canvas = new Canvas(bitmap);
1042         canvas.drawColor(Color.RED);
1043         mWallpaperManager.setBitmap(bitmap);
1044 
1045         Rect actualSize = mWallpaperManager.peekBitmapDimensions();
1046 
1047         assertThat(actualSize).isEqualTo(expectedSize);
1048     }
1049 
1050     @Test
peekWallpaperDimensions_lockScreenUnset_succeeds()1051     public void peekWallpaperDimensions_lockScreenUnset_succeeds() {
1052         Rect actualSize = mWallpaperManager.peekBitmapDimensions(FLAG_LOCK);
1053 
1054         assertThat(actualSize).isNull();
1055     }
1056 
1057     @Test
peekWallpaperDimensions_lockScreenSet_succeeds()1058     public void peekWallpaperDimensions_lockScreenSet_succeeds() throws IOException {
1059         Bitmap homeBitmap = Bitmap.createBitmap(150 /* width */, 150 /* width */,
1060                 Bitmap.Config.ARGB_8888);
1061         Canvas homeCanvas = new Canvas(homeBitmap);
1062         homeCanvas.drawColor(Color.RED);
1063         mWallpaperManager.setBitmap(homeBitmap, /* visibleCropHint */ null, /* allowBackup */true,
1064                 FLAG_SYSTEM);
1065         final int width = 100;
1066         final int height = 200;
1067         final Rect expectedSize = new Rect(0, 0, width, height);
1068         Bitmap lockBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
1069         Canvas lockCanvas = new Canvas(lockBitmap);
1070         lockCanvas.drawColor(Color.RED);
1071         mWallpaperManager.setBitmap(lockBitmap, /* visibleCropHint */ null, /* allowBackup */true,
1072                 FLAG_LOCK);
1073 
1074         Rect actualSize = mWallpaperManager.peekBitmapDimensions(FLAG_LOCK);
1075 
1076         assertThat(actualSize).isEqualTo(expectedSize);
1077     }
1078 
1079     @Test
getDrawable_homeScreen_succeeds()1080     public void getDrawable_homeScreen_succeeds() throws IOException {
1081         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1082         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1083 
1084         Drawable actual = mWallpaperManager.getDrawable(FLAG_SYSTEM);
1085 
1086         assertWithMessage("Drawables must represent the same image").that(
1087                 isSimilar(actual, expected, true)).isTrue();
1088     }
1089 
1090     @Test
getDrawable_lockScreenUnset_returnsNull()1091     public void getDrawable_lockScreenUnset_returnsNull() {
1092         Drawable actual = mWallpaperManager.getDrawable(FLAG_LOCK);
1093 
1094         assertThat(actual).isNull();
1095     }
1096 
1097     @Test
getDrawable_lockScreenSet_succeeds()1098     public void getDrawable_lockScreenSet_succeeds() throws IOException {
1099         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1100         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
1101 
1102         Drawable actual = mWallpaperManager.getDrawable(FLAG_LOCK);
1103 
1104         assertWithMessage("Drawables must represent the same image").that(
1105                 isSimilar(actual, expected, true)).isTrue();
1106     }
1107 
1108     @Test
getDrawable_default_sameAsHome()1109     public void getDrawable_default_sameAsHome() throws IOException {
1110         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1111         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1112 
1113         Drawable actual = mWallpaperManager.getDrawable();
1114 
1115         assertWithMessage("Drawables must represent the same image").that(
1116                 isSimilar(actual, expected, true)).isTrue();
1117     }
1118 
1119     @Test
getFastDrawable_homeScreen_succeeds()1120     public void getFastDrawable_homeScreen_succeeds() throws IOException {
1121         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1122         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1123 
1124         Drawable actual = mWallpaperManager.getFastDrawable(FLAG_SYSTEM);
1125 
1126         assertWithMessage("Drawables must represent the same image").that(
1127                 isSimilar(actual, expected, true)).isTrue();
1128     }
1129 
1130     @Test
getFastDrawable_lockScreenUnset_returnsNull()1131     public void getFastDrawable_lockScreenUnset_returnsNull() {
1132         Drawable actual = mWallpaperManager.getFastDrawable(FLAG_LOCK);
1133 
1134         assertThat(actual).isNull();
1135     }
1136 
1137     @Test
getFastDrawable_lockScreenSet_succeeds()1138     public void getFastDrawable_lockScreenSet_succeeds() throws IOException {
1139         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1140         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
1141 
1142         Drawable actual = mWallpaperManager.getFastDrawable(FLAG_LOCK);
1143 
1144         assertWithMessage("Drawables must represent the same image").that(
1145                 isSimilar(actual, expected, true)).isTrue();
1146     }
1147 
1148     @Test
getFastDrawable_default_sameAsHome()1149     public void getFastDrawable_default_sameAsHome() throws IOException {
1150         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1151         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1152 
1153         Drawable actual = mWallpaperManager.getFastDrawable();
1154 
1155         assertWithMessage("Drawables must represent the same image").that(
1156                 isSimilar(actual, expected, true)).isTrue();
1157     }
1158 
1159     @Test
peekDrawable_homeScreen_succeeds()1160     public void peekDrawable_homeScreen_succeeds() throws IOException {
1161         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1162         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1163 
1164         Drawable actual = mWallpaperManager.peekDrawable(FLAG_SYSTEM);
1165 
1166         assertWithMessage("Drawables must represent the same image").that(
1167                 isSimilar(actual, expected, true)).isTrue();
1168     }
1169 
1170     @Test
peekDrawable_lockScreenUnset_returnsNull()1171     public void peekDrawable_lockScreenUnset_returnsNull() {
1172         Drawable actual = mWallpaperManager.peekDrawable(FLAG_LOCK);
1173 
1174         assertThat(actual).isNull();
1175     }
1176 
1177     @Test
peekDrawable_lockScreenSet_succeeds()1178     public void peekDrawable_lockScreenSet_succeeds() throws IOException {
1179         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1180         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
1181 
1182         Drawable actual = mWallpaperManager.peekDrawable(FLAG_LOCK);
1183 
1184         assertWithMessage("Drawables must represent the same image").that(
1185                 isSimilar(actual, expected, true)).isTrue();
1186     }
1187 
1188     @Test
peekDrawable_default_sameAsHome()1189     public void peekDrawable_default_sameAsHome() throws IOException {
1190         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1191         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1192 
1193         Drawable actual = mWallpaperManager.peekDrawable();
1194 
1195         assertWithMessage("Drawables must represent the same image").that(
1196                 isSimilar(actual, expected, true)).isTrue();
1197     }
1198 
1199     @Test
peekFastDrawable_homeScreen_succeeds()1200     public void peekFastDrawable_homeScreen_succeeds() throws IOException {
1201         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1202         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1203 
1204         Drawable actual = mWallpaperManager.peekFastDrawable(FLAG_SYSTEM);
1205 
1206         assertWithMessage("Drawables must represent the same image").that(
1207                 isSimilar(actual, expected, true)).isTrue();
1208     }
1209 
1210     @Test
peekFastDrawable_lockScreenUnset_returnsNull()1211     public void peekFastDrawable_lockScreenUnset_returnsNull() {
1212         Drawable actual = mWallpaperManager.peekFastDrawable(FLAG_LOCK);
1213 
1214         assertThat(actual).isNull();
1215     }
1216 
1217     @Test
peekFastDrawable_lockScreenSet_succeeds()1218     public void peekFastDrawable_lockScreenSet_succeeds() throws IOException {
1219         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1220         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK);
1221 
1222         Drawable actual = mWallpaperManager.peekFastDrawable(FLAG_LOCK);
1223 
1224         assertWithMessage("Drawables must represent the same image").that(
1225                 isSimilar(actual, expected, true)).isTrue();
1226     }
1227 
1228     @Test
peekFastDrawable_default_sameAsHome()1229     public void peekFastDrawable_default_sameAsHome() throws IOException {
1230         Drawable expected = mContext.getDrawable(R.drawable.icon_red);
1231         mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM);
1232 
1233         Drawable actual = mWallpaperManager.peekFastDrawable();
1234 
1235         assertWithMessage("Drawables must represent the same image").that(
1236                 isSimilar(actual, expected, true)).isTrue();
1237     }
1238 
1239     /**
1240      * For every possible (state, change) couple, checks that the number of times
1241      * {@link TestWallpaperService.FakeEngine#onDestroy} and
1242      * {@link TestWallpaperService.FakeEngine#onCreate} are called is correct.
1243      */
1244     @Test
testEngineCallbackCounts()1245     public void testEngineCallbackCounts() throws IOException {
1246         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
1247         ArrayList<String> errorMessages = new ArrayList<>();
1248         runWithShellPermissionIdentity(() -> {
1249             for (WallpaperState state : WallpaperManagerTestUtils.allPossibleStates()) {
1250 
1251                 for (WallpaperChange change: state.allPossibleChanges()) {
1252                     WallpaperManagerTestUtils.goToState(mWallpaperManager, state);
1253                     TestWallpaperService.Companion.resetCounts();
1254                     WallpaperManagerTestUtils.performChange(mWallpaperManager, change);
1255 
1256                     int expectedCreateCount = state.expectedNumberOfLiveWallpaperCreate(change);
1257                     int actualCreateCount = TestWallpaperService.Companion.getCreateCount();
1258                     String createMessage = String.format(
1259                             "Expected %s calls to Engine#onCreate, got %s. ",
1260                             expectedCreateCount, actualCreateCount);
1261                     if (actualCreateCount != expectedCreateCount) {
1262                         errorMessages.add(
1263                                 createMessage + "\n" + state.reproduceDescription(change));
1264                     }
1265 
1266                     int expectedDestroyCount = state.expectedNumberOfLiveWallpaperDestroy(change);
1267                     int actualDestroyCount = TestWallpaperService.Companion.getDestroyCount();
1268                     String destroyMessage = String.format(
1269                             "Expected %s calls to Engine#onDestroy, got %s. ",
1270                             expectedDestroyCount, actualDestroyCount);
1271                     if (actualDestroyCount != expectedDestroyCount) {
1272                         errorMessages.add(
1273                                 destroyMessage + "\n" + state.reproduceDescription(change));
1274                     }
1275                 }
1276             }
1277         });
1278         assertWithMessage(String.join("\n\n", errorMessages))
1279                 .that(errorMessages.size()).isEqualTo(0);
1280     }
1281 
1282     /**
1283      * Check that the wallpaper windows that window manager is handling
1284      * are exactly the expected ones
1285      */
1286     @Test
testExistingWallpaperWindows()1287     public void testExistingWallpaperWindows() {
1288         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
1289         assumeTrue("Skipping testExistingWallpaperWindows: FEATURE_LIVE_WALLPAPER missing.",
1290                 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER));
1291         runWithShellPermissionIdentity(() -> {
1292             WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper =
1293                     new WallpaperWindowsTestUtils.WallpaperWindowsHelper(sWindowManagerStateHelper);
1294             // Two independent wallpapers
1295             WallpaperManagerTestUtils.goToState(mWallpaperManager, TWO_DIFFERENT_LIVE_WALLPAPERS);
1296             assertWallpapersMatching(wallpaperWindowsHelper,
1297                     List.of(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM).getServiceName(),
1298                             mWallpaperManager.getWallpaperInfo(FLAG_LOCK).getServiceName()));
1299             // One shared wallpaper
1300             WallpaperManagerTestUtils.goToState(mWallpaperManager, TWO_SAME_LIVE_WALLPAPERS);
1301             assertWallpapersMatching(wallpaperWindowsHelper, List.of(
1302                     mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM).getServiceName()));
1303         });
1304     }
1305 
1306     /**
1307      * Check that the windows which have the role of home screen wallpapers
1308      * are actually visible on home screen
1309      */
1310     @Test
testSystemAndLockWallpaperVisibility_onHomeScreen()1311     public void testSystemAndLockWallpaperVisibility_onHomeScreen() {
1312         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
1313         assumeTrue("Skipping testSystemAndLockWallpaperVisibility_onHomeScreen:"
1314                         + " FEATURE_LIVE_WALLPAPER missing.",
1315                 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER));
1316         // Launch an activity that shows the wallpaper to make sure it is not behind opaque
1317         // activities
1318         mActivityTestRule.launchActivity(null);
1319         try {
1320             runWithShellPermissionIdentity(() -> {
1321                 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper =
1322                         new WallpaperWindowsTestUtils.WallpaperWindowsHelper(
1323                                 sWindowManagerStateHelper);
1324                 wallpaperWindowsHelper.showHomeScreenAndUpdate();
1325 
1326                 // Two independent wallpapers
1327                 WallpaperManagerTestUtils.goToState(mWallpaperManager,
1328                         TWO_DIFFERENT_LIVE_WALLPAPERS);
1329                 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM,
1330                         true /* shouldBeShown */, "System wallpaper is hidden on home screen");
1331 
1332                 // Shared wallpaper
1333                 WallpaperManagerTestUtils.goToState(mWallpaperManager, TWO_SAME_LIVE_WALLPAPERS);
1334                 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM | FLAG_LOCK,
1335                         true /* shouldBeShown */, "Shared wallpaper is hidden on home screen");
1336             });
1337         } finally {
1338             mActivityTestRule.finishActivity();
1339         }
1340     }
1341 
1342     /**
1343      * Check that the windows which have the role of lock screen wallpapers
1344      * are actually visible on lock screen
1345      */
1346     @Test
testSystemAndLockWallpaperVisibility_onLockScreen()1347     public void testSystemAndLockWallpaperVisibility_onLockScreen() throws Exception {
1348         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
1349         assumeTrue("Skipping assert_SystemWallpaperHidden_LockWallpaperShow_OnLockscreen:"
1350                         + " FEATURE_SECURE_LOCK_SCREEN missing.",
1351                 mContext.getPackageManager().hasSystemFeature(FEATURE_SECURE_LOCK_SCREEN));
1352         assumeTrue("Skipping testSystemAndLockWallpaperVisibility_onLockScreen:"
1353                         + " FEATURE_LIVE_WALLPAPER missing.",
1354                 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER));
1355         WallpaperWindowsTestUtils.runWithKeyguardEnabled(sWindowManagerStateHelper, () -> {
1356             runWithShellPermissionIdentity(() -> {
1357                 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper =
1358                         new WallpaperWindowsTestUtils.WallpaperWindowsHelper(
1359                                 sWindowManagerStateHelper);
1360 
1361                 // Two independent wallpapers
1362                 WallpaperManagerTestUtils.goToState(mWallpaperManager,
1363                         TWO_DIFFERENT_LIVE_WALLPAPERS);
1364                 wallpaperWindowsHelper.showLockScreenAndUpdate();
1365                 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM,
1366                         false /* shouldBeShown */,
1367                         "System wallpaper is showing on lock screen");
1368                 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_LOCK, true /* shouldBeShown */,
1369                         "Lock wallpaper is hidden on lock screen");
1370 
1371                 // Shared wallpaper
1372                 WallpaperManagerTestUtils.goToState(mWallpaperManager, TWO_SAME_LIVE_WALLPAPERS);
1373                 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM | FLAG_LOCK,
1374                         true /* shouldBeShown */, "Shared wallpaper is hidden on lock screen");
1375             });
1376         });
1377     }
1378 
1379     @Test
1380     @Ignore("b/281082882")
setDimAmount_lockScreenUnset_singleEngine_notifiesColorsChangedHomeOnly()1381     public void setDimAmount_lockScreenUnset_singleEngine_notifiesColorsChangedHomeOnly() {
1382         assumeFalse(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
1383         ensureCleanState();
1384 
1385         final CountDownLatch latch = new CountDownLatch(1);
1386         WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> latch.countDown();
1387         final LinkedList<Integer> receivedFlags = new LinkedList<>();
1388         WallpaperManager.OnColorsChangedListener listener = (colors, whichWp) -> receivedFlags.add(
1389                 whichWp);
1390         mWallpaperManager.addOnColorsChangedListener(listener, mHandler);
1391         mWallpaperManager.addOnColorsChangedListener(counter, mHandler);
1392         final float initialDim = runWithShellPermissionIdentity(
1393                 mWallpaperManager::getWallpaperDimAmount);
1394         final float newDim = initialDim > 0 ? 0.5f * initialDim : 0.5f;
1395 
1396         try {
1397             runWithShellPermissionIdentity(() -> {
1398                 mWallpaperManager.setWallpaperDimAmount(newDim);
1399             });
1400             boolean latchSuccess = latch.await(DIM_LISTENER_TIMEOUT_SECS, TimeUnit.SECONDS);
1401             assertWithMessage("Registered listener not invoked").that(latchSuccess).isTrue();
1402         } catch (InterruptedException e) {
1403             throw new RuntimeException(e);
1404         } finally {
1405             runWithShellPermissionIdentity(() ->
1406                     mWallpaperManager.setWallpaperDimAmount(initialDim));
1407         }
1408 
1409         assertThat(receivedFlags).containsExactly(FLAG_SYSTEM);
1410         mWallpaperManager.removeOnColorsChangedListener(listener);
1411         mWallpaperManager.removeOnColorsChangedListener(counter);
1412     }
1413 
1414     @Test
1415     @Ignore("b/281082882")
setDimAmount_lockScreenUnset_multiEngine_notifiesColorsChangedBothTogether()1416     public void setDimAmount_lockScreenUnset_multiEngine_notifiesColorsChangedBothTogether() {
1417         assumeTrue(mWallpaperManager.isLockscreenLiveWallpaperEnabled());
1418         ensureCleanState();
1419 
1420         final CountDownLatch latch = new CountDownLatch(1);
1421         WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> latch.countDown();
1422         final LinkedList<Integer> receivedFlags = new LinkedList<>();
1423         WallpaperManager.OnColorsChangedListener listener = (colors, whichWp) -> receivedFlags.add(
1424                 whichWp);
1425         mWallpaperManager.addOnColorsChangedListener(listener, mHandler);
1426         mWallpaperManager.addOnColorsChangedListener(counter, mHandler);
1427         final float initialDim = runWithShellPermissionIdentity(
1428                 mWallpaperManager::getWallpaperDimAmount);
1429         final float newDim = initialDim > 0 ? 0.5f * initialDim : 0.5f;
1430 
1431         try {
1432             runWithShellPermissionIdentity(() -> {
1433                 mWallpaperManager.setWallpaperDimAmount(newDim);
1434             });
1435             boolean latchSuccess = latch.await(DIM_LISTENER_TIMEOUT_SECS, TimeUnit.SECONDS);
1436             assertWithMessage("Registered listener not invoked").that(latchSuccess).isTrue();
1437         } catch (InterruptedException e) {
1438             throw new RuntimeException(e);
1439         } finally {
1440             runWithShellPermissionIdentity(() ->
1441                     mWallpaperManager.setWallpaperDimAmount(initialDim));
1442         }
1443 
1444         assertThat(receivedFlags).containsExactly(FLAG_SYSTEM | FLAG_LOCK);
1445         mWallpaperManager.removeOnColorsChangedListener(listener);
1446         mWallpaperManager.removeOnColorsChangedListener(counter);
1447     }
1448 
1449     @Test
1450     @Ignore("b/281082882")
setDimAmount_lockScreenSet_notifiesColorsChangedBothSeparately()1451     public void setDimAmount_lockScreenSet_notifiesColorsChangedBothSeparately() {
1452         ensureCleanState(FLAG_LOCK);
1453         ensureCleanState(FLAG_SYSTEM);
1454 
1455         final CountDownLatch latch = new CountDownLatch(2);
1456         WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> latch.countDown();
1457         final LinkedList<Integer> receivedFlags = new LinkedList<>();
1458         WallpaperManager.OnColorsChangedListener listener = (colors, whichWp) -> receivedFlags.add(
1459                 whichWp);
1460         mWallpaperManager.addOnColorsChangedListener(listener, mHandler);
1461         final float initialDim = runWithShellPermissionIdentity(
1462                 mWallpaperManager::getWallpaperDimAmount);
1463         final float newDim = initialDim > 0 ? 0.5f * initialDim : 0.5f;
1464 
1465         mWallpaperManager.addOnColorsChangedListener(counter, mHandler);
1466         try {
1467             runWithShellPermissionIdentity(() -> {
1468                 mWallpaperManager.setWallpaperDimAmount(newDim);
1469             });
1470             boolean latchSuccess = latch.await(DIM_LISTENER_TIMEOUT_SECS, TimeUnit.SECONDS);
1471             assertWithMessage("Registered listener not invoked").that(latchSuccess).isTrue();
1472         } catch (InterruptedException e) {
1473             throw new RuntimeException(e);
1474         } finally {
1475             runWithShellPermissionIdentity(() ->
1476                     mWallpaperManager.setWallpaperDimAmount(initialDim));
1477         }
1478 
1479         assertThat(receivedFlags).containsExactly(FLAG_SYSTEM, FLAG_LOCK);
1480         mWallpaperManager.removeOnColorsChangedListener(listener);
1481         mWallpaperManager.removeOnColorsChangedListener(counter);
1482     }
1483 
assertWallpapersMatching(WallpaperWindowsTestUtils.WallpaperWindowsHelper windows, List<String> expectedWallpaperPackageNames)1484     private void assertWallpapersMatching(WallpaperWindowsTestUtils.WallpaperWindowsHelper windows,
1485             List<String> expectedWallpaperPackageNames) {
1486 
1487         boolean match = windows.waitForMatchingPackages(expectedWallpaperPackageNames);
1488         assertWithMessage("Lists do not match. Expected: "
1489                 + expectedWallpaperPackageNames + " but received " + windows.dumpPackages())
1490                 .that(match).isTrue();
1491     }
1492 
1493     /** Check if wallpaper corresponding to wallpaperFlag has visibility matching shouldBeShown */
assertWallpaperIsShown( WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper, int wallpaperFlag, boolean shouldBeShown, String errorMsg)1494     private void assertWallpaperIsShown(
1495             WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper,
1496             int wallpaperFlag,
1497             boolean shouldBeShown,
1498             String errorMsg) {
1499         String wpServiceName = mWallpaperManager.getWallpaperInfo(
1500                 (wallpaperFlag & FLAG_SYSTEM) != 0 ? FLAG_SYSTEM : FLAG_LOCK).getServiceName();
1501 
1502         boolean matchingVisibility = wallpaperWindowsHelper
1503                 .waitForMatchingWindowVisibility(wpServiceName, shouldBeShown);
1504         assertWithMessage(errorMsg + "\n" + wallpaperWindowsHelper.dumpWindows())
1505                 .that(matchingVisibility).isTrue();
1506     }
1507 
assertBitmapDimensions(Bitmap bitmap)1508     private void assertBitmapDimensions(Bitmap bitmap) {
1509         int maxSize = getMaxTextureSize();
1510         boolean safe = false;
1511         if (bitmap != null) {
1512             safe = bitmap.getWidth() <= maxSize && bitmap.getHeight() <= maxSize;
1513         }
1514         assertThat(safe).isTrue();
1515     }
1516 
assertDesiredDimension(Point suggestedSize, Point expectedSize)1517     private void assertDesiredDimension(Point suggestedSize, Point expectedSize) {
1518         mWallpaperManager.suggestDesiredDimensions(suggestedSize.x, suggestedSize.y);
1519         Point actualSize = new Point(mWallpaperManager.getDesiredMinimumWidth(),
1520                 mWallpaperManager.getDesiredMinimumHeight());
1521         if (actualSize.x > 0 || actualSize.y > 0) {
1522             if ((actualSize.x != expectedSize.x || actualSize.y != expectedSize.y)) {
1523                 throw new AssertionError(
1524                         "Expected x: " + expectedSize.x + " y: " + expectedSize.y
1525                                 + ", got x: " + actualSize.x + " y: " + actualSize.y);
1526             }
1527         }
1528     }
1529 
getScreenSize()1530     private Point getScreenSize() {
1531         WindowManager wm = mContext.getSystemService(WindowManager.class);
1532         Display d = wm.getDefaultDisplay();
1533         Point p = new Point();
1534         d.getRealSize(p);
1535         return p;
1536     }
1537 
1538     /**
1539      * Helper to set a listener and verify if it was called with the same flags.
1540      * Executes operation synchronously. Params are FLAG_LOCK, FLAG_SYSTEM or a combination of both.
1541      *
1542      * @param which wallpaper destinations to set
1543      * @param whichExpected wallpaper destinations that should receive listener calls
1544      */
verifyColorListenerInvoked(int which, int whichExpected)1545     private void verifyColorListenerInvoked(int which, int whichExpected) {
1546         ensureCleanState();
1547         int expected = 0;
1548         if ((whichExpected & FLAG_LOCK) != 0) expected++;
1549         if ((whichExpected & FLAG_SYSTEM) != 0) expected++;
1550         ArrayList<Integer> received = new ArrayList<>();
1551 
1552         final CountDownLatch latch = new CountDownLatch(expected);
1553         Handler handler = new Handler(Looper.getMainLooper());
1554 
1555         WallpaperManager.OnColorsChangedListener listener = getTestableListener();
1556         final AtomicBoolean allOk = new AtomicBoolean(true);
1557         WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> {
1558             handler.post(() -> {
1559                 final boolean wantSystem = (whichExpected & FLAG_SYSTEM) != 0;
1560                 final boolean wantLock = (whichExpected & FLAG_LOCK) != 0;
1561                 final boolean gotSystem = (whichWp & FLAG_SYSTEM) != 0;
1562                 final boolean gotLock = (whichWp & FLAG_LOCK) != 0;
1563                 received.add(whichWp);
1564                 boolean ok = true;
1565 
1566                 if (gotLock) {
1567                     if (wantLock) {
1568                         latch.countDown();
1569                     } else {
1570                         ok = false;
1571                     }
1572                 }
1573                 if (gotSystem) {
1574                     if (wantSystem) {
1575                         latch.countDown();
1576                     } else {
1577                         ok = false;
1578                     }
1579                 }
1580                 if (!ok) {
1581                     allOk.set(false);
1582                     Log.e(TAG,
1583                             "Unexpected which flag: " + whichWp + " should be: " + whichExpected);
1584                 }
1585             });
1586         };
1587 
1588         mWallpaperManager.addOnColorsChangedListener(listener, mHandler);
1589         mWallpaperManager.addOnColorsChangedListener(counter, mHandler);
1590 
1591         try {
1592             mWallpaperManager.setResource(R.drawable.icon_red, which);
1593             boolean eventsReceived = latch.await(5, TimeUnit.SECONDS);
1594             assertWithMessage("Timed out waiting for color events. Expected: "
1595                     + whichExpected + " received: " + received)
1596                     .that(eventsReceived).isTrue();
1597             // Wait in case there are additional unwanted callbacks
1598             Thread.sleep(SLEEP_MS);
1599             assertWithMessage("Unexpected which flag, check logs for details")
1600                     .that(allOk.get()).isTrue();
1601         } catch (InterruptedException | IOException e) {
1602             throw new RuntimeException(e);
1603         } finally {
1604             mWallpaperManager.removeOnColorsChangedListener(listener);
1605             mWallpaperManager.removeOnColorsChangedListener(counter);
1606         }
1607     }
1608 
1609     /**
1610      * Helper to clear a wallpaper synchronously.
1611      *
1612      * @param which FLAG_LOCK, FLAG_SYSTEM or a combination of both.
1613      */
verifyColorListenerInvokedClearing(int which)1614     private void verifyColorListenerInvokedClearing(int which) {
1615         ensureCleanState();
1616 
1617         final CountDownLatch latch = new CountDownLatch(1);
1618 
1619         WallpaperManager.OnColorsChangedListener listener = getTestableListener();
1620         WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> {
1621             latch.countDown();
1622         };
1623 
1624         mWallpaperManager.addOnColorsChangedListener(listener, mHandler);
1625         mWallpaperManager.addOnColorsChangedListener(counter, mHandler);
1626 
1627         try {
1628             mWallpaperManager.clear(which);
1629             latch.await(5, TimeUnit.SECONDS);
1630         } catch (InterruptedException | IOException e) {
1631             throw new RuntimeException(e);
1632         }
1633 
1634         verify(listener, atLeast(1))
1635                 .onColorsChanged(nullable(WallpaperColors.class), anyInt());
1636 
1637         mWallpaperManager.removeOnColorsChangedListener(listener);
1638         mWallpaperManager.removeOnColorsChangedListener(counter);
1639     }
1640 
ensureCleanState()1641     private void ensureCleanState() {
1642         ensureCleanState(FLAG_SYSTEM | FLAG_LOCK);
1643     }
1644 
1645     /**
1646      * Helper method to make sure that a) wallpaper is set for the destination(s) specified by
1647      * `flags`, and b) wallpaper callbacks related to setting the wallpaper have completed. This is
1648      * necessary before testing further callback interactions. Previously this was also necessary to
1649      * avoid race conditions between tests; not sure if that's still true as of April 2023.
1650      */
ensureCleanState(int flags)1651     private void ensureCleanState(int flags) {
1652         Bitmap bmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
1653         // We expect 3 events to happen when we change a wallpaper:
1654         // • Wallpaper changed
1655         // • System colors are known
1656         // • Lock colors are known
1657         int expectedEvents = 1;
1658         if ((flags & FLAG_SYSTEM) != 0) expectedEvents++;
1659         if ((flags & FLAG_LOCK) != 0) expectedEvents++;
1660         mCountDownLatch = new CountDownLatch(expectedEvents);
1661         if (DEBUG) {
1662             Log.d(TAG, "Started latch expecting: " + mCountDownLatch.getCount());
1663         }
1664 
1665         WallpaperManager.OnColorsChangedListener callback = (colors, which) -> {
1666             if ((which & FLAG_LOCK) != 0) {
1667                 mCountDownLatch.countDown();
1668             }
1669             if ((which & FLAG_SYSTEM) != 0) {
1670                 mCountDownLatch.countDown();
1671             }
1672             if (DEBUG) {
1673                 Log.d(TAG, "color state count down: " + which + " - " + colors);
1674             }
1675         };
1676         mWallpaperManager.addOnColorsChangedListener(callback, mHandler);
1677 
1678         try {
1679             if (flags == (FLAG_SYSTEM | FLAG_LOCK)) {
1680                 mWallpaperManager.setBitmap(bmp);
1681             } else {
1682                 mWallpaperManager.setBitmap(bmp, /* visibleCropHint= */
1683                         null, /* allowBackup= */true, flags);
1684             }
1685 
1686             // Wait for up to 10 sec since this is an async call.
1687             // Will pass as soon as the expected callbacks are executed.
1688             assertWithMessage("Timed out waiting for events").that(
1689                     mCountDownLatch.await(10, TimeUnit.SECONDS)).isTrue();
1690             assertThat(mCountDownLatch.getCount()).isEqualTo(0);
1691         } catch (InterruptedException | IOException e) {
1692             throw new RuntimeException("Can't ensure a clean state.");
1693         } finally {
1694             mWallpaperManager.removeOnColorsChangedListener(callback);
1695             bmp.recycle();
1696         }
1697     }
1698 
setWallpaperComponentAndWait(ComponentName component, int which)1699     private void setWallpaperComponentAndWait(ComponentName component, int which) {
1700         mWallpaperManager.setWallpaperComponentWithFlags(component, which);
1701         try {
1702             // Allow time for callbacks since setting component is async
1703             Thread.sleep(SLEEP_MS);
1704         } catch (InterruptedException e) {
1705             Log.e(TAG, "Live wallpaper wait interrupted", e);
1706         }
1707     }
getTestableListener()1708     public WallpaperManager.OnColorsChangedListener getTestableListener() {
1709         // Unfortunately mockito cannot mock anonymous classes or lambdas.
1710         return spy(new TestableColorListener());
1711     }
1712 
1713     public static class TestableColorListener implements WallpaperManager.OnColorsChangedListener {
1714         @Override
onColorsChanged(WallpaperColors colors, int which)1715         public void onColorsChanged(WallpaperColors colors, int which) {
1716         }
1717     }
1718 }
1719