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