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.deviceowner; 18 19 import android.bluetooth.BluetoothAdapter; 20 import android.content.ComponentName; 21 import android.content.pm.PackageManager; 22 import android.os.SystemClock; 23 import android.os.UserManager; 24 25 /** 26 * Test interaction between {@link UserManager#DISALLOW_BLUETOOTH} user restriction and the state 27 * of Bluetooth. 28 */ 29 public class BluetoothRestrictionTest extends BaseDeviceOwnerTest { 30 31 private static final int DISABLE_TIMEOUT_MS = 8000; // ms timeout for BT disable 32 private static final int ENABLE_TIMEOUT_MS = 10000; // ms timeout for BT enable 33 private static final int POLL_TIME_MS = 400; // ms to poll BT state 34 private static final int CHECK_WAIT_TIME_MS = 1000; // ms to wait before enable/disable 35 private static final int COMPONENT_STATE_TIMEOUT_MS = 10000; 36 private static final ComponentName OPP_LAUNCHER_COMPONENT = new ComponentName( 37 "com.android.bluetooth", "com.android.bluetooth.opp.BluetoothOppLauncherActivity"); 38 39 private BluetoothAdapter mBluetoothAdapter; 40 private PackageManager mPackageManager; 41 42 @Override 43 protected void setUp() throws Exception { 44 super.setUp(); 45 mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 46 mPackageManager = mContext.getPackageManager(); 47 } 48 49 @Override 50 protected void tearDown() throws Exception { 51 super.tearDown(); 52 mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH); 53 enable(); 54 } 55 56 public void testEnableBluetoothFailsWhenDisallowed() throws Exception { 57 if (mBluetoothAdapter == null) { 58 return; 59 } 60 61 // Make sure Bluetooth is initially disabled. 62 disable(); 63 64 // Add the user restriction disallowing Bluetooth. 65 mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH); 66 67 // Check that enabling Bluetooth fails. 68 assertFalse(mBluetoothAdapter.enable()); 69 } 70 71 public void testBluetoothGetsDisabledAfterRestrictionSet() throws Exception { 72 if (mBluetoothAdapter == null) { 73 return; 74 } 75 76 // Make sure Bluetooth is enabled first. 77 enable(); 78 79 // Add the user restriction to disallow Bluetooth. 80 mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH); 81 82 // Check that Bluetooth gets disabled as a result. 83 assertDisabledAfterTimeout(); 84 } 85 86 public void testEnableBluetoothSucceedsAfterRestrictionRemoved() throws Exception { 87 if (mBluetoothAdapter == null) { 88 return; 89 } 90 91 // Add the user restriction. 92 mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH); 93 94 // Make sure Bluetooth is disabled. 95 assertDisabledAfterTimeout(); 96 97 // Remove the user restriction. 98 mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_BLUETOOTH); 99 100 // Check that it is possible to enable Bluetooth again once the restriction has been 101 // removed. 102 enable(); 103 } 104 105 /** 106 * Tests that BluetoothOppLauncherActivity gets disabled when Bluetooth itself or Bluetooth 107 * sharing is disallowed. 108 * 109 * <p> It also checks the state of the activity is set back to default if Bluetooth is not 110 * disallowed anymore. 111 */ 112 public void testOppDisabledWhenRestrictionSet() throws Exception { 113 if (mBluetoothAdapter == null) { 114 return; 115 } 116 117 // First verify DISALLOW_BLUETOOTH. 118 testOppDisabledWhenRestrictionSet(UserManager.DISALLOW_BLUETOOTH); 119 // Verify DISALLOW_BLUETOOTH_SHARING which leaves bluetooth workable but the sharing 120 // component should be disabled. 121 testOppDisabledWhenRestrictionSet(UserManager.DISALLOW_BLUETOOTH_SHARING); 122 } 123 124 /** Verifies that a given restriction disables the bluetooth sharing component. */ 125 private void testOppDisabledWhenRestrictionSet(String restriction) { 126 // Add the user restriction. 127 mDevicePolicyManager.addUserRestriction(getWho(), restriction); 128 129 // The BluetoothOppLauncherActivity's component should be disabled. 130 assertComponentStateAfterTimeout( 131 OPP_LAUNCHER_COMPONENT, PackageManager.COMPONENT_ENABLED_STATE_DISABLED); 132 133 // Remove the user restriction. 134 mDevicePolicyManager.clearUserRestriction(getWho(), restriction); 135 136 // The BluetoothOppLauncherActivity's component should be in the default state. 137 assertComponentStateAfterTimeout( 138 OPP_LAUNCHER_COMPONENT, PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); 139 } 140 141 /** Helper to turn BT off. 142 * This method will either fail on an assert, or return with BT turned off. 143 * Behavior of getState() and isEnabled() are validated along the way. 144 */ 145 private void disable() { 146 // Can't disable a bluetooth adapter that does not exist. 147 if (mBluetoothAdapter == null) 148 return; 149 150 sleep(CHECK_WAIT_TIME_MS); 151 if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_OFF) { 152 assertFalse(mBluetoothAdapter.isEnabled()); 153 return; 154 } 155 156 assertEquals(BluetoothAdapter.STATE_ON, mBluetoothAdapter.getState()); 157 assertTrue(mBluetoothAdapter.isEnabled()); 158 mBluetoothAdapter.disable(); 159 assertDisabledAfterTimeout(); 160 } 161 162 /** 163 * Helper method which waits for Bluetooth to be disabled. Fails if it doesn't happen in a 164 * given time. 165 */ 166 private void assertDisabledAfterTimeout() { 167 boolean turnOff = false; 168 final long timeout = SystemClock.elapsedRealtime() + DISABLE_TIMEOUT_MS; 169 while (SystemClock.elapsedRealtime() < timeout) { 170 int state = mBluetoothAdapter.getState(); 171 switch (state) { 172 case BluetoothAdapter.STATE_OFF: 173 assertFalse(mBluetoothAdapter.isEnabled()); 174 return; 175 default: 176 if (state != BluetoothAdapter.STATE_ON || turnOff) { 177 assertEquals(BluetoothAdapter.STATE_TURNING_OFF, state); 178 turnOff = true; 179 } 180 break; 181 } 182 sleep(POLL_TIME_MS); 183 } 184 fail("disable() timeout"); 185 } 186 187 private void assertComponentStateAfterTimeout(ComponentName component, int expectedState) { 188 final long timeout = SystemClock.elapsedRealtime() + COMPONENT_STATE_TIMEOUT_MS; 189 int state = -1; 190 while (SystemClock.elapsedRealtime() < timeout) { 191 state = mPackageManager.getComponentEnabledSetting(component); 192 if (expectedState == state) { 193 // Success 194 return; 195 } 196 sleep(POLL_TIME_MS); 197 } 198 fail("The state of " + component + " should have been " + expectedState + ", it but was " 199 + state + " after timeout."); 200 } 201 202 /** Helper to turn BT on. 203 * This method will either fail on an assert, or return with BT turned on. 204 * Behavior of getState() and isEnabled() are validated along the way. 205 */ 206 private void enable() { 207 // Can't enable a bluetooth adapter that does not exist. 208 if (mBluetoothAdapter == null) 209 return; 210 211 sleep(CHECK_WAIT_TIME_MS); 212 if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { 213 assertTrue(mBluetoothAdapter.isEnabled()); 214 return; 215 } 216 217 assertEquals(BluetoothAdapter.STATE_OFF, mBluetoothAdapter.getState()); 218 assertFalse(mBluetoothAdapter.isEnabled()); 219 mBluetoothAdapter.enable(); 220 assertEnabledAfterTimeout(); 221 } 222 223 /** 224 * Helper method which waits for Bluetooth to be enabled. Fails if it doesn't happen in a given 225 * time. 226 */ 227 private void assertEnabledAfterTimeout() { 228 boolean turnOn = false; 229 final long timeout = SystemClock.elapsedRealtime() + ENABLE_TIMEOUT_MS; 230 while (SystemClock.elapsedRealtime() < timeout) { 231 int state = mBluetoothAdapter.getState(); 232 switch (state) { 233 case BluetoothAdapter.STATE_ON: 234 assertTrue(mBluetoothAdapter.isEnabled()); 235 return; 236 default: 237 if (state != BluetoothAdapter.STATE_OFF || turnOn) { 238 assertEquals(BluetoothAdapter.STATE_TURNING_ON, state); 239 turnOn = true; 240 } 241 break; 242 } 243 sleep(POLL_TIME_MS); 244 } 245 fail("enable() timeout"); 246 } 247 248 private static void sleep(long t) { 249 try { 250 Thread.sleep(t); 251 } catch (InterruptedException e) {} 252 } 253 254 } 255