1 /* 2 * Copyright (C) 2016 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.cts.deviceandprofileowner; 18 19 import static android.Manifest.permission.READ_WALLPAPER_INTERNAL; 20 21 import android.app.WallpaperManager; 22 import android.content.BroadcastReceiver; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.IntentFilter; 26 import android.graphics.Bitmap; 27 import android.os.UserManager; 28 29 import com.android.compatibility.common.util.BitmapUtils; 30 import com.android.compatibility.common.util.SystemUtil; 31 32 import java.io.Closeable; 33 import java.io.IOException; 34 import java.util.concurrent.ArrayBlockingQueue; 35 import java.util.concurrent.BlockingQueue; 36 import java.util.concurrent.TimeUnit; 37 38 /** 39 * These tests verify that the device / profile owner can use appropriate API for customization 40 * (DevicePolicyManager.setUserIcon(), WallpaperManager.setBitmap(), etc.) even in case, 41 * when appropriate restrictions are set. The tested restrictions are 42 * {@link UserManager#DISALLOW_SET_WALLPAPER} and {@link UserManager#DISALLOW_SET_USER_ICON}. 43 */ 44 public class CustomizationRestrictionsTest extends BaseDeviceAdminTest { 45 46 private static final int BROADCAST_TIMEOUT_SEC = 3; 47 48 // Class sets/resets restriction in try-with-resources statement. 49 private class RestrictionApplicator implements Closeable { 50 private final String mRestriction; 51 RestrictionApplicator(String restriction)52 RestrictionApplicator(String restriction) { 53 mRestriction = restriction; 54 mLocalDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction); 55 mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction); 56 } 57 58 @Override close()59 public void close() throws IOException { 60 mLocalDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction); 61 mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction); 62 } 63 } 64 65 // Class subscribes/unsubscribe for broadcast notification in try-with-resources statement. 66 private class BroadcastReceiverRegistrator implements Closeable { 67 private final BlockingBroadcastReceiver mReceiver; 68 BroadcastReceiverRegistrator(String action)69 public BroadcastReceiverRegistrator(String action) { 70 final IntentFilter filter = new IntentFilter(); 71 filter.addAction(action); 72 mReceiver = new BlockingBroadcastReceiver(); 73 mContext.registerReceiver(mReceiver, filter); 74 } 75 76 @Override close()77 public void close() throws IOException { 78 mContext.unregisterReceiver(mReceiver); 79 } 80 waitForBroadcast()81 public void waitForBroadcast() throws Exception { 82 mReceiver.waitForBroadcast(); 83 } 84 } 85 86 private class BlockingBroadcastReceiver extends BroadcastReceiver { 87 private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer>(1); 88 89 @Override onReceive(Context context, Intent intent)90 public void onReceive(Context context, Intent intent) { 91 assertTrue(mQueue.add(0)); 92 } 93 waitForBroadcast()94 public void waitForBroadcast() throws Exception { 95 Integer result = mQueue.poll(BROADCAST_TIMEOUT_SEC, TimeUnit.SECONDS); 96 assertNotNull(result); 97 } 98 } 99 100 // The idea of testing is check if a DO/PO can set a wallpapper despite the 101 // DISALLOW_SET_WALLPAPER restriction is set. But we can't use 102 // pixel-by-pixel comparison of the reference bitmap (the bitmap we want to be a 103 // wallpaper) and current wallpaper bitmap, because the reference bitmap can be 104 // processed while setting (e.g. crop or scale), and getter may return us different 105 // (but visually the same) Bitmap object. Thus in this test we check if the new 106 // wallpaper is different from the old one after we ran a setter method. testDisallowSetWallpaper_allowed()107 public void testDisallowSetWallpaper_allowed() throws Exception { 108 final WallpaperManager wallpaperManager = WallpaperManager.getInstance(mContext); 109 final Bitmap originalWallpaper = getWallpaperBitmapWithPermission(); 110 final Bitmap originalWallpaperCopy = 111 originalWallpaper.copy(originalWallpaper.getConfig(), false); 112 113 try ( 114 // Set restriction and subscribe for the broadcast. 115 final RestrictionApplicator restr = 116 new RestrictionApplicator(UserManager.DISALLOW_SET_WALLPAPER); 117 final BroadcastReceiverRegistrator bcast = 118 new BroadcastReceiverRegistrator(Intent.ACTION_WALLPAPER_CHANGED); 119 ) { 120 assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER)); 121 122 // Checking setBitmap() method. 123 Bitmap oldWallpaper = originalWallpaperCopy; 124 wallpaperManager.setBitmap(BitmapUtils.generateRandomBitmap(97, 73)); 125 bcast.waitForBroadcast(); 126 Bitmap newWallpaper = getWallpaperBitmapWithPermission(); 127 assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper)); 128 129 // Checking setStream() method. 130 oldWallpaper = newWallpaper; 131 final Bitmap wallpaperForStream = BitmapUtils.generateRandomBitmap(83, 69); 132 wallpaperManager.setStream(BitmapUtils.bitmapToInputStream(wallpaperForStream)); 133 bcast.waitForBroadcast(); 134 newWallpaper = getWallpaperBitmapWithPermission(); 135 assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper)); 136 137 // Checking setResource() method. 138 oldWallpaper = newWallpaper; 139 wallpaperManager.setResource(R.raw.wallpaper); 140 bcast.waitForBroadcast(); 141 newWallpaper = getWallpaperBitmapWithPermission(); 142 assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper)); 143 } finally { 144 wallpaperManager.setBitmap(originalWallpaperCopy); 145 } 146 assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER)); 147 } 148 getWallpaperBitmapWithPermission()149 private Bitmap getWallpaperBitmapWithPermission() { 150 return SystemUtil.runWithShellPermissionIdentity( 151 () -> BitmapUtils.getWallpaperBitmap(mContext), READ_WALLPAPER_INTERNAL); 152 } 153 } 154