1 /*
2  * Copyright (C) 2021 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.settings.biometrics;
18 
19 import static android.provider.Settings.ACTION_BIOMETRIC_ENROLL;
20 
21 import static androidx.test.espresso.intent.Intents.intended;
22 import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
23 
24 import static com.google.common.truth.Truth.assertThat;
25 
26 import static org.junit.Assume.assumeTrue;
27 
28 import android.content.Context;
29 import android.content.Intent;
30 import android.content.pm.PackageManager;
31 import android.os.UserHandle;
32 
33 import androidx.test.core.app.ActivityScenario;
34 import androidx.test.core.app.ApplicationProvider;
35 import androidx.test.espresso.intent.Intents;
36 import androidx.test.ext.junit.runners.AndroidJUnit4;
37 import androidx.test.filters.MediumTest;
38 
39 import com.android.internal.widget.LockPatternChecker;
40 import com.android.internal.widget.LockPatternUtils;
41 import com.android.internal.widget.LockscreenCredential;
42 import com.android.settings.biometrics.face.FaceEnrollIntroduction;
43 import com.android.settings.biometrics.fingerprint.FingerprintEnrollIntroduction;
44 import com.android.settings.password.ChooseLockGeneric;
45 import com.android.settings.password.ChooseLockSettingsHelper;
46 import com.android.settings.password.ConfirmLockPassword;
47 import com.android.settings.testutils.AdbUtils;
48 
49 import org.junit.After;
50 import org.junit.Before;
51 import org.junit.Test;
52 import org.junit.runner.RunWith;
53 
54 @RunWith(AndroidJUnit4.class)
55 @MediumTest
56 public class BiometricEnrollActivityTest {
57 
58     private static final String TAG = "BiometricEnrollActivityTest";
59     private static final int ADB_TIMEOUT_MS = 5000;
60     private static final String TEST_PIN = "1234";
61 
62     private final Context  mContext = ApplicationProvider.getApplicationContext();
63     private boolean mHasFace;
64     private boolean mHasFingerprint;
65 
66     @Before
setup()67     public void setup() {
68         Intents.init();
69         final PackageManager pm = mContext.getPackageManager();
70         mHasFingerprint = pm.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
71         mHasFace = pm.hasSystemFeature(PackageManager.FEATURE_FACE);
72     }
73 
74     @After
teardown()75     public void teardown() throws Exception {
76         Intents.release();
77         AdbUtils.checkStringInAdbCommandOutput(TAG, "locksettings clear --old " + TEST_PIN,
78                 "", "", ADB_TIMEOUT_MS);
79     }
80 
81     @Test
launchWithoutPin_setsPin()82     public void launchWithoutPin_setsPin() {
83         try (ActivityScenario<BiometricEnrollActivity> scenario =
84                      ActivityScenario.launch(getIntent())) {
85             intended(hasComponent(ChooseLockGeneric.class.getName()));
86         }
87     }
88 
89     @Test
launchWithPin_confirmsPin()90     public void launchWithPin_confirmsPin() throws Exception  {
91         setPin();
92         try (ActivityScenario<BiometricEnrollActivity> scenario =
93                      ActivityScenario.launch(getIntent())) {
94             intended(hasComponent(ConfirmLockPassword.InternalActivity.class.getName()));
95         }
96     }
97 
98     @Test
launchWithPinAndPwHandle_confirmsPin()99     public void launchWithPinAndPwHandle_confirmsPin() throws Exception {
100         assumeTrue(mHasFace || mHasFingerprint);
101 
102         setPin();
103         final Intent intent = getIntent(true /* useInternal */);
104         LockPatternChecker.verifyCredential(new LockPatternUtils(mContext),
105                 LockscreenCredential.createPin(TEST_PIN), UserHandle.myUserId(),
106                 LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, (response, timeoutMs) -> {
107                     assertThat(response.containsGatekeeperPasswordHandle()).isTrue();
108                     intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_GK_PW_HANDLE,
109                             response.getGatekeeperPasswordHandle());
110                 }).get();
111 
112 
113 
114         try (ActivityScenario<BiometricEnrollActivity> scenario =
115                      ActivityScenario.launch(intent)) {
116             intended(hasComponent(mHasFace
117                     ? FaceEnrollIntroduction.class.getName()
118                     : FingerprintEnrollIntroduction.class.getName()));
119         }
120     }
121 
getIntent()122     private Intent getIntent() {
123         return getIntent(false /* useInternal */);
124     }
125 
getIntent(boolean useInternal)126     private Intent getIntent(boolean useInternal) {
127         final Intent intent = new Intent(mContext, useInternal
128                 ? BiometricEnrollActivity.InternalActivity.class : BiometricEnrollActivity.class);
129         intent.setAction(ACTION_BIOMETRIC_ENROLL);
130         return intent;
131     }
132 
setPin()133     private static void setPin() throws Exception  {
134         assertThat(AdbUtils.checkStringInAdbCommandOutput(TAG, "locksettings set-pin " + TEST_PIN,
135                 "Pin set to ", "'" + TEST_PIN + "'", ADB_TIMEOUT_MS)).isTrue();
136     }
137 }
138