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.ArgumentMatchers.anyInt;
22 import static org.mockito.ArgumentMatchers.eq;
23 import static org.mockito.Mockito.doAnswer;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.content.ComponentName;
29 import android.content.Context;
30 
31 import androidx.test.InstrumentationRegistry;
32 import androidx.test.filters.SmallTest;
33 
34 import com.android.managedprovisioning.R;
35 import com.android.managedprovisioning.model.ProvisioningParams;
36 import com.android.managedprovisioning.task.AbstractProvisioningTask;
37 import com.android.managedprovisioning.task.AddWifiNetworkTask;
38 import com.android.managedprovisioning.task.CreateAndProvisionManagedProfileTask;
39 
40 import org.mockito.Mock;
41 import org.mockito.invocation.InvocationOnMock;
42 import org.mockito.stubbing.Answer;
43 
44 import java.util.concurrent.CountDownLatch;
45 import java.util.concurrent.TimeUnit;
46 
47 /**
48  * Unit tests for {@link ProfileOwnerProvisioningController}.
49  */
50 
51 public class ProfileOwnerProvisioningControllerTest extends ProvisioningControllerBaseTest {
52 
53     private static final int TEST_PARENT_USER_ID = 1;
54     private static final int TEST_PROFILE_USER_ID = 2;
55     private static final ComponentName TEST_ADMIN = new ComponentName("com.test.admin",
56             "com.test.admin.AdminReceiver");
57     private static final ProvisioningParams PROVISIONING_PARAMS = new ProvisioningParams.Builder()
58             .setDeviceAdminComponentName(TEST_ADMIN)
59             .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE)
60             .build();
61 
62     @Mock private ProvisioningControllerCallback mCallback;
63     private static final Context mContext = InstrumentationRegistry.getTargetContext();
64 
65     private static final String TEST_ERROR_MESSAGE = "test error message";
66 
67     private static final AbstractProvisioningTask TASK =
68             new AddWifiNetworkTask(mContext,
69                     PROVISIONING_PARAMS,
70                     createTaskCallback());
71 
72     @SmallTest
testRunAllTasks()73     public void testRunAllTasks() throws Exception {
74         // GIVEN device profile owner provisioning was invoked
75         createController();
76 
77         // WHEN starting the test run
78         mController.start(mHandler);
79 
80         // THEN the create and provision managed profile task is run
81         verifyTaskRun(CreateAndProvisionManagedProfileTask.class);
82 
83         // WHEN the task completes successfully
84         CreateAndProvisionManagedProfileTask createAndProvisionManagedProfileTask = mock(
85                 CreateAndProvisionManagedProfileTask.class);
86         when(createAndProvisionManagedProfileTask.getProfileUserId()).thenReturn(
87                 TEST_PROFILE_USER_ID);
88         mController.onSuccess(createAndProvisionManagedProfileTask);
89 
90         // THEN the provisioning complete callback should have happened
91         verify(mCallback).provisioningTasksCompleted();
92     }
93 
94     @SmallTest
testCancel()95     public void testCancel() throws Exception {
96         // GIVEN device profile owner provisioning was invoked
97         createController();
98 
99         // WHEN starting the test run
100         mController.start(mHandler);
101 
102         // THEN the create and provision managed profile task is run
103         AbstractProvisioningTask task = verifyTaskRun(CreateAndProvisionManagedProfileTask.class);
104 
105         // latch used to wait for onCancelled callback
106         final CountDownLatch latch = new CountDownLatch(1);
107         doAnswer(new Answer<Void>() {
108             @Override
109             public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
110                 latch.countDown();
111                 return null;
112             }
113         }).when(mCallback).cleanUpCompleted();
114 
115         // WHEN the user cancels the provisioning progress
116         mController.cancel();
117 
118         // THEN the activity is informed that progress has been cancelled
119         assertTrue(latch.await(1, TimeUnit.SECONDS));
120 
121         // WHEN the create and provision managed profile task eventually finishes
122         mController.onSuccess(task);
123 
124         // THEN no more tasks should be run
125         assertNull(mHandler.getLastTask());
126     }
127 
128     @SmallTest
testError()129     public void testError() throws Exception {
130         // GIVEN device profile owner provisioning was invoked
131         createController();
132 
133         // WHEN starting the test run
134         mController.start(mHandler);
135 
136         // THEN the create and provision managed profile task is run
137         AbstractProvisioningTask task = verifyTaskRun(CreateAndProvisionManagedProfileTask.class);
138 
139         // WHEN the task encountered an error
140         mController.onError(task, 0, /* errorMessage= */ null);
141 
142         // THEN the activity should be informed about the error
143         verify(mCallback).error(R.string.cant_set_up_profile,
144                 mContext.getString(R.string.managed_provisioning_error_text), false);
145     }
146 
147     @SmallTest
testErrorWithStringMessage()148     public void testErrorWithStringMessage() {
149         createController();
150         mController.start(mHandler);
151 
152         mController.onError(TASK, /* errorCode= */ 0, TEST_ERROR_MESSAGE);
153 
154         verify(mCallback).error(anyInt(), eq(TEST_ERROR_MESSAGE), eq(false));
155     }
156 
createController()157     private void createController() {
158         mController = ProfileOwnerProvisioningController.createInstance(
159                 mContext,
160                 PROVISIONING_PARAMS,
161                 TEST_PARENT_USER_ID,
162                 mCallback);
163     }
164 
createTaskCallback()165     private static AbstractProvisioningTask.Callback createTaskCallback() {
166         return new AbstractProvisioningTask.Callback() {
167             @Override
168             public void onSuccess(AbstractProvisioningTask task) {
169 
170             }
171 
172             @Override
173             public void onError(AbstractProvisioningTask task, int errorCode,
174                     String errorMessage) {
175 
176             }
177         };
178     }
179 }
180