Home | History | Annotate | Download | only in task
      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.managedprovisioning.task;
     18 
     19 import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE;
     20 import static org.mockito.Matchers.eq;
     21 import static org.mockito.Mockito.doAnswer;
     22 import static org.mockito.Mockito.verify;
     23 import static org.mockito.Mockito.verifyNoMoreInteractions;
     24 import static org.mockito.Mockito.verifyZeroInteractions;
     25 import static org.mockito.Mockito.when;
     26 
     27 import android.app.IActivityManager;
     28 import android.content.BroadcastReceiver;
     29 import android.content.Context;
     30 import android.content.Intent;
     31 import android.os.Handler;
     32 import android.os.HandlerThread;
     33 import android.os.RemoteException;
     34 import android.os.UserHandle;
     35 import android.test.AndroidTestCase;
     36 import android.test.suitebuilder.annotation.SmallTest;
     37 
     38 import com.android.managedprovisioning.model.ProvisioningParams;
     39 
     40 import org.mockito.ArgumentCaptor;
     41 import org.mockito.Mock;
     42 import org.mockito.MockitoAnnotations;
     43 import org.mockito.invocation.InvocationOnMock;
     44 
     45 import java.util.concurrent.CountDownLatch;
     46 import java.util.concurrent.TimeUnit;
     47 
     48 /**
     49  * Unit tests for {@link StartManagedProfileTask}.
     50  */
     51 public class StartManagedProfileTaskTest extends AndroidTestCase {
     52     private static final int TEST_USER_ID = 123;
     53     private static final String TEST_MDM_PACKAGE_NAME = "com.test.mdm";
     54     private static final ProvisioningParams TEST_PARAMS = new ProvisioningParams.Builder()
     55             .setDeviceAdminPackageName(TEST_MDM_PACKAGE_NAME)
     56             .setProvisioningAction(ACTION_PROVISION_MANAGED_PROFILE)
     57             .build();
     58     private static final Intent UNLOCK_INTENT = new Intent(Intent.ACTION_USER_UNLOCKED)
     59             .putExtra(Intent.EXTRA_USER_HANDLE, TEST_USER_ID);
     60 
     61     @Mock private IActivityManager mIActivityManager;
     62     @Mock private Context mContext;
     63     @Mock private AbstractProvisioningTask.Callback mCallback;
     64     private ArgumentCaptor<BroadcastReceiver> mReceiverCaptor =
     65             ArgumentCaptor.forClass(BroadcastReceiver.class);
     66 
     67     private StartManagedProfileTask mTask;
     68     private HandlerThread mHandlerThread;
     69     private final CountDownLatch mStartInBackgroundLatch = new CountDownLatch(1);
     70     private final CountDownLatch mSuccessLatch = new CountDownLatch(1);
     71 
     72     public void setUp() {
     73         // this is necessary for mockito to work
     74         System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
     75         MockitoAnnotations.initMocks(this);
     76 
     77         mHandlerThread = new HandlerThread("Test thread");
     78         mHandlerThread.start();
     79 
     80         mTask = new StartManagedProfileTask(mIActivityManager, mContext, TEST_PARAMS, mCallback);
     81 
     82         // register a countdown latch for the success callback
     83         doAnswer((InvocationOnMock invocationOnMock) -> {
     84                 mSuccessLatch.countDown();
     85                 return null;
     86             }).when(mCallback).onSuccess(mTask);
     87     }
     88 
     89     public void tearDown() {
     90         mHandlerThread.quitSafely();
     91     }
     92 
     93     @SmallTest
     94     public void testSuccess() throws Exception {
     95         // GIVEN that starting the user succeeds
     96         doAnswer((InvocationOnMock invocationOnMock) -> {
     97                 mStartInBackgroundLatch.countDown();
     98                 return true;
     99             }).when(mIActivityManager).startUserInBackground(TEST_USER_ID);
    100 
    101         // WHEN the task is run (on a handler thread to avoid deadlocks)
    102         new Handler(mHandlerThread.getLooper()).post(() -> mTask.run(TEST_USER_ID));
    103 
    104         // THEN user unlock should have been called
    105         assertTrue(mStartInBackgroundLatch.await(1, TimeUnit.SECONDS));
    106 
    107         // THEN an unlock receiver should be registered
    108         verify(mContext).registerReceiverAsUser(
    109                 mReceiverCaptor.capture(),
    110                 eq(UserHandle.of(TEST_USER_ID)),
    111                 eq(StartManagedProfileTask.UNLOCK_FILTER),
    112                 eq(null), eq(null));
    113 
    114         // THEN the success callback should not have been called
    115         verifyZeroInteractions(mCallback);
    116 
    117         // WHEN the unlock broadcast is sent
    118         mReceiverCaptor.getValue().onReceive(mContext, UNLOCK_INTENT);
    119 
    120         // THEN the success callback should be called
    121         assertTrue(mSuccessLatch.await(1, TimeUnit.SECONDS));
    122         verify(mCallback).onSuccess(mTask);
    123         verifyNoMoreInteractions(mCallback);
    124 
    125         verify(mContext).unregisterReceiver(mReceiverCaptor.getValue());
    126     }
    127 
    128     @SmallTest
    129     public void testError() throws Exception {
    130         // GIVEN that starting the user in background fails
    131         when(mIActivityManager.startUserInBackground(TEST_USER_ID)).thenReturn(false);
    132 
    133         // WHEN the task is run
    134         mTask.run(TEST_USER_ID);
    135 
    136         // THEN an unlock receiver should be registered
    137         verify(mContext).registerReceiverAsUser(
    138                 mReceiverCaptor.capture(),
    139                 eq(UserHandle.of(TEST_USER_ID)),
    140                 eq(StartManagedProfileTask.UNLOCK_FILTER),
    141                 eq(null), eq(null));
    142 
    143         // THEN the error callback should have been called
    144         verify(mCallback).onError(mTask, 0);
    145         verifyNoMoreInteractions(mCallback);
    146 
    147         verify(mContext).unregisterReceiver(mReceiverCaptor.getValue());
    148     }
    149 
    150     @SmallTest
    151     public void testRemoteException() throws Exception {
    152         // GIVEN that starting the user in background throws a remote exception
    153         when(mIActivityManager.startUserInBackground(TEST_USER_ID))
    154                 .thenThrow(new RemoteException());
    155 
    156         // WHEN the task is run
    157         mTask.run(TEST_USER_ID);
    158 
    159         // THEN an unlock receiver should be registered
    160         verify(mContext).registerReceiverAsUser(
    161                 mReceiverCaptor.capture(),
    162                 eq(UserHandle.of(TEST_USER_ID)),
    163                 eq(StartManagedProfileTask.UNLOCK_FILTER),
    164                 eq(null), eq(null));
    165 
    166         // THEN the error callback should have been called
    167         verify(mCallback).onError(mTask, 0);
    168         verifyNoMoreInteractions(mCallback);
    169 
    170         verify(mContext).unregisterReceiver(mReceiverCaptor.getValue());
    171     }
    172 }
    173