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.app.ActivityManager;
20 import android.app.admin.DeviceAdminReceiver;
21 import android.app.admin.DevicePolicyManager;
22 import android.content.BroadcastReceiver;
23 import android.content.ComponentName;
24 import android.content.Context;
25 import android.content.Intent;
26 import android.content.IntentFilter;
27 import android.content.pm.PackageManager;
28 import android.os.Bundle;
29 import android.os.PersistableBundle;
30 import android.os.Process;
31 import android.os.UserHandle;
32 import android.os.UserManager;
33 import android.provider.Settings;
34 import android.support.v4.content.LocalBroadcastManager;
35 import android.util.Log;
36 import java.lang.reflect.Field;
37 import java.util.concurrent.SynchronousQueue;
38 import java.util.concurrent.TimeUnit;
39 
40 /**
41  * Test {@link DevicePolicyManager#createAndManageUser}.
42  */
43 public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
44     private static final String TAG = "CreateAndManageUserTest";
45 
46     private static final String BROADCAST_EXTRA = "broadcastExtra";
47     private static final String ACTION_EXTRA = "actionExtra";
48     private static final String SERIAL_EXTRA = "serialExtra";
49     private static final String PROFILE_OWNER_EXTRA = "profileOwnerExtra";
50     private static final String SETUP_COMPLETE_EXTRA = "setupCompleteExtra";
51     private static final int BROADCAST_TIMEOUT = 15_000;
52     private static final int USER_SWITCH_DELAY = 10_000;
53     private PackageManager mPackageManager;
54     private ActivityManager mActivityManager;
55     private volatile boolean mReceived;
56     private volatile boolean mTestProfileOwnerWasUsed;
57     private volatile boolean mSetupComplete;
58     private UserHandle mUserHandle;
59 
60     @Override
setUp()61     protected void setUp() throws Exception {
62         super.setUp();
63         mPackageManager = mContext.getPackageManager();
64         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
65     }
66 
67     @Override
tearDown()68     protected void tearDown() throws Exception {
69         mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER);
70         mDevicePolicyManager.clearUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER);
71         // Remove user in case of failed test.
72         if (mUserHandle != null) {
73             mDevicePolicyManager.removeUser(getWho(), mUserHandle);
74             mUserHandle = null;
75         }
76         super.tearDown();
77     }
78 
79     // This class is used by createAndManageUserTest as profile owner for the new user. When
80     // enabled, it sends a broadcast to signal success.
81     public static class TestProfileOwner extends DeviceAdminReceiver {
82         @Override
onEnabled(Context context, Intent intent)83         public void onEnabled(Context context, Intent intent) {
84             if (intent.getBooleanExtra(BROADCAST_EXTRA, false)) {
85                 Intent i = new Intent(intent.getStringExtra(ACTION_EXTRA));
86                 UserManager userManager = (UserManager)
87                         context.getSystemService(Context.USER_SERVICE);
88                 long serial = intent.getLongExtra(SERIAL_EXTRA, 0);
89                 UserHandle handle = userManager.getUserForSerialNumber(serial);
90                 i.putExtra(PROFILE_OWNER_EXTRA, true);
91                 // find value of user_setup_complete on new user, and send the result back
92                 try {
93                     boolean setupComplete = (Settings.Secure.getInt(context.getContentResolver(),
94                             "user_setup_complete") == 1);
95                     i.putExtra(SETUP_COMPLETE_EXTRA, setupComplete);
96                 } catch (Settings.SettingNotFoundException e) {
97                     fail("Did not find settings user_setup_complete");
98                 }
99 
100                 context.sendBroadcastAsUser(i, handle);
101             }
102         }
103 
getComponentName()104         public static ComponentName getComponentName() {
105             return new ComponentName(CreateAndManageUserTest.class.getPackage().getName(),
106                     TestProfileOwner.class.getName());
107         }
108     }
109 
waitForBroadcastLocked()110     private void waitForBroadcastLocked() {
111         // Wait for broadcast. Time is measured in a while loop because of spurious wakeups.
112         final long initTime = System.currentTimeMillis();
113         while (!mReceived) {
114             try {
115                 wait(BROADCAST_TIMEOUT - (System.currentTimeMillis() - initTime));
116             } catch (InterruptedException e) {
117                 fail("InterruptedException: " + e.getMessage());
118             }
119             if (!mReceived && System.currentTimeMillis() - initTime > BROADCAST_TIMEOUT) {
120                 fail("Timeout while waiting for broadcast after createAndManageUser.");
121             }
122         }
123     }
124 
125 // Disabled due to b/29072728
126 //    // This test will create a user that will get passed a bundle that we specify. The bundle will
127 //    // contain an action and a serial (for user handle) to broadcast to notify the test that the
128 //    // configuration was triggered.
129 //    private void createAndManageUserTest(final int flags) {
130 //        // This test sets a profile owner on the user, which requires the managed_users feature.
131 //        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
132 //            return;
133 //        }
134 //
135 //        final boolean expectedSetupComplete = (flags & DevicePolicyManager.SKIP_SETUP_WIZARD) != 0;
136 //        UserManager userManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
137 //
138 //        UserHandle firstUser = Process.myUserHandle();
139 //        final String testUserName = "TestUser_" + System.currentTimeMillis();
140 //        String action = "com.android.cts.TEST_USER_ACTION";
141 //        PersistableBundle bundle = new PersistableBundle();
142 //        bundle.putBoolean(BROADCAST_EXTRA, true);
143 //        bundle.putLong(SERIAL_EXTRA, userManager.getSerialNumberForUser(firstUser));
144 //        bundle.putString(ACTION_EXTRA, action);
145 //
146 //        mReceived = false;
147 //        mTestProfileOwnerWasUsed = false;
148 //        mSetupComplete = !expectedSetupComplete;
149 //        BroadcastReceiver receiver = new BroadcastReceiver() {
150 //            @Override
151 //            public void onReceive(Context context, Intent intent) {
152 //                mReceived = true;
153 //                if (intent.getBooleanExtra(PROFILE_OWNER_EXTRA, false)) {
154 //                    mTestProfileOwnerWasUsed = true;
155 //                }
156 //                mSetupComplete = intent.getBooleanExtra(SETUP_COMPLETE_EXTRA,
157 //                        !expectedSetupComplete);
158 //                synchronized (CreateAndManageUserTest.this) {
159 //                    CreateAndManageUserTest.this.notify();
160 //                }
161 //            }
162 //        };
163 //
164 //        IntentFilter filter = new IntentFilter();
165 //        filter.addAction(action);
166 //        mContext.registerReceiver(receiver, filter);
167 //
168 //        synchronized (this) {
169 //            mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), testUserName,
170 //                    TestProfileOwner.getComponentName(), bundle, flags);
171 //            assertNotNull(mUserHandle);
172 //
173 //            mDevicePolicyManager.switchUser(getWho(), mUserHandle);
174 //            try {
175 //                wait(USER_SWITCH_DELAY);
176 //            } catch (InterruptedException e) {
177 //                fail("InterruptedException: " + e.getMessage());
178 //            }
179 //            mDevicePolicyManager.switchUser(getWho(), firstUser);
180 //
181 //            waitForBroadcastLocked();
182 //
183 //            assertTrue(mReceived);
184 //            assertTrue(mTestProfileOwnerWasUsed);
185 //            assertEquals(expectedSetupComplete, mSetupComplete);
186 //
187 //            assertTrue(mDevicePolicyManager.removeUser(getWho(), mUserHandle));
188 //
189 //            mUserHandle = null;
190 //        }
191 //
192 //        mContext.unregisterReceiver(receiver);
193 //    }
194 
195     /**
196      * Test creating an ephemeral user using the {@link DevicePolicyManager#createAndManageUser}
197      * method.
198      *
199      * <p>The test creates a user by calling to {@link DevicePolicyManager#createAndManageUser}. It
200      * doesn't remove the user afterwards, so its properties can be queried and tested by host-side
201      * tests.
202      * <p>The user's flags will be checked from the corresponding host-side test.
203      */
testCreateAndManageEphemeralUser()204     public void testCreateAndManageEphemeralUser() throws Exception {
205         String testUserName = "TestUser_" + System.currentTimeMillis();
206 
207         // Use reflection to get the value of the hidden flag to make the new user ephemeral.
208         Field field = DevicePolicyManager.class.getField("MAKE_USER_EPHEMERAL");
209         int makeEphemeralFlag = field.getInt(null);
210 
211         // Do not assign return value to mUserHandle, so it is not removed in tearDown.
212         mDevicePolicyManager.createAndManageUser(
213                 getWho(),
214                 testUserName,
215                 getWho(),
216                 null,
217                 makeEphemeralFlag);
218     }
219 
220     /**
221      * Test creating an ephemeral user using the {@link DevicePolicyManager#createAndManageUser}
222      * method fails on systems without the split system user.
223      *
224      * <p>To be used by host-side test on systems without the split system user.
225      */
testCreateAndManageEphemeralUserFails()226     public void testCreateAndManageEphemeralUserFails() throws Exception {
227         String testUserName = "TestUser_" + System.currentTimeMillis();
228 
229         // Use reflection to get the value of the hidden flag to make the new user ephemeral.
230         Field field = DevicePolicyManager.class.getField("MAKE_USER_EPHEMERAL");
231         int makeEphemeralFlag = field.getInt(null);
232 
233         try {
234             mDevicePolicyManager.createAndManageUser(
235                     getWho(),
236                     testUserName,
237                     getWho(),
238                     null,
239                     makeEphemeralFlag);
240         } catch (IllegalArgumentException e) {
241             // Success, the expected exception was thrown.
242             return;
243         }
244         fail("createAndManageUser should have thrown IllegalArgumentException");
245     }
246 
247 // Disabled due to b/29072728
248 //    public void testCreateAndManageUser_SkipSetupWizard() {
249 //        createAndManageUserTest(DevicePolicyManager.SKIP_SETUP_WIZARD);
250 //    }
251 //
252 //    public void testCreateAndManageUser_DontSkipSetupWizard() {
253 //        if (!mActivityManager.isRunningInTestHarness()) {
254 //            // In test harness, the setup wizard will be disabled by default, so this test is always
255 //            // failing.
256 //            createAndManageUserTest(0);
257 //        }
258 //    }
259 
260     // createAndManageUser should circumvent the DISALLOW_ADD_USER restriction
testCreateAndManageUser_AddRestrictionSet()261     public void testCreateAndManageUser_AddRestrictionSet() {
262         mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_ADD_USER);
263 
264         mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
265                 null, 0);
266         assertNotNull(mUserHandle);
267     }
268 
testCreateAndManageUser_RemoveRestrictionSet()269     public void testCreateAndManageUser_RemoveRestrictionSet() {
270         mDevicePolicyManager.addUserRestriction(getWho(), UserManager.DISALLOW_REMOVE_USER);
271 
272         mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
273                 null, 0);
274         assertNotNull(mUserHandle);
275 
276         boolean removed = mDevicePolicyManager.removeUser(getWho(), mUserHandle);
277         // When the device owner itself has set the user restriction, it should still be allowed
278         // to remove a user.
279         assertTrue(removed);
280     }
281 
testUserAddedOrRemovedBroadcasts()282     public void testUserAddedOrRemovedBroadcasts() throws InterruptedException {
283         LocalBroadcastReceiver receiver = new LocalBroadcastReceiver();
284         LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(
285                 getContext());
286         localBroadcastManager.registerReceiver(receiver, new IntentFilter(ACTION_USER_ADDED));
287         try {
288             mUserHandle = mDevicePolicyManager.createAndManageUser(getWho(), "Test User", getWho(),
289                     null, 0);
290             assertNotNull(mUserHandle);
291             assertEquals(mUserHandle, receiver.waitForBroadcastReceived());
292         } finally {
293             localBroadcastManager.unregisterReceiver(receiver);
294         }
295         localBroadcastManager.registerReceiver(receiver, new IntentFilter(ACTION_USER_REMOVED));
296         try {
297             assertTrue(mDevicePolicyManager.removeUser(getWho(), mUserHandle));
298             assertEquals(mUserHandle, receiver.waitForBroadcastReceived());
299             mUserHandle = null;
300         } finally {
301             localBroadcastManager.unregisterReceiver(receiver);
302         }
303     }
304 
305     static class LocalBroadcastReceiver extends BroadcastReceiver {
306         private SynchronousQueue<UserHandle> mQueue = new SynchronousQueue<UserHandle>();
307 
308         @Override
onReceive(Context context, Intent intent)309         public void onReceive(Context context, Intent intent) {
310             UserHandle userHandle = intent.getParcelableExtra(EXTRA_USER_HANDLE);
311             Log.d(TAG, "broadcast receiver received " + intent + " with userHandle "
312                     + userHandle);
313             mQueue.offer(userHandle);
314 
315         }
316 
waitForBroadcastReceived()317         public UserHandle waitForBroadcastReceived() throws InterruptedException {
318             return mQueue.poll(BROADCAST_TIMEOUT, TimeUnit.MILLISECONDS);
319         }
320     }
321 }
322