1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.wallpaperbackup; 18 19 import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING; 20 import static android.app.WallpaperManager.FLAG_LOCK; 21 import static android.app.WallpaperManager.FLAG_SYSTEM; 22 import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; 23 24 import static com.android.wallpaperbackup.WallpaperBackupAgent.LOCK_WALLPAPER_STAGE; 25 import static com.android.wallpaperbackup.WallpaperBackupAgent.SYSTEM_WALLPAPER_STAGE; 26 import static com.android.wallpaperbackup.WallpaperBackupAgent.WALLPAPER_INFO_STAGE; 27 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_INELIGIBLE; 28 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA; 29 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER; 30 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED; 31 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_LOCK; 32 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_SYSTEM; 33 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK; 34 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM; 35 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK; 36 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_SYSTEM; 37 import static com.android.window.flags.Flags.multiCrop; 38 39 import static com.google.common.truth.Truth.assertThat; 40 41 import static org.junit.Assert.assertEquals; 42 import static org.junit.Assume.assumeTrue; 43 import static org.mockito.ArgumentMatchers.any; 44 import static org.mockito.ArgumentMatchers.anyBoolean; 45 import static org.mockito.ArgumentMatchers.anyInt; 46 import static org.mockito.ArgumentMatchers.argThat; 47 import static org.mockito.ArgumentMatchers.eq; 48 import static org.mockito.Mockito.never; 49 import static org.mockito.Mockito.times; 50 import static org.mockito.Mockito.verify; 51 import static org.mockito.Mockito.when; 52 53 import android.app.WallpaperInfo; 54 import android.app.WallpaperManager; 55 import android.app.backup.BackupAnnotations; 56 import android.app.backup.BackupManager; 57 import android.app.backup.BackupRestoreEventLogger; 58 import android.app.backup.BackupRestoreEventLogger.DataTypeResult; 59 import android.app.backup.FullBackupDataOutput; 60 import android.app.wallpaper.WallpaperDescription; 61 import android.content.ComponentName; 62 import android.content.Context; 63 import android.content.Intent; 64 import android.content.pm.PackageManager; 65 import android.content.pm.ResolveInfo; 66 import android.graphics.Rect; 67 import android.os.FileUtils; 68 import android.os.ParcelFileDescriptor; 69 import android.os.UserHandle; 70 import android.platform.test.annotations.EnableFlags; 71 import android.platform.test.flag.junit.SetFlagsRule; 72 import android.service.wallpaper.WallpaperService; 73 import android.util.Pair; 74 import android.util.SparseArray; 75 import android.util.Xml; 76 77 import androidx.test.InstrumentationRegistry; 78 import androidx.test.core.app.ApplicationProvider; 79 import androidx.test.runner.AndroidJUnit4; 80 81 import com.android.internal.content.PackageMonitor; 82 import com.android.modules.utils.TypedXmlSerializer; 83 import com.android.wallpaperbackup.utils.ContextWithServiceOverrides; 84 85 import org.junit.After; 86 import org.junit.Before; 87 import org.junit.Rule; 88 import org.junit.Test; 89 import org.junit.rules.RuleChain; 90 import org.junit.rules.TemporaryFolder; 91 import org.junit.runner.RunWith; 92 import org.mockito.ArgumentMatcher; 93 import org.mockito.Mock; 94 import org.mockito.MockitoAnnotations; 95 96 import java.io.File; 97 import java.io.FileInputStream; 98 import java.io.FileOutputStream; 99 import java.io.IOException; 100 import java.util.ArrayList; 101 import java.util.List; 102 import java.util.Map; 103 import java.util.Optional; 104 105 @RunWith(AndroidJUnit4.class) 106 public class WallpaperBackupAgentTest { 107 private static final String TEST_WALLPAPER_PACKAGE = "wallpaper_package"; 108 109 private static final int TEST_SYSTEM_WALLPAPER_ID = 1; 110 private static final int TEST_LOCK_WALLPAPER_ID = 2; 111 private static final int NO_LOCK_WALLPAPER_ID = -1; 112 // An arbitrary user. 113 private static final UserHandle USER_HANDLE = new UserHandle(15); 114 115 @Mock 116 private FullBackupDataOutput mOutput; 117 @Mock 118 private WallpaperManager mWallpaperManager; 119 @Mock 120 private Context mMockContext; 121 @Mock 122 private BackupManager mBackupManager; 123 124 private ContextWithServiceOverrides mContext; 125 private IsolatedWallpaperBackupAgent mWallpaperBackupAgent; 126 private ComponentName mWallpaperComponent; 127 private WallpaperDescription mWallpaperDescription; 128 129 private final TemporaryFolder mTemporaryFolder = new TemporaryFolder(); 130 131 @Rule 132 public RuleChain mRuleChain = RuleChain.outerRule(new SetFlagsRule()).around(mTemporaryFolder); 133 134 @Before setUp()135 public void setUp() { 136 MockitoAnnotations.initMocks(this); 137 when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_SYSTEM))).thenReturn(true); 138 when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_LOCK))).thenReturn(true); 139 140 mContext = new ContextWithServiceOverrides(ApplicationProvider.getApplicationContext()); 141 mContext.injectSystemService(WallpaperManager.class, mWallpaperManager); 142 143 mWallpaperBackupAgent = new IsolatedWallpaperBackupAgent(); 144 mWallpaperBackupAgent.attach(mContext); 145 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 146 BackupAnnotations.OperationType.BACKUP); 147 148 mWallpaperComponent = new ComponentName(TEST_WALLPAPER_PACKAGE, ""); 149 mWallpaperDescription = new WallpaperDescription.Builder().setComponent( 150 mWallpaperComponent).setId("id").build(); 151 } 152 153 @After tearDown()154 public void tearDown() { 155 FileUtils.deleteContents(mContext.getFilesDir()); 156 } 157 158 @Test testOnFullBackup_backsUpEmptyFile()159 public void testOnFullBackup_backsUpEmptyFile() throws IOException { 160 mWallpaperBackupAgent.onFullBackup(mOutput); 161 162 assertThat(getBackedUpFileOptional("empty").isPresent()).isTrue(); 163 } 164 165 @Test testOnFullBackup_noExistingInfoStage_backsUpInfoFile()166 public void testOnFullBackup_noExistingInfoStage_backsUpInfoFile() throws Exception { 167 mockWallpaperInfoFileWithContents("fake info file"); 168 169 mWallpaperBackupAgent.onFullBackup(mOutput); 170 171 assertFileContentEquals(getBackedUpFileOptional(WALLPAPER_INFO_STAGE).get(), 172 "fake info file"); 173 } 174 175 @Test testOnFullBackup_existingInfoStage_noChange_backsUpAlreadyStagedInfoFile()176 public void testOnFullBackup_existingInfoStage_noChange_backsUpAlreadyStagedInfoFile() 177 throws Exception { 178 // Do a backup first so the info file is staged. 179 mockWallpaperInfoFileWithContents("old info file"); 180 // Provide system and lock wallpapers but don't change them in between backups. 181 mockSystemWallpaperFileWithContents("system wallpaper"); 182 mockLockWallpaperFileWithContents("lock wallpaper"); 183 mWallpaperBackupAgent.onFullBackup(mOutput); 184 mWallpaperBackupAgent.mBackedUpFiles.clear(); 185 // This new wallpaper should be ignored since the ID of neither wallpaper changed. 186 mockWallpaperInfoFileWithContents("new info file"); 187 188 mWallpaperBackupAgent.onFullBackup(mOutput); 189 190 assertFileContentEquals(getBackedUpFileOptional(WALLPAPER_INFO_STAGE).get(), 191 "old info file"); 192 } 193 194 @Test testOnFullBackup_existingInfoStage_sysChanged_backsUpNewInfoFile()195 public void testOnFullBackup_existingInfoStage_sysChanged_backsUpNewInfoFile() 196 throws Exception { 197 // Do a backup first so the backed up system wallpaper ID is persisted to disk. 198 mockWallpaperInfoFileWithContents("old info file"); 199 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 200 mWallpaperBackupAgent.onFullBackup(mOutput); 201 mWallpaperBackupAgent.mBackedUpFiles.clear(); 202 // Mock that the user changed the system wallpaper. 203 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID + 1, TEST_LOCK_WALLPAPER_ID); 204 mockWallpaperInfoFileWithContents("new info file"); 205 206 mWallpaperBackupAgent.onFullBackup(mOutput); 207 208 assertFileContentEquals(getBackedUpFileOptional(WALLPAPER_INFO_STAGE).get(), 209 "new info file"); 210 } 211 212 @Test testOnFullBackup_existingInfoStage_lockChanged_backsUpNewInfoFile()213 public void testOnFullBackup_existingInfoStage_lockChanged_backsUpNewInfoFile() 214 throws Exception { 215 // Do a backup first so the backed up lock wallpaper ID is persisted to disk. 216 mockWallpaperInfoFileWithContents("old info file"); 217 mockLockWallpaperFileWithContents("lock wallpaper"); 218 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 219 mWallpaperBackupAgent.onFullBackup(mOutput); 220 mWallpaperBackupAgent.mBackedUpFiles.clear(); 221 // Mock that the user changed the system wallpaper. 222 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID + 1); 223 mockWallpaperInfoFileWithContents("new info file"); 224 225 mWallpaperBackupAgent.onFullBackup(mOutput); 226 227 assertFileContentEquals(getBackedUpFileOptional(WALLPAPER_INFO_STAGE).get(), 228 "new info file"); 229 } 230 231 @Test testOnFullBackup_systemWallpaperNotEligible_doesNotBackUpSystemWallpaper()232 public void testOnFullBackup_systemWallpaperNotEligible_doesNotBackUpSystemWallpaper() 233 throws Exception { 234 when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_SYSTEM))).thenReturn(false); 235 mockSystemWallpaperFileWithContents("system wallpaper"); 236 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID); 237 238 mWallpaperBackupAgent.onFullBackup(mOutput); 239 240 assertThat(getBackedUpFileOptional(SYSTEM_WALLPAPER_STAGE).isPresent()).isFalse(); 241 } 242 243 @Test testOnFullBackup_existingSystemStage_noSysChange_backsUpAlreadyStagedFile()244 public void testOnFullBackup_existingSystemStage_noSysChange_backsUpAlreadyStagedFile() 245 throws Exception { 246 // Do a backup first so that a stage file is created. 247 mockSystemWallpaperFileWithContents("system wallpaper"); 248 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID); 249 mWallpaperBackupAgent.onFullBackup(mOutput); 250 mWallpaperBackupAgent.mBackedUpFiles.clear(); 251 // This new file should be ignored since the ID of the wallpaper did not change. 252 mockSystemWallpaperFileWithContents("new system wallpaper"); 253 254 mWallpaperBackupAgent.onFullBackup(mOutput); 255 256 assertFileContentEquals(getBackedUpFileOptional(SYSTEM_WALLPAPER_STAGE).get(), 257 "system wallpaper"); 258 } 259 260 @Test testOnFullBackup_existingSystemStage_sysChanged_backsUpNewSystemWallpaper()261 public void testOnFullBackup_existingSystemStage_sysChanged_backsUpNewSystemWallpaper() 262 throws Exception { 263 // Do a backup first so that a stage file is created. 264 mockSystemWallpaperFileWithContents("system wallpaper"); 265 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID); 266 mWallpaperBackupAgent.onFullBackup(mOutput); 267 mWallpaperBackupAgent.mBackedUpFiles.clear(); 268 // Mock that the system wallpaper was changed by the user. 269 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID + 1, NO_LOCK_WALLPAPER_ID); 270 mockSystemWallpaperFileWithContents("new system wallpaper"); 271 272 mWallpaperBackupAgent.onFullBackup(mOutput); 273 274 assertFileContentEquals(getBackedUpFileOptional(SYSTEM_WALLPAPER_STAGE).get(), 275 "new system wallpaper"); 276 } 277 278 @Test testOnFullBackup_noExistingSystemStage_backsUpSystemWallpaper()279 public void testOnFullBackup_noExistingSystemStage_backsUpSystemWallpaper() 280 throws Exception { 281 mockSystemWallpaperFileWithContents("system wallpaper"); 282 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID); 283 284 mWallpaperBackupAgent.onFullBackup(mOutput); 285 286 assertFileContentEquals(getBackedUpFileOptional(SYSTEM_WALLPAPER_STAGE).get(), 287 "system wallpaper"); 288 } 289 290 @Test testOnFullBackup_lockWallpaperNotEligible_doesNotBackUpLockWallpaper()291 public void testOnFullBackup_lockWallpaperNotEligible_doesNotBackUpLockWallpaper() 292 throws Exception { 293 when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_LOCK))).thenReturn(false); 294 mockLockWallpaperFileWithContents("lock wallpaper"); 295 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 296 297 mWallpaperBackupAgent.onFullBackup(mOutput); 298 299 assertThat(getBackedUpFileOptional(LOCK_WALLPAPER_STAGE).isPresent()).isFalse(); 300 } 301 302 @Test testOnFullBackup_existingLockStage_lockWallpaperRemovedByUser_NotBackUpOldStage()303 public void testOnFullBackup_existingLockStage_lockWallpaperRemovedByUser_NotBackUpOldStage() 304 throws Exception { 305 // Do a backup first so that a stage file is created. 306 mockLockWallpaperFileWithContents("lock wallpaper"); 307 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 308 mWallpaperBackupAgent.onFullBackup(mOutput); 309 mWallpaperBackupAgent.mBackedUpFiles.clear(); 310 // Mock the ID of the lock wallpaper to indicate it's not set. 311 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID); 312 313 mWallpaperBackupAgent.onFullBackup(mOutput); 314 315 assertThat(getBackedUpFileOptional(LOCK_WALLPAPER_STAGE).isPresent()).isFalse(); 316 } 317 318 @Test testOnFullBackup_existingLockStage_lockWallpaperRemovedByUser_deletesExistingStage()319 public void testOnFullBackup_existingLockStage_lockWallpaperRemovedByUser_deletesExistingStage() 320 throws Exception { 321 // Do a backup first so that a stage file is created. 322 mockLockWallpaperFileWithContents("lock wallpaper"); 323 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 324 mWallpaperBackupAgent.onFullBackup(mOutput); 325 mWallpaperBackupAgent.mBackedUpFiles.clear(); 326 // Mock the ID of the lock wallpaper to indicate it's not set. 327 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID); 328 329 mWallpaperBackupAgent.onFullBackup(mOutput); 330 331 assertThat(new File(mContext.getFilesDir(), LOCK_WALLPAPER_STAGE).exists()).isFalse(); 332 } 333 334 @Test testOnFullBackup_existingLockStage_noLockChange_backsUpAlreadyStagedFile()335 public void testOnFullBackup_existingLockStage_noLockChange_backsUpAlreadyStagedFile() 336 throws Exception { 337 // Do a backup first so that a stage file is created. 338 mockLockWallpaperFileWithContents("old lock wallpaper"); 339 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 340 mWallpaperBackupAgent.onFullBackup(mOutput); 341 mWallpaperBackupAgent.mBackedUpFiles.clear(); 342 // This new file should be ignored since the ID of the wallpaper did not change. 343 mockLockWallpaperFileWithContents("new lock wallpaper"); 344 345 mWallpaperBackupAgent.onFullBackup(mOutput); 346 347 assertFileContentEquals(getBackedUpFileOptional(LOCK_WALLPAPER_STAGE).get(), 348 "old lock wallpaper"); 349 } 350 351 @Test testOnFullBackup_existingLockStage_lockChanged_backsUpNewLockWallpaper()352 public void testOnFullBackup_existingLockStage_lockChanged_backsUpNewLockWallpaper() 353 throws Exception { 354 // Do a backup first so that a stage file is created. 355 mockLockWallpaperFileWithContents("old lock wallpaper"); 356 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 357 mWallpaperBackupAgent.onFullBackup(mOutput); 358 mWallpaperBackupAgent.mBackedUpFiles.clear(); 359 // Mock that the lock wallpaper was changed by the user. 360 mockLockWallpaperFileWithContents("new lock wallpaper"); 361 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID + 1); 362 363 mWallpaperBackupAgent.onFullBackup(mOutput); 364 365 assertFileContentEquals(getBackedUpFileOptional(LOCK_WALLPAPER_STAGE).get(), 366 "new lock wallpaper"); 367 } 368 369 @Test testOnFullBackup_noExistingLockStage_backsUpLockWallpaper()370 public void testOnFullBackup_noExistingLockStage_backsUpLockWallpaper() 371 throws Exception { 372 mockLockWallpaperFileWithContents("lock wallpaper"); 373 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 374 375 mWallpaperBackupAgent.onFullBackup(mOutput); 376 377 assertFileContentEquals(getBackedUpFileOptional(LOCK_WALLPAPER_STAGE).get(), 378 "lock wallpaper"); 379 } 380 381 @Test testUpdateWallpaperComponent_immediate_systemAndLock()382 public void testUpdateWallpaperComponent_immediate_systemAndLock() throws IOException { 383 mWallpaperBackupAgent.mPackageExists = true; 384 385 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 386 /* which */ FLAG_LOCK | FLAG_SYSTEM); 387 388 assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0); 389 verify(mWallpaperManager, times(1)) 390 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); 391 verify(mWallpaperManager, never()) 392 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); 393 verify(mWallpaperManager, never()) 394 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); 395 verify(mWallpaperManager, never()).clear(anyInt()); 396 } 397 398 @Test testUpdateWallpaperComponent_immediate_systemOnly()399 public void testUpdateWallpaperComponent_immediate_systemOnly() 400 throws IOException { 401 mWallpaperBackupAgent.mPackageExists = true; 402 403 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 404 /* which */ FLAG_SYSTEM); 405 406 assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0); 407 verify(mWallpaperManager, times(1)) 408 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); 409 verify(mWallpaperManager, never()) 410 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); 411 verify(mWallpaperManager, never()) 412 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); 413 verify(mWallpaperManager, never()).clear(anyInt()); 414 } 415 416 @Test 417 @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testUpdateWallpaperDescription_immediate_systemAndLock()418 public void testUpdateWallpaperDescription_immediate_systemAndLock() 419 throws IOException { 420 mWallpaperBackupAgent.mPackageExists = true; 421 422 mWallpaperBackupAgent.updateWallpaperComponent( 423 new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ 424 FLAG_LOCK | FLAG_SYSTEM); 425 426 verify(mWallpaperManager, times(1)) 427 .setWallpaperComponentWithDescription(mWallpaperDescription, 428 FLAG_LOCK | FLAG_SYSTEM); 429 verify(mWallpaperManager, never()) 430 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM); 431 verify(mWallpaperManager, never()) 432 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK); 433 verify(mWallpaperManager, never()).clear(anyInt()); 434 } 435 436 @Test 437 @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testUpdateWallpaperDescription_immediate_systemOnly()438 public void testUpdateWallpaperDescription_immediate_systemOnly() throws IOException { 439 mWallpaperBackupAgent.mPackageExists = true; 440 441 mWallpaperBackupAgent.updateWallpaperComponent( 442 new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM); 443 444 verify(mWallpaperManager, times(1)) 445 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM); 446 verify(mWallpaperManager, never()) 447 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK); 448 verify(mWallpaperManager, never()) 449 .setWallpaperComponentWithDescription(mWallpaperDescription, 450 FLAG_LOCK | FLAG_SYSTEM); 451 verify(mWallpaperManager, never()).clear(anyInt()); 452 } 453 454 @Test 455 @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testUpdateWallpaperDescription_delayed_systemAndLock()456 public void testUpdateWallpaperDescription_delayed_systemAndLock() 457 throws IOException { 458 mWallpaperBackupAgent.mIsDeviceInRestore = true; 459 mWallpaperBackupAgent.updateWallpaperComponent( 460 new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ 461 FLAG_LOCK | FLAG_SYSTEM); 462 463 // Imitate wallpaper component installation. 464 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 465 /* uid */0); 466 verify(mWallpaperManager, times(1)) 467 .setWallpaperComponentWithDescription(mWallpaperDescription, 468 FLAG_LOCK | FLAG_SYSTEM); 469 verify(mWallpaperManager, never()) 470 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM); 471 verify(mWallpaperManager, never()) 472 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK); 473 verify(mWallpaperManager, never()).clear(anyInt()); 474 } 475 476 @Test 477 @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testUpdateWallpaperDescription_delayed_systemOnly()478 public void testUpdateWallpaperDescription_delayed_systemOnly() throws IOException { 479 mWallpaperBackupAgent.mIsDeviceInRestore = true; 480 481 mWallpaperBackupAgent.updateWallpaperComponent( 482 new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM); 483 484 // Imitate wallpaper component installation. 485 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 486 /* uid */0); 487 488 verify(mWallpaperManager, times(1)) 489 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM); 490 verify(mWallpaperManager, never()) 491 .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK); 492 verify(mWallpaperManager, never()) 493 .setWallpaperComponentWithDescription(mWallpaperDescription, 494 FLAG_LOCK | FLAG_SYSTEM); 495 verify(mWallpaperManager, never()).clear(anyInt()); 496 } 497 498 @Test testUpdateWallpaperComponent_delayed_systemAndLock()499 public void testUpdateWallpaperComponent_delayed_systemAndLock() throws IOException { 500 mWallpaperBackupAgent.mIsDeviceInRestore = true; 501 502 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 503 /* which */ FLAG_LOCK | FLAG_SYSTEM); 504 // Imitate wallpaper component installation. 505 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 506 /* uid */0); 507 verify(mWallpaperManager, times(1)) 508 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); 509 verify(mWallpaperManager, never()) 510 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); 511 verify(mWallpaperManager, never()) 512 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); 513 verify(mWallpaperManager, never()).clear(anyInt()); 514 } 515 516 @Test testUpdateWallpaperComponent_delayed_systemOnly()517 public void testUpdateWallpaperComponent_delayed_systemOnly() 518 throws IOException { 519 mWallpaperBackupAgent.mIsDeviceInRestore = true; 520 521 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 522 /* which */ FLAG_SYSTEM); 523 // Imitate wallpaper component installation. 524 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 525 /* uid */0); 526 527 verify(mWallpaperManager, times(1)) 528 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM); 529 verify(mWallpaperManager, never()) 530 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK); 531 verify(mWallpaperManager, never()) 532 .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM); 533 verify(mWallpaperManager, never()).clear(anyInt()); 534 } 535 536 @Test testUpdateWallpaperComponent_delayed_deviceNotInRestore_doesNotApply()537 public void testUpdateWallpaperComponent_delayed_deviceNotInRestore_doesNotApply() 538 throws IOException { 539 mWallpaperBackupAgent.mIsDeviceInRestore = false; 540 541 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 542 /* which */ FLAG_LOCK | FLAG_SYSTEM); 543 544 // Imitate wallpaper component installation. 545 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 546 /* uid */0); 547 548 verify(mWallpaperManager, never()).setWallpaperComponent(mWallpaperComponent); 549 verify(mWallpaperManager, never()).clear(eq(FLAG_LOCK)); 550 } 551 552 @Test testUpdateWallpaperComponent_delayed_differentPackageInstalled_doesNotApply()553 public void testUpdateWallpaperComponent_delayed_differentPackageInstalled_doesNotApply() 554 throws IOException { 555 mWallpaperBackupAgent.mIsDeviceInRestore = false; 556 557 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 558 /* which */ FLAG_LOCK | FLAG_SYSTEM); 559 560 // Imitate "wrong" wallpaper component installation. 561 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(/* packageName */"", 562 /* uid */0); 563 564 verify(mWallpaperManager, never()).setWallpaperComponent(mWallpaperComponent); 565 verify(mWallpaperManager, never()).clear(eq(FLAG_LOCK)); 566 } 567 568 @Test testOnFullBackup_systemWallpaperImgSuccess_logsSuccess()569 public void testOnFullBackup_systemWallpaperImgSuccess_logsSuccess() throws Exception { 570 mockSystemWallpaperFileWithContents("system wallpaper"); 571 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, NO_LOCK_WALLPAPER_ID); 572 573 mWallpaperBackupAgent.onFullBackup(mOutput); 574 575 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 576 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 577 assertThat(result).isNotNull(); 578 assertThat(result.getSuccessCount()).isEqualTo(1); 579 } 580 581 @Test testOnFullBackup_systemWallpaperImgIneligible_logsFailure()582 public void testOnFullBackup_systemWallpaperImgIneligible_logsFailure() throws Exception { 583 when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_SYSTEM))).thenReturn(false); 584 mockSystemWallpaperFileWithContents("system wallpaper"); 585 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 586 587 mWallpaperBackupAgent.onFullBackup(mOutput); 588 589 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 590 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 591 assertThat(result).isNotNull(); 592 assertThat(result.getFailCount()).isEqualTo(1); 593 assertThat(result.getErrors()).containsKey(ERROR_INELIGIBLE); 594 } 595 596 @Test testOnFullBackup_systemWallpaperImgMissing_logsFailure()597 public void testOnFullBackup_systemWallpaperImgMissing_logsFailure() throws Exception { 598 mWallpaperBackupAgent.onFullBackup(mOutput); 599 600 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 601 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 602 assertThat(result).isNotNull(); 603 assertThat(result.getFailCount()).isEqualTo(1); 604 assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); 605 } 606 607 @Test testOnFullBackup_systemWallpaperImgMissingButHasLiveComponent_logsLiveSuccess()608 public void testOnFullBackup_systemWallpaperImgMissingButHasLiveComponent_logsLiveSuccess() 609 throws Exception { 610 mockWallpaperInfoFileWithContents("info file"); 611 when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo()); 612 613 mWallpaperBackupAgent.onFullBackup(mOutput); 614 615 DataTypeResult result = getLoggingResult(WALLPAPER_LIVE_SYSTEM, 616 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 617 assertThat(result).isNotNull(); 618 assertThat(result.getSuccessCount()).isEqualTo(1); 619 assertThat(result.getMetadataHash()).isNotNull(); 620 } 621 622 @Test testOnFullBackup_systemWallpaperImgMissingButHasLiveComponent_logsNothingForImg()623 public void testOnFullBackup_systemWallpaperImgMissingButHasLiveComponent_logsNothingForImg() 624 throws Exception { 625 mockWallpaperInfoFileWithContents("info file"); 626 when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo()); 627 628 mWallpaperBackupAgent.onFullBackup(mOutput); 629 630 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 631 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 632 assertThat(result).isNull(); 633 } 634 635 @Test testOnFullBackup_lockWallpaperImgSuccess_logsSuccess()636 public void testOnFullBackup_lockWallpaperImgSuccess_logsSuccess() throws Exception { 637 mockLockWallpaperFileWithContents("lock wallpaper"); 638 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 639 640 mWallpaperBackupAgent.onFullBackup(mOutput); 641 642 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, 643 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 644 assertThat(result).isNotNull(); 645 assertThat(result.getSuccessCount()).isEqualTo(1); 646 } 647 648 @Test testOnFullBackup_lockWallpaperImgIneligible_logsFailure()649 public void testOnFullBackup_lockWallpaperImgIneligible_logsFailure() throws Exception { 650 when(mWallpaperManager.isWallpaperBackupEligible(eq(FLAG_LOCK))).thenReturn(false); 651 mockLockWallpaperFileWithContents("lock wallpaper"); 652 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 653 654 mWallpaperBackupAgent.onFullBackup(mOutput); 655 656 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, 657 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 658 assertThat(result).isNotNull(); 659 assertThat(result.getFailCount()).isEqualTo(1); 660 assertThat(result.getErrors()).containsKey(ERROR_INELIGIBLE); 661 } 662 663 @Test testOnFullBackup_lockWallpaperImgMissing_logsFailure()664 public void testOnFullBackup_lockWallpaperImgMissing_logsFailure() throws Exception { 665 mWallpaperBackupAgent.onFullBackup(mOutput); 666 667 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, 668 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 669 assertThat(result).isNotNull(); 670 assertThat(result.getFailCount()).isEqualTo(1); 671 assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); 672 } 673 674 @Test testOnFullBackup_lockWallpaperImgMissingButHasLiveComponent_logsLiveSuccess()675 public void testOnFullBackup_lockWallpaperImgMissingButHasLiveComponent_logsLiveSuccess() 676 throws Exception { 677 mockWallpaperInfoFileWithContents("info file"); 678 when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo()); 679 680 mWallpaperBackupAgent.onFullBackup(mOutput); 681 682 DataTypeResult result = getLoggingResult(WALLPAPER_LIVE_LOCK, 683 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 684 assertThat(result).isNotNull(); 685 assertThat(result.getSuccessCount()).isEqualTo(1); 686 assertThat(result.getMetadataHash()).isNotNull(); 687 } 688 689 @Test testOnFullBackup_lockWallpaperImgMissingButHasLiveComponent_logsNothingForImg()690 public void testOnFullBackup_lockWallpaperImgMissingButHasLiveComponent_logsNothingForImg() 691 throws Exception { 692 mockWallpaperInfoFileWithContents("info file"); 693 when(mWallpaperManager.getWallpaperInfo(anyInt())).thenReturn(getFakeWallpaperInfo()); 694 695 mWallpaperBackupAgent.onFullBackup(mOutput); 696 697 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, 698 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 699 assertThat(result).isNull(); 700 } 701 702 703 @Test testOnFullBackup_exceptionThrown_logsException()704 public void testOnFullBackup_exceptionThrown_logsException() throws Exception { 705 when(mWallpaperManager.isWallpaperBackupEligible(anyInt())).thenThrow( 706 new RuntimeException()); 707 mWallpaperBackupAgent.onFullBackup(mOutput); 708 709 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, 710 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 711 assertThat(result).isNotNull(); 712 assertThat(result.getFailCount()).isEqualTo(1); 713 assertThat(result.getErrors()).containsKey(RuntimeException.class.getName()); 714 } 715 716 @Test testOnFullBackup_lastBackupOverQuota_logsLockFailure()717 public void testOnFullBackup_lastBackupOverQuota_logsLockFailure() throws Exception { 718 mockSystemWallpaperFileWithContents("system wallpaper"); 719 mockLockWallpaperFileWithContents("lock wallpaper"); 720 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 721 markAgentAsOverQuota(); 722 723 mWallpaperBackupAgent.onFullBackup(mOutput); 724 725 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, 726 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 727 assertThat(result).isNotNull(); 728 assertThat(result.getFailCount()).isEqualTo(1); 729 assertThat(result.getErrors()).containsKey(ERROR_QUOTA_EXCEEDED); 730 } 731 732 @Test testOnFullBackup_lastBackupOverQuota_logsSystemSuccess()733 public void testOnFullBackup_lastBackupOverQuota_logsSystemSuccess() throws Exception { 734 mockSystemWallpaperFileWithContents("system wallpaper"); 735 mockLockWallpaperFileWithContents("lock wallpaper"); 736 mockCurrentWallpaperIds(TEST_SYSTEM_WALLPAPER_ID, TEST_LOCK_WALLPAPER_ID); 737 markAgentAsOverQuota(); 738 739 mWallpaperBackupAgent.onFullBackup(mOutput); 740 741 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 742 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 743 assertThat(result).isNotNull(); 744 assertThat(result.getSuccessCount()).isEqualTo(1); 745 } 746 747 @Test testOnRestore_wallpaperImgSuccess_logsSuccess()748 public void testOnRestore_wallpaperImgSuccess_logsSuccess() throws Exception { 749 mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); 750 mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); 751 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 752 BackupAnnotations.OperationType.RESTORE); 753 754 mWallpaperBackupAgent.onRestoreFinished(); 755 756 // wallpaper will be applied to home & lock screen, a success for both screens is expected 757 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 758 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 759 assertThat(result).isNotNull(); 760 assertThat(result.getSuccessCount()).isEqualTo(1); 761 762 result = getLoggingResult(WALLPAPER_IMG_LOCK, 763 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 764 assertThat(result).isNotNull(); 765 assertThat(result.getSuccessCount()).isEqualTo(1); 766 } 767 768 @Test testOnRestore_lockWallpaperImgSuccess_logsSuccess()769 public void testOnRestore_lockWallpaperImgSuccess_logsSuccess() throws Exception { 770 mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); 771 mockStagedWallpaperFile(LOCK_WALLPAPER_STAGE); 772 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 773 BackupAnnotations.OperationType.RESTORE); 774 775 mWallpaperBackupAgent.onRestoreFinished(); 776 777 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_LOCK, 778 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 779 assertThat(result).isNotNull(); 780 assertThat(result.getSuccessCount()).isEqualTo(1); 781 } 782 783 @Test testOnRestore_systemWallpaperImgMissingAndNoLive_logsFailure()784 public void testOnRestore_systemWallpaperImgMissingAndNoLive_logsFailure() throws Exception { 785 mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); 786 mockStagedWallpaperFile(LOCK_WALLPAPER_STAGE); 787 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 788 BackupAnnotations.OperationType.RESTORE); 789 790 mWallpaperBackupAgent.onRestoreFinished(); 791 792 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 793 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 794 assertThat(result).isNotNull(); 795 assertThat(result.getFailCount()).isEqualTo(1); 796 assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); 797 798 } 799 800 @Test testOnRestore_wallpaperImgMissingAndNoLive_logsFailure()801 public void testOnRestore_wallpaperImgMissingAndNoLive_logsFailure() throws Exception { 802 mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); 803 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 804 BackupAnnotations.OperationType.RESTORE); 805 806 mWallpaperBackupAgent.onRestoreFinished(); 807 808 for (String wallpaper: List.of(WALLPAPER_IMG_LOCK, WALLPAPER_IMG_SYSTEM)) { 809 DataTypeResult result = getLoggingResult(wallpaper, 810 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 811 assertThat(result).isNotNull(); 812 assertThat(result.getFailCount()).isEqualTo(1); 813 assertThat(result.getErrors()).containsKey(ERROR_NO_WALLPAPER); 814 } 815 } 816 817 @Test testOnRestore_wallpaperInfoMissing_logsFailure()818 public void testOnRestore_wallpaperInfoMissing_logsFailure() throws Exception { 819 mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); 820 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 821 BackupAnnotations.OperationType.RESTORE); 822 823 mWallpaperBackupAgent.onRestoreFinished(); 824 825 DataTypeResult result = getLoggingResult(WALLPAPER_IMG_SYSTEM, 826 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 827 assertThat(result).isNotNull(); 828 assertThat(result.getFailCount()).isEqualTo(1); 829 assertThat(result.getErrors()).containsKey(ERROR_NO_METADATA); 830 } 831 832 @Test testOnRestore_imgMissingButWallpaperInfoHasLive_doesNotLogImg()833 public void testOnRestore_imgMissingButWallpaperInfoHasLive_doesNotLogImg() throws Exception { 834 mockRestoredLiveWallpaperFile(); 835 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 836 BackupAnnotations.OperationType.RESTORE); 837 838 mWallpaperBackupAgent.onRestoreFinished(); 839 840 DataTypeResult system = getLoggingResult(WALLPAPER_IMG_SYSTEM, 841 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 842 DataTypeResult lock = getLoggingResult(WALLPAPER_IMG_LOCK, 843 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 844 assertThat(system).isNull(); 845 assertThat(lock).isNull(); 846 } 847 848 @Test testOnRestore_throwsException_logsErrors()849 public void testOnRestore_throwsException_logsErrors() throws Exception { 850 if (!multiCrop()) { 851 when(mWallpaperManager.setStream(any(), any(), anyBoolean(), anyInt())) 852 .thenThrow(new RuntimeException()); 853 } else { 854 when(mWallpaperManager.setStreamWithCrops(any(), any(SparseArray.class), anyBoolean(), 855 anyInt())).thenThrow(new RuntimeException()); 856 } 857 mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); 858 mockStagedWallpaperFile(WALLPAPER_INFO_STAGE); 859 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 860 BackupAnnotations.OperationType.RESTORE); 861 862 mWallpaperBackupAgent.onRestoreFinished(); 863 864 DataTypeResult system = getLoggingResult(WALLPAPER_IMG_SYSTEM, 865 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 866 DataTypeResult lock = getLoggingResult(WALLPAPER_IMG_LOCK, 867 mWallpaperBackupAgent.getBackupRestoreEventLogger().getLoggingResults()); 868 assertThat(system).isNotNull(); 869 assertThat(system.getFailCount()).isEqualTo(1); 870 assertThat(system.getErrors()).containsKey(RuntimeException.class.getName()); 871 assertThat(lock).isNotNull(); 872 assertThat(lock.getFailCount()).isEqualTo(1); 873 assertThat(lock.getErrors()).containsKey(RuntimeException.class.getName()); 874 } 875 876 @Test testUpdateWallpaperComponent_delayed_succeeds_logsSuccess()877 public void testUpdateWallpaperComponent_delayed_succeeds_logsSuccess() throws Exception { 878 mWallpaperBackupAgent.mIsDeviceInRestore = true; 879 when(mWallpaperManager.setWallpaperComponentWithFlags(any(), eq(FLAG_LOCK | FLAG_SYSTEM))) 880 .thenReturn(true); 881 BackupRestoreEventLogger logger = new BackupRestoreEventLogger( 882 BackupAnnotations.OperationType.RESTORE); 883 when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger); 884 mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); 885 886 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 887 /* which */ FLAG_LOCK | FLAG_SYSTEM); 888 // Imitate wallpaper component installation. 889 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 890 /* uid */0); 891 892 DataTypeResult system = getLoggingResult(WALLPAPER_LIVE_SYSTEM, logger.getLoggingResults()); 893 DataTypeResult lock = getLoggingResult(WALLPAPER_LIVE_LOCK, logger.getLoggingResults()); 894 assertThat(system).isNotNull(); 895 assertThat(system.getSuccessCount()).isEqualTo(1); 896 assertThat(lock).isNotNull(); 897 assertThat(lock.getSuccessCount()).isEqualTo(1); 898 } 899 900 901 @Test 902 @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testUpdateWallpaperDescription_delayed_succeeds_logsSuccess()903 public void testUpdateWallpaperDescription_delayed_succeeds_logsSuccess() throws Exception { 904 mWallpaperBackupAgent.mIsDeviceInRestore = true; 905 when(mWallpaperManager.setWallpaperComponentWithDescription(any(), 906 eq(FLAG_LOCK | FLAG_SYSTEM))).thenReturn(true); 907 BackupRestoreEventLogger logger = new BackupRestoreEventLogger( 908 BackupAnnotations.OperationType.RESTORE); 909 when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger); 910 mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); 911 912 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription), 913 /* which */ FLAG_LOCK | FLAG_SYSTEM); 914 // Imitate wallpaper component installation. 915 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 916 /* uid */0); 917 918 DataTypeResult system = getLoggingResult(WALLPAPER_DESCRIPTION_SYSTEM, 919 logger.getLoggingResults()); 920 DataTypeResult lock = getLoggingResult(WALLPAPER_DESCRIPTION_LOCK, 921 logger.getLoggingResults()); 922 assertThat(system).isNotNull(); 923 assertThat(system.getSuccessCount()).isEqualTo(1); 924 assertThat(lock).isNotNull(); 925 assertThat(lock.getSuccessCount()).isEqualTo(1); 926 } 927 928 @Test testUpdateWallpaperComponent_delayed_fails_logsFailure()929 public void testUpdateWallpaperComponent_delayed_fails_logsFailure() throws Exception { 930 mWallpaperBackupAgent.mIsDeviceInRestore = true; 931 BackupRestoreEventLogger logger = new BackupRestoreEventLogger( 932 BackupAnnotations.OperationType.RESTORE); 933 when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger); 934 mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); 935 936 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 937 /* which */ FLAG_LOCK | FLAG_SYSTEM); 938 // Imitate wallpaper component installation. 939 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 940 /* uid */0); 941 942 DataTypeResult system = getLoggingResult(WALLPAPER_LIVE_SYSTEM, logger.getLoggingResults()); 943 assertThat(system).isNotNull(); 944 assertThat(system.getFailCount()).isEqualTo(1); 945 assertThat(system.getErrors()).containsKey( 946 WallpaperEventLogger.ERROR_SET_COMPONENT_EXCEPTION); 947 } 948 949 @Test 950 @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING) testUpdateWallpaperDescription_delayed_fails_logsFailure()951 public void testUpdateWallpaperDescription_delayed_fails_logsFailure() throws Exception { 952 mWallpaperBackupAgent.mIsDeviceInRestore = true; 953 BackupRestoreEventLogger logger = new BackupRestoreEventLogger( 954 BackupAnnotations.OperationType.RESTORE); 955 when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger); 956 mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); 957 958 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription), 959 /* which */ FLAG_LOCK | FLAG_SYSTEM); 960 // Imitate wallpaper component installation. 961 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 962 /* uid */0); 963 964 DataTypeResult system = getLoggingResult(WALLPAPER_LIVE_SYSTEM, logger.getLoggingResults()); 965 assertThat(system).isNotNull(); 966 assertThat(system.getFailCount()).isEqualTo(1); 967 assertThat(system.getErrors()).containsKey( 968 WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION); 969 } 970 971 @Test testUpdateWallpaperComponent_delayed_packageNotInstalled_logsFailure()972 public void testUpdateWallpaperComponent_delayed_packageNotInstalled_logsFailure() 973 throws Exception { 974 mWallpaperBackupAgent.mIsDeviceInRestore = false; 975 BackupRestoreEventLogger logger = new BackupRestoreEventLogger( 976 BackupAnnotations.OperationType.RESTORE); 977 when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger); 978 mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager); 979 980 mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null), 981 /* which */ FLAG_LOCK | FLAG_SYSTEM); 982 983 // Imitate wallpaper component installation. 984 mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE, 985 /* uid */0); 986 987 DataTypeResult system = getLoggingResult(WALLPAPER_LIVE_SYSTEM, logger.getLoggingResults()); 988 DataTypeResult lock = getLoggingResult(WALLPAPER_LIVE_LOCK, logger.getLoggingResults()); 989 assertThat(system).isNotNull(); 990 assertThat(system.getFailCount()).isEqualTo(1); 991 assertThat(system.getErrors()).containsKey( 992 WallpaperEventLogger.ERROR_LIVE_PACKAGE_NOT_INSTALLED); 993 assertThat(lock).isNotNull(); 994 assertThat(lock.getFailCount()).isEqualTo(1); 995 assertThat(lock.getErrors()).containsKey( 996 WallpaperEventLogger.ERROR_LIVE_PACKAGE_NOT_INSTALLED); 997 } 998 999 @Test testOnRestore_noCropHints()1000 public void testOnRestore_noCropHints() throws Exception { 1001 testParseCropHints(Map.of()); 1002 } 1003 1004 @Test testOnRestore_singleCropHint()1005 public void testOnRestore_singleCropHint() throws Exception { 1006 Map<Integer, Rect> testMap = Map.of( 1007 WallpaperManager.ORIENTATION_PORTRAIT, new Rect(1, 2, 3, 4)); 1008 testParseCropHints(testMap); 1009 } 1010 1011 @Test testOnRestore_multipleCropHints()1012 public void testOnRestore_multipleCropHints() throws Exception { 1013 Map<Integer, Rect> testMap = Map.of( 1014 WallpaperManager.ORIENTATION_PORTRAIT, new Rect(1, 2, 3, 4), 1015 WallpaperManager.ORIENTATION_SQUARE_PORTRAIT, new Rect(5, 6, 7, 8), 1016 WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE, new Rect(9, 10, 11, 12)); 1017 testParseCropHints(testMap); 1018 } 1019 testParseCropHints(Map<Integer, Rect> testMap)1020 private void testParseCropHints(Map<Integer, Rect> testMap) throws Exception { 1021 assumeTrue(multiCrop()); 1022 mockRestoredStaticWallpaperFile(testMap); 1023 mockStagedWallpaperFile(SYSTEM_WALLPAPER_STAGE); 1024 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 1025 BackupAnnotations.OperationType.RESTORE); 1026 1027 mWallpaperBackupAgent.onRestoreFinished(); 1028 1029 ArgumentMatcher<SparseArray<Rect>> matcher = array -> { 1030 boolean result = testMap.entrySet().stream().allMatch(entry -> { 1031 int key = entry.getKey(); 1032 return (array.contains(key) && array.get(key).equals(testMap.get(key))); 1033 }); 1034 for (int i = 0; i < array.size(); i++) { 1035 if (!testMap.containsKey(array.keyAt(i))) result = false; 1036 } 1037 return result; 1038 }; 1039 verify(mWallpaperManager).setStreamWithCrops(any(), argThat(matcher), eq(true), anyInt()); 1040 } 1041 mockCurrentWallpaperIds(int systemWallpaperId, int lockWallpaperId)1042 private void mockCurrentWallpaperIds(int systemWallpaperId, int lockWallpaperId) { 1043 when(mWallpaperManager.getWallpaperId(eq(FLAG_SYSTEM))).thenReturn(systemWallpaperId); 1044 when(mWallpaperManager.getWallpaperId(eq(FLAG_LOCK))).thenReturn(lockWallpaperId); 1045 } 1046 createTemporaryFileWithContentString(String contents)1047 private File createTemporaryFileWithContentString(String contents) throws Exception { 1048 File file = mTemporaryFolder.newFile(); 1049 try (FileOutputStream outputStream = new FileOutputStream(file)) { 1050 outputStream.write(contents.getBytes()); 1051 } 1052 return file; 1053 } 1054 assertFileContentEquals(File file, String expected)1055 private void assertFileContentEquals(File file, String expected) throws Exception { 1056 try (FileInputStream inputStream = new FileInputStream(file)) { 1057 assertThat(new String(inputStream.readAllBytes())).isEqualTo(expected); 1058 } 1059 } 1060 getBackedUpFileOptional(String fileName)1061 private Optional<File> getBackedUpFileOptional(String fileName) { 1062 return mWallpaperBackupAgent.mBackedUpFiles.stream().filter( 1063 file -> file.getName().equals(fileName)).findFirst(); 1064 } 1065 mockWallpaperInfoFileWithContents(String contents)1066 private void mockWallpaperInfoFileWithContents(String contents) throws Exception { 1067 File fakeInfoFile = createTemporaryFileWithContentString(contents); 1068 when(mWallpaperManager.getWallpaperInfoFile()).thenReturn( 1069 ParcelFileDescriptor.open(fakeInfoFile, MODE_READ_ONLY)); 1070 } 1071 mockSystemWallpaperFileWithContents(String contents)1072 private void mockSystemWallpaperFileWithContents(String contents) throws Exception { 1073 File fakeSystemWallpaperFile = createTemporaryFileWithContentString(contents); 1074 when(mWallpaperManager.getWallpaperFile(eq(FLAG_SYSTEM), /* cropped = */ 1075 eq(false))).thenReturn( 1076 ParcelFileDescriptor.open(fakeSystemWallpaperFile, MODE_READ_ONLY)); 1077 } 1078 mockLockWallpaperFileWithContents(String contents)1079 private void mockLockWallpaperFileWithContents(String contents) throws Exception { 1080 File fakeLockWallpaperFile = createTemporaryFileWithContentString(contents); 1081 when(mWallpaperManager.getWallpaperFile(eq(FLAG_LOCK), /* cropped = */ 1082 eq(false))).thenReturn( 1083 ParcelFileDescriptor.open(fakeLockWallpaperFile, MODE_READ_ONLY)); 1084 } 1085 mockStagedWallpaperFile(String location)1086 private void mockStagedWallpaperFile(String location) throws Exception { 1087 File wallpaperFile = new File(mContext.getFilesDir(), location); 1088 wallpaperFile.createNewFile(); 1089 } 1090 mockRestoredLiveWallpaperFile()1091 private void mockRestoredLiveWallpaperFile() throws Exception { 1092 File wallpaperFile = new File(mContext.getFilesDir(), WALLPAPER_INFO_STAGE); 1093 wallpaperFile.createNewFile(); 1094 FileOutputStream fstream = new FileOutputStream(wallpaperFile, false); 1095 TypedXmlSerializer out = Xml.resolveSerializer(fstream); 1096 out.startDocument(null, true); 1097 out.startTag(null, "wp"); 1098 out.attribute(null, "component", 1099 getFakeWallpaperInfo().getComponent().flattenToShortString()); 1100 out.endTag(null, "wp"); 1101 out.endDocument(); 1102 fstream.flush(); 1103 FileUtils.sync(fstream); 1104 fstream.close(); 1105 } 1106 mockRestoredStaticWallpaperFile(Map<Integer, Rect> crops)1107 private void mockRestoredStaticWallpaperFile(Map<Integer, Rect> crops) throws Exception { 1108 File wallpaperFile = new File(mContext.getFilesDir(), WALLPAPER_INFO_STAGE); 1109 wallpaperFile.createNewFile(); 1110 FileOutputStream fstream = new FileOutputStream(wallpaperFile, false); 1111 TypedXmlSerializer out = Xml.resolveSerializer(fstream); 1112 out.startDocument(null, true); 1113 out.startTag(null, "wp"); 1114 for (Map.Entry<Integer, Rect> entry: crops.entrySet()) { 1115 String orientation = switch (entry.getKey()) { 1116 case WallpaperManager.ORIENTATION_PORTRAIT -> "Portrait"; 1117 case WallpaperManager.ORIENTATION_LANDSCAPE -> "Landscape"; 1118 case WallpaperManager.ORIENTATION_SQUARE_PORTRAIT -> "SquarePortrait"; 1119 case WallpaperManager.ORIENTATION_SQUARE_LANDSCAPE -> "SquareLandscape"; 1120 default -> throw new IllegalArgumentException("Invalid orientation"); 1121 }; 1122 Rect rect = entry.getValue(); 1123 out.attributeInt(null, "cropLeft" + orientation, rect.left); 1124 out.attributeInt(null, "cropTop" + orientation, rect.top); 1125 out.attributeInt(null, "cropRight" + orientation, rect.right); 1126 out.attributeInt(null, "cropBottom" + orientation, rect.bottom); 1127 } 1128 out.endTag(null, "wp"); 1129 out.endDocument(); 1130 fstream.flush(); 1131 FileUtils.sync(fstream); 1132 fstream.close(); 1133 } 1134 getFakeWallpaperInfo()1135 private WallpaperInfo getFakeWallpaperInfo() throws Exception { 1136 Context context = InstrumentationRegistry.getTargetContext(); 1137 Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); 1138 intent.setPackage("com.android.wallpaperbackup.tests"); 1139 PackageManager pm = context.getPackageManager(); 1140 List<ResolveInfo> result = pm.queryIntentServices(intent, PackageManager.GET_META_DATA); 1141 assertEquals(1, result.size()); 1142 ResolveInfo info = result.get(0); 1143 return new WallpaperInfo(context, info); 1144 } 1145 markAgentAsOverQuota()1146 private void markAgentAsOverQuota() throws Exception { 1147 // Create over quota file to indicate the last backup was over quota 1148 File quotaFile = new File(mContext.getFilesDir(), WallpaperBackupAgent.QUOTA_SENTINEL); 1149 quotaFile.createNewFile(); 1150 1151 // Now redo the setup of the agent to pick up the over quota 1152 mWallpaperBackupAgent.onCreate(USER_HANDLE, BackupAnnotations.BackupDestination.CLOUD, 1153 BackupAnnotations.OperationType.BACKUP); 1154 } 1155 getLoggingResult(String dataType, List<DataTypeResult> results)1156 private static DataTypeResult getLoggingResult(String dataType, List<DataTypeResult> results) { 1157 for (DataTypeResult result : results) { 1158 if ((result.getDataType()).equals(dataType)) { 1159 return result; 1160 } 1161 } 1162 return null; 1163 } 1164 1165 private class IsolatedWallpaperBackupAgent extends WallpaperBackupAgent { 1166 List<File> mBackedUpFiles = new ArrayList<>(); 1167 PackageMonitor mWallpaperPackageMonitor; 1168 boolean mIsDeviceInRestore = false; 1169 boolean mPackageExists = false; 1170 int mGetPackageMonitorCallCount = 0; 1171 1172 @Override backupFile(File file, FullBackupDataOutput data)1173 protected void backupFile(File file, FullBackupDataOutput data) { 1174 mBackedUpFiles.add(file); 1175 } 1176 1177 @Override servicePackageExists(ComponentName comp)1178 boolean servicePackageExists(ComponentName comp) { 1179 return mPackageExists; 1180 } 1181 1182 @Override isDeviceInRestore()1183 boolean isDeviceInRestore() { 1184 return mIsDeviceInRestore; 1185 } 1186 1187 @Override getWallpaperPackageMonitor(ComponentName componentName, WallpaperDescription description, int which)1188 PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, 1189 WallpaperDescription description, int which) { 1190 mGetPackageMonitorCallCount++; 1191 mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, description, 1192 which); 1193 return mWallpaperPackageMonitor; 1194 } 1195 1196 @Override getBaseContext()1197 public Context getBaseContext() { 1198 return mMockContext; 1199 } 1200 } 1201 } 1202