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