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