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.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; 22 import static android.app.Flags.liveWallpaperContentHandling; 23 import static android.app.WallpaperManager.FLAG_LOCK; 24 import static android.app.WallpaperManager.FLAG_SYSTEM; 25 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.WallpaperChange; 26 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.WallpaperState; 27 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.runAndAwaitChanges; 28 import static android.app.cts.wallpapers.WallpaperManagerTestUtils.runAndAwaitColorChanges; 29 import static android.app.cts.wallpapers.util.WallpaperTestUtils.isSimilar; 30 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE; 31 import static android.content.pm.PackageManager.FEATURE_LIVE_WALLPAPER; 32 import static android.content.pm.PackageManager.FEATURE_SECURE_LOCK_SCREEN; 33 import static android.content.pm.PackageManager.FEATURE_WATCH; 34 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 35 import static android.opengl.cts.Egl14Utils.getMaxTextureSize; 36 37 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 38 import static com.android.window.flags.Flags.FLAG_MULTI_CROP; 39 40 import static com.google.common.truth.Truth.assertThat; 41 import static com.google.common.truth.Truth.assertWithMessage; 42 43 import static org.junit.Assert.assertThrows; 44 import static org.junit.Assert.assertTrue; 45 import static org.junit.Assume.assumeFalse; 46 import static org.junit.Assume.assumeTrue; 47 import static org.mockito.ArgumentMatchers.any; 48 import static org.mockito.ArgumentMatchers.anyInt; 49 import static org.mockito.ArgumentMatchers.nullable; 50 import static org.mockito.Mockito.atLeast; 51 import static org.mockito.Mockito.never; 52 import static org.mockito.Mockito.spy; 53 import static org.mockito.Mockito.verify; 54 55 import android.app.Activity; 56 import android.app.Instrumentation; 57 import android.app.WallpaperColors; 58 import android.app.WallpaperInfo; 59 import android.app.WallpaperManager; 60 import android.app.wallpaper.WallpaperDescription; 61 import android.app.wallpaper.WallpaperInstance; 62 import android.content.BroadcastReceiver; 63 import android.content.ComponentName; 64 import android.content.Context; 65 import android.content.Intent; 66 import android.content.IntentFilter; 67 import android.graphics.Bitmap; 68 import android.graphics.Canvas; 69 import android.graphics.Color; 70 import android.graphics.ColorSpace; 71 import android.graphics.Paint; 72 import android.graphics.Point; 73 import android.graphics.Rect; 74 import android.graphics.drawable.Drawable; 75 import android.hardware.display.DisplayManager; 76 import android.os.Handler; 77 import android.os.HandlerThread; 78 import android.os.IBinder; 79 import android.os.Looper; 80 import android.platform.test.annotations.RequiresFlagsDisabled; 81 import android.platform.test.annotations.RequiresFlagsEnabled; 82 import android.platform.test.flag.junit.CheckFlagsRule; 83 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 84 import android.server.wm.LockScreenSession; 85 import android.server.wm.WindowManagerState; 86 import android.server.wm.WindowManagerStateHelper; 87 import android.util.Log; 88 import android.util.SparseArray; 89 import android.view.Display; 90 import android.view.Window; 91 import android.view.WindowManager; 92 93 import androidx.test.InstrumentationRegistry; 94 import androidx.test.rule.ActivityTestRule; 95 96 import com.android.compatibility.common.util.CtsTouchUtils; 97 import com.android.window.flags.Flags; 98 99 import com.google.testing.junit.testparameterinjector.TestParameter; 100 import com.google.testing.junit.testparameterinjector.TestParameterInjector; 101 102 import org.junit.After; 103 import org.junit.AfterClass; 104 import org.junit.Before; 105 import org.junit.Ignore; 106 import org.junit.Rule; 107 import org.junit.Test; 108 import org.junit.runner.RunWith; 109 import org.mockito.MockitoAnnotations; 110 111 import java.io.ByteArrayInputStream; 112 import java.io.ByteArrayOutputStream; 113 import java.io.IOException; 114 import java.util.ArrayList; 115 import java.util.LinkedList; 116 import java.util.List; 117 import java.util.Map; 118 import java.util.concurrent.CountDownLatch; 119 import java.util.concurrent.TimeUnit; 120 import java.util.concurrent.atomic.AtomicBoolean; 121 import java.util.function.Consumer; 122 123 /** 124 * Tests for {@link WallpaperManager} and related classes. 125 * <p> 126 * Note: the wallpapers {@link TestLiveWallpaper}, {@link TestLiveWallpaperNoUnfoldTransition}, 127 * {@link TestLiveWallpaperSupportingAmbientMode} draw the screen in 128 * cyan, magenta, yellow, respectively. 129 * </p> 130 */ 131 @RunWith(TestParameterInjector.class) 132 public class WallpaperManagerTest { 133 134 private static final boolean DEBUG = false; 135 private static final String TAG = "WallpaperManagerTest"; 136 137 private static final ComponentName TEST_COMPONENT_NAME = new ComponentName( 138 TestLiveWallpaper.class.getPackageName(), TestLiveWallpaper.class.getName()); 139 // Default wait time for async operations 140 private static final int SLEEP_MS = 500; 141 private static final int DIM_LISTENER_TIMEOUT_SECS = 30; 142 143 private WallpaperManager mWallpaperManager; 144 private static WallpaperManager sWallpaperManager = null; 145 private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();; 146 private Context mContext; 147 private CtsTouchUtils mCtsTouchUtils; 148 private Handler mHandler; 149 private BroadcastReceiver mBroadcastReceiver; 150 private CountDownLatch mCountDownLatch; 151 private boolean mEnableWcg; 152 153 // WallpaperInfo object for the built-in default wallpaper of the device. 154 // Always null if the device uses ImageWallpaper by default. 155 private WallpaperInfo mDefaultWallpaperInfo; 156 157 private static final WindowManagerStateHelper sWindowManagerStateHelper = 158 new WindowManagerStateHelper(); 159 160 @Rule 161 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 162 163 @Rule 164 public ActivityTestRule<WallpaperTestActivity> mActivityTestRule = new ActivityTestRule<>( 165 WallpaperTestActivity.class, 166 false /* initialTouchMode */, 167 false /* launchActivity */); 168 169 @Rule 170 public ActivityTestRule<WallpaperOverlayTestActivity> mOverlayActivityTestRule = 171 new ActivityTestRule<>( 172 WallpaperOverlayTestActivity.class, 173 false /* initialTouchMode */, 174 false /* launchActivity */); 175 176 @Before setUp()177 public void setUp() throws Exception { 178 // grant READ_WALLPAPER_INTERNAL for all tests 179 mInstrumentation.getUiAutomation() 180 .adoptShellPermissionIdentity(READ_WALLPAPER_INTERNAL); 181 182 mContext = InstrumentationRegistry.getTargetContext(); 183 WallpaperWindowsTestUtils.setContext(mContext); 184 mCtsTouchUtils = new CtsTouchUtils(mContext); 185 mWallpaperManager = WallpaperManager.getInstance(mContext); 186 sWallpaperManager = mWallpaperManager; 187 assumeTrue("Device does not support wallpapers", mWallpaperManager.isWallpaperSupported()); 188 189 // TODO(b/328312997): revisit this test once we have a strategy for live wallpaper on AAOS. 190 assumeFalse("AAOS doesn't support FEATURE_LIVE_WALLPAPER", 191 mContext.getPackageManager().hasSystemFeature(FEATURE_AUTOMOTIVE)); 192 193 MockitoAnnotations.initMocks(this); 194 final HandlerThread handlerThread = new HandlerThread("TestCallbacks"); 195 handlerThread.start(); 196 mHandler = new Handler(handlerThread.getLooper()); 197 mCountDownLatch = new CountDownLatch(1); 198 mBroadcastReceiver = new BroadcastReceiver() { 199 @Override 200 public void onReceive(Context context, Intent intent) { 201 mCountDownLatch.countDown(); 202 if (DEBUG) { 203 Log.d(TAG, "broadcast state count down: " + mCountDownLatch.getCount()); 204 } 205 } 206 }; 207 mContext.registerReceiver(mBroadcastReceiver, 208 new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED)); 209 mEnableWcg = mWallpaperManager.shouldEnableWideColorGamut(); 210 runAndAwaitColorChanges(5, TimeUnit.SECONDS, FLAG_SYSTEM | FLAG_LOCK, 211 mWallpaperManager, mHandler, mWallpaperManager::clear); 212 if (mDefaultWallpaperInfo == null) { 213 mDefaultWallpaperInfo = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM); 214 } 215 216 assertWithMessage("Home screen wallpaper must be set after setUp()").that( 217 mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isAtLeast(0); 218 assertWithMessage("Lock screen wallpaper must be unset after setUp()").that( 219 mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 220 221 TestWallpaperService.Companion.resetCounts(); 222 } 223 224 @After tearDown()225 public void tearDown() { 226 // drop READ_WALLPAPER_INTERNAL 227 mInstrumentation.getUiAutomation().dropShellPermissionIdentity(); 228 229 if (mBroadcastReceiver != null) { 230 mContext.unregisterReceiver(mBroadcastReceiver); 231 } 232 TestWallpaperService.Companion.checkAssertions(); 233 TestWallpaperService.Companion.resetCounts(); 234 } 235 236 /** 237 * Reset all wallpapers to default after the test suite has been executed. 238 */ 239 @AfterClass tearDownClass()240 public static void tearDownClass() throws IOException { 241 if (sWallpaperManager != null) { 242 sWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK); 243 } 244 sWallpaperManager = null; 245 } 246 247 @Test setBitmap_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome()248 public void setBitmap_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome() 249 throws IOException { 250 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 251 Canvas canvas = new Canvas(tmpWallpaper); 252 canvas.drawColor(Color.RED); 253 254 try { 255 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 256 mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */ 257 null, /* allowBackup= */true, FLAG_SYSTEM); 258 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 259 origHomeWallpaperId); 260 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId); 261 } finally { 262 tmpWallpaper.recycle(); 263 } 264 } 265 266 @Test setBitmap_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome()267 public void setBitmap_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome() 268 throws IOException { 269 runWithShellPermissionIdentity(() -> { 270 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK); 271 }); 272 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 273 Canvas canvas = new Canvas(tmpWallpaper); 274 canvas.drawColor(Color.RED); 275 276 try { 277 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 278 mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */ 279 null, /* allowBackup= */true, FLAG_SYSTEM); 280 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 281 origHomeWallpaperId); 282 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId); 283 } finally { 284 tmpWallpaper.recycle(); 285 } 286 } 287 288 @Test setBitmap_lockScreen_lockScreenUnset_changesLockOnly()289 public void setBitmap_lockScreen_lockScreenUnset_changesLockOnly() throws IOException { 290 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 291 Canvas canvas = new Canvas(tmpWallpaper); 292 canvas.drawColor(Color.RED); 293 294 try { 295 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 296 mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */ 297 null, /* allowBackup= */true, FLAG_LOCK); 298 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo( 299 origHomeWallpaperId); 300 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isAtLeast(0); 301 } finally { 302 tmpWallpaper.recycle(); 303 } 304 } 305 306 @Test setBitmap_lockScreen_lockScreenSet_changesLockOnly()307 public void setBitmap_lockScreen_lockScreenSet_changesLockOnly() throws IOException { 308 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 309 Canvas canvas = new Canvas(tmpWallpaper); 310 canvas.drawColor(Color.GREEN); 311 312 try { 313 mWallpaperManager.setBitmap(tmpWallpaper, null, true, FLAG_LOCK); 314 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 315 int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK); 316 canvas.drawColor(Color.RED); 317 mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */ 318 null, /* allowBackup= */true, FLAG_LOCK); 319 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo( 320 origHomeWallpaperId); 321 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isNotEqualTo( 322 origLockWallpaperId); 323 } finally { 324 tmpWallpaper.recycle(); 325 } 326 } 327 328 @Test setBitmap_both_lockScreenUnset_changesHome()329 public void setBitmap_both_lockScreenUnset_changesHome() 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, /* visibleCropHint= */ 337 null, /* allowBackup= */true, FLAG_SYSTEM | FLAG_LOCK); 338 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 339 origHomeWallpaperId); 340 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 341 } finally { 342 tmpWallpaper.recycle(); 343 } 344 } 345 346 @Test setBitmap_both_lockScreenSet_changesHomeAndClearsLock()347 public void setBitmap_both_lockScreenSet_changesHomeAndClearsLock() throws IOException { 348 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 349 Canvas canvas = new Canvas(tmpWallpaper); 350 canvas.drawColor(Color.GREEN); 351 352 try { 353 mWallpaperManager.setBitmap(tmpWallpaper, null, true, FLAG_LOCK); 354 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 355 int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK); 356 canvas.drawColor(Color.RED); 357 mWallpaperManager.setBitmap(tmpWallpaper, /* visibleCropHint= */ 358 null, /* allowBackup= */true, FLAG_SYSTEM | FLAG_LOCK); 359 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 360 origHomeWallpaperId); 361 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 362 } finally { 363 tmpWallpaper.recycle(); 364 } 365 } 366 367 @Test setBitmap_default_lockScreenUnset_sameAsBoth()368 public void setBitmap_default_lockScreenUnset_sameAsBoth() throws IOException { 369 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 370 Canvas canvas = new Canvas(tmpWallpaper); 371 canvas.drawColor(Color.RED); 372 373 try { 374 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 375 mWallpaperManager.setBitmap(tmpWallpaper); 376 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 377 origHomeWallpaperId); 378 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 379 } finally { 380 tmpWallpaper.recycle(); 381 } 382 } 383 384 @Test setResource_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome()385 public void setResource_homeScreen_homeStatic_lockScreenUnset_setsLockToHomeAndUpdatesHome() 386 throws IOException { 387 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 388 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 389 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 390 origHomeWallpaperId); 391 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId); 392 } 393 394 @Test setResource_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome()395 public void setResource_homeScreen_homeLive_lockScreenUnset_setsLockToHomeAndUpdatesHome() 396 throws IOException { 397 runWithShellPermissionIdentity(() -> { 398 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK); 399 }); 400 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 401 402 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 403 404 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 405 origHomeWallpaperId); 406 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId); 407 } 408 409 @Test setResource_homeScreen_lockScreenSet_changesHomeOnly()410 public void setResource_homeScreen_lockScreenSet_changesHomeOnly() throws IOException { 411 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 412 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 413 int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK); 414 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_SYSTEM); 415 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 416 origHomeWallpaperId); 417 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origLockWallpaperId); 418 } 419 420 @Test setResource_lockScreen_lockScreenUnset_changesLockOnly()421 public void setResource_lockScreen_lockScreenUnset_changesLockOnly() throws IOException { 422 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 423 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 424 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo( 425 origHomeWallpaperId); 426 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isAtLeast(0); 427 } 428 429 @Test setResource_lockScreen_lockScreenSet_changesLockOnly()430 public void setResource_lockScreen_lockScreenSet_changesLockOnly() throws IOException { 431 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 432 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 433 int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK); 434 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_LOCK); 435 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo( 436 origHomeWallpaperId); 437 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isNotEqualTo( 438 origLockWallpaperId); 439 } 440 441 @Test setResource_both_lockScreenUnset_changesHome()442 public void setResource_both_lockScreenUnset_changesHome() throws IOException { 443 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 444 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM | FLAG_LOCK); 445 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 446 origHomeWallpaperId); 447 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 448 } 449 450 @Test setResource_both_lockScreenSet_changesHomeAndClearsLock()451 public void setResource_both_lockScreenSet_changesHomeAndClearsLock() throws IOException { 452 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 453 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 454 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_SYSTEM | FLAG_LOCK); 455 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 456 origHomeWallpaperId); 457 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 458 } 459 460 // This is just to be sure that setResource call the overload with `which`. 461 @Test setResource_default_lockScreenUnset_sameAsBoth()462 public void setResource_default_lockScreenUnset_sameAsBoth() throws IOException { 463 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 464 mWallpaperManager.setResource(R.drawable.icon_red); 465 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo( 466 origHomeWallpaperId); 467 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 468 } 469 470 @Test setWallpaperComponent_homeScreen_homeStatic_lockScreenUnset_migratesThenSetsHome()471 public void setWallpaperComponent_homeScreen_homeStatic_lockScreenUnset_migratesThenSetsHome() { 472 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 473 runWithShellPermissionIdentity(() -> { 474 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM); 475 }); 476 477 assertWithMessage("System wallpaper must change").that( 478 mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId); 479 assertWithMessage("Lock wallpaper mush not change").that( 480 mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId); 481 } 482 483 @Test setWallpaperComponent_homeScreen_homeLive_lockScreenUnset_migratesThenSetsHome()484 public void setWallpaperComponent_homeScreen_homeLive_lockScreenUnset_migratesThenSetsHome() { 485 runWithShellPermissionIdentity(() -> { 486 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK); 487 }); 488 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 489 490 runWithShellPermissionIdentity(() -> { 491 ComponentName newComponentName = new ComponentName( 492 TestLiveWallpaperNoUnfoldTransition.class.getPackageName(), 493 TestLiveWallpaperNoUnfoldTransition.class.getName()); 494 setWallpaperComponentAndWait(newComponentName, FLAG_SYSTEM); 495 }); 496 497 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId); 498 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origHomeWallpaperId); 499 } 500 501 @Test setWallpaperComponent_homeScreen_lockScreenSet_changesHomeOnly()502 public void setWallpaperComponent_homeScreen_lockScreenSet_changesHomeOnly() 503 throws IOException { 504 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 505 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 506 int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK); 507 runWithShellPermissionIdentity(() -> { 508 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM); 509 }); 510 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId); 511 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isEqualTo(origLockWallpaperId); 512 } 513 514 @Test setWallpaperComponent_lockScreen_lockScreenUnset_changesLockOnly()515 public void setWallpaperComponent_lockScreen_lockScreenUnset_changesLockOnly() { 516 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 517 runWithShellPermissionIdentity(() -> { 518 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_LOCK); 519 }); 520 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(origHomeWallpaperId); 521 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isAtLeast(0); 522 } 523 524 @Test setWallpaperComponent_lockScreen_lockScreenSet_changeLockOnly()525 public void setWallpaperComponent_lockScreen_lockScreenSet_changeLockOnly() 526 throws IOException { 527 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 528 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 529 int origLockWallpaperId = mWallpaperManager.getWallpaperId(FLAG_LOCK); 530 runWithShellPermissionIdentity(() -> { 531 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_LOCK); 532 }); 533 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isEqualTo(origHomeWallpaperId); 534 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isNotEqualTo(origLockWallpaperId); 535 } 536 537 @Test setWallpaperComponent_both_lockScreenUnset_setsHomeToBoth()538 public void setWallpaperComponent_both_lockScreenUnset_setsHomeToBoth() { 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_both_lockScreenSet_changesLockOnly()548 public void setWallpaperComponent_both_lockScreenSet_changesLockOnly() 549 throws IOException { 550 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 551 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 552 runWithShellPermissionIdentity(() -> { 553 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK); 554 }); 555 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId); 556 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 557 } 558 559 @Test setWallpaperComponent_default_lockScreenUnset_behavesLikeBoth()560 public void setWallpaperComponent_default_lockScreenUnset_behavesLikeBoth() { 561 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 562 runWithShellPermissionIdentity(() -> { 563 mWallpaperManager.setWallpaperComponent(TEST_COMPONENT_NAME); 564 }); 565 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId); 566 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 567 } 568 569 @Test setStaticWallpaper_doesNotSetWallpaperInfo()570 public void setStaticWallpaper_doesNotSetWallpaperInfo() throws IOException { 571 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 572 assertNullOrDefaultWallpaper(FLAG_LOCK); 573 574 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 575 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_LOCK); 576 577 assertThat(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM)).isNull(); 578 assertThat(mWallpaperManager.getWallpaperInfo(FLAG_LOCK)).isNull(); 579 } 580 581 @Test setLiveWallpaper_homeScreen_setsHomeWallpaperInfo()582 public void setLiveWallpaper_homeScreen_setsHomeWallpaperInfo() { 583 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 584 assertNullOrDefaultWallpaper(FLAG_LOCK); 585 586 runWithShellPermissionIdentity(() -> { 587 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM); 588 }); 589 590 assertNotNullOrDefaultWallpaper(FLAG_SYSTEM); 591 assertNullOrDefaultWallpaper(FLAG_LOCK); 592 } 593 594 @Test setLiveWallpaper_lockScreen_setsLockWallpaperInfo()595 public void setLiveWallpaper_lockScreen_setsLockWallpaperInfo() { 596 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 597 assertNullOrDefaultWallpaper(FLAG_LOCK); 598 599 runWithShellPermissionIdentity(() -> { 600 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_LOCK); 601 }); 602 603 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 604 assertNotNullOrDefaultWallpaper(FLAG_LOCK); 605 } 606 607 @Test getWallpaperInfo_badFlagsArgument_throwsException()608 public void getWallpaperInfo_badFlagsArgument_throwsException() { 609 assertThrows(IllegalArgumentException.class, () -> 610 mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM | FLAG_LOCK)); 611 } 612 613 @Test setStaticWallpaper_homeScreen_wallpaperInstanceCorrect()614 public void setStaticWallpaper_homeScreen_wallpaperInstanceCorrect() throws IOException { 615 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 616 617 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 618 619 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_SYSTEM)).isNotNull(); 620 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_SYSTEM).getInfo()).isNull(); 621 } 622 623 @Test setStaticWallpaper_lockScreen_wallpaperInstanceCorrect()624 public void setStaticWallpaper_lockScreen_wallpaperInstanceCorrect() throws IOException { 625 assertNullOrDefaultWallpaper(FLAG_LOCK); 626 627 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_LOCK); 628 629 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_LOCK)).isNotNull(); 630 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_LOCK).getInfo()).isNull(); 631 } 632 633 @Test setStaticWallpaper_both_wallpaperInstanceCorrect()634 public void setStaticWallpaper_both_wallpaperInstanceCorrect() throws IOException { 635 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 636 assertNullOrDefaultWallpaper(FLAG_LOCK); 637 638 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_SYSTEM | FLAG_LOCK); 639 640 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_SYSTEM)).isNotNull(); 641 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_SYSTEM).getInfo()).isNull(); 642 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_LOCK)).isNull(); 643 } 644 645 @Test setLiveWallpaper_homeScreen_wallpaperInstanceCorrect()646 public void setLiveWallpaper_homeScreen_wallpaperInstanceCorrect() { 647 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 648 649 runWithShellPermissionIdentity(() -> 650 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM)); 651 652 assertNotNullOrDefaultInstance(FLAG_SYSTEM); 653 } 654 655 @Test setLiveWallpaper_lockScreen_wallpaperInstanceCorrect()656 public void setLiveWallpaper_lockScreen_wallpaperInstanceCorrect() { 657 assertNullOrDefaultWallpaper(FLAG_LOCK); 658 659 runWithShellPermissionIdentity(() -> 660 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_LOCK)); 661 662 assertNotNullOrDefaultInstance(FLAG_LOCK); 663 } 664 665 @Test setLiveWallpaper_both_wallpaperInstanceCorrect()666 public void setLiveWallpaper_both_wallpaperInstanceCorrect() { 667 assertNullOrDefaultWallpaper(FLAG_SYSTEM); 668 assertNullOrDefaultWallpaper(FLAG_LOCK); 669 670 runWithShellPermissionIdentity(() -> 671 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK)); 672 673 assertNotNullOrDefaultInstance(FLAG_SYSTEM); 674 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_LOCK)).isNull(); 675 } 676 677 @Test getWallpaperInstance_badFlagsArgument_throwsException()678 public void getWallpaperInstance_badFlagsArgument_throwsException() { 679 assertThrows(IllegalArgumentException.class, () -> 680 mWallpaperManager.getWallpaperInstance(FLAG_SYSTEM | FLAG_LOCK)); 681 } 682 683 @Test wallpaperChangedBroadcastTest()684 public void wallpaperChangedBroadcastTest() { 685 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 686 Canvas canvas = new Canvas(tmpWallpaper); 687 canvas.drawColor(Color.BLACK); 688 689 try { 690 mWallpaperManager.setBitmap(tmpWallpaper); 691 692 // Wait for up to 5 sec since this is an async call. 693 // Should fail if Intent.ACTION_WALLPAPER_CHANGED isn't delivered. 694 assertWithMessage("Timed out waiting for Intent").that( 695 mCountDownLatch.await(5, TimeUnit.SECONDS)).isTrue(); 696 } catch (InterruptedException | IOException e) { 697 throw new AssertionError("Intent.ACTION_WALLPAPER_CHANGED not received."); 698 } finally { 699 tmpWallpaper.recycle(); 700 } 701 } 702 703 @Test wallpaperClearBroadcastTest()704 public void wallpaperClearBroadcastTest() { 705 try { 706 mWallpaperManager.clear(FLAG_LOCK | FLAG_SYSTEM); 707 708 // Wait for 5 sec since this is an async call. 709 // Should fail if Intent.ACTION_WALLPAPER_CHANGED isn't delivered. 710 assertWithMessage("Timed out waiting for Intent").that( 711 mCountDownLatch.await(5, TimeUnit.SECONDS)).isTrue(); 712 } catch (InterruptedException | IOException e) { 713 throw new AssertionError(e); 714 } 715 } 716 717 /** 718 * Test that {@link WallpaperManager#clear(int)} triggers the correct number of 719 * {@link android.service.wallpaper.WallpaperService.Engine#onDestroy()} in different scenarios. 720 */ 721 @Test testClear()722 public void testClear() throws IOException { 723 // map of: argument passed to clear(int) -> WallpaperState -> expected number of onDestroy 724 Map<Integer, Map<WallpaperState, Integer>> testMap = Map.of( 725 FLAG_LOCK, 726 Map.of(WallpaperState.LIVE_DIFF_MULTI, 1, WallpaperState.LIVE_SAME_SINGLE, 0), 727 FLAG_SYSTEM, 728 Map.of(WallpaperState.LIVE_DIFF_MULTI, 1, WallpaperState.LIVE_SAME_SINGLE, 0), 729 FLAG_SYSTEM | FLAG_LOCK, Map.of( 730 WallpaperState.LIVE_DIFF_MULTI, 2, WallpaperState.LIVE_SAME_SINGLE, 1)); 731 732 Map<WallpaperState, String> stateDescriptions = Map.of( 733 WallpaperState.LIVE_DIFF_MULTI, "two different live wallpapers", 734 WallpaperState.LIVE_SAME_SINGLE, "a shared live wallpaper"); 735 736 Map<Integer, String> flagDescriptions = Map.of( 737 FLAG_LOCK, "FLAG_LOCK", 738 FLAG_SYSTEM, "FLAG_SYSTEM", 739 FLAG_SYSTEM | FLAG_LOCK, "FLAG_SYSTEM | FLAG_LOCK"); 740 741 Map<Integer, String> destroyCountDescriptions = Map.of( 742 0, "not destroy any engine", 743 1, "destroy exactly one engine", 744 2, "destroy two engines"); 745 746 runWithShellPermissionIdentity(() -> { 747 for (Map.Entry<Integer, Map<WallpaperState, Integer>> entry : testMap.entrySet()) { 748 int which = entry.getKey(); 749 Map<WallpaperState, Integer> map = entry.getValue(); 750 for (Map.Entry<WallpaperState, Integer> e : map.entrySet()) { 751 WallpaperState initialState = e.getKey(); 752 int expectedCount = e.getValue(); 753 WallpaperManagerTestUtils.goToState(mWallpaperManager, initialState); 754 TestWallpaperService.Companion.resetCounts(); 755 runAndAwaitChanges(5, TimeUnit.SECONDS, 0, expectedCount, 0, () -> { 756 mWallpaperManager.clear(which); 757 }); 758 for (int testWhich : List.of(FLAG_SYSTEM, FLAG_LOCK)) { 759 if ((testWhich & which) > 0) { 760 assertNullOrDefaultWallpaper(testWhich); 761 } else { 762 assertNotNullOrDefaultWallpaper(testWhich); 763 } 764 } 765 String expectedBehaviourMessage = String.format("With %s, clear(%s) should %s", 766 stateDescriptions.get(initialState), 767 flagDescriptions.get(which), 768 destroyCountDescriptions.get(expectedCount)); 769 assertWithMessage(expectedBehaviourMessage) 770 .that(TestWallpaperService.Companion.getDestroyCount()) 771 .isEqualTo(expectedCount); 772 } 773 } 774 }); 775 } 776 777 @Test invokeOnColorsChangedListenerTest_systemOnly()778 public void invokeOnColorsChangedListenerTest_systemOnly() { 779 verifyColorListenerInvoked(FLAG_SYSTEM, FLAG_SYSTEM); 780 } 781 782 @Test invokeOnColorsChangedListenerTest_lockOnly()783 public void invokeOnColorsChangedListenerTest_lockOnly() { 784 verifyColorListenerInvoked(FLAG_LOCK, FLAG_LOCK); 785 } 786 787 @Test invokeOnColorsChangedListenerTest_both()788 public void invokeOnColorsChangedListenerTest_both() { 789 int both = FLAG_LOCK | FLAG_SYSTEM; 790 verifyColorListenerInvoked(both, both); 791 } 792 793 @Test invokeOnColorsChangedListenerTest_clearLock()794 public void invokeOnColorsChangedListenerTest_clearLock() throws IOException { 795 verifyColorListenerInvokedClearing(FLAG_LOCK); 796 } 797 798 @Test invokeOnColorsChangedListenerTest_clearSystem()799 public void invokeOnColorsChangedListenerTest_clearSystem() throws IOException { 800 verifyColorListenerInvokedClearing(FLAG_SYSTEM); 801 } 802 803 /** 804 * Removing a listener should not invoke it anymore 805 */ 806 @Test addRemoveOnColorsChangedListenerTest_onlyInvokeAdded()807 public void addRemoveOnColorsChangedListenerTest_onlyInvokeAdded() throws IOException { 808 ensureCleanState(); 809 810 final CountDownLatch latch = new CountDownLatch(1); 811 WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> latch.countDown(); 812 813 // Add and remove listener 814 WallpaperManager.OnColorsChangedListener listener = getTestableListener(); 815 mWallpaperManager.addOnColorsChangedListener(listener, mHandler); 816 mWallpaperManager.removeOnColorsChangedListener(listener); 817 818 // Verify that the listener is not called 819 mWallpaperManager.addOnColorsChangedListener(counter, mHandler); 820 try { 821 mWallpaperManager.setResource(R.drawable.icon_red); 822 if (!latch.await(5, TimeUnit.SECONDS)) { 823 throw new AssertionError("Registered listener not invoked"); 824 } 825 } catch (InterruptedException | IOException e) { 826 throw new RuntimeException(e); 827 } 828 verify(listener, never()).onColorsChanged(any(WallpaperColors.class), anyInt()); 829 mWallpaperManager.removeOnColorsChangedListener(counter); 830 } 831 832 /** 833 * Suggesting desired dimensions is only a hint to the system that can be ignored. 834 * 835 * Test if the desired minimum width or height the WallpaperManager returns 836 * is greater than 0. If so, then we check whether that the size is the dimension 837 * that was suggested. 838 */ 839 @Test suggestDesiredDimensionsTest()840 public void suggestDesiredDimensionsTest() { 841 final Point min = getScreenSize(); 842 int w = min.x * 3; 843 int h = min.y * 2; 844 845 // b/120847476: WallpaperManager limits at GL_MAX_TEXTURE_SIZE 846 final int max = getMaxTextureSize(); 847 if (max > 0) { 848 w = Math.min(w, max); 849 h = Math.min(h, max); 850 } 851 852 assertDesiredDimension(new Point(min.x / 2, min.y / 2), new Point(min.x / 2, min.y / 2)); 853 854 assertDesiredDimension(new Point(w, h), new Point(w, h)); 855 856 assertDesiredDimension(new Point(min.x / 2, h), new Point(min.x / 2, h)); 857 858 assertDesiredDimension(new Point(w, min.y / 2), new Point(w, min.y / 2)); 859 } 860 861 @Test 862 @Ignore("b/265007420") wallpaperColors_primary()863 public void wallpaperColors_primary() { 864 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 865 Canvas canvas = new Canvas(tmpWallpaper); 866 canvas.drawColor(Color.RED); 867 868 try { 869 mWallpaperManager.setBitmap(tmpWallpaper); 870 WallpaperColors colors = mWallpaperManager.getWallpaperColors( 871 FLAG_SYSTEM); 872 873 // Check that primary color is almost red 874 Color primary = colors.getPrimaryColor(); 875 final float delta = 0.1f; 876 assertWithMessage("red").that(primary.red()).isWithin(delta).of(1f); 877 assertWithMessage("green").that(primary.green()).isWithin(delta).of(0f); 878 assertWithMessage("blue").that(primary.blue()).isWithin(delta).of(0f); 879 880 assertThat(colors.getSecondaryColor()).isNull(); 881 assertThat(colors.getTertiaryColor()).isNull(); 882 } catch (IOException e) { 883 throw new RuntimeException(e); 884 } finally { 885 tmpWallpaper.recycle(); 886 } 887 } 888 889 @Test 890 @Ignore("b/265007420") wallpaperColors_secondary()891 public void wallpaperColors_secondary() { 892 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 893 Canvas canvas = new Canvas(tmpWallpaper); 894 canvas.drawColor(Color.RED); 895 // Make 20% of the wallpaper BLUE so that secondary color is BLUE 896 canvas.clipRect(0, 0, 100, 20); 897 canvas.drawColor(Color.BLUE); 898 899 try { 900 mWallpaperManager.setBitmap(tmpWallpaper); 901 WallpaperColors colors = mWallpaperManager.getWallpaperColors( 902 FLAG_SYSTEM); 903 904 // Check that the secondary color is almost blue 905 Color secondary = colors.getSecondaryColor(); 906 final float delta = 0.15f; 907 assertWithMessage("red").that(secondary.red()).isWithin(delta).of(0f); 908 assertWithMessage("green").that(secondary.green()).isWithin(delta).of(0f); 909 assertWithMessage("blue").that(secondary.blue()).isWithin(delta).of(1f); 910 } catch (IOException e) { 911 throw new RuntimeException(e); 912 } finally { 913 tmpWallpaper.recycle(); 914 } 915 } 916 917 @Test highRatioWallpaper_largeWidth()918 public void highRatioWallpaper_largeWidth() throws Exception { 919 Bitmap highRatioWallpaper = Bitmap.createBitmap(8000, 800, Bitmap.Config.ARGB_8888); 920 Canvas canvas = new Canvas(highRatioWallpaper); 921 canvas.drawColor(Color.RED); 922 923 try { 924 mWallpaperManager.setBitmap(highRatioWallpaper); 925 assertBitmapDimensions(mWallpaperManager.getBitmap()); 926 } finally { 927 highRatioWallpaper.recycle(); 928 } 929 } 930 931 @Test highRatioWallpaper_largeHeight()932 public void highRatioWallpaper_largeHeight() throws Exception { 933 Bitmap highRatioWallpaper = Bitmap.createBitmap(800, 8000, Bitmap.Config.ARGB_8888); 934 Canvas canvas = new Canvas(highRatioWallpaper); 935 canvas.drawColor(Color.RED); 936 937 try { 938 mWallpaperManager.setBitmap(highRatioWallpaper); 939 assertBitmapDimensions(mWallpaperManager.getBitmap()); 940 } finally { 941 highRatioWallpaper.recycle(); 942 } 943 } 944 945 @Test highResolutionWallpaper()946 public void highResolutionWallpaper() throws Exception { 947 Bitmap highResolutionWallpaper = Bitmap.createBitmap(10000, 10000, Bitmap.Config.ARGB_8888); 948 Canvas canvas = new Canvas(highResolutionWallpaper); 949 canvas.drawColor(Color.BLUE); 950 951 try { 952 mWallpaperManager.setBitmap(highResolutionWallpaper); 953 assertBitmapDimensions(mWallpaperManager.getBitmap()); 954 } finally { 955 highResolutionWallpaper.recycle(); 956 } 957 } 958 959 @Test testWideGamutWallpaper()960 public void testWideGamutWallpaper() throws IOException { 961 final ColorSpace srgb = ColorSpace.get(ColorSpace.Named.SRGB); 962 final ColorSpace p3 = ColorSpace.get(ColorSpace.Named.DISPLAY_P3); 963 final Bitmap.Config config = Bitmap.Config.ARGB_8888; 964 final Bitmap srgbBitmap = Bitmap.createBitmap(100, 100, config); 965 final Bitmap p3Bitmap = Bitmap.createBitmap(100, 100, config, false, p3); 966 967 try { 968 // sRGB is the default color space 969 mWallpaperManager.setBitmap(srgbBitmap); 970 assertThat(mWallpaperManager.getBitmap().getColorSpace()).isEqualTo(srgb); 971 972 // If wide gamut is enabled, Display-P3 should be supported. 973 mWallpaperManager.setBitmap(p3Bitmap); 974 975 final boolean isDisplayP3 = mWallpaperManager.getBitmap().getColorSpace().equals(p3); 976 // Assert false only when device enabled WCG, but display does not support Display-P3 977 assertThat(mEnableWcg && !isDisplayP3).isFalse(); 978 } finally { 979 srgbBitmap.recycle(); 980 p3Bitmap.recycle(); 981 } 982 } 983 984 @Test testWallpaperSupportsWcg()985 public void testWallpaperSupportsWcg() throws IOException { 986 final int sysWallpaper = FLAG_SYSTEM; 987 988 final Bitmap srgbBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 989 final Bitmap p3Bitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888, false, 990 ColorSpace.get(ColorSpace.Named.DISPLAY_P3)); 991 992 try { 993 mWallpaperManager.setBitmap(srgbBitmap); 994 assertThat(mWallpaperManager.wallpaperSupportsWcg(sysWallpaper)).isFalse(); 995 996 mWallpaperManager.setBitmap(p3Bitmap); 997 assertThat(mWallpaperManager.wallpaperSupportsWcg(sysWallpaper)).isEqualTo(mEnableWcg); 998 } finally { 999 srgbBitmap.recycle(); 1000 p3Bitmap.recycle(); 1001 } 1002 } 1003 1004 /** 1005 * Check that all the callback methods of the wallpaper are invoked by the same thread. 1006 * Also checks that the callback methods are called in a proper order. 1007 * See {@link TestWallpaperService} to see the checks that are performed. 1008 */ 1009 @Test wallpaperCallbackMainThreadTest()1010 public void wallpaperCallbackMainThreadTest() { 1011 1012 // use a wallpaper supporting ambient mode, to trigger Engine.onAmbientModeChanged 1013 ComponentName componentName = new ComponentName( 1014 TestLiveWallpaperSupportingAmbientMode.class.getPackageName(), 1015 TestLiveWallpaperSupportingAmbientMode.class.getName()); 1016 runWithShellPermissionIdentity(() -> 1017 mWallpaperManager.setWallpaperComponent(componentName)); 1018 1019 // trigger Engine.onDesiredDimensionsChanged 1020 mWallpaperManager.suggestDesiredDimensions(1000, 1000); 1021 1022 Activity activity = mActivityTestRule.launchActivity(null); 1023 1024 Window window = activity.getWindow(); 1025 IBinder windowToken = window.getDecorView().getWindowToken(); 1026 1027 // send some command to trigger Engine.onCommand 1028 mWallpaperManager.sendWallpaperCommand( 1029 windowToken, WallpaperManager.COMMAND_TAP, 50, 50, 0, null); 1030 1031 // trigger Engine.onZoomChanged 1032 mWallpaperManager.setWallpaperZoomOut(windowToken, 0.5f); 1033 1034 // trigger Engine.onTouchEvent 1035 mCtsTouchUtils.emulateTapOnViewCenter( 1036 InstrumentationRegistry.getInstrumentation(), null, 1037 activity.findViewById(android.R.id.content)); 1038 1039 mActivityTestRule.finishActivity(); 1040 runWithShellPermissionIdentity(() -> mWallpaperManager.clearWallpaper()); 1041 } 1042 1043 @Test peekWallpaperCaching_cachesWallpaper()1044 public void peekWallpaperCaching_cachesWallpaper() throws IOException { 1045 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1046 1047 // Get the current bitmap, and check that the second call returns the cached bitmap 1048 Bitmap bitmap1 = mWallpaperManager.getBitmapAsUser(mContext.getUserId(), 1049 false /* hardware */, FLAG_SYSTEM); 1050 assertThat(bitmap1).isNotNull(); 1051 assertThat(mWallpaperManager.getBitmapAsUser(mContext.getUserId(), false /* hardware */, 1052 FLAG_SYSTEM)).isSameInstanceAs(bitmap1); 1053 1054 // Change the wallpaper to invalidate the cached bitmap 1055 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_SYSTEM); 1056 1057 // Get the new bitmap, and check that the second call returns the newly cached bitmap 1058 Bitmap bitmap2 = mWallpaperManager.getBitmapAsUser(mContext.getUserId(), 1059 false /* hardware */, FLAG_SYSTEM); 1060 assertThat(bitmap2).isNotSameInstanceAs(bitmap1); 1061 assertThat(mWallpaperManager.getBitmapAsUser(mContext.getUserId(), false /* hardware */, 1062 FLAG_SYSTEM)).isSameInstanceAs(bitmap2); 1063 } 1064 1065 @Test peekWallpaperCaching_differentWhich_doesNotReturnCached()1066 public void peekWallpaperCaching_differentWhich_doesNotReturnCached() throws IOException { 1067 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1068 mWallpaperManager.setResource(R.drawable.icon_green, FLAG_LOCK); 1069 1070 Bitmap bitmapSystem = mWallpaperManager.getBitmapAsUser(mContext.getUserId(), 1071 false /* hardware */, FLAG_SYSTEM); 1072 Bitmap bitmapLock = mWallpaperManager.getBitmapAsUser(mContext.getUserId(), 1073 false /* hardware */, FLAG_LOCK); 1074 assertThat(bitmapLock).isNotSameInstanceAs(bitmapSystem); 1075 1076 } 1077 1078 @Test peekWallpaperCaching_bitmapRecycled_doesNotReturnCached()1079 public void peekWallpaperCaching_bitmapRecycled_doesNotReturnCached() throws IOException { 1080 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1081 1082 Bitmap bitmap = mWallpaperManager.getBitmapAsUser(mContext.getUserId(), 1083 false /* hardware */, FLAG_SYSTEM); 1084 assertThat(bitmap).isNotNull(); 1085 bitmap.recycle(); 1086 assertThat(mWallpaperManager.getBitmapAsUser(mContext.getUserId(), false /* hardware */, 1087 FLAG_SYSTEM)).isNotSameInstanceAs(bitmap); 1088 } 1089 1090 @Test peekWallpaperCaching_differentUser_doesNotReturnCached()1091 public void peekWallpaperCaching_differentUser_doesNotReturnCached() throws IOException { 1092 final int bogusUserId = -1; 1093 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1094 1095 Bitmap bitmap = mWallpaperManager.getBitmapAsUser(mContext.getUserId(), 1096 false /* hardware */, FLAG_SYSTEM); 1097 assertThat(bitmap).isNotNull(); 1098 1099 // If the cached bitmap was determined to be invalid, this leads to a call to 1100 // WallpaperManager.Globals#getCurrentWallpaperLocked() for a different user, which 1101 // generates a security exception: the exception indicates that the cached bitmap was 1102 // invalid, which is the desired result. 1103 assertThrows(SecurityException.class, 1104 () -> mWallpaperManager.getBitmapAsUser(bogusUserId, false /* hardware */, 1105 FLAG_SYSTEM)); 1106 } 1107 1108 @Test peekWallpaperDimensions_homeScreen_succeeds()1109 public void peekWallpaperDimensions_homeScreen_succeeds() throws IOException { 1110 final int width = 100; 1111 final int height = 200; 1112 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 1113 Canvas canvas = new Canvas(bitmap); 1114 canvas.drawColor(Color.RED); 1115 mWallpaperManager.setBitmap(bitmap); 1116 1117 Bitmap croppedBitmap = mWallpaperManager.getBitmap(); 1118 Rect expectedSize = new Rect(0, 0, croppedBitmap.getWidth(), croppedBitmap.getHeight()); 1119 Rect actualSize = mWallpaperManager.peekBitmapDimensions(); 1120 1121 assertThat(actualSize).isEqualTo(expectedSize); 1122 } 1123 1124 @Test peekWallpaperDimensions_lockScreenUnset_succeeds()1125 public void peekWallpaperDimensions_lockScreenUnset_succeeds() { 1126 Rect actualSize = mWallpaperManager.peekBitmapDimensions(FLAG_LOCK); 1127 1128 assertThat(actualSize).isNull(); 1129 } 1130 1131 @Test peekWallpaperDimensions_lockScreenSet_succeeds()1132 public void peekWallpaperDimensions_lockScreenSet_succeeds() throws IOException { 1133 Bitmap homeBitmap = Bitmap.createBitmap(150 /* width */, 150 /* width */, 1134 Bitmap.Config.ARGB_8888); 1135 Canvas homeCanvas = new Canvas(homeBitmap); 1136 homeCanvas.drawColor(Color.RED); 1137 mWallpaperManager.setBitmap(homeBitmap, /* visibleCropHint */ null, /* allowBackup */true, 1138 FLAG_SYSTEM); 1139 final int width = 100; 1140 final int height = 200; 1141 Bitmap lockBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 1142 Canvas lockCanvas = new Canvas(lockBitmap); 1143 lockCanvas.drawColor(Color.RED); 1144 mWallpaperManager.setBitmap(lockBitmap, /* visibleCropHint */ null, /* allowBackup */true, 1145 FLAG_LOCK); 1146 1147 Drawable drawable = mWallpaperManager.getDrawable(FLAG_LOCK); 1148 Rect expectedSize = new Rect( 1149 0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 1150 Rect actualSize = mWallpaperManager.peekBitmapDimensions(FLAG_LOCK); 1151 1152 assertThat(actualSize).isEqualTo(expectedSize); 1153 } 1154 1155 @Test getDrawable_homeScreen_succeeds()1156 public void getDrawable_homeScreen_succeeds() throws IOException { 1157 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1158 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1159 1160 Drawable actual = mWallpaperManager.getDrawable(FLAG_SYSTEM); 1161 1162 assertWithMessage("Drawables must represent the same image").that( 1163 isSimilar(actual, expected, true)).isTrue(); 1164 } 1165 1166 @Test getDrawable_lockScreenUnset_returnsNull()1167 public void getDrawable_lockScreenUnset_returnsNull() { 1168 Drawable actual = mWallpaperManager.getDrawable(FLAG_LOCK); 1169 1170 assertThat(actual).isNull(); 1171 } 1172 1173 @Test getDrawable_lockScreenSet_succeeds()1174 public void getDrawable_lockScreenSet_succeeds() throws IOException { 1175 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1176 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 1177 1178 Drawable actual = mWallpaperManager.getDrawable(FLAG_LOCK); 1179 1180 assertWithMessage("Drawables must represent the same image").that( 1181 isSimilar(actual, expected, true)).isTrue(); 1182 } 1183 1184 @Test getDrawable_default_sameAsHome()1185 public void getDrawable_default_sameAsHome() throws IOException { 1186 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1187 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1188 1189 Drawable actual = mWallpaperManager.getDrawable(); 1190 1191 assertWithMessage("Drawables must represent the same image").that( 1192 isSimilar(actual, expected, true)).isTrue(); 1193 } 1194 1195 @Test getFastDrawable_homeScreen_succeeds()1196 public void getFastDrawable_homeScreen_succeeds() throws IOException { 1197 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1198 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1199 1200 Drawable actual = mWallpaperManager.getFastDrawable(FLAG_SYSTEM); 1201 1202 assertWithMessage("Drawables must represent the same image").that( 1203 isSimilar(actual, expected, true)).isTrue(); 1204 } 1205 1206 @Test getFastDrawable_lockScreenUnset_returnsNull()1207 public void getFastDrawable_lockScreenUnset_returnsNull() { 1208 Drawable actual = mWallpaperManager.getFastDrawable(FLAG_LOCK); 1209 1210 assertThat(actual).isNull(); 1211 } 1212 1213 @Test getFastDrawable_lockScreenSet_succeeds()1214 public void getFastDrawable_lockScreenSet_succeeds() throws IOException { 1215 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1216 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 1217 1218 Drawable actual = mWallpaperManager.getFastDrawable(FLAG_LOCK); 1219 1220 assertWithMessage("Drawables must represent the same image").that( 1221 isSimilar(actual, expected, true)).isTrue(); 1222 } 1223 1224 @Test getFastDrawable_default_sameAsHome()1225 public void getFastDrawable_default_sameAsHome() throws IOException { 1226 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1227 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1228 1229 Drawable actual = mWallpaperManager.getFastDrawable(); 1230 1231 assertWithMessage("Drawables must represent the same image").that( 1232 isSimilar(actual, expected, true)).isTrue(); 1233 } 1234 1235 @Test peekDrawable_homeScreen_succeeds()1236 public void peekDrawable_homeScreen_succeeds() throws IOException { 1237 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1238 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1239 1240 Drawable actual = mWallpaperManager.peekDrawable(FLAG_SYSTEM); 1241 1242 assertWithMessage("Drawables must represent the same image").that( 1243 isSimilar(actual, expected, true)).isTrue(); 1244 } 1245 1246 @Test peekDrawable_lockScreenUnset_returnsNull()1247 public void peekDrawable_lockScreenUnset_returnsNull() { 1248 Drawable actual = mWallpaperManager.peekDrawable(FLAG_LOCK); 1249 1250 assertThat(actual).isNull(); 1251 } 1252 1253 @Test peekDrawable_lockScreenSet_succeeds()1254 public void peekDrawable_lockScreenSet_succeeds() throws IOException { 1255 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1256 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 1257 1258 Drawable actual = mWallpaperManager.peekDrawable(FLAG_LOCK); 1259 1260 assertWithMessage("Drawables must represent the same image").that( 1261 isSimilar(actual, expected, true)).isTrue(); 1262 } 1263 1264 @Test peekDrawable_default_sameAsHome()1265 public void peekDrawable_default_sameAsHome() throws IOException { 1266 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1267 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1268 1269 Drawable actual = mWallpaperManager.peekDrawable(); 1270 1271 assertWithMessage("Drawables must represent the same image").that( 1272 isSimilar(actual, expected, true)).isTrue(); 1273 } 1274 1275 @Test peekFastDrawable_homeScreen_succeeds()1276 public void peekFastDrawable_homeScreen_succeeds() throws IOException { 1277 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1278 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1279 1280 Drawable actual = mWallpaperManager.peekFastDrawable(FLAG_SYSTEM); 1281 1282 assertWithMessage("Drawables must represent the same image").that( 1283 isSimilar(actual, expected, true)).isTrue(); 1284 } 1285 1286 @Test peekFastDrawable_lockScreenUnset_returnsNull()1287 public void peekFastDrawable_lockScreenUnset_returnsNull() { 1288 Drawable actual = mWallpaperManager.peekFastDrawable(FLAG_LOCK); 1289 1290 assertThat(actual).isNull(); 1291 } 1292 1293 @Test peekFastDrawable_lockScreenSet_succeeds()1294 public void peekFastDrawable_lockScreenSet_succeeds() throws IOException { 1295 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1296 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_LOCK); 1297 1298 Drawable actual = mWallpaperManager.peekFastDrawable(FLAG_LOCK); 1299 1300 assertWithMessage("Drawables must represent the same image").that( 1301 isSimilar(actual, expected, true)).isTrue(); 1302 } 1303 1304 @Test peekFastDrawable_default_sameAsHome()1305 public void peekFastDrawable_default_sameAsHome() throws IOException { 1306 Drawable expected = mContext.getDrawable(R.drawable.icon_red); 1307 mWallpaperManager.setResource(R.drawable.icon_red, FLAG_SYSTEM); 1308 1309 Drawable actual = mWallpaperManager.peekFastDrawable(); 1310 1311 assertWithMessage("Drawables must represent the same image").that( 1312 isSimilar(actual, expected, true)).isTrue(); 1313 } 1314 1315 /** 1316 * For every possible (state, change) couple, checks that the number of times 1317 * {@link TestWallpaperService.FakeEngine#onDestroy} and 1318 * {@link TestWallpaperService.FakeEngine#onCreate} are called is correct. 1319 */ 1320 @Test testEngineCallbackCountsParam( @estParameter WallpaperManagerTestUtils.WallpaperState state)1321 public void testEngineCallbackCountsParam( 1322 @TestParameter WallpaperManagerTestUtils.WallpaperState state) 1323 throws IOException { 1324 DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); 1325 assumeTrue("this test item is not suitable for multi screen devices" 1326 + " that expand display screens", displayManager.getDisplays().length <= 1); 1327 1328 ArrayList<String> errorMessages = new ArrayList<>(); 1329 runWithShellPermissionIdentity(() -> { 1330 for (WallpaperChange change: state.allPossibleChanges()) { 1331 WallpaperManagerTestUtils.goToState(mWallpaperManager, state); 1332 TestWallpaperService.Companion.resetCounts(); 1333 final int expectedCreateCount = 1334 state.expectedNumberOfLiveWallpaperCreate(change); 1335 final int expectedDestroyCount = 1336 state.expectedNumberOfLiveWallpaperDestroy(change); 1337 1338 runAndAwaitChanges(5, TimeUnit.SECONDS, 1339 expectedCreateCount, expectedDestroyCount, 0, () -> { 1340 WallpaperManagerTestUtils.performChange(mWallpaperManager, change); 1341 }); 1342 1343 int actualCreateCount = TestWallpaperService.Companion.getCreateCount(); 1344 String createMessage = String.format( 1345 "Expected %s calls to Engine#onCreate, got %s. ", 1346 expectedCreateCount, actualCreateCount); 1347 if (actualCreateCount != expectedCreateCount) { 1348 errorMessages.add( 1349 createMessage + "\n" + state.reproduceDescription(change)); 1350 } 1351 1352 int actualDestroyCount = TestWallpaperService.Companion.getDestroyCount(); 1353 String destroyMessage = String.format( 1354 "Expected %s calls to Engine#onDestroy, got %s. ", 1355 expectedDestroyCount, actualDestroyCount); 1356 if (actualDestroyCount != expectedDestroyCount) { 1357 errorMessages.add( 1358 destroyMessage + "\n" + state.reproduceDescription(change)); 1359 } 1360 } 1361 }); 1362 assertWithMessage(String.join("\n\n", errorMessages)) 1363 .that(errorMessages.size()).isEqualTo(0); 1364 } 1365 1366 /** 1367 * Check that the wallpaper windows that window manager is handling 1368 * are exactly the expected ones 1369 */ 1370 @Test testExistingWallpaperWindows()1371 public void testExistingWallpaperWindows() { 1372 DisplayManager displayManager = mContext.getSystemService(DisplayManager.class); 1373 assumeTrue("this test item is not suitable for multi screen devices" 1374 + " that expand display screens", displayManager.getDisplays().length <= 1); 1375 1376 assumeTrue("Test requires FEATURE_LIVE_WALLPAPER", 1377 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER)); 1378 runWithShellPermissionIdentity(() -> { 1379 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper = 1380 new WallpaperWindowsTestUtils.WallpaperWindowsHelper(sWindowManagerStateHelper); 1381 // Two independent wallpapers 1382 WallpaperManagerTestUtils.goToState( 1383 mWallpaperManager, WallpaperState.LIVE_DIFF_MULTI); 1384 assertWallpapersMatching(wallpaperWindowsHelper, 1385 List.of(mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM).getServiceName(), 1386 mWallpaperManager.getWallpaperInfo(FLAG_LOCK).getServiceName())); 1387 // One shared wallpaper 1388 WallpaperManagerTestUtils.goToState( 1389 mWallpaperManager, WallpaperState.LIVE_SAME_SINGLE); 1390 assertWallpapersMatching(wallpaperWindowsHelper, List.of( 1391 mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM).getServiceName())); 1392 }); 1393 } 1394 startAndWaitActivity()1395 private void startAndWaitActivity() { 1396 mActivityTestRule.launchActivity(null); 1397 sWindowManagerStateHelper.waitAndAssertActivityState( 1398 mActivityTestRule.getActivity().getComponentName(), 1399 WindowManagerState.STATE_RESUMED); 1400 } 1401 1402 /** 1403 * Check that the windows which have the role of home screen wallpapers 1404 * are actually visible on home screen 1405 */ 1406 @Test testSystemAndLockWallpaperVisibility_onHomeScreen()1407 public void testSystemAndLockWallpaperVisibility_onHomeScreen() { 1408 assumeTrue("Test requires FEATURE_LIVE_WALLPAPER", 1409 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER)); 1410 try (LockScreenSession lockScreenSession = 1411 new LockScreenSession(mInstrumentation, sWindowManagerStateHelper)) { 1412 runWithShellPermissionIdentity(() -> { 1413 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper = 1414 new WallpaperWindowsTestUtils.WallpaperWindowsHelper( 1415 sWindowManagerStateHelper); 1416 lockScreenSession.disableLockScreen().unlockDevice(); 1417 1418 // Launch an activity that shows the wallpaper to make sure it is not behind 1419 // opaque activities 1420 startAndWaitActivity(); 1421 1422 // Two independent wallpapers 1423 WallpaperManagerTestUtils.goToState(mWallpaperManager, 1424 WallpaperState.LIVE_DIFF_MULTI); 1425 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM, 1426 true /* shouldBeShown */, "System wallpaper is hidden on home screen"); 1427 1428 // Shared wallpaper 1429 WallpaperManagerTestUtils.goToState( 1430 mWallpaperManager, WallpaperState.LIVE_SAME_SINGLE); 1431 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM | FLAG_LOCK, 1432 true /* shouldBeShown */, "Shared wallpaper is hidden on home screen"); 1433 }); 1434 } 1435 } 1436 1437 /** 1438 * Check that the windows which have the role of lock screen wallpapers 1439 * are actually visible on lock screen 1440 */ 1441 @Test testSystemAndLockWallpaperVisibility_onLockScreen()1442 public void testSystemAndLockWallpaperVisibility_onLockScreen() throws Exception { 1443 assumeFalse("Test requires support for different lock and home screen wallpapers", 1444 mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)); 1445 1446 assumeTrue("Test requires FEATURE_SECURE_LOCK_SCREEN", 1447 mContext.getPackageManager().hasSystemFeature(FEATURE_SECURE_LOCK_SCREEN)); 1448 assumeTrue("Test requires FEATURE_LIVE_WALLPAPER", 1449 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER)); 1450 try (LockScreenSession lockScreenSession = 1451 new LockScreenSession(mInstrumentation, sWindowManagerStateHelper)) { 1452 runWithShellPermissionIdentity(() -> { 1453 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper = 1454 new WallpaperWindowsTestUtils.WallpaperWindowsHelper( 1455 sWindowManagerStateHelper); 1456 1457 // Two independent wallpapers 1458 WallpaperManagerTestUtils.goToState(mWallpaperManager, 1459 WallpaperState.LIVE_DIFF_MULTI); 1460 1461 lockScreenSession.gotoKeyguard(); 1462 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM, 1463 false /* shouldBeShown */, 1464 "System wallpaper is showing on lock screen"); 1465 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_LOCK, true /* shouldBeShown */, 1466 "Lock wallpaper is hidden on lock screen"); 1467 1468 // Shared wallpaper 1469 WallpaperManagerTestUtils.goToState( 1470 mWallpaperManager, WallpaperState.LIVE_SAME_SINGLE); 1471 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM | FLAG_LOCK, 1472 true /* shouldBeShown */, "Shared wallpaper is hidden on lock screen"); 1473 }); 1474 } 1475 } 1476 1477 /** 1478 * Verify that a shared wallpaper is visible behind a show wallpaper activity on lockscreen 1479 */ 1480 @Test testSharedWallpaperVisibilityBehindActivity_onLockScreen()1481 public void testSharedWallpaperVisibilityBehindActivity_onLockScreen() throws Exception { 1482 assumeTrue("Test requires FEATURE_SECURE_LOCK_SCREEN", 1483 mContext.getPackageManager().hasSystemFeature(FEATURE_SECURE_LOCK_SCREEN)); 1484 assumeTrue("Test requires FEATURE_LIVE_WALLPAPER", 1485 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER)); 1486 try (LockScreenSession lockScreenSession = 1487 new LockScreenSession(mInstrumentation, sWindowManagerStateHelper)) { 1488 runWithShellPermissionIdentity(() -> { 1489 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper = 1490 new WallpaperWindowsTestUtils.WallpaperWindowsHelper( 1491 sWindowManagerStateHelper); 1492 1493 startAndWaitActivity(); 1494 1495 // Make sure a live wallpaper is configured and used for both home and lock 1496 // screens. 1497 final WallpaperInfo homeInfo = mWallpaperManager.getWallpaperInfo(FLAG_SYSTEM); 1498 final int lockInfo = mWallpaperManager.getWallpaperId(FLAG_LOCK); 1499 if (homeInfo == null || lockInfo >= 0) { 1500 WallpaperManagerTestUtils.goToState(mWallpaperManager, 1501 WallpaperState.LIVE_SAME_SINGLE); 1502 } 1503 1504 lockScreenSession.gotoKeyguard(); 1505 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM | FLAG_LOCK, 1506 true /* shouldBeShown */, 1507 "Shared wallpaper should be showing behind activity"); 1508 }); 1509 } 1510 } 1511 1512 /** 1513 * Verify that the home wallpaper is never visible behind an activity on lock screen, and that 1514 * the lock screen wallpaper is visible when it has its own window. 1515 */ 1516 @Test testIndependentWallpaperVisibilityBehindActivity_onLockScreen()1517 public void testIndependentWallpaperVisibilityBehindActivity_onLockScreen() throws Exception { 1518 assumeFalse("Test requires support for different lock and home screen wallpapers", 1519 mContext.getPackageManager().hasSystemFeature(FEATURE_WATCH)); 1520 assumeTrue("Test requires FEATURE_SECURE_LOCK_SCREEN", 1521 mContext.getPackageManager().hasSystemFeature(FEATURE_SECURE_LOCK_SCREEN)); 1522 assumeTrue("Test requires FEATURE_LIVE_WALLPAPER", 1523 mContext.getPackageManager().hasSystemFeature(FEATURE_LIVE_WALLPAPER)); 1524 1525 try (LockScreenSession lockScreenSession = 1526 new LockScreenSession(mInstrumentation, sWindowManagerStateHelper)) { 1527 runWithShellPermissionIdentity(() -> { 1528 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper = 1529 new WallpaperWindowsTestUtils.WallpaperWindowsHelper( 1530 sWindowManagerStateHelper); 1531 1532 startAndWaitActivity(); 1533 1534 WallpaperState wallpaperState = WallpaperState.LIVE_DIFF_MULTI; 1535 WallpaperManagerTestUtils.goToState(mWallpaperManager, wallpaperState); 1536 lockScreenSession.gotoKeyguard(); 1537 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_LOCK, 1538 true /* shouldBeShown */, 1539 "Lock wallpaper should be showing behind an activity"); 1540 assertWallpaperIsShown(wallpaperWindowsHelper, FLAG_SYSTEM, 1541 false /* shouldBeShown */, 1542 "Home wallpaper should not be showing behind an activity on lock screen"); 1543 }); 1544 } 1545 } 1546 1547 @Test 1548 @Ignore("b/281082882") setDimAmount_lockScreenUnset_notifiesColorsChangedBothTogether()1549 public void setDimAmount_lockScreenUnset_notifiesColorsChangedBothTogether() { 1550 ensureCleanState(); 1551 1552 final CountDownLatch latch = new CountDownLatch(1); 1553 WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> latch.countDown(); 1554 final LinkedList<Integer> receivedFlags = new LinkedList<>(); 1555 WallpaperManager.OnColorsChangedListener listener = (colors, whichWp) -> receivedFlags.add( 1556 whichWp); 1557 mWallpaperManager.addOnColorsChangedListener(listener, mHandler); 1558 mWallpaperManager.addOnColorsChangedListener(counter, mHandler); 1559 final float initialDim = runWithShellPermissionIdentity( 1560 mWallpaperManager::getWallpaperDimAmount); 1561 final float newDim = initialDim > 0 ? 0.5f * initialDim : 0.5f; 1562 1563 try { 1564 runWithShellPermissionIdentity(() -> { 1565 mWallpaperManager.setWallpaperDimAmount(newDim); 1566 }); 1567 boolean latchSuccess = latch.await(DIM_LISTENER_TIMEOUT_SECS, TimeUnit.SECONDS); 1568 assertWithMessage("Registered listener not invoked").that(latchSuccess).isTrue(); 1569 } catch (InterruptedException e) { 1570 throw new RuntimeException(e); 1571 } finally { 1572 runWithShellPermissionIdentity(() -> 1573 mWallpaperManager.setWallpaperDimAmount(initialDim)); 1574 } 1575 1576 assertThat(receivedFlags).containsExactly(FLAG_SYSTEM | FLAG_LOCK); 1577 mWallpaperManager.removeOnColorsChangedListener(listener); 1578 mWallpaperManager.removeOnColorsChangedListener(counter); 1579 } 1580 1581 @Test 1582 @Ignore("b/281082882") setDimAmount_lockScreenSet_notifiesColorsChangedBothSeparately()1583 public void setDimAmount_lockScreenSet_notifiesColorsChangedBothSeparately() { 1584 ensureCleanState(FLAG_LOCK); 1585 ensureCleanState(FLAG_SYSTEM); 1586 1587 final CountDownLatch latch = new CountDownLatch(2); 1588 WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> latch.countDown(); 1589 final LinkedList<Integer> receivedFlags = new LinkedList<>(); 1590 WallpaperManager.OnColorsChangedListener listener = (colors, whichWp) -> receivedFlags.add( 1591 whichWp); 1592 mWallpaperManager.addOnColorsChangedListener(listener, mHandler); 1593 final float initialDim = runWithShellPermissionIdentity( 1594 mWallpaperManager::getWallpaperDimAmount); 1595 final float newDim = initialDim > 0 ? 0.5f * initialDim : 0.5f; 1596 1597 mWallpaperManager.addOnColorsChangedListener(counter, mHandler); 1598 try { 1599 runWithShellPermissionIdentity(() -> { 1600 mWallpaperManager.setWallpaperDimAmount(newDim); 1601 }); 1602 boolean latchSuccess = latch.await(DIM_LISTENER_TIMEOUT_SECS, TimeUnit.SECONDS); 1603 assertWithMessage("Registered listener not invoked").that(latchSuccess).isTrue(); 1604 } catch (InterruptedException e) { 1605 throw new RuntimeException(e); 1606 } finally { 1607 runWithShellPermissionIdentity(() -> 1608 mWallpaperManager.setWallpaperDimAmount(initialDim)); 1609 } 1610 1611 assertThat(receivedFlags).containsExactly(FLAG_SYSTEM, FLAG_LOCK); 1612 mWallpaperManager.removeOnColorsChangedListener(listener); 1613 mWallpaperManager.removeOnColorsChangedListener(counter); 1614 } 1615 assertWallpapersMatching(WallpaperWindowsTestUtils.WallpaperWindowsHelper windows, List<String> expectedWallpaperPackageNames)1616 private void assertWallpapersMatching(WallpaperWindowsTestUtils.WallpaperWindowsHelper windows, 1617 List<String> expectedWallpaperPackageNames) { 1618 1619 boolean match = windows.waitForMatchingPackages(expectedWallpaperPackageNames); 1620 assertWithMessage("Lists do not match. Expected: " 1621 + expectedWallpaperPackageNames + " but received " + windows.dumpPackages()) 1622 .that(match).isTrue(); 1623 } 1624 1625 /** Check if wallpaper corresponding to wallpaperFlag has visibility matching shouldBeShown */ assertWallpaperIsShown( WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper, int wallpaperFlag, boolean shouldBeShown, String errorMsg)1626 private void assertWallpaperIsShown( 1627 WallpaperWindowsTestUtils.WallpaperWindowsHelper wallpaperWindowsHelper, 1628 int wallpaperFlag, 1629 boolean shouldBeShown, 1630 String errorMsg) { 1631 String wpServiceName = mWallpaperManager.getWallpaperInfo( 1632 (wallpaperFlag & FLAG_SYSTEM) != 0 ? FLAG_SYSTEM : FLAG_LOCK).getServiceName(); 1633 1634 boolean matchingVisibility = wallpaperWindowsHelper 1635 .waitForMatchingWindowVisibility(wpServiceName, shouldBeShown); 1636 assertWithMessage(errorMsg + "\n" + wallpaperWindowsHelper.dumpWindows()) 1637 .that(matchingVisibility).isTrue(); 1638 } 1639 1640 /** 1641 * Granting android.permission.ALWAYS_UPDATE_WALLPAPER should allow the wallpaper 1642 * commands to be sent even when activity is not in focus 1643 * Note that there is no window to focus in this test 1644 */ 1645 @RequiresFlagsEnabled(Flags.FLAG_ALWAYS_UPDATE_WALLPAPER_PERMISSION) 1646 @Test 1647 @Ignore("b/313534425") testAlwaysUpdateWallpaperPermission_allowOutOfFocusWallpaperCommand()1648 public void testAlwaysUpdateWallpaperPermission_allowOutOfFocusWallpaperCommand() { 1649 1650 /* Clear previous wallpaper commands */ 1651 TestLiveWallpaper.Companion.resetPrevAction(); 1652 1653 runWithShellPermissionIdentity( 1654 () -> { 1655 mWallpaperManager.setWallpaperComponent(TEST_COMPONENT_NAME); 1656 1657 /* Activity that will be overlaid and lose focus */ 1658 WallpaperOverlayTestActivity overlayActivity = 1659 mOverlayActivityTestRule.launchActivity(null); 1660 sWindowManagerStateHelper.waitAndAssertActivityState( 1661 overlayActivity.getComponentName(), 1662 WindowManagerState.STATE_RESUMED); 1663 assertTrue( 1664 "overlayActivity does not have required permission", 1665 overlayActivity.checkSelfPermission(ALWAYS_UPDATE_WALLPAPER) 1666 == PERMISSION_GRANTED); 1667 1668 /* Launch base activity to cover the overlay activity */ 1669 Activity baseActivity = mActivityTestRule.launchActivity(null); 1670 sWindowManagerStateHelper.waitAndAssertActivityState( 1671 baseActivity.getComponentName(), 1672 WindowManagerState.STATE_RESUMED); 1673 1674 /* Send wallpaper command with ALWAYS_UPDATE_WALLPAPER permission */ 1675 overlayActivity.sendWallpaperCommand(WallpaperManager.COMMAND_TAP); 1676 1677 /* Allow time for the wallpaper command to be sent over IPC stack */ 1678 try { 1679 Thread.sleep(SLEEP_MS); 1680 } catch (InterruptedException e) { 1681 throw new RuntimeException(e); 1682 } 1683 1684 assertWithMessage("Wallpaper command is not sent with permission") 1685 .that(TestLiveWallpaper.Companion.getPrevAction()) 1686 .isEqualTo(WallpaperManager.COMMAND_TAP); 1687 }); 1688 } 1689 1690 @Test 1691 @RequiresFlagsEnabled({FLAG_MULTI_CROP}) testSetWallpaperWithCrops_noCrop()1692 public void testSetWallpaperWithCrops_noCrop() { 1693 Point screenSize = getScreenSize(); 1694 int bitmapHeight = 3 * screenSize.y; 1695 int bitmapWidth = 2 * screenSize.x; 1696 Point bitmapSize = new Point(bitmapWidth, bitmapHeight); 1697 Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); 1698 Canvas canvas = new Canvas(bitmap); 1699 canvas.drawColor(Color.RED); 1700 runWithShellPermissionIdentity(() -> { 1701 for (int which : List.of(FLAG_SYSTEM, FLAG_LOCK, FLAG_SYSTEM | FLAG_LOCK)) { 1702 Rect expectedCrop = mWallpaperManager 1703 .getBitmapCrops(bitmapSize, List.of(screenSize), Map.of()).getFirst(); 1704 mWallpaperManager.setBitmapWithCrops(bitmap, Map.of(), true, which); 1705 int sourceFlag = which == FLAG_LOCK ? FLAG_LOCK : FLAG_SYSTEM; 1706 Rect absoluteCrop = mWallpaperManager.getBitmapCrops( 1707 List.of(screenSize), sourceFlag, true).getFirst(); 1708 assertAlmostEqual(expectedCrop, absoluteCrop); 1709 Rect relativeCrop = mWallpaperManager.getBitmapCrops( 1710 List.of(screenSize), sourceFlag, false).getFirst(); 1711 float tolerance = 2f / Math.min(relativeCrop.width(), relativeCrop.height()); 1712 assertThat((float) relativeCrop.width() / relativeCrop.height()).isWithin(tolerance) 1713 .of((float) expectedCrop.width() / expectedCrop.height()); 1714 } 1715 }); 1716 } 1717 1718 @Test 1719 @RequiresFlagsEnabled({FLAG_MULTI_CROP}) 1720 @RequiresFlagsDisabled(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testSetWallpaperWithCrops_singleCrop()1721 public void testSetWallpaperWithCrops_singleCrop() { 1722 Point displaySize = getScreenSize(); 1723 1724 Point bitmapSize = new Point(100, 100); 1725 Bitmap bitmap = Bitmap.createBitmap(bitmapSize.x, bitmapSize.y, Bitmap.Config.ARGB_8888); 1726 1727 float scale = Math.max((float) displaySize.x / bitmapSize.x, 1728 (float) displaySize.y / bitmapSize.y); 1729 Rect crop = new Rect(0, 0, (int) (displaySize.x / scale), (int) (displaySize.y / scale)); 1730 Map<Point, Rect> cropHints = Map.of(displaySize, crop); 1731 1732 assertCorrectCrop(bitmap, cropHints, false); 1733 } 1734 1735 @Test 1736 @RequiresFlagsEnabled({FLAG_MULTI_CROP, FLAG_LIVE_WALLPAPER_CONTENT_HANDLING}) testSetWallpaperWithCrops_description_singleCrop()1737 public void testSetWallpaperWithCrops_description_singleCrop() { 1738 Point displaySize = getScreenSize(); 1739 1740 Point bitmapSize = new Point(100, 100); 1741 Bitmap bitmap = Bitmap.createBitmap(bitmapSize.x, bitmapSize.y, Bitmap.Config.ARGB_8888); 1742 1743 float scale = Math.max((float) displaySize.x / bitmapSize.x, 1744 (float) displaySize.y / bitmapSize.y); 1745 Rect crop = new Rect(0, 0, (int) (displaySize.x / scale), (int) (displaySize.y / scale)); 1746 Map<Point, Rect> cropHints = Map.of(displaySize, crop); 1747 1748 assertCorrectCrop(bitmap, cropHints, true); 1749 } 1750 1751 @Test 1752 @RequiresFlagsEnabled({FLAG_MULTI_CROP}) 1753 @RequiresFlagsDisabled(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testSetWallpaperWithCrops_twoCrops()1754 public void testSetWallpaperWithCrops_twoCrops() { 1755 Point displaySize = getScreenSize(); 1756 assumeFalse(displaySize.x == displaySize.y); 1757 Point rotatedDisplaySize = new Point(displaySize.y, displaySize.x); 1758 1759 Point bitmapSize = new Point(300, 800); 1760 Bitmap bitmap = Bitmap.createBitmap(bitmapSize.x, bitmapSize.y, Bitmap.Config.ARGB_8888); 1761 1762 float scale = Math.max((float) displaySize.x / bitmapSize.x, 1763 (float) displaySize.y / bitmapSize.y); 1764 Rect crop = new Rect( 1765 bitmapSize.x - (int) (displaySize.x / scale), 1766 bitmapSize.y - (int) (displaySize.y / scale), 1767 bitmapSize.x, bitmapSize.y); 1768 float rotatedScale = Math.max((float) rotatedDisplaySize.x / bitmapSize.x, 1769 (float) rotatedDisplaySize.y / bitmapSize.y); 1770 Rect rotatedCrop = new Rect(0, 0, 1771 (int) (rotatedDisplaySize.x / rotatedScale), 1772 (int) (rotatedDisplaySize.y / rotatedScale)); 1773 Map<Point, Rect> cropHints = Map.of(displaySize, crop, rotatedDisplaySize, rotatedCrop); 1774 1775 assertCorrectCrop(bitmap, cropHints, false); 1776 } 1777 1778 @Test 1779 @RequiresFlagsEnabled({FLAG_MULTI_CROP, FLAG_LIVE_WALLPAPER_CONTENT_HANDLING}) testSetWallpaperWithCrops_description_twoCrops()1780 public void testSetWallpaperWithCrops_description_twoCrops() { 1781 Point displaySize = getScreenSize(); 1782 assumeFalse(displaySize.x == displaySize.y); 1783 Point rotatedDisplaySize = new Point(displaySize.y, displaySize.x); 1784 1785 Point bitmapSize = new Point(300, 800); 1786 Bitmap bitmap = Bitmap.createBitmap(bitmapSize.x, bitmapSize.y, Bitmap.Config.ARGB_8888); 1787 1788 float scale = Math.max((float) displaySize.x / bitmapSize.x, 1789 (float) displaySize.y / bitmapSize.y); 1790 Rect crop = new Rect( 1791 bitmapSize.x - (int) (displaySize.x / scale), 1792 bitmapSize.y - (int) (displaySize.y / scale), 1793 bitmapSize.x, bitmapSize.y); 1794 float rotatedScale = Math.max((float) rotatedDisplaySize.x / bitmapSize.x, 1795 (float) rotatedDisplaySize.y / bitmapSize.y); 1796 Rect rotatedCrop = new Rect(0, 0, 1797 (int) (rotatedDisplaySize.x / rotatedScale), 1798 (int) (rotatedDisplaySize.y / rotatedScale)); 1799 Map<Point, Rect> cropHints = Map.of(displaySize, crop, rotatedDisplaySize, rotatedCrop); 1800 1801 assertCorrectCrop(bitmap, cropHints, true); 1802 } 1803 1804 //// Tests specific to live wallpaper content handling 1805 1806 @Test 1807 @Ignore("b/393392368") 1808 @RequiresFlagsEnabled(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) setWallpaperComponentWithDescription_succeeds()1809 public void setWallpaperComponentWithDescription_succeeds() { 1810 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 1811 // TODO(b/393392368) Add component 1812 WallpaperDescription description = new WallpaperDescription.Builder().build(); 1813 1814 runWithShellPermissionIdentity( 1815 () -> setWallpaperDescriptionAndWait(description, FLAG_SYSTEM | FLAG_LOCK)); 1816 1817 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)).isNotEqualTo(origHomeWallpaperId); 1818 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 1819 // TODO(b/393392368) Verify instance or component 1820 } 1821 1822 @Test 1823 @RequiresFlagsEnabled(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) getWallpaperInstance_liveWallpaper_both_succeeds()1824 public void getWallpaperInstance_liveWallpaper_both_succeeds() { 1825 String id = "id_1"; 1826 // TODO(b/393392368) Use setWallpaperDescriptionAndWait 1827 runWithShellPermissionIdentity( 1828 () -> { 1829 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_SYSTEM | FLAG_LOCK); 1830 WallpaperInstance instance = 1831 mWallpaperManager.getWallpaperInstance(FLAG_SYSTEM); 1832 assertThat(instance).isNotNull(); 1833 assertThat(instance.getDescription().getComponent()) 1834 .isEqualTo(TEST_COMPONENT_NAME); 1835 assertThat(mWallpaperManager.getWallpaperInstance(FLAG_LOCK)).isNull(); 1836 }); 1837 } 1838 1839 @Test 1840 @RequiresFlagsEnabled(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) getWallpaperInstance_liveWallpaper_lockOnly_succeeds()1841 public void getWallpaperInstance_liveWallpaper_lockOnly_succeeds() { 1842 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 1843 String id = "id_1"; 1844 // TODO(b/393392368) Use setWallpaperDescriptionAndWait 1845 runWithShellPermissionIdentity( 1846 () -> { 1847 setWallpaperComponentAndWait(TEST_COMPONENT_NAME, FLAG_LOCK); 1848 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)) 1849 .isEqualTo(origHomeWallpaperId); 1850 WallpaperInstance homeInstance = 1851 mWallpaperManager.getWallpaperInstance(FLAG_SYSTEM); 1852 assertThat(homeInstance).isNotNull(); 1853 assertThat(homeInstance.getDescription()).isNotNull(); 1854 WallpaperInstance lockInstance = 1855 mWallpaperManager.getWallpaperInstance(FLAG_LOCK); 1856 assertThat(lockInstance).isNotNull(); 1857 assertThat(lockInstance.getDescription().getComponent()) 1858 .isEqualTo(TEST_COMPONENT_NAME); 1859 }); 1860 } 1861 1862 @Test 1863 @RequiresFlagsEnabled(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) setBitmapWithDescription_both_succeeds()1864 public void setBitmapWithDescription_both_succeeds() throws IOException { 1865 // based on setBitmap_both_lockScreenSet_changesHomeAndClearsLock() 1866 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 1867 Canvas canvas = new Canvas(tmpWallpaper); 1868 canvas.drawColor(Color.GREEN); 1869 WallpaperDescription description = new WallpaperDescription.Builder().setId("id").build(); 1870 1871 try { 1872 mWallpaperManager.setBitmapWithDescription( 1873 tmpWallpaper, 1874 new WallpaperDescription.Builder().setId("ignored").build(), 1875 true, 1876 FLAG_LOCK); 1877 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 1878 canvas.drawColor(Color.RED); 1879 1880 mWallpaperManager.setBitmapWithDescription( 1881 tmpWallpaper, description, /* allowBackup= */ true, FLAG_SYSTEM | FLAG_LOCK); 1882 1883 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)) 1884 .isNotEqualTo(origHomeWallpaperId); 1885 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 1886 // TODO(b/380245309) Verify instance id and description 1887 } finally { 1888 tmpWallpaper.recycle(); 1889 } 1890 } 1891 1892 @Test 1893 @RequiresFlagsEnabled(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) setStreamWithDescription_both_succeeds()1894 public void setStreamWithDescription_both_succeeds() throws IOException { 1895 Bitmap tmpWallpaper = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 1896 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 1897 tmpWallpaper.compress(Bitmap.CompressFormat.PNG, 100, outputStream); 1898 ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); 1899 WallpaperDescription description = new WallpaperDescription.Builder().setId("id").build(); 1900 1901 try { 1902 mWallpaperManager.setStreamWithDescription( 1903 inputStream, 1904 new WallpaperDescription.Builder().setId("ignored").build(), 1905 true, 1906 FLAG_LOCK); 1907 int origHomeWallpaperId = mWallpaperManager.getWallpaperId(FLAG_SYSTEM); 1908 1909 mWallpaperManager.setStreamWithDescription( 1910 inputStream, description, /* allowBackup= */ true, FLAG_SYSTEM | FLAG_LOCK); 1911 1912 assertThat(mWallpaperManager.getWallpaperId(FLAG_SYSTEM)) 1913 .isNotEqualTo(origHomeWallpaperId); 1914 assertThat(mWallpaperManager.getWallpaperId(FLAG_LOCK)).isLessThan(0); 1915 // TODO(b/380245309) Verify instance id and description 1916 } finally { 1917 tmpWallpaper.recycle(); 1918 } 1919 } 1920 1921 //// Helper methods 1922 1923 /** 1924 * Helper to check the consistency between the following when correct cropsHints are provided: 1925 * 1926 * <ul> 1927 * <li>{@link WallpaperManager#setBitmapWithCrops(Bitmap, Map, boolean, int)} 1928 * <li>{@link WallpaperManager#getBitmapCrops(List, int, boolean)} 1929 * <li>{@link WallpaperManager#getBitmapCrops(Point, List, Map)} 1930 * </ul> 1931 * 1932 * <p>This helper is called with cropHints that: 1933 * 1934 * <ul> 1935 * <li>have an entry for the current screen size 1936 * <li>have crops that are proportional to their associated display size. 1937 * </ul> 1938 * 1939 * In such a case, the suggested crops should not be modified or adjusted. 1940 * 1941 * <p>This function can use either the older set functions that take crop hints directly or the 1942 * newer functions that use {@link WallpaperDescription}. Specify useDescription=true for the 1943 * latter. This value must match the flag state or an exception will be thrown. 1944 */ assertCorrectCrop( Bitmap bitmap, Map<Point, Rect> cropHints, boolean useDescription)1945 private void assertCorrectCrop( 1946 Bitmap bitmap, Map<Point, Rect> cropHints, boolean useDescription) { 1947 if (useDescription ^ liveWallpaperContentHandling()) { 1948 throw new IllegalArgumentException("useDescription does not match flag value"); 1949 } 1950 Point currentScreenSize = getScreenSize(); 1951 Rect currentScreenCrop = cropHints.get(currentScreenSize); 1952 if (currentScreenCrop == null) throw new IllegalArgumentException(); 1953 1954 // paint the crop for the current display in green, and the rest of the bitmap in red 1955 Canvas canvas = new Canvas(bitmap); 1956 canvas.drawColor(Color.RED); 1957 Paint paint = new Paint(); 1958 paint.setColor(Color.GREEN); 1959 canvas.drawRect(currentScreenCrop, paint); 1960 1961 Point bitmapSize = new Point(bitmap.getWidth(), bitmap.getHeight()); 1962 List<Point> displaySizes = cropHints.keySet().stream().toList(); 1963 1964 // check that getBitmapCrops doesn't modify the crops when correct crops hints are provided 1965 List<Rect> expectedBitmapCrops = mWallpaperManager.getBitmapCrops( 1966 bitmapSize, displaySizes, cropHints); 1967 for (int i = 0; i < displaySizes.size(); i++) { 1968 Point displaySize = displaySizes.get(i); 1969 Rect crop = cropHints.get(displaySize); 1970 if (crop != null) assertAlmostEqual(crop, expectedBitmapCrops.get(i)); 1971 } 1972 1973 Consumer<Integer> setStreamUtil = which -> { 1974 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 1975 bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream); 1976 ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray()); 1977 try { 1978 if (useDescription) { 1979 WallpaperDescription description = new WallpaperDescription.Builder() 1980 .setCropHints(cropHints).build(); 1981 mWallpaperManager.setStreamWithDescription(inputStream, description, true, 1982 which); 1983 } else { 1984 mWallpaperManager.setStreamWithCrops(inputStream, cropHints, true, which); 1985 } 1986 } catch (IOException e) { 1987 throw new RuntimeException(e); 1988 } 1989 }; 1990 1991 Consumer<Integer> setBitmapUtil = which -> { 1992 try { 1993 if (useDescription) { 1994 WallpaperDescription description = new WallpaperDescription.Builder() 1995 .setCropHints(cropHints).build(); 1996 mWallpaperManager.setBitmapWithDescription(bitmap, description, true, which); 1997 } else { 1998 mWallpaperManager.setBitmapWithCrops(bitmap, cropHints, true, which); 1999 } 2000 } catch (IOException e) { 2001 throw new RuntimeException(e); 2002 } 2003 }; 2004 2005 runWithShellPermissionIdentity(() -> { 2006 for (int which : List.of(FLAG_SYSTEM, FLAG_LOCK, FLAG_SYSTEM | FLAG_LOCK)) { 2007 for (Consumer<Integer> setWallpaperUtil : List.of(setStreamUtil, setBitmapUtil)) { 2008 setWallpaperUtil.accept(which); 2009 2010 int sourceFlag = which == FLAG_LOCK ? FLAG_LOCK : FLAG_SYSTEM; 2011 2012 if (useDescription) { 2013 // TODO(b/380245309) Update this check when description crop logic updated. 2014 WallpaperInstance instance = mWallpaperManager.getWallpaperInstance( 2015 sourceFlag); 2016 if (instance != null) { 2017 assertThat(instance.getDescription()).isNotNull(); 2018 SparseArray<Rect> descCropHints = 2019 instance.getDescription().getCropHints(); 2020 assertThat(descCropHints).isNotNull(); 2021 } 2022 } 2023 2024 List<Rect> actualBitmapCrops = mWallpaperManager.getBitmapCrops( 2025 displaySizes, sourceFlag, true); 2026 2027 for (int i = 0; i < actualBitmapCrops.size(); i++) { 2028 assertAlmostEqual(expectedBitmapCrops.get(i), actualBitmapCrops.get(i)); 2029 } 2030 2031 Bitmap croppedBitmap = mWallpaperManager.getBitmapAsUser( 2032 mContext.getUserId(), false, sourceFlag); 2033 Rect actualScreenCrop = mWallpaperManager.getBitmapCrops( 2034 List.of(currentScreenSize), sourceFlag, false).getFirst(); 2035 assertAlmostGreen(croppedBitmap, actualScreenCrop); 2036 } 2037 } 2038 }); 2039 } 2040 assertAlmostEqual(Rect expected, Rect actual)2041 private void assertAlmostEqual(Rect expected, Rect actual) { 2042 assertThat(actual.left).isAtLeast(expected.left - 1); 2043 assertThat(actual.left).isAtMost(expected.left + 1); 2044 assertThat(actual.top).isAtLeast(expected.top - 1); 2045 assertThat(actual.top).isAtMost(expected.top + 1); 2046 assertThat(actual.right).isAtLeast(expected.right - 1); 2047 assertThat(actual.right).isAtMost(expected.right + 1); 2048 assertThat(actual.bottom).isAtLeast(expected.bottom - 1); 2049 assertThat(actual.bottom).isAtMost(expected.bottom + 1); 2050 } 2051 assertAlmostGreen(Bitmap bitmap, Rect crop)2052 private void assertAlmostGreen(Bitmap bitmap, Rect crop) { 2053 for (int y = crop.bottom + 1; y < crop.top - 1; y += 5) { 2054 for (int x = crop.left + 1; x < crop.right - 1; x += 5) { 2055 assertThat(bitmap.getPixel(x, y)).isEqualTo(Color.GREEN); 2056 } 2057 } 2058 } 2059 assertBitmapDimensions(Bitmap bitmap)2060 private void assertBitmapDimensions(Bitmap bitmap) { 2061 int maxSize = getMaxTextureSize(); 2062 boolean safe = false; 2063 if (bitmap != null) { 2064 safe = bitmap.getWidth() <= maxSize && bitmap.getHeight() <= maxSize; 2065 } 2066 assertThat(safe).isTrue(); 2067 } 2068 assertDesiredDimension(Point suggestedSize, Point expectedSize)2069 private void assertDesiredDimension(Point suggestedSize, Point expectedSize) { 2070 mWallpaperManager.suggestDesiredDimensions(suggestedSize.x, suggestedSize.y); 2071 Point actualSize = new Point(mWallpaperManager.getDesiredMinimumWidth(), 2072 mWallpaperManager.getDesiredMinimumHeight()); 2073 if (actualSize.x > 0 || actualSize.y > 0) { 2074 if ((actualSize.x != expectedSize.x || actualSize.y != expectedSize.y)) { 2075 throw new AssertionError( 2076 "Expected x: " + expectedSize.x + " y: " + expectedSize.y 2077 + ", got x: " + actualSize.x + " y: " + actualSize.y); 2078 } 2079 } 2080 } 2081 getScreenSize()2082 private Point getScreenSize() { 2083 WindowManager wm = mContext.getSystemService(WindowManager.class); 2084 Display d = wm.getDefaultDisplay(); 2085 Point p = new Point(); 2086 d.getRealSize(p); 2087 return p; 2088 } 2089 2090 /** 2091 * Helper to set a listener and verify if it was called with the same flags. 2092 * Executes operation synchronously. Params are FLAG_LOCK, FLAG_SYSTEM or a combination of both. 2093 * 2094 * @param which wallpaper destinations to set 2095 * @param whichExpected wallpaper destinations that should receive listener calls 2096 */ verifyColorListenerInvoked(int which, int whichExpected)2097 private void verifyColorListenerInvoked(int which, int whichExpected) { 2098 ensureCleanState(); 2099 int expected = 0; 2100 if ((whichExpected & FLAG_LOCK) != 0) expected++; 2101 if ((whichExpected & FLAG_SYSTEM) != 0) expected++; 2102 ArrayList<Integer> received = new ArrayList<>(); 2103 2104 final CountDownLatch latch = new CountDownLatch(expected); 2105 Handler handler = new Handler(Looper.getMainLooper()); 2106 2107 WallpaperManager.OnColorsChangedListener listener = getTestableListener(); 2108 final AtomicBoolean allOk = new AtomicBoolean(true); 2109 WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> { 2110 handler.post(() -> { 2111 final boolean wantSystem = (whichExpected & FLAG_SYSTEM) != 0; 2112 final boolean wantLock = (whichExpected & FLAG_LOCK) != 0; 2113 final boolean gotSystem = (whichWp & FLAG_SYSTEM) != 0; 2114 final boolean gotLock = (whichWp & FLAG_LOCK) != 0; 2115 received.add(whichWp); 2116 boolean ok = true; 2117 2118 if (gotLock) { 2119 if (wantLock) { 2120 latch.countDown(); 2121 } else { 2122 ok = false; 2123 } 2124 } 2125 if (gotSystem) { 2126 if (wantSystem) { 2127 latch.countDown(); 2128 } else { 2129 ok = false; 2130 } 2131 } 2132 if (!ok) { 2133 allOk.set(false); 2134 Log.e(TAG, 2135 "Unexpected which flag: " + whichWp + " should be: " + whichExpected); 2136 } 2137 }); 2138 }; 2139 2140 mWallpaperManager.addOnColorsChangedListener(listener, mHandler); 2141 mWallpaperManager.addOnColorsChangedListener(counter, mHandler); 2142 2143 try { 2144 mWallpaperManager.setResource(R.drawable.icon_red, which); 2145 boolean eventsReceived = latch.await(5, TimeUnit.SECONDS); 2146 assertWithMessage("Timed out waiting for color events. Expected: " 2147 + whichExpected + " received: " + received) 2148 .that(eventsReceived).isTrue(); 2149 // Wait in case there are additional unwanted callbacks 2150 Thread.sleep(SLEEP_MS); 2151 assertWithMessage("Unexpected which flag, check logs for details") 2152 .that(allOk.get()).isTrue(); 2153 } catch (InterruptedException | IOException e) { 2154 throw new RuntimeException(e); 2155 } finally { 2156 mWallpaperManager.removeOnColorsChangedListener(listener); 2157 mWallpaperManager.removeOnColorsChangedListener(counter); 2158 } 2159 } 2160 2161 /** 2162 * Helper to clear a wallpaper synchronously. 2163 * 2164 * @param which FLAG_LOCK, FLAG_SYSTEM or a combination of both. 2165 */ verifyColorListenerInvokedClearing(int which)2166 private void verifyColorListenerInvokedClearing(int which) { 2167 ensureCleanState(which); 2168 2169 final CountDownLatch latch = new CountDownLatch(1); 2170 2171 WallpaperManager.OnColorsChangedListener listener = getTestableListener(); 2172 WallpaperManager.OnColorsChangedListener counter = (colors, whichWp) -> { 2173 latch.countDown(); 2174 }; 2175 2176 mWallpaperManager.addOnColorsChangedListener(listener, mHandler); 2177 mWallpaperManager.addOnColorsChangedListener(counter, mHandler); 2178 2179 try { 2180 mWallpaperManager.clear(which); 2181 latch.await(5, TimeUnit.SECONDS); 2182 } catch (InterruptedException | IOException e) { 2183 throw new RuntimeException(e); 2184 } 2185 2186 verify(listener, atLeast(1)) 2187 .onColorsChanged(nullable(WallpaperColors.class), anyInt()); 2188 2189 mWallpaperManager.removeOnColorsChangedListener(listener); 2190 mWallpaperManager.removeOnColorsChangedListener(counter); 2191 } 2192 ensureCleanState()2193 private void ensureCleanState() { 2194 ensureCleanState(FLAG_SYSTEM | FLAG_LOCK); 2195 } 2196 2197 /** 2198 * Helper method to set a bitmap on the specified destination(s). 2199 */ ensureCleanState(int flags)2200 private void ensureCleanState(int flags) { 2201 Bitmap bmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 2202 Canvas canvas = new Canvas(bmp); 2203 canvas.drawColor(Color.BLUE); 2204 2205 try { 2206 runAndAwaitColorChanges(5, TimeUnit.SECONDS, flags, mWallpaperManager, mHandler, () -> { 2207 if (flags == (FLAG_SYSTEM | FLAG_LOCK)) { 2208 mWallpaperManager.setBitmap(bmp); 2209 } else { 2210 mWallpaperManager.setBitmap(bmp, /* visibleCropHint= */ 2211 null, /* allowBackup= */true, flags); 2212 } 2213 }); 2214 } catch (Exception e) { 2215 throw new RuntimeException(e); 2216 } finally { 2217 bmp.recycle(); 2218 } 2219 } 2220 assertNullOrDefaultWallpaper(int which)2221 private void assertNullOrDefaultWallpaper(int which) { 2222 WallpaperInfo wallpaperInfo = mWallpaperManager.getWallpaperInfo(which); 2223 if (mDefaultWallpaperInfo == null) assertThat(wallpaperInfo).isNull(); 2224 if (wallpaperInfo == null) return; 2225 assertThat(wallpaperInfo.getComponent()).isEqualTo(mDefaultWallpaperInfo.getComponent()); 2226 } 2227 assertNotNullOrDefaultWallpaper(int which)2228 private void assertNotNullOrDefaultWallpaper(int which) { 2229 WallpaperInfo wallpaperInfo = mWallpaperManager.getWallpaperInfo(which); 2230 assertThat(wallpaperInfo).isNotNull(); 2231 if (mDefaultWallpaperInfo != null) { 2232 assertThat(wallpaperInfo.getComponent()).isNotEqualTo( 2233 mDefaultWallpaperInfo.getComponent()); 2234 } 2235 } 2236 assertNotNullOrDefaultInstance(int which)2237 private void assertNotNullOrDefaultInstance(int which) { 2238 runWithShellPermissionIdentity(() -> { 2239 WallpaperInstance instance = mWallpaperManager.getWallpaperInstance(which); 2240 assertThat(instance).isNotNull(); 2241 assertThat(instance.getInfo()).isNotNull(); 2242 if (mDefaultWallpaperInfo != null) { 2243 assertThat(instance.getInfo().getComponent()).isNotEqualTo( 2244 mDefaultWallpaperInfo.getComponent()); 2245 } 2246 }); 2247 } 2248 setWallpaperComponentAndWait(ComponentName component, int which)2249 private void setWallpaperComponentAndWait(ComponentName component, int which) { 2250 setWallpaperComponentAndWait(component, which, 1, 1); 2251 } 2252 setWallpaperComponentAndWait(ComponentName component, int which, int created, int destroyed)2253 private void setWallpaperComponentAndWait(ComponentName component, int which, int created, 2254 int destroyed) { 2255 runAndAwaitChanges( 2256 SLEEP_MS, TimeUnit.MILLISECONDS, created, destroyed, 0, 2257 () -> mWallpaperManager.setWallpaperComponentWithFlags(component, which)); 2258 } 2259 setWallpaperDescriptionAndWait(WallpaperDescription description, int which)2260 private void setWallpaperDescriptionAndWait(WallpaperDescription description, int which) { 2261 int createdCount = 1; 2262 int destroyedCount = 1; 2263 runAndAwaitChanges( 2264 SLEEP_MS, 2265 TimeUnit.MILLISECONDS, 2266 createdCount, 2267 destroyedCount, 2268 0, 2269 () -> mWallpaperManager.setWallpaperComponentWithDescription(description, which)); 2270 } 2271 getTestableListener()2272 public WallpaperManager.OnColorsChangedListener getTestableListener() { 2273 // Unfortunately mockito cannot mock anonymous classes or lambdas. 2274 return spy(new TestableColorListener()); 2275 } 2276 2277 public static class TestableColorListener implements WallpaperManager.OnColorsChangedListener { 2278 @Override onColorsChanged(WallpaperColors colors, int which)2279 public void onColorsChanged(WallpaperColors colors, int which) { 2280 Log.d(TAG, "TestableColorListener received colors: " + colors + ", which: " + which); 2281 } 2282 } 2283 } 2284