1 /*
2  * Copyright 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.managedprovisioning.provisioning;
18 
19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
20 
21 import static org.mockito.Matchers.anyInt;
22 import static org.mockito.Matchers.anyString;
23 import static org.mockito.Matchers.eq;
24 import static org.mockito.Mockito.doAnswer;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.verify;
27 import static org.mockito.Mockito.when;
28 
29 import android.content.ComponentName;
30 import android.content.Context;
31 import android.content.ContextWrapper;
32 import android.content.pm.UserInfo;
33 import android.os.UserManager;
34 import android.support.test.filters.MediumTest;
35 import android.support.test.filters.SmallTest;
36 
37 import com.android.managedprovisioning.R;
38 import com.android.managedprovisioning.finalization.FinalizationController;
39 import com.android.managedprovisioning.model.ProvisioningParams;
40 import com.android.managedprovisioning.task.AbstractProvisioningTask;
41 import com.android.managedprovisioning.task.CopyAccountToUserTask;
42 import com.android.managedprovisioning.task.CreateManagedProfileTask;
43 import com.android.managedprovisioning.task.DisableInstallShortcutListenersTask;
44 import com.android.managedprovisioning.task.InstallExistingPackageTask;
45 import com.android.managedprovisioning.task.ManagedProfileSettingsTask;
46 import com.android.managedprovisioning.task.SetDevicePolicyTask;
47 import com.android.managedprovisioning.task.StartManagedProfileTask;
48 
49 import org.mockito.Mock;
50 import org.mockito.invocation.InvocationOnMock;
51 import org.mockito.stubbing.Answer;
52 
53 import java.util.concurrent.CountDownLatch;
54 import java.util.concurrent.TimeUnit;
55 
56 /**
57  * Unit tests for {@link ProfileOwnerProvisioningController}.
58  */
59 
60 public class ProfileOwnerProvisioningControllerTest extends ProvisioningControllerBaseTest {
61 
62     private static final int TEST_PARENT_USER_ID = 1;
63     private static final int TEST_PROFILE_USER_ID = 2;
64     private static final ComponentName TEST_ADMIN = new ComponentName("com.test.admin",
65             "com.test.admin.AdminReceiver");
66 
67     @Mock private ProvisioningControllerCallback mCallback;
68     @Mock private FinalizationController mFinalizationController;
69     @Mock private UserManager mUserManager;
70     private Context mContext;
71     private ProvisioningParams mParams;
72 
73     @Override
setUp()74     public void setUp() throws Exception {
75         super.setUp();
76 
77         mContext = new ContextWrapper(getContext()) {
78             @Override
79             public Object getSystemService(String name) {
80                 if (Context.USER_SERVICE.equals(name)) {
81                     return mUserManager;
82                 }
83                 return super.getSystemService(name);
84             }
85         };
86 
87         when(mUserManager.createProfileForUser(anyString(), anyInt(), eq(TEST_PARENT_USER_ID)))
88                 .thenReturn(new UserInfo(TEST_PROFILE_USER_ID, null, 0));
89     }
90 
91     @SmallTest
testRunAllTasks()92     public void testRunAllTasks() throws Exception {
93         // GIVEN device profile owner provisioning was invoked
94         createController();
95 
96         // WHEN starting the test run
97         mController.start(mHandler);
98 
99         // THEN the create managed profile task is run first
100         verifyTaskRun(CreateManagedProfileTask.class);
101 
102         // WHEN the task completes successfully
103         CreateManagedProfileTask createManagedProfileTask = mock(CreateManagedProfileTask.class);
104         when(createManagedProfileTask.getProfileUserId()).thenReturn(TEST_PROFILE_USER_ID);
105         mController.onSuccess(createManagedProfileTask);
106 
107         // THEN the install existing package task is run
108         taskSucceeded(InstallExistingPackageTask.class);
109 
110         // THEN the set device policy task is run
111         taskSucceeded(SetDevicePolicyTask.class);
112 
113         // THEN the managed profile settings task is run
114         taskSucceeded(ManagedProfileSettingsTask.class);
115 
116         // THEN the disable install shortcut listeners task is run
117         taskSucceeded(DisableInstallShortcutListenersTask.class);
118 
119         // THEN the start managed profile task is run
120         taskSucceeded(StartManagedProfileTask.class);
121 
122         // THEN the copy account to user task is run
123         taskSucceeded(CopyAccountToUserTask.class);
124 
125         // THEN the provisioning complete callback should have happened
126         verify(mCallback).provisioningTasksCompleted();
127     }
128 
129     @MediumTest
testCancel()130     public void testCancel() throws Exception {
131         // GIVEN device profile owner provisioning was invoked
132         createController();
133 
134         // WHEN starting the test run
135         mController.start(mHandler);
136 
137         // THEN the create managed profile task is run first
138         verifyTaskRun(CreateManagedProfileTask.class);
139 
140         // WHEN the task completes successfully
141         CreateManagedProfileTask createManagedProfileTask = mock(CreateManagedProfileTask.class);
142         when(createManagedProfileTask.getProfileUserId()).thenReturn(TEST_PROFILE_USER_ID);
143         mController.onSuccess(createManagedProfileTask);
144 
145         // THEN the install existing package task is run
146         AbstractProvisioningTask task = verifyTaskRun(InstallExistingPackageTask.class);
147 
148         // latch used to wait for onCancelled callback
149         final CountDownLatch latch = new CountDownLatch(1);
150         doAnswer(new Answer<Void>() {
151             @Override
152             public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
153                 latch.countDown();
154                 return null;
155             }
156         }).when(mCallback).cleanUpCompleted();
157 
158         // WHEN the user cancels the provisioning progress
159         mController.cancel();
160 
161         // THEN the activity is informed that progress has been cancelled
162         assertTrue(latch.await(1, TimeUnit.SECONDS));
163 
164         // THEN the managed profile is deleted
165         verify(mUserManager).removeUserEvenWhenDisallowed(TEST_PROFILE_USER_ID);
166 
167         // WHEN the install existing package task eventually finishes
168         mController.onSuccess(task);
169 
170         // THEN no more tasks should be run
171         assertNull(mHandler.getLastTask());
172     }
173 
174     @SmallTest
testError()175     public void testError() throws Exception {
176         // GIVEN device profile owner provisioning was invoked
177         createController();
178 
179         // WHEN starting the test run
180         mController.start(mHandler);
181 
182         // THEN the create managed profile task is run first
183         verifyTaskRun(CreateManagedProfileTask.class);
184 
185         // WHEN the task completes successfully
186         CreateManagedProfileTask createManagedProfileTask = mock(CreateManagedProfileTask.class);
187         when(createManagedProfileTask.getProfileUserId()).thenReturn(TEST_PROFILE_USER_ID);
188         mController.onSuccess(createManagedProfileTask);
189 
190         // THEN the install existing package task is run
191         AbstractProvisioningTask task = verifyTaskRun(InstallExistingPackageTask.class);
192 
193         // WHEN the task encountered an error
194         mController.onError(task, 0);
195 
196         // THEN the activity should be informed about the error
197         verify(mCallback).error(R.string.cant_set_up_profile,
198                 R.string.managed_provisioning_error_text, false);
199     }
200 
createController()201     private void createController() {
202         mParams = new ProvisioningParams.Builder()
203                 .setDeviceAdminComponentName(TEST_ADMIN)
204                 .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE)
205                 .build();
206 
207         mController = new ProfileOwnerProvisioningController(
208                 mContext,
209                 mParams,
210                 TEST_PARENT_USER_ID,
211                 mCallback,
212                 mFinalizationController);
213     }
214 }
215