Home | History | Annotate | Download | only in finalization
      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
     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.findDeviceAdmin(null, TEST_MDM_ADMIN, mContext))
     75                 .thenReturn(TEST_MDM_ADMIN);
     76         when(mUtils.canResolveIntentAsUser(any(Context.class), any(Intent.class), anyInt()))
     77                 .thenReturn(true);
     78         when(mContext.getFilesDir()).thenReturn(getContext().getFilesDir());
     79 
     80         mController = new FinalizationController(mContext, mUtils, mSettingsFacade, mHelper);
     81     }
     82 
     83     @Override
     84     public void tearDown() throws Exception {
     85         mController.loadProvisioningParamsAndClearFile();
     86     }
     87 
     88     @SmallTest
     89     public void testInitiallyDone_alreadyCalled() {
     90         // GIVEN that provisioningInitiallyDone has already been called
     91         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
     92         final ProvisioningParams params = createProvisioningParams(
     93                 ACTION_PROVISION_MANAGED_PROFILE);
     94 
     95         // WHEN calling provisioningInitiallyDone
     96         mController.provisioningInitiallyDone(params);
     97 
     98         // THEN nothing should happen
     99         verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params);
    100         verify(mHelper, never()).markUserProvisioningStateFinalized(params);
    101     }
    102 
    103     @SmallTest
    104     public void testFinalized_alreadyCalled() {
    105         // GIVEN that provisioningInitiallyDone has already been called
    106         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
    107         final ProvisioningParams params = createProvisioningParams(
    108                 ACTION_PROVISION_MANAGED_PROFILE);
    109 
    110         // WHEN calling provisioningFinalized
    111         mController.provisioningFinalized();
    112 
    113         // THEN nothing should happen
    114         verify(mHelper, never()).markUserProvisioningStateInitiallyDone(params);
    115         verify(mHelper, never()).markUserProvisioningStateFinalized(params);
    116     }
    117 
    118     @SmallTest
    119     public void testFinalized_noParamsStored() {
    120         // GIVEN that the user provisioning state is correct
    121         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
    122 
    123         // WHEN calling provisioningFinalized
    124         mController.provisioningFinalized();
    125 
    126         // THEN nothing should happen
    127         verify(mHelper, never())
    128                 .markUserProvisioningStateInitiallyDone(any(ProvisioningParams.class));
    129         verify(mHelper, never()).markUserProvisioningStateFinalized(any(ProvisioningParams.class));
    130     }
    131 
    132     @SmallTest
    133     public void testManagedProfileAfterSuw() {
    134         // GIVEN that provisioningInitiallyDone has never been called
    135         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
    136         // GIVEN that we've provisioned a managed profile after SUW
    137         final ProvisioningParams params = createProvisioningParams(
    138                 ACTION_PROVISION_MANAGED_PROFILE);
    139         when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(true);
    140         when(mUtils.getManagedProfile(mContext))
    141                 .thenReturn(MANAGED_PROFILE_USER_HANDLE);
    142 
    143         // WHEN calling provisioningInitiallyDone
    144         mController.provisioningInitiallyDone(params);
    145 
    146         // THEN the user provisioning state should be marked as initially done
    147         verify(mHelper).markUserProvisioningStateInitiallyDone(params);
    148 
    149         // THEN provisioning successful intent should be sent to the dpc.
    150         verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE);
    151 
    152         // THEN an ordered broadcast should be sent to the DPC
    153         verifyOrderedBroadcast();
    154     }
    155 
    156     @SmallTest
    157     public void testManagedProfileDuringSuw() {
    158         // GIVEN that provisioningInitiallyDone has never been called
    159         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
    160         // GIVEN that we've provisioned a managed profile after SUW
    161         final ProvisioningParams params = createProvisioningParams(
    162                 ACTION_PROVISION_MANAGED_PROFILE);
    163         when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false);
    164         when(mUtils.getManagedProfile(mContext))
    165                 .thenReturn(MANAGED_PROFILE_USER_HANDLE);
    166 
    167         // WHEN calling provisioningInitiallyDone
    168         mController.provisioningInitiallyDone(params);
    169 
    170         // THEN the user provisioning state should be marked as initially done
    171         verify(mHelper).markUserProvisioningStateInitiallyDone(params);
    172         // THEN the provisioning params have been stored and will be read in provisioningFinalized
    173 
    174         // GIVEN that the provisioning state is now incomplete
    175         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
    176 
    177         // WHEN calling provisioningFinalized
    178         mController.provisioningFinalized();
    179 
    180         // THEN the user provisioning state is finalized
    181         verify(mHelper).markUserProvisioningStateFinalized(params);
    182 
    183         // THEN provisioning successful intent should be sent to the dpc.
    184         verifyDpcLaunchedForUser(MANAGED_PROFILE_USER_HANDLE);
    185 
    186         // THEN an ordered broadcast should be sent to the DPC
    187         verifyOrderedBroadcast();
    188     }
    189 
    190     @SmallTest
    191     public void testDeviceOwner() {
    192         // GIVEN that provisioningInitiallyDone has never been called
    193         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(true);
    194         // GIVEN that we've provisioned a managed profile after SUW
    195         final ProvisioningParams params = createProvisioningParams(
    196                 ACTION_PROVISION_MANAGED_DEVICE);
    197         when(mSettingsFacade.isUserSetupCompleted(mContext)).thenReturn(false);
    198 
    199         // WHEN calling provisioningInitiallyDone
    200         mController.provisioningInitiallyDone(params);
    201 
    202         // THEN the user provisioning state should be marked as initially done
    203         verify(mHelper).markUserProvisioningStateInitiallyDone(params);
    204         // THEN the provisioning params have been stored and will be read in provisioningFinalized
    205 
    206         // GIVEN that the provisioning state is now incomplete
    207         when(mHelper.isStateUnmanagedOrFinalized()).thenReturn(false);
    208 
    209         // WHEN calling provisioningFinalized
    210         mController.provisioningFinalized();
    211 
    212         // THEN the user provisioning state is finalized
    213         verify(mHelper).markUserProvisioningStateFinalized(params);
    214 
    215         // THEN provisioning successful intent should be sent to the dpc.
    216         verifyDpcLaunchedForUser(UserHandle.of(UserHandle.myUserId()));
    217 
    218         // THEN a broadcast was sent to the primary user
    219         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
    220         verify(mContext).sendBroadcast(intentCaptor.capture());
    221 
    222         // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE
    223         assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction());
    224         // THEN the intent should be sent to the admin receiver
    225         assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent());
    226         // THEN the admin extras bundle should contain mdm extras
    227         assertExtras(intentCaptor.getValue());
    228     }
    229 
    230     private void verifyOrderedBroadcast() {
    231         // THEN an ordered broadcast should be sent to the DPC
    232         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
    233         verify(mContext).sendOrderedBroadcastAsUser(
    234                 intentCaptor.capture(),
    235                 eq(MANAGED_PROFILE_USER_HANDLE),
    236                 eq(null),
    237                 any(BroadcastReceiver.class),
    238                 eq(null),
    239                 eq(Activity.RESULT_OK),
    240                 eq(null),
    241                 eq(null));
    242         // THEN the intent should be ACTION_PROFILE_PROVISIONING_COMPLETE
    243         assertEquals(ACTION_PROFILE_PROVISIONING_COMPLETE, intentCaptor.getValue().getAction());
    244         // THEN the intent should be sent to the admin receiver
    245         assertEquals(TEST_MDM_ADMIN, intentCaptor.getValue().getComponent());
    246         // THEN the admin extras bundle should contain mdm extras
    247         assertExtras(intentCaptor.getValue());
    248     }
    249 
    250     private void verifyDpcLaunchedForUser(UserHandle userHandle) {
    251         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
    252         verify(mContext).startActivityAsUser(intentCaptor.capture(), eq(userHandle));
    253         // THEN the intent should be ACTION_PROVISIONING_SUCCESSFUL
    254         assertEquals(ACTION_PROVISIONING_SUCCESSFUL, intentCaptor.getValue().getAction());
    255         // THEN the intent should only be sent to the dpc
    256         assertEquals(TEST_MDM_PACKAGE_NAME, intentCaptor.getValue().getPackage());
    257         // THEN the admin extras bundle should contain mdm extras
    258         assertExtras(intentCaptor.getValue());
    259     }
    260 
    261     private void assertExtras(Intent intent) {
    262         TestUtils.bundleEquals(TEST_MDM_EXTRA_BUNDLE,
    263                 (PersistableBundle) intent.getExtra(EXTRA_PROVISIONING_ADMIN_EXTRAS_BUNDLE));
    264     }
    265 
    266     private ProvisioningParams createProvisioningParams(String action) {
    267         return new ProvisioningParams.Builder()
    268                 .setDeviceAdminComponentName(TEST_MDM_ADMIN)
    269                 .setProvisioningAction(action)
    270                 .setAdminExtrasBundle(TEST_MDM_EXTRA_BUNDLE)
    271                 .build();
    272     }
    273 }
    274