Home | History | Annotate | Download | only in managedprofile
      1 /*
      2  * Copyright (C) 2017 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.cts.managedprofile;
     17 
     18 
     19 import android.bluetooth.BluetoothAdapter;
     20 import android.content.ComponentName;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.pm.ComponentInfo;
     24 import android.content.pm.PackageManager;
     25 import android.content.pm.ResolveInfo;
     26 import android.net.Uri;
     27 import android.os.SystemClock;
     28 import android.os.UserManager;
     29 
     30 import junit.framework.TestCase;
     31 
     32 import java.util.List;
     33 
     34 
     35 /**
     36  * Test {@link UserManager#DISALLOW_BLUETOOTH_SHARING} in profile owner.
     37  *
     38  * Shamelessly copied from BluetoothRestrictionTest, would be nice to extract common stuff to a lib.
     39  */
     40 public class BluetoothSharingRestrictionTest extends BaseManagedProfileTest {
     41     /** How long should we wait for the component state to change. */
     42     private static final int COMPONENT_STATE_TIMEOUT_MS = 2000;
     43     /** How often to check component state. */
     44     private static final int POLL_TIME_MS = 400;
     45     /** Activity that handles Bluetooth sharing. */
     46     private static final ComponentName OPP_LAUNCHER_COMPONENT = new ComponentName(
     47             "com.android.bluetooth", "com.android.bluetooth.opp.BluetoothOppLauncherActivity");
     48 
     49     /**
     50      * Tests that Bluetooth sharing activity gets disabled when the restriction is enforced.
     51      */
     52     public void testOppDisabledWhenRestrictionSet() throws Exception {
     53         if (BluetoothAdapter.getDefaultAdapter() == null) {
     54             // No Bluetooth - nothing to test.
     55             return;
     56         }
     57 
     58         // The restriction is active by default for managed profiles.
     59         assertBluetoothSharingAvailable(mContext, false);
     60 
     61         // Remove the user restriction.
     62         mDevicePolicyManager.clearUserRestriction(
     63                 ADMIN_RECEIVER_COMPONENT, UserManager.DISALLOW_BLUETOOTH_SHARING);
     64         // Bluetooth sharing should become available.
     65         assertBluetoothSharingAvailable(mContext, true);
     66 
     67         // Add the user restriction back (which is the default state).
     68         mDevicePolicyManager.addUserRestriction(
     69                 ADMIN_RECEIVER_COMPONENT, UserManager.DISALLOW_BLUETOOTH_SHARING);
     70         // Bluetooth sharing should be disabled once again.
     71         assertBluetoothSharingAvailable(mContext, false);
     72     }
     73 
     74     /** Verifies restriction enforcement. */
     75     private static void assertRestrictionEnforced(Context context, boolean enforced) {
     76         final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
     77         assertEquals("Invalid restriction enforcement status", enforced,
     78                 um.getUserRestrictions().getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING, false));
     79     }
     80 
     81     /**
     82      * Builds an intent to share an image file. If Bluetooth sharing is allowed, it should be
     83      * handled by {@link #OPP_LAUNCHER_COMPONENT}.
     84      */
     85     private static Intent fileSharingIntent() {
     86         final Intent result = new Intent(Intent.ACTION_SEND);
     87         final Uri uri = Uri.parse("content://foo/bar");
     88         result.setDataAndType(uri, "image/*");
     89         return result;
     90     }
     91 
     92     /**
     93      * Verifies bluetooth sharing availability.
     94      */
     95     static void assertBluetoothSharingAvailable(Context context, boolean available)
     96             throws Exception {
     97         // Check restriction.
     98         assertRestrictionEnforced(context, !available);
     99         // Check component status.
    100         final int componentEnabledState = available
    101                 ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
    102                 : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
    103         assertComponentStateAfterTimeout(context, OPP_LAUNCHER_COMPONENT, componentEnabledState);
    104         // Check whether sharing activity is offered.
    105         assertHandlerAvailable(context, fileSharingIntent(), OPP_LAUNCHER_COMPONENT, available);
    106     }
    107 
    108     /** Waits for package state to change to a desired one or fails. */
    109     private static void assertComponentStateAfterTimeout(Context context, ComponentName component,
    110             int expectedState)
    111             throws Exception {
    112         final long timeout = SystemClock.elapsedRealtime() + COMPONENT_STATE_TIMEOUT_MS;
    113         int state = -1;
    114         while (SystemClock.elapsedRealtime() < timeout) {
    115             state = context.getPackageManager().getComponentEnabledSetting(component);
    116             if (expectedState == state) {
    117                 // Success
    118                 return;
    119             }
    120             Thread.sleep(POLL_TIME_MS);
    121         }
    122         TestCase.fail("The state of " + component + " should have been " + expectedState
    123                 + ", it but was " + state + " after timeout.");
    124     }
    125 
    126     /** Verifies that {@code component} is offered when handling {@code intent}. */
    127     private static void assertHandlerAvailable(Context context, Intent intent,
    128             ComponentName component,
    129             boolean shouldResolve) {
    130         final List<ResolveInfo> infos =
    131                 context.getPackageManager().queryIntentActivities(intent, 0);
    132         for (final ResolveInfo info : infos) {
    133             final ComponentInfo componentInfo =
    134                     info.activityInfo != null ? info.activityInfo :
    135                             info.serviceInfo != null ? info.serviceInfo :
    136                                     info.providerInfo;
    137             final ComponentName resolvedComponent =
    138                     new ComponentName(componentInfo.packageName, componentInfo.name);
    139 
    140             if (resolvedComponent.equals(component)) {
    141                 if (shouldResolve) {
    142                     // Found it, assertion passed.
    143                     return;
    144                 } else {
    145                     TestCase.fail(component + " is available as a handler for " + intent);
    146                 }
    147             }
    148         }
    149         // If we get to this point, there was no match.
    150         if (shouldResolve) {
    151             TestCase.fail(component + " isn't available as a handler for " + intent);
    152         }
    153     }
    154 }
    155