blob: 80385e69cfa4c4fb73e649e7ffbe3eaf90236a9f [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.keyguard;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.AdditionalAnswers.answerVoid;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.admin.IKeyguardCallback;
import android.app.admin.IKeyguardClient;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Handler;
import android.os.RemoteException;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.ViewUtils;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceView;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.SysuiTestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWithLooper
@RunWith(AndroidTestingRunner.class)
@SmallTest
public class AdminSecondaryLockScreenControllerTest extends SysuiTestCase {
private static final int TARGET_USER_ID = KeyguardUpdateMonitor.getCurrentUser();
private AdminSecondaryLockScreenController mTestController;
private ComponentName mComponentName;
private Intent mServiceIntent;
private TestableLooper mTestableLooper;
private KeyguardSecurityContainer mKeyguardSecurityContainer;
@Mock
private Handler mHandler;
@Mock
private IKeyguardClient.Stub mKeyguardClient;
@Mock
private KeyguardSecurityCallback mKeyguardCallback;
@Mock
private KeyguardUpdateMonitor mUpdateMonitor;
@Mock
private SurfaceControlViewHost.SurfacePackage mSurfacePackage;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mKeyguardSecurityContainer = spy(new KeyguardSecurityContainer(mContext));
ViewUtils.attachView(mKeyguardSecurityContainer);
mTestableLooper = TestableLooper.get(this);
mComponentName = new ComponentName(mContext, "FakeKeyguardClient.class");
mServiceIntent = new Intent().setComponent(mComponentName);
mContext.addMockService(mComponentName, mKeyguardClient);
// Have Stub.asInterface return the mocked interface.
when(mKeyguardClient.queryLocalInterface(anyString())).thenReturn(mKeyguardClient);
when(mKeyguardClient.asBinder()).thenReturn(mKeyguardClient);
mTestController = new AdminSecondaryLockScreenController.Factory(
mContext, mKeyguardSecurityContainer, mUpdateMonitor, mHandler)
.create(mKeyguardCallback);
}
@After
public void tearDown() {
ViewUtils.detachView(mKeyguardSecurityContainer);
}
@Test
public void testShow() throws Exception {
doAnswer(invocation -> {
IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
callback.onRemoteContentReady(mSurfacePackage);
return null;
}).when(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
mTestController.show(mServiceIntent);
verifySurfaceReady();
assertThat(mContext.isBound(mComponentName)).isTrue();
}
@Test
public void testShow_dismissedByCallback() throws Exception {
doAnswer(answerVoid(Runnable::run)).when(mHandler).post(any(Runnable.class));
doAnswer(invocation -> {
IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
callback.onDismiss();
return null;
}).when(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
mTestController.show(mServiceIntent);
verifyViewDismissed(verifySurfaceReady());
}
@Test
public void testHide() throws Exception {
// Show the view first, then hide.
doAnswer(invocation -> {
IKeyguardCallback callback = (IKeyguardCallback) invocation.getArguments()[1];
callback.onRemoteContentReady(mSurfacePackage);
return null;
}).when(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
mTestController.show(mServiceIntent);
SurfaceView v = verifySurfaceReady();
mTestController.hide();
verify(mKeyguardSecurityContainer).removeView(v);
assertThat(mContext.isBound(mComponentName)).isFalse();
}
@Test
public void testHide_notShown() throws Exception {
mTestController.hide();
// Nothing should happen if trying to hide when the view isn't attached yet.
verify(mKeyguardSecurityContainer, never()).removeView(any(SurfaceView.class));
}
@Test
public void testDismissed_onCreateKeyguardSurface_RemoteException() throws Exception {
doThrow(new RemoteException()).when(mKeyguardClient)
.onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
mTestController.show(mServiceIntent);
verifyViewDismissed(verifySurfaceReady());
}
@Test
public void testDismissed_onCreateKeyguardSurface_timeout() throws Exception {
// Mocked KeyguardClient never handles the onCreateKeyguardSurface, so the operation
// times out, resulting in the view being dismissed.
doAnswer(answerVoid(Runnable::run)).when(mHandler)
.postDelayed(any(Runnable.class), anyLong());
mTestController.show(mServiceIntent);
verifyViewDismissed(verifySurfaceReady());
}
private SurfaceView verifySurfaceReady() throws Exception {
mTestableLooper.processAllMessages();
ArgumentCaptor<SurfaceView> captor = ArgumentCaptor.forClass(SurfaceView.class);
verify(mKeyguardSecurityContainer).addView(captor.capture());
mTestableLooper.processAllMessages();
verify(mKeyguardClient).onCreateKeyguardSurface(any(), any(IKeyguardCallback.class));
return captor.getValue();
}
private void verifyViewDismissed(SurfaceView v) throws Exception {
verify(mKeyguardSecurityContainer).removeView(v);
verify(mKeyguardCallback).dismiss(true, TARGET_USER_ID, true, SecurityMode.Invalid);
assertThat(mContext.isBound(mComponentName)).isFalse();
}
}