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      */
testOppDisabledWhenRestrictionSet()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. */
assertRestrictionEnforced(Context context, boolean enforced)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      */
fileSharingIntent()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      */
assertBluetoothSharingAvailable(Context context, boolean available)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. */
assertComponentStateAfterTimeout(Context context, ComponentName component, int expectedState)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}. */
assertHandlerAvailable(Context context, Intent intent, ComponentName component, boolean shouldResolve)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