• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.finalization;
18 
19 import static android.app.admin.DeviceAdminReceiver.ACTION_PROFILE_PROVISIONING_COMPLETE;
20 import static android.app.admin.DevicePolicyManager.ACTION_PROVISIONING_SUCCESSFUL;
21 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
22 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
23 import static android.app.admin.DevicePolicyManager.EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE;
24 import static com.android.managedprovisioning.TestUtils.createTestAdminExtras;
25 import static org.mockito.Matchers.any;
26 import static org.mockito.Matchers.anyInt;
27 import static org.mockito.Matchers.eq;
28 import static org.mockito.Mockito.never;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 
32 import android.app.Activity;
33 import android.content.BroadcastReceiver;
34 import android.content.ComponentName;
35 import android.content.Context;
36 import android.content.Intent;
37 import android.os.PersistableBundle;
38 import android.os.UserHandle;
39 import android.test.AndroidTestCase;
40 import android.test.suitebuilder.annotation.SmallTest;
41 
42 import com.android.managedprovisioning.TestUtils;
43 import com.android.managedprovisioning.common.SettingsFacade;
44 import com.android.managedprovisioning.common.Utils;
45 import com.android.managedprovisioning.model.ProvisioningParams;
46 
47 import org.mockito.ArgumentCaptor;
48 import org.mockito.Mock;
49 import org.mockito.MockitoAnnotations;
50 
51 /**
52  * Unit tests for {@link FinalizationController}.
53  */
54 public class FinalizationControllerTest extends AndroidTestCase {
55     private static final UserHandle MANAGED_PROFILE_USER_HANDLE = UserHandle.of(123);
56     private static final String TEST_MDM_PACKAGE_NAME = "mdm.package.name";
57     private static final String TEST_MDM_ADMIN_RECEIVER = TEST_MDM_PACKAGE_NAME + ".AdminReceiver";
58     private static final ComponentName TEST_MDM_ADMIN = new ComponentName(TEST_MDM_PACKAGE_NAME,
59             TEST_MDM_ADMIN_RECEIVER);
60     private static final PersistableBundle TEST_MDM_EXTRA_BUNDLE = createTestAdminExtras();
61 
62     @Mock private Context mContext;
63     @Mock private Utils mUtils;
64     @Mock private SettingsFacade mSettingsFacade;
65     @Mock private UserProvisioningStateHelper mHelper;
66 
67     private FinalizationController mController;
68 
69     @Override
setUp()70     public void setUp() throws Exception {
71         // this is necessary for mockito to work
72         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
73         MockitoAnnotations.initMocks(this);
74         when(mUtils.canResolveIntentAsUser(any(Context.class), any(Intent.class), anyInt()))
75                 .thenReturn(true);
76         when(mContext.getFilesDir()).thenReturn(getContext().getFilesDir());
77 
78         mController = new FinalizationController(mContext, mUtils, mSettingsFacade, mHelper);
79     }
80 
81     @Override
tearDown()82     public void tearDown() throws Exception {
83         mController.loadProvisioningParamsAndClearFile();
84     }
85 
86     @SmallTest
testInitiallyDone_alreadyCalled()87     public void testInitiallyDone_alreadyCalled() {
88         // GIVEN that provisioningInitiallyDone has already been called
89         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
90         final ProvisioningParams params = createProvisioningParams(
91                 ACTION_PROVISION_MANAGED_PROFILE);
92 
93         // WHEN calling provisioningInitiallyDone
94         mController.provisioningInitiallyDone(params);
95 
96         // THEN nothing should happen
97         verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params);
98         verify(mHelper, never()).markUserProvisioningStateFinalized(params);
99     }
100 
101     @SmallTest
testFinalized_alreadyCalled()102     public void testFinalized_alreadyCalled() {
103         // GIVEN that provisioningInitiallyDone has already been called
104         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
105         final ProvisioningParams params = createProvisioningParams(
106                 ACTION_PROVISION_MANAGED_PROFILE);
107 
108         // WHEN calling provisioningFinalized
109         mController.provisioningFinalized();
110 
111         // THEN nothing should happen
112         verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params);
113         verify(mHelper, never()).markUserProvisioningStateFinalized(params);
114     }
115 
116     @SmallTest
testFinalized_noParamsStored()117     public void testFinalized_noParamsStored() {
118         // GIVEN that the user provisioning state is correct
119         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
120 
121         // WHEN calling provisioningFinalized
122         mController.provisioningFinalized();
123 
124         // THEN nothing should happen
125         verify(mHelper, never())
126                 .markUserProvisioningStateInitiallyDone(any(ProvisioningParams.class));
127         verify(mHelper, never()).markUserProvisioningStateFinalized(any(ProvisioningParams.class));
128     }
129 
130     @SmallTest
testManagedProfileAfterSuw()131     public void testManagedProfileAfterSuw() {
132         // GIVEN that provisioningInitiallyDone has never been called
133         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
134         // GIVEN that we've provisioned a managed profile after SUW
135         final ProvisioningParams params = createProvisioningParams(
136                 ACTION_PROVISION_MANAGED_PROFILE);
137         when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(true);
138         when(mUtils.getManagedProfile(mContext))
139                 .thenReturn(MANAGED_PROFILE_USER_HANDLE);
140 
141         // WHEN calling provisioningInitiallyDone
142         mController.provisioningInitiallyDone(params);
143 
144         // THEN the user provisioning state should be marked as initially done
145         verify(mHelper).markUserProvisioningStateInitiallyDone(params);
146 
147         // THEN provisioning successful intent should be sent to the dpc.
148         verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE);
149 
150         // THEN an ordered broadcast should be sent to the DPC
151         verifyOrderedBroadcast();
152     }
153 
154     @SmallTest
testManagedProfileDuringSuw()155     public void testManagedProfileDuringSuw() {
156         // GIVEN that provisioningInitiallyDone has never been called
157         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
158         // GIVEN that we've provisioned a managed profile after SUW
159         final ProvisioningParams params = createProvisioningParams(
160                 ACTION_PROVISION_MANAGED_PROFILE);
161         when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false);
162         when(mUtils.getManagedProfile(mContext))
163                 .thenReturn(MANAGED_PROFILE_USER_HANDLE);
164 
165         // WHEN calling provisioningInitiallyDone
166         mController.provisioningInitiallyDone(params);
167 
168         // THEN the user provisioning state should be marked as initially done
169         verify(mHelper).markUserProvisioningStateInitiallyDone(params);
170         // THEN the provisioning params have been stored and will be read in provisioningFinalized
171 
172         // GIVEN that the provisioning state is now incomplete
173         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
174 
175         // WHEN calling provisioningFinalized
176         mController.provisioningFinalized();
177 
178         // THEN the user provisioning state is finalized
179         verify(mHelper).markUserProvisioningStateFinalized(params);
180 
181         // THEN provisioning successful intent should be sent to the dpc.
182         verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE);
183 
184         // THEN an ordered broadcast should be sent to the DPC
185         verifyOrderedBroadcast();
186     }
187 
188     @SmallTest
testDeviceOwner()189     public void testDeviceOwner() {
190         // GIVEN that provisioningInitiallyDone has never been called
191         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
192         // GIVEN that we've provisioned a managed profile after SUW
193         final ProvisioningParams params = createProvisioningParams(
194                 ACTION_PROVISION_MANAGED_DEVICE);
195         when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false);
196 
197         // WHEN calling provisioningInitiallyDone
198         mController.provisioningInitiallyDone(params);
199 
200         // THEN the user provisioning state should be marked as initially done
201         verify(mHelper).markUserProvisioningStateInitiallyDone(params);
202         // THEN the provisioning params have been stored and will be read in provisioningFinalized
203 
204         // GIVEN that the provisioning state is now incomplete
205         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
206 
207         // WHEN calling provisioningFinalized
208         mController.provisioningFinalized();
209 
210         // THEN the user provisioning state is finalized
211         verify(mHelper).markUserProvisioningStateFinalized(params);
212 
213         // THEN provisioning successful intent should be sent to the dpc.
214         verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId()));
215 
216         // THEN a broadcast was sent to the primary user
217         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
218         verify(mContext).sendBroadcast(intentCaptor.capture());
219 
220         // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE
221         assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction());
222         // THEN the intent should be sent to the admin receiver
223         assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent());
224         // THEN the admin extras bundle should contain mdm extras
225         assertExtras(intentCaptor.getValue());
226     }
227 
verifyOrderedBroadcast()228     private void verifyOrderedBroadcast() {
229         // THEN an ordered broadcast should be sent to the DPC
230         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
231         verify(mContext).sendOrderedBroadcastAsUser(
232                 intentCaptor.capture(),
233                 eq(MANAGED_PROFILE_USER_HANDLE),
234                 eq(null),
235                 any(BroadcastReceiver.class),
236                 eq(null),
237                 eq(Activity.RESULT_OK),
238                 eq(null),
239                 eq(null));
240         // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE
241         assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction());
242         // THEN the intent should be sent to the admin receiver
243         assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent());
244         // THEN the admin extras bundle should contain mdm extras
245         assertExtras(intentCaptor.getValue());
246     }
247 
verifyDpcLaunchedForUser(UserHandle userHandle)248     private void verifyDpcLaunchedForUser(UserHandle userHandle) {
249         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
250         verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(userHandle));
251         // THEN the intent should be ACTION_PROVISIONING_SUCCESSFUL
252         assertEquals(ACTION_PROVISIONING_SUCCESSFUL, intentCaptor.getValue().getAction());
253         // THEN the intent should only be sent to the dpc
254         assertEquals(TEST_MDM_PACKAGE_NAME, intentCaptor.getValue().getPackage());
255         // THEN the admin extras bundle should contain mdm extras
256         assertExtras(intentCaptor.getValue());
257     }
258 
assertExtras(Intent intent)259     private void assertExtras(Intent intent) {
260         TestUtils.bundleEquals(TEST_MDM_EXTRA_BUNDLE,
261                 (PersistableBundle) intent.getExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE));
262     }
263 
createProvisioningParams(String action)264     private ProvisioningParams createProvisioningParams(String action) {
265         return new ProvisioningParams.Builder()
266                 .setDeviceAdminComponentName(TEST_MDM_ADMIN)
267                 .setProvisioningAction(action)
268                 .setAdminExtrasBundle(TEST_MDM_EXTRA_BUNDLE)
269                 .build();
270     }
271 }
272