Add plumbing and placeholder screens for parental consent flow.
Bug: 188847063 Test: adb shell am start -a android.settings.BIOMETRIC_ENROLL --ez require_consent true Test: atest com.android.settings.biometrics.ParentalConsentHelperTest Change-Id: Ie136036d5f550775fd0b021979581a5d222f1b68
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.settings.biometrics;
|
||||
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
|
||||
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_NONE;
|
||||
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.EXTRA_KEY_MODALITY;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_DENIED;
|
||||
import static com.android.settings.biometrics.BiometricEnrollBase.RESULT_CONSENT_GRANTED;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import com.android.settings.biometrics.face.FaceEnrollParentalConsent;
|
||||
import com.android.settings.biometrics.fingerprint.FingerprintEnrollParentalConsent;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ParentalConsentHelperTest {
|
||||
|
||||
private static final int REQUEST_CODE = 12;
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMocks = MockitoJUnit.rule();
|
||||
|
||||
@Mock
|
||||
private Activity mRootActivity;
|
||||
@Mock
|
||||
private Intent mRootActivityIntent;
|
||||
@Captor
|
||||
ArgumentCaptor<Intent> mLastStarted;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
when(mRootActivity.getIntent()).thenAnswer(invocation -> mRootActivityIntent);
|
||||
when(mRootActivityIntent.getBundleExtra(any())).thenAnswer(invocation -> null);
|
||||
when(mRootActivityIntent.getStringExtra(any())).thenAnswer(invocation -> null);
|
||||
when(mRootActivityIntent.getBooleanExtra(any(), anyBoolean()))
|
||||
.thenAnswer(invocation -> invocation.getArguments()[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_all_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, true /* grantFace */,
|
||||
true /* requireFingerprint */, true /* grantFace */,
|
||||
90 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_nothing_to_consent() {
|
||||
testLaunchNext(
|
||||
false /* requireFace */, false /* grantFace */,
|
||||
false /* requireFingerprint */, false /* grantFace */,
|
||||
80 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_no_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, false /* grantFace */,
|
||||
70 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_only_face_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, true /* grantFace */,
|
||||
true /* requireFingerprint */, false /* grantFace */,
|
||||
60 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_and_fingerprint_only_fingerprint_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, true /* grantFace */,
|
||||
50 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_with_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, true /* grantFace */,
|
||||
false /* requireFingerprint */, false /* grantFace */,
|
||||
40 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_face_without_consent() {
|
||||
testLaunchNext(
|
||||
true /* requireFace */, false /* grantFace */,
|
||||
false /* requireFingerprint */, false /* grantFace */,
|
||||
30 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_fingerprint_with_consent() {
|
||||
testLaunchNext(
|
||||
false /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, true /* grantFace */,
|
||||
20 /* gkpw */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLaunchNext_fingerprint_without_consent() {
|
||||
testLaunchNext(
|
||||
false /* requireFace */, false /* grantFace */,
|
||||
true /* requireFingerprint */, false /* grantFace */,
|
||||
10 /* gkpw */);
|
||||
}
|
||||
|
||||
private void testLaunchNext(
|
||||
boolean requireFace, boolean grantFace,
|
||||
boolean requireFingerprint, boolean grantFingerprint,
|
||||
long gkpw) {
|
||||
final List<Pair<String, Boolean>> expectedLaunches = new ArrayList<>();
|
||||
if (requireFace) {
|
||||
expectedLaunches.add(new Pair(FaceEnrollParentalConsent.class.getName(), grantFace));
|
||||
}
|
||||
if (requireFingerprint) {
|
||||
expectedLaunches.add(
|
||||
new Pair(FingerprintEnrollParentalConsent.class.getName(), grantFingerprint));
|
||||
}
|
||||
|
||||
// initial consent status
|
||||
final ParentalConsentHelper helper =
|
||||
new ParentalConsentHelper(requireFace, requireFingerprint, gkpw);
|
||||
assertThat(ParentalConsentHelper.hasFaceConsent(helper.getConsentResult()))
|
||||
.isFalse();
|
||||
assertThat(ParentalConsentHelper.hasFingerprintConsent(helper.getConsentResult()))
|
||||
.isFalse();
|
||||
|
||||
// check expected launches
|
||||
for (int i = 0; i <= expectedLaunches.size(); i++) {
|
||||
final Pair<String, Boolean> expected = i > 0 ? expectedLaunches.get(i - 1) : null;
|
||||
final boolean launchedNext = i == 0
|
||||
? helper.launchNext(mRootActivity, REQUEST_CODE)
|
||||
: helper.launchNext(mRootActivity, REQUEST_CODE,
|
||||
expected.second ? RESULT_CONSENT_GRANTED : RESULT_CONSENT_DENIED,
|
||||
getResultIntent(getStartedModality(expected.first)));
|
||||
assertThat(launchedNext).isEqualTo(i < expectedLaunches.size());
|
||||
}
|
||||
verify(mRootActivity, times(expectedLaunches.size()))
|
||||
.startActivityForResult(mLastStarted.capture(), eq(REQUEST_CODE));
|
||||
assertThat(mLastStarted.getAllValues()
|
||||
.stream().map(i -> i.getComponent().getClassName()).collect(Collectors.toList()))
|
||||
.containsExactlyElementsIn(
|
||||
expectedLaunches.stream().map(i -> i.first).collect(Collectors.toList()))
|
||||
.inOrder();
|
||||
if (!expectedLaunches.isEmpty()) {
|
||||
assertThat(mLastStarted.getAllValues()
|
||||
.stream().map(BiometricUtils::getGatekeeperPasswordHandle).distinct()
|
||||
.collect(Collectors.toList()))
|
||||
.containsExactly(gkpw);
|
||||
}
|
||||
|
||||
// final consent status
|
||||
assertThat(ParentalConsentHelper.hasFaceConsent(helper.getConsentResult()))
|
||||
.isEqualTo(requireFace && grantFace);
|
||||
assertThat(ParentalConsentHelper.hasFingerprintConsent(helper.getConsentResult()))
|
||||
.isEqualTo(requireFingerprint && grantFingerprint);
|
||||
}
|
||||
|
||||
private static Intent getResultIntent(@BiometricAuthenticator.Modality int modality) {
|
||||
final Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_KEY_MODALITY, modality);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@BiometricAuthenticator.Modality
|
||||
private static int getStartedModality(String name) {
|
||||
if (name.equals(FaceEnrollParentalConsent.class.getName())) {
|
||||
return TYPE_FACE;
|
||||
}
|
||||
if (name.equals(FingerprintEnrollParentalConsent.class.getName())) {
|
||||
return TYPE_FINGERPRINT;
|
||||
}
|
||||
return TYPE_NONE;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user