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.QUERY_ALL_PACKAGES; 20 import static android.Manifest.permission.READ_WALLPAPER_INTERNAL; 21 import static android.app.WallpaperManager.FLAG_LOCK; 22 import static android.app.WallpaperManager.FLAG_SYSTEM; 23 import static android.app.cts.wallpapers.util.WallpaperTestUtils.getBitmap; 24 import static android.app.cts.wallpapers.util.WallpaperTestUtils.isSimilar; 25 26 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 27 28 import static com.google.common.truth.Truth.assertWithMessage; 29 30 import static org.junit.Assume.assumeFalse; 31 import static org.junit.Assume.assumeTrue; 32 33 import android.app.WallpaperManager; 34 import android.content.Context; 35 import android.content.pm.PackageManager; 36 import android.graphics.Bitmap; 37 import android.graphics.BitmapFactory; 38 import android.graphics.Canvas; 39 import android.graphics.Color; 40 import android.graphics.drawable.Drawable; 41 import android.os.ParcelFileDescriptor; 42 43 import androidx.test.InstrumentationRegistry; 44 import androidx.test.runner.AndroidJUnit4; 45 46 import org.junit.AfterClass; 47 import org.junit.Before; 48 import org.junit.BeforeClass; 49 import org.junit.Test; 50 import org.junit.runner.RunWith; 51 import org.mockito.MockitoAnnotations; 52 53 import java.io.IOException; 54 import java.util.function.Supplier; 55 56 /** 57 * Tests for {@link WallpaperManager} and related classes for target SDK 33. 58 * This tests that for API U and above, 59 * apps that target SDK 33 will receive data from the default wallpaper 60 * when trying to read the wallpaper through the public API, except if the app has the permission 61 * {@value android.Manifest.permission#READ_WALLPAPER_INTERNAL}. 62 * 63 * <p> 64 * See the different test cases to see which methods are concerned. 65 * </p> 66 */ 67 @RunWith(AndroidJUnit4.class) 68 public class WallpaperManagerSdk33Test { 69 70 private static WallpaperManager sWallpaperManager; 71 private static Bitmap sDefaultBitmap; 72 private static Bitmap sRedBitmap; 73 private static boolean sTvTarget; 74 75 /** 76 * Note: all tests in this class assume to start with a red bitmap on both system & lock screen. 77 * As changing the wallpaper takes time, this initialization is only done here 78 * and not in {@link #setUp}, since doing so would slow down the test suite substantially. 79 * Tests that change the wallpaper are responsible to restore the red wallpaper 80 * with {@link #setRedWallpaper()} when finished. 81 */ 82 @BeforeClass setUpClass()83 public static void setUpClass() throws IOException { 84 Context context = InstrumentationRegistry.getTargetContext(); 85 86 // ignore for TV targets 87 PackageManager packageManager = context.getPackageManager(); 88 sTvTarget = packageManager != null 89 && (packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) 90 || packageManager.hasSystemFeature(PackageManager.FEATURE_TELEVISION)); 91 if (sTvTarget) return; 92 93 sWallpaperManager = WallpaperManager.getInstance(context); 94 sWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK); 95 96 // ignore for targets that have a live default wallpaper 97 runWithShellPermissionIdentity( 98 () -> assumeTrue(sWallpaperManager.getWallpaperInfo(FLAG_SYSTEM) == null), 99 QUERY_ALL_PACKAGES); 100 101 sDefaultBitmap = runWithShellPermissionIdentity( 102 () -> sWallpaperManager.getBitmap(), READ_WALLPAPER_INTERNAL); 103 104 sRedBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); 105 Canvas canvas = new Canvas(sRedBitmap); 106 canvas.drawColor(Color.RED); 107 setRedWallpaper(); 108 } 109 110 @Before setUp()111 public void setUp() throws Exception { 112 assumeFalse("WallpaperManagerSdk33Test is not meaningful for TV targets", sTvTarget); 113 assumeTrue("Device does not support wallpapers", sWallpaperManager.isWallpaperSupported()); 114 MockitoAnnotations.initMocks(this); 115 } 116 117 @AfterClass tearDownClass()118 public static void tearDownClass() throws IOException { 119 if (sRedBitmap != null && !sRedBitmap.isRecycled()) sRedBitmap.recycle(); 120 if (sWallpaperManager != null) sWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK); 121 sWallpaperManager = null; 122 } 123 124 @Test getDrawable_noPermission_returnsDefault()125 public void getDrawable_noPermission_returnsDefault() { 126 assertReturnsDefault(sWallpaperManager::getDrawable, "getDrawable"); 127 } 128 129 @Test getDrawable_withPermission_returnsCurrent()130 public void getDrawable_withPermission_returnsCurrent() { 131 assertReturnsCurrent(sWallpaperManager::getDrawable, "getDrawable"); 132 } 133 134 @Test getFastDrawable_noPermission_returnsDefault()135 public void getFastDrawable_noPermission_returnsDefault() { 136 assertReturnsDefault(sWallpaperManager::getFastDrawable, "getFastDrawable"); 137 } 138 139 @Test getFastDrawable_withPermission_returnsCurrent()140 public void getFastDrawable_withPermission_returnsCurrent() { 141 assertReturnsCurrent(sWallpaperManager::getFastDrawable, "getFastDrawable"); 142 } 143 144 @Test peekDrawable_noPermission_returnsDefault()145 public void peekDrawable_noPermission_returnsDefault() { 146 assertReturnsDefault(sWallpaperManager::peekDrawable, "peekDrawable"); 147 } 148 149 @Test peekDrawable_withPermission_returnsCurrent()150 public void peekDrawable_withPermission_returnsCurrent() { 151 assertReturnsCurrent(sWallpaperManager::peekDrawable, "peekDrawable"); 152 } 153 154 @Test peekFastDrawable_noPermission_returnsDefault()155 public void peekFastDrawable_noPermission_returnsDefault() { 156 assertReturnsDefault(sWallpaperManager::peekFastDrawable, "peekFastDrawable"); 157 } 158 159 @Test peekFastDrawable_withPermission_returnsCurrent()160 public void peekFastDrawable_withPermission_returnsCurrent() { 161 assertReturnsCurrent(sWallpaperManager::peekFastDrawable, "peekFastDrawable"); 162 } 163 164 @Test getWallpaperFile_system_noPermission_returnsDefault()165 public void getWallpaperFile_system_noPermission_returnsDefault() { 166 ParcelFileDescriptor parcelFileDescriptor = sWallpaperManager.getWallpaperFile(FLAG_SYSTEM); 167 if (parcelFileDescriptor != null) { 168 Bitmap bitmap = BitmapFactory.decodeFileDescriptor( 169 parcelFileDescriptor.getFileDescriptor()); 170 assertWithMessage( 171 "with no permission, getWallpaperFile(FLAG_SYSTEM) " 172 + "should return the default system wallpaper file") 173 .that(isSimilar(bitmap, sDefaultBitmap, false)) 174 .isTrue(); 175 } 176 } 177 178 @Test getWallpaperFile_lock_noPermission_returnsDefault()179 public void getWallpaperFile_lock_noPermission_returnsDefault() throws IOException { 180 sWallpaperManager.setBitmap(sRedBitmap, null, true, FLAG_LOCK); 181 ParcelFileDescriptor parcelFileDescriptor = sWallpaperManager.getWallpaperFile(FLAG_LOCK); 182 sWallpaperManager.clear(FLAG_SYSTEM | FLAG_LOCK); 183 try { 184 if (parcelFileDescriptor != null) { 185 Bitmap bitmap = BitmapFactory.decodeFileDescriptor( 186 parcelFileDescriptor.getFileDescriptor()); 187 assertWithMessage( 188 "with no permission, getWallpaperFile(FLAG_LOCK) " 189 + "should return the default system wallpaper file") 190 .that(isSimilar(bitmap, sDefaultBitmap, false)) 191 .isTrue(); 192 } 193 } finally { 194 setRedWallpaper(); 195 } 196 } 197 198 @Test getWallpaperFile_system_withPermission_returnsCurrent()199 public void getWallpaperFile_system_withPermission_returnsCurrent() { 200 ParcelFileDescriptor parcelFileDescriptor = runWithShellPermissionIdentity( 201 () -> sWallpaperManager.getWallpaperFile(FLAG_SYSTEM), READ_WALLPAPER_INTERNAL); 202 Bitmap bitmap = BitmapFactory.decodeFileDescriptor( 203 parcelFileDescriptor.getFileDescriptor()); 204 assertWithMessage( 205 "with permission, getWallpaperFile(FLAG_SYSTEM)" 206 + "should return the currennt system wallpaper file") 207 .that(isSimilar(bitmap, sRedBitmap, true)) 208 .isTrue(); 209 } 210 211 @Test getWallpaperFile_lock_withPermission_doesNotReturnDefault()212 public void getWallpaperFile_lock_withPermission_doesNotReturnDefault() throws IOException { 213 sWallpaperManager.setBitmap(sRedBitmap, null, true, FLAG_LOCK); 214 ParcelFileDescriptor parcelFileDescriptor = runWithShellPermissionIdentity( 215 () -> sWallpaperManager.getWallpaperFile(FLAG_LOCK), READ_WALLPAPER_INTERNAL); 216 try { 217 if (parcelFileDescriptor != null) { 218 Bitmap bitmap = BitmapFactory.decodeFileDescriptor( 219 parcelFileDescriptor.getFileDescriptor()); 220 assertWithMessage( 221 "with permission, getWallpaperFile(FLAG_LOCK)" 222 + "should not return the default system wallpaper") 223 .that(isSimilar(bitmap, sDefaultBitmap, true)) 224 .isFalse(); 225 } 226 } finally { 227 setRedWallpaper(); 228 } 229 } 230 assertReturnsDefault(Supplier<Drawable> methodToTest, String methodName)231 private void assertReturnsDefault(Supplier<Drawable> methodToTest, String methodName) { 232 Drawable drawable = methodToTest.get(); 233 assertWithMessage( 234 "with no permission, " + methodName + " should return null or the default bitmap") 235 .that(drawable == null || isSimilar(getBitmap(drawable), sDefaultBitmap, false)) 236 .isTrue(); 237 } 238 assertReturnsCurrent(Supplier<Drawable> methodToTest, String methodName)239 private void assertReturnsCurrent(Supplier<Drawable> methodToTest, String methodName) { 240 Drawable drawable = runWithShellPermissionIdentity( 241 () -> methodToTest.get(), READ_WALLPAPER_INTERNAL); 242 assertWithMessage( 243 "with permission, " + methodName + " should return the current bitmap") 244 .that(isSimilar(getBitmap(drawable), sRedBitmap, true)).isTrue(); 245 } 246 setRedWallpaper()247 private static void setRedWallpaper() throws IOException { 248 sWallpaperManager.setBitmap(sRedBitmap, 249 null /* visibleCropHint= */, 250 true /* allowBackup */, 251 FLAG_SYSTEM | FLAG_LOCK /* which */); 252 } 253 } 254