blob: 021aace70805d67d24edefaeb3fb932525fd6917 [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.cts.deviceandprofileowner;
import android.app.WallpaperManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
import android.cts.util.BitmapUtils;
import com.android.cts.deviceandprofileowner.R;
import java.io.Closeable;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* These tests verify that the device / profile owner can use appropriate API for customization
* (DevicePolicyManager.setUserIcon(), WallpaperManager.setBitmap(), etc.) even in case,
* when appropriate restrictions are set. The tested restrictions are
* {@link UserManager#DISALLOW_SET_WALLPAPER} and {@link UserManager#DISALLOW_SET_USER_ICON}.
*/
public class CustomizationRestrictionsTest extends BaseDeviceAdminTest {
private static final int BROADCAST_TIMEOUT_SEC = 3;
// Class sets/resets restriction in try-with-resources statement.
private class RestrictionApplicator implements Closeable {
private final String mRestriction;
RestrictionApplicator(String restriction) {
mRestriction = restriction;
mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction);
}
@Override
public void close() throws IOException {
mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction);
}
}
// Class subscribes/unsubscribe for broadcast notification in try-with-resources statement.
private class BroadcastReceiverRegistrator implements Closeable {
private final BlockingBroadcastReceiver mReceiver;
public BroadcastReceiverRegistrator(String action) {
final IntentFilter filter = new IntentFilter();
filter.addAction(action);
mReceiver = new BlockingBroadcastReceiver();
mContext.registerReceiver(mReceiver, filter);
}
@Override
public void close() throws IOException {
mContext.unregisterReceiver(mReceiver);
}
public void waitForBroadcast() throws Exception {
mReceiver.waitForBroadcast();
}
}
private class BlockingBroadcastReceiver extends BroadcastReceiver {
private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer> (1);
@Override
public void onReceive(Context context, Intent intent) {
assertTrue(mQueue.add(0));
}
public void waitForBroadcast() throws Exception {
Integer result = mQueue.poll(BROADCAST_TIMEOUT_SEC, TimeUnit.SECONDS);
assertNotNull(result);
}
}
private static int getUserId() throws Exception {
UserHandle userHandle = Process.myUserHandle();
Class<?>[] noParam = {};
Class<?> userHandleClass = userHandle.getClass();
Method methodGetIdentifier = userHandleClass.getDeclaredMethod("getIdentifier", noParam);
return (Integer) methodGetIdentifier.invoke(userHandle, null);
}
private Bitmap getUserIcon() throws Exception {
Class<?>[] paramInt = new Class[1];
paramInt[0] = Integer.TYPE;
Class<?> umClass = mUserManager.getClass();
Method methodGetUserIcon = umClass.getDeclaredMethod("getUserIcon", paramInt);
return (Bitmap) methodGetUserIcon.invoke(mUserManager, getUserId());
}
// The idea of testing is check if a DO/PO can set a wallpapper despite the
// DISALLOW_SET_WALLPAPER restriction is set. But we can't use
// pixel-by-pixel comparison of the reference bitmap (the bitmap we want to be a
// wallpaper) and current wallpaper bitmap, because the reference bitmap can be
// processed while setting (e.g. crop or scale), and getter may return us different
// (but visually the same) Bitmap object. Thus in this test we check if the new
// wallpaper is different from the old one after we ran a setter method.
public void testDisallowSetWallpaper_allowed() throws Exception {
final WallpaperManager wallpaperManager = WallpaperManager.getInstance(mContext);
final Bitmap originalWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
try (
// Set restriction and subscribe for the broadcast.
final RestrictionApplicator restr =
new RestrictionApplicator(UserManager.DISALLOW_SET_WALLPAPER);
final BroadcastReceiverRegistrator bcast =
new BroadcastReceiverRegistrator(Intent.ACTION_WALLPAPER_CHANGED);
) {
assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER));
// Checking setBitmap() method.
Bitmap oldWallpaper = originalWallpaper;
wallpaperManager.setBitmap(BitmapUtils.generateRandomBitmap(97, 73));
bcast.waitForBroadcast();
Bitmap newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper));
// Checking setStream() method.
oldWallpaper = newWallpaper;
final Bitmap wallpaperForStream = BitmapUtils.generateRandomBitmap(83, 69);
wallpaperManager.setStream(BitmapUtils.bitmapToInputStream(wallpaperForStream));
bcast.waitForBroadcast();
newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper));
// Checking setResource() method.
oldWallpaper = newWallpaper;
wallpaperManager.setResource(R.raw.wallpaper);
bcast.waitForBroadcast();
newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper));
} finally {
wallpaperManager.setBitmap(originalWallpaper);
}
assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER));
}
// The idea behind this test is similar to testDisallowSetWallpaper_allowed
public void testDisallowSetUserIcon_allowed() throws Exception {
final Bitmap originalIcon = getUserIcon();
try (
// Apply restriction.
final RestrictionApplicator restr =
new RestrictionApplicator(UserManager.DISALLOW_SET_USER_ICON);
) {
assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON));
final Bitmap randomBmp = BitmapUtils.generateRandomBitmap(17, 31);
mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT, randomBmp);
final Bitmap currentIcon = getUserIcon();
assertNotSame(randomBmp, currentIcon);
assertFalse(BitmapUtils.compareBitmaps(originalIcon, currentIcon));
} finally {
if (originalIcon == null) {
// There is no way to restore absence of an icon. Thus set white
// icon for esthetic reasons.
mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT,
BitmapUtils.generateWhiteBitmap(20, 20));
} else {
mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT, originalIcon);
}
}
assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON));
}
}