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