1 /* 2 * Copyright (C) 2023 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 package com.android.wallpaper.module; 17 18 import static android.app.WallpaperManager.FLAG_LOCK; 19 import static android.app.WallpaperManager.FLAG_SYSTEM; 20 21 import static com.android.wallpaper.module.WallpaperPersister.DEST_BOTH; 22 23 import static com.google.common.truth.Truth.assertThat; 24 25 import static org.mockito.Mockito.doReturn; 26 import static org.mockito.Mockito.spy; 27 import static org.robolectric.shadows.ShadowLooper.shadowMainLooper; 28 29 import android.app.WallpaperManager; 30 import android.content.Context; 31 import android.graphics.drawable.BitmapDrawable; 32 import android.util.Log; 33 34 import androidx.annotation.Nullable; 35 import androidx.test.platform.app.InstrumentationRegistry; 36 37 import com.android.wallpaper.model.WallpaperInfo; 38 import com.android.wallpaper.module.DefaultWallpaperPersisterTest.TestSetWallpaperCallback.SetWallpaperStatus; 39 import com.android.wallpaper.module.WallpaperPersister.SetWallpaperCallback; 40 import com.android.wallpaper.testing.TestAsset; 41 import com.android.wallpaper.testing.TestBitmapCropper; 42 import com.android.wallpaper.testing.TestStaticWallpaperInfo; 43 import com.android.wallpaper.testing.TestWallpaperPreferences; 44 import com.android.wallpaper.testing.TestWallpaperStatusChecker; 45 import com.android.wallpaper.util.DisplayUtils; 46 47 import org.junit.Before; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.robolectric.RobolectricTestRunner; 51 import org.robolectric.android.util.concurrent.PausedExecutorService; 52 import org.robolectric.shadows.ShadowPausedAsyncTask; 53 54 import java.util.ArrayList; 55 import java.util.List; 56 57 @RunWith(RobolectricTestRunner.class) 58 public class DefaultWallpaperPersisterTest { 59 private static final String TAG = "DefaultWallpaperPersisterTest"; 60 private static final String ACTION_URL = "http://google.com"; 61 62 private Context mContext; 63 /** DefaultWallpaperPersister object under test */ 64 private DefaultWallpaperPersister mPersister; 65 /** Spy on real WallpaperManager instance */ 66 private WallpaperManager mManager; 67 /** Fake instance of WallpaperPreferences */ 68 private TestWallpaperPreferences mPrefs; 69 /** Executor to use for AsyncTask */ 70 private final PausedExecutorService mPausedExecutor = new PausedExecutorService(); 71 72 @Before setUp()73 public void setUp() { 74 mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 75 mManager = spy(WallpaperManager.getInstance(mContext)); 76 mPrefs = new TestWallpaperPreferences(); 77 WallpaperChangedNotifier changedNotifier = spy(WallpaperChangedNotifier.getInstance()); 78 DisplayUtils displayUtils = new DisplayUtils(mContext); 79 TestBitmapCropper cropper = new TestBitmapCropper(); 80 TestWallpaperStatusChecker statusChecker = new TestWallpaperStatusChecker(); 81 82 mPersister = new DefaultWallpaperPersister(mContext, mManager, mPrefs, changedNotifier, 83 displayUtils, cropper, statusChecker, false); 84 } 85 86 @Test isSeparateLockScreenWallpaperSet_trueIfSet()87 public void isSeparateLockScreenWallpaperSet_trueIfSet() { 88 doReturn(-1).when(mManager).getWallpaperId(FLAG_LOCK); 89 90 assertThat(mPersister.getDefaultWhichWallpaper()).isEqualTo(FLAG_SYSTEM | FLAG_LOCK); 91 } 92 93 @Test isSeparateLockScreenWallpaperSet_falseIfUnset()94 public void isSeparateLockScreenWallpaperSet_falseIfUnset() { 95 doReturn(1).when(mManager).getWallpaperId(FLAG_LOCK); 96 97 assertThat(mPersister.getDefaultWhichWallpaper()).isEqualTo(FLAG_SYSTEM); 98 } 99 100 @Test setBitmapWallpaper_succeeds()101 public void setBitmapWallpaper_succeeds() { 102 TestStaticWallpaperInfo wallpaperInfo = newStaticWallpaperInfo(); 103 prepareWallpaperSetFromInfo(wallpaperInfo); 104 TestSetWallpaperCallback callback = new TestSetWallpaperCallback(); 105 106 mPersister.setIndividualWallpaper(wallpaperInfo, wallpaperInfo.getAsset(mContext), null, 107 1.0f, DEST_BOTH, callback); 108 109 verifyWallpaperSetSuccess(callback); 110 } 111 112 @Test setBitmapWallpaper_setsActionUrl()113 public void setBitmapWallpaper_setsActionUrl() { 114 TestStaticWallpaperInfo wallpaperInfo = newStaticWallpaperInfo(); 115 prepareWallpaperSetFromInfo(wallpaperInfo); 116 TestSetWallpaperCallback callback = new TestSetWallpaperCallback(); 117 118 mPersister.setIndividualWallpaper(wallpaperInfo, wallpaperInfo.getAsset(mContext), null, 119 1.0f, DEST_BOTH, callback); 120 121 verifyWallpaperSetSuccess(callback); 122 assertThat(mPrefs.getHomeWallpaperActionUrl()).isEqualTo(ACTION_URL); 123 assertThat(mPrefs.getLockWallpaperActionUrl()).isEqualTo(ACTION_URL); 124 } 125 126 // Creates a basic test wallpaper info instance. newStaticWallpaperInfo()127 private static TestStaticWallpaperInfo newStaticWallpaperInfo() { 128 List<String> attributions = new ArrayList<>(); 129 attributions.add("Title"); 130 attributions.add("Subtitle 1"); 131 attributions.add("Subtitle 2"); 132 TestStaticWallpaperInfo wallpaperInfo = new TestStaticWallpaperInfo( 133 TestStaticWallpaperInfo.COLOR_DEFAULT); 134 wallpaperInfo.setAttributions(attributions); 135 wallpaperInfo.setCollectionId("collectionStatic"); 136 wallpaperInfo.setWallpaperId("wallpaperStatic"); 137 wallpaperInfo.setActionUrl(ACTION_URL); 138 return wallpaperInfo; 139 } 140 141 // Call this method to prepare for a call to setIndividualWallpaper with non-streamable bitmap. prepareWallpaperSetFromInfo(TestStaticWallpaperInfo wallpaperInfo)142 private void prepareWallpaperSetFromInfo(TestStaticWallpaperInfo wallpaperInfo) { 143 // Retrieve the bitmap to be set by the given WallpaperInfo, and override the return value 144 // from WallpaperManager.getDrawable(). 145 TestAsset asset = (TestAsset) wallpaperInfo.getAsset(mContext); 146 doReturn(new BitmapDrawable(mContext.getResources(), asset.getBitmap())).when(mManager) 147 .getDrawable(); 148 // Override the background executor for AsyncTask to that we can explicitly execute its 149 // tasks - otherwise this will remain in the queue even after main looper idle. 150 ShadowPausedAsyncTask.overrideExecutor(mPausedExecutor); 151 } 152 verifyWallpaperSetSuccess(TestSetWallpaperCallback callback)153 private void verifyWallpaperSetSuccess(TestSetWallpaperCallback callback) { 154 // Execute pending Asset#decodeBitmap; queues SetWallpaperTask background job 155 shadowMainLooper().idle(); 156 // Execute SetWallpaperTask background job; queues onPostExecute on main thread 157 mPausedExecutor.runAll(); 158 // Execute SetWallpaperTask#onPostExecute 159 shadowMainLooper().idle(); 160 161 assertThat(callback.getStatus()).isEqualTo(SetWallpaperStatus.SUCCESS); 162 } 163 164 /** 165 * Simple wallpaper callback to either record success or log on failure. 166 */ 167 static class TestSetWallpaperCallback implements SetWallpaperCallback { 168 enum SetWallpaperStatus { 169 UNCALLED, 170 SUCCESS, 171 FAILURE 172 } 173 SetWallpaperStatus mStatus = SetWallpaperStatus.UNCALLED; 174 @Override onSuccess(WallpaperInfo wallpaperInfo, int destination)175 public void onSuccess(WallpaperInfo wallpaperInfo, int destination) { 176 mStatus = SetWallpaperStatus.SUCCESS; 177 } 178 179 @Override onError(@ullable Throwable throwable)180 public void onError(@Nullable Throwable throwable) { 181 mStatus = SetWallpaperStatus.FAILURE; 182 Log.e(TAG, "Set wallpaper failed", throwable); 183 } 184 getStatus()185 public SetWallpaperStatus getStatus() { 186 return mStatus; 187 } 188 } 189 } 190