1 /*
2  * Copyright (C) 2019 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 static com.android.cts.deviceandprofileowner.BaseDeviceAdminTest.ADMIN_RECEIVER_COMPONENT;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import android.app.UiAutomation;
24 import android.app.admin.DevicePolicyManager;
25 import android.content.ContentResolver;
26 import android.content.Context;
27 import android.hardware.camera2.CameraManager;
28 import android.os.Bundle;
29 import android.os.Handler;
30 import android.os.HandlerThread;
31 import android.os.UserHandle;
32 import android.os.UserManager;
33 import android.provider.Settings;
34 import android.test.InstrumentationTestCase;
35 import android.util.Log;
36 
37 import com.android.cts.devicepolicy.CameraUtils;
38 
39 import com.google.common.collect.ImmutableSet;
40 
41 import java.util.Set;
42 import java.util.concurrent.TimeUnit;
43 
44 public class UserRestrictionsParentTest extends InstrumentationTestCase {
45 
46     private static final String TAG = "UserRestrictionsParentTest";
47 
48     protected Context mContext;
49     private ContentResolver mContentResolver;
50     private UiAutomation mUiAutomation;
51     private DevicePolicyManager mDevicePolicyManager;
52     private UserManager mUserManager;
53 
54     private CameraManager mCameraManager;
55 
56     private HandlerThread mBackgroundThread;
57     private static final long GET_UIAUTOMATION_TIMEOUT_NS = TimeUnit.SECONDS.toNanos(60);
58 
59     /**
60      * A {@link Handler} for running tasks in the background.
61      */
62     private Handler mBackgroundHandler;
63 
64     @Override
setUp()65     protected void setUp() throws Exception {
66         super.setUp();
67         mContext = getInstrumentation().getContext();
68         mContentResolver = mContext.getContentResolver();
69         mUiAutomation = getUiAutomation();
70 
71         mDevicePolicyManager = (DevicePolicyManager)
72                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
73         assertNotNull(mDevicePolicyManager);
74 
75         mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
76         assertNotNull(mCameraManager);
77 
78         mUserManager = mContext.getSystemService(UserManager.class);
79         assertNotNull(mUserManager);
80 
81         startBackgroundThread();
82     }
83 
84     @Override
tearDown()85     protected void tearDown() throws Exception {
86         mUiAutomation.dropShellPermissionIdentity();
87         stopBackgroundThread();
88         super.tearDown();
89     }
90 
getUiAutomation()91     private UiAutomation getUiAutomation() throws InterruptedException {
92         final long deadline = System.nanoTime() + GET_UIAUTOMATION_TIMEOUT_NS;
93         while (System.nanoTime() < deadline) {
94             UiAutomation ui = getInstrumentation().getUiAutomation();
95             if (ui != null) {
96                  return ui;
97             }
98             Thread.sleep(1000);
99         }
100         throw new AssertionError("Failed to get UiAutomation");
101     }
102 
testAddUserRestrictionDisallowConfigDateTime_onParent()103     public void testAddUserRestrictionDisallowConfigDateTime_onParent() {
104         DevicePolicyManager parentDevicePolicyManager =
105                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
106         assertNotNull(parentDevicePolicyManager);
107 
108         parentDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
109                 UserManager.DISALLOW_CONFIG_DATE_TIME);
110     }
111 
testHasUserRestrictionDisallowConfigDateTime()112     public void testHasUserRestrictionDisallowConfigDateTime() {
113         assertThat(mUserManager.
114                 hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)).isTrue();
115     }
116 
testUserRestrictionDisallowConfigDateTimeIsNotPersisted()117     public void testUserRestrictionDisallowConfigDateTimeIsNotPersisted() throws Exception {
118         final long deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(30);
119         while (System.nanoTime() <= deadline) {
120             if (!mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_DATE_TIME)) {
121                 return;
122             }
123             Thread.sleep(100);
124         }
125         fail("The restriction didn't go away.");
126     }
127 
testAddUserRestrictionDisallowAddUser_onParent()128     public void testAddUserRestrictionDisallowAddUser_onParent() {
129         DevicePolicyManager parentDevicePolicyManager =
130                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
131         assertNotNull(parentDevicePolicyManager);
132 
133         parentDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT,
134                 UserManager.DISALLOW_ADD_USER);
135     }
136 
testHasUserRestrictionDisallowAddUser()137     public void testHasUserRestrictionDisallowAddUser() {
138         assertThat(hasUserRestriction(UserManager.DISALLOW_ADD_USER)).isTrue();
139     }
140 
testClearUserRestrictionDisallowAddUser()141     public void testClearUserRestrictionDisallowAddUser() {
142         DevicePolicyManager parentDevicePolicyManager =
143                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
144 
145         parentDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
146                 UserManager.DISALLOW_ADD_USER);
147     }
148 
testAddUserRestrictionCameraDisabled_onParent()149     public void testAddUserRestrictionCameraDisabled_onParent() {
150         DevicePolicyManager parentDevicePolicyManager =
151                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
152         parentDevicePolicyManager.setCameraDisabled(ADMIN_RECEIVER_COMPONENT, true);
153         boolean actualDisabled =
154                 parentDevicePolicyManager.getCameraDisabled(ADMIN_RECEIVER_COMPONENT);
155 
156         assertThat(actualDisabled).isTrue();
157     }
158 
testRemoveUserRestrictionCameraEnabled_onParent()159     public void testRemoveUserRestrictionCameraEnabled_onParent() {
160         DevicePolicyManager parentDevicePolicyManager =
161                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
162         parentDevicePolicyManager.setCameraDisabled(ADMIN_RECEIVER_COMPONENT, false);
163         boolean actualDisabled =
164                 parentDevicePolicyManager.getCameraDisabled(ADMIN_RECEIVER_COMPONENT);
165 
166         assertThat(actualDisabled).isFalse();
167     }
168 
testCannotOpenCamera()169     public void testCannotOpenCamera() throws Exception {
170         checkCanOpenCamera(false);
171     }
172 
testCanOpenCamera()173     public void testCanOpenCamera() throws Exception {
174         checkCanOpenCamera(true);
175     }
176 
checkCanOpenCamera(boolean canOpen)177     private void checkCanOpenCamera(boolean canOpen) throws Exception {
178         // If the device does not support a camera it will return an empty camera ID list.
179         if (mCameraManager.getCameraIdList() == null
180                 || mCameraManager.getCameraIdList().length == 0) {
181             return;
182         }
183         int retries = 10;
184         boolean successToOpen = !canOpen;
185         while (successToOpen != canOpen && retries > 0) {
186             retries--;
187             Thread.sleep(500);
188             successToOpen = CameraUtils.blockUntilOpenCamera(mCameraManager, mBackgroundHandler);
189         }
190         assertEquals(String.format("Timed out waiting the value to change to %b (actual=%b)",
191                 canOpen, successToOpen), canOpen, successToOpen);
192     }
193 
194     private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS =
195             ImmutableSet.of(
196                     UserManager.DISALLOW_BLUETOOTH,
197                     UserManager.DISALLOW_BLUETOOTH_SHARING,
198                     UserManager.DISALLOW_CONFIG_BLUETOOTH,
199                     UserManager.DISALLOW_CONFIG_CELL_BROADCASTS,
200                     UserManager.DISALLOW_CONFIG_LOCATION,
201                     UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS,
202                     UserManager.DISALLOW_CONFIG_TETHERING,
203                     UserManager.DISALLOW_CONFIG_WIFI,
204                     UserManager.DISALLOW_CONTENT_CAPTURE,
205                     UserManager.DISALLOW_CONTENT_SUGGESTIONS,
206                     UserManager.DISALLOW_DATA_ROAMING,
207                     UserManager.DISALLOW_SAFE_BOOT,
208                     UserManager.DISALLOW_SHARE_LOCATION,
209                     UserManager.DISALLOW_SMS,
210                     UserManager.DISALLOW_USB_FILE_TRANSFER,
211                     UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
212                     UserManager.DISALLOW_OUTGOING_CALLS,
213                     UserManager.DISALLOW_UNMUTE_MICROPHONE
214                     // This restriction disables ADB, so is not used in test.
215                     // UserManager.DISALLOW_DEBUGGING_FEATURES
216             );
217 
testPerProfileUserRestriction_onParent()218     public void testPerProfileUserRestriction_onParent() throws Settings.SettingNotFoundException {
219         mUiAutomation.adoptShellPermissionIdentity(
220                 "android.permission.INTERACT_ACROSS_USERS_FULL",
221                 "android.permission.CREATE_USERS");
222 
223         DevicePolicyManager parentDevicePolicyManager =
224                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
225         assertNotNull(parentDevicePolicyManager);
226 
227         int locationMode = Settings.Secure.getIntForUser(mContentResolver,
228                 Settings.Secure.LOCATION_MODE, UserHandle.USER_SYSTEM);
229 
230         for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_LOCAL_RESTRICTIONS) {
231             try {
232                 boolean hasRestrictionOnManagedProfile = mUserManager.hasUserRestriction(
233                         restriction);
234 
235                 parentDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
236                 // Assert user restriction on personal profile has been added
237                 assertThat(hasUserRestriction(restriction)).isTrue();
238                 // Assert user restriction on managed profile has not changed
239                 assertThat(mUserManager.hasUserRestriction(restriction)).isEqualTo(
240                         hasRestrictionOnManagedProfile);
241             } finally {
242                 parentDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
243                         restriction);
244                 assertThat(hasUserRestriction(restriction)).isFalse();
245             }
246         }
247 
248         // Restore the location mode setting after adding and removing the
249         // DISALLOW_SHARE_LOCATION user restriction. This is because, modifying this user
250         // restriction causes the location mode setting to be turned off.
251         Settings.Secure.putIntForUser(mContentResolver, Settings.Secure.LOCATION_MODE, locationMode,
252                 UserHandle.USER_SYSTEM);
253     }
254 
255     private static final Set<String> PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS =
256             ImmutableSet.of(
257                     UserManager.DISALLOW_CONFIG_PRIVATE_DNS,
258                     UserManager.DISALLOW_CONFIG_DATE_TIME,
259                     UserManager.DISALLOW_AIRPLANE_MODE
260             );
261 
testPerDeviceUserRestriction_onParent()262     public void testPerDeviceUserRestriction_onParent() {
263         DevicePolicyManager parentDevicePolicyManager =
264                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
265         assertNotNull(parentDevicePolicyManager);
266 
267         for (String restriction : PROFILE_OWNER_ORGANIZATION_OWNED_GLOBAL_RESTRICTIONS) {
268             try {
269                 parentDevicePolicyManager.addUserRestriction(ADMIN_RECEIVER_COMPONENT, restriction);
270                 // Assert user restriction on personal profile has been added
271                 assertThat(hasUserRestriction(restriction)).isTrue();
272                 // Assert user restriction on managed profile has been added
273                 assertThat(mUserManager.hasUserRestriction(restriction)).isTrue();
274             } finally {
275                 parentDevicePolicyManager.clearUserRestriction(ADMIN_RECEIVER_COMPONENT,
276                         restriction);
277                 assertThat(hasUserRestriction(restriction)).isFalse();
278                 assertThat(mUserManager.hasUserRestriction(restriction)).isFalse();
279             }
280         }
281     }
282 
hasUserRestriction(String key)283     private boolean hasUserRestriction(String key) {
284         DevicePolicyManager parentDevicePolicyManager =
285                 mDevicePolicyManager.getParentProfileInstance(ADMIN_RECEIVER_COMPONENT);
286         Bundle userRestrictions =
287                 parentDevicePolicyManager.getUserRestrictions(ADMIN_RECEIVER_COMPONENT);
288         return userRestrictions.getBoolean(key);
289     }
290 
291     /**
292      * Starts a background thread and its {@link Handler}.
293      */
startBackgroundThread()294     private void startBackgroundThread() {
295         mBackgroundThread = new HandlerThread("CameraBackground");
296         mBackgroundThread.start();
297         mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
298     }
299 
300     /**
301      * Stops the background thread and its {@link Handler}.
302      */
stopBackgroundThread()303     private void stopBackgroundThread() {
304         mBackgroundThread.quitSafely();
305         try {
306             mBackgroundThread.join();
307             mBackgroundThread = null;
308             mBackgroundHandler = null;
309         } catch (InterruptedException e) {
310             Log.e(TAG, "Interrupted exception thrown while stopping background thread.");
311         }
312     }
313 
314 }
315