Home | History | Annotate | Download | only in deviceandprofileowner
      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 android.app.WallpaperManager;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.graphics.Bitmap;
     25 import android.os.Process;
     26 import android.os.UserHandle;
     27 import android.os.UserManager;
     28 import com.android.compatibility.common.util.BitmapUtils;
     29 
     30 import java.io.Closeable;
     31 import java.io.IOException;
     32 import java.lang.reflect.Method;
     33 import java.util.concurrent.ArrayBlockingQueue;
     34 import java.util.concurrent.BlockingQueue;
     35 import java.util.concurrent.TimeUnit;
     36 
     37 /**
     38  * These tests verify that the device / profile owner can use appropriate API for customization
     39  * (DevicePolicyManager.setUserIcon(), WallpaperManager.setBitmap(), etc.) even in case,
     40  * when appropriate restrictions are set. The tested restrictions are
     41  * {@link UserManager#DISALLOW_SET_WALLPAPER} and {@link UserManager#DISALLOW_SET_USER_ICON}.
     42  */
     43 public class CustomizationRestrictionsTest extends BaseDeviceAdminTest {
     44 
     45     private static final int BROADCAST_TIMEOUT_SEC = 3;
     46 
     47     // Class sets/resets restriction in try-with-resources statement.
     48     private class RestrictionApplicator implements Closeable {
     49         private final String mRestriction;
     50         RestrictionApplicator(String restriction) {
     51             mRestriction = restriction;
     52             mDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction);
     53         }
     54 
     55         @Override
     56         public void close() throws IOException {
     57             mDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT, mRestriction);
     58         }
     59     }
     60 
     61     // Class subscribes/unsubscribe for broadcast notification in try-with-resources statement.
     62     private class BroadcastReceiverRegistrator implements Closeable {
     63         private final BlockingBroadcastReceiver mReceiver;
     64         public BroadcastReceiverRegistrator(String action) {
     65             final IntentFilter filter = new IntentFilter();
     66             filter.addAction(action);
     67             mReceiver = new BlockingBroadcastReceiver();
     68             mContext.registerReceiver(mReceiver, filter);
     69         }
     70 
     71         @Override
     72         public void close() throws IOException {
     73             mContext.unregisterReceiver(mReceiver);
     74         }
     75 
     76         public void waitForBroadcast() throws Exception {
     77             mReceiver.waitForBroadcast();
     78         }
     79     }
     80 
     81     private class BlockingBroadcastReceiver extends BroadcastReceiver {
     82         private BlockingQueue<Integer> mQueue = new ArrayBlockingQueue<Integer> (1);
     83 
     84         @Override
     85         public void onReceive(Context context, Intent intent) {
     86             assertTrue(mQueue.add(0));
     87         }
     88 
     89         public void waitForBroadcast() throws Exception {
     90             Integer result = mQueue.poll(BROADCAST_TIMEOUT_SEC, TimeUnit.SECONDS);
     91             assertNotNull(result);
     92         }
     93     }
     94 
     95     private static int getUserId() throws Exception {
     96         UserHandle userHandle = Process.myUserHandle();
     97         Class<?>[] noParam = {};
     98         Class<?> userHandleClass = userHandle.getClass();
     99         Method methodGetIdentifier = userHandleClass.getDeclaredMethod("getIdentifier", noParam);
    100         return (Integer) methodGetIdentifier.invoke(userHandle, null);
    101     }
    102 
    103     private Bitmap getUserIcon() throws Exception {
    104         Class<?>[] paramInt = new Class[1];
    105         paramInt[0] = Integer.TYPE;
    106         Class<?> umClass = mUserManager.getClass();
    107         Method methodGetUserIcon = umClass.getDeclaredMethod("getUserIcon", paramInt);
    108         return (Bitmap) methodGetUserIcon.invoke(mUserManager, getUserId());
    109     }
    110 
    111     // The idea of testing is check if a DO/PO can set a wallpapper despite the
    112     // DISALLOW_SET_WALLPAPER restriction is set. But we can't use
    113     // pixel-by-pixel comparison of the reference bitmap (the bitmap we want to be a
    114     // wallpaper) and current wallpaper bitmap, because the reference bitmap can be
    115     // processed while setting (e.g. crop or scale), and getter may return us different
    116     // (but visually the same) Bitmap object. Thus in this test we check if the new
    117     // wallpaper is different from the old one after we ran a setter method.
    118     public void testDisallowSetWallpaper_allowed() throws Exception {
    119         final WallpaperManager wallpaperManager = WallpaperManager.getInstance(mContext);
    120         final Bitmap originalWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
    121         final Bitmap originalWallpaperCopy =
    122                 originalWallpaper.copy(originalWallpaper.getConfig(), false);
    123 
    124         try (
    125             // Set restriction and subscribe for the broadcast.
    126             final RestrictionApplicator restr =
    127                     new RestrictionApplicator(UserManager.DISALLOW_SET_WALLPAPER);
    128             final BroadcastReceiverRegistrator bcast =
    129                     new BroadcastReceiverRegistrator(Intent.ACTION_WALLPAPER_CHANGED);
    130         ) {
    131             assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER));
    132 
    133             // Checking setBitmap() method.
    134             Bitmap oldWallpaper = originalWallpaperCopy;
    135             wallpaperManager.setBitmap(BitmapUtils.generateRandomBitmap(97, 73));
    136             bcast.waitForBroadcast();
    137             Bitmap newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
    138             assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper));
    139 
    140             // Checking setStream() method.
    141             oldWallpaper = newWallpaper;
    142             final Bitmap wallpaperForStream = BitmapUtils.generateRandomBitmap(83, 69);
    143             wallpaperManager.setStream(BitmapUtils.bitmapToInputStream(wallpaperForStream));
    144             bcast.waitForBroadcast();
    145             newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
    146             assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper));
    147 
    148             // Checking setResource() method.
    149             oldWallpaper = newWallpaper;
    150             wallpaperManager.setResource(R.raw.wallpaper);
    151             bcast.waitForBroadcast();
    152             newWallpaper = BitmapUtils.getWallpaperBitmap(mContext);
    153             assertFalse(BitmapUtils.compareBitmaps(newWallpaper, oldWallpaper));
    154         } finally {
    155             wallpaperManager.setBitmap(originalWallpaperCopy);
    156         }
    157         assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_WALLPAPER));
    158     }
    159 
    160     // The idea behind this test is similar to testDisallowSetWallpaper_allowed
    161     public void testDisallowSetUserIcon_allowed() throws Exception {
    162         final Bitmap originalIcon = getUserIcon();
    163 
    164         try (
    165             // Apply restriction.
    166             final RestrictionApplicator restr =
    167                     new RestrictionApplicator(UserManager.DISALLOW_SET_USER_ICON);
    168         ) {
    169             assertTrue(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON));
    170             final Bitmap randomBmp = BitmapUtils.generateRandomBitmap(17, 31);
    171             mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT, randomBmp);
    172             final Bitmap currentIcon = getUserIcon();
    173             assertNotSame(randomBmp, currentIcon);
    174             assertFalse(BitmapUtils.compareBitmaps(originalIcon, currentIcon));
    175         } finally {
    176             if (originalIcon == null) {
    177                 // There is no way to restore absence of an icon. Thus set white
    178                 // icon for esthetic reasons.
    179                 mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT,
    180                         BitmapUtils.generateWhiteBitmap(20, 20));
    181             } else {
    182                 mDevicePolicyManager.setUserIcon(ADMIN_RECEIVER_COMPONENT, originalIcon);
    183             }
    184         }
    185         assertFalse(mUserManager.hasUserRestriction(UserManager.DISALLOW_SET_USER_ICON));
    186     }
    187 }
    188