• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.server.biometrics.sensors.fingerprint.aidl;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import static org.mockito.Mockito.any;
22 import static org.mockito.Mockito.eq;
23 import static org.mockito.Mockito.never;
24 import static org.mockito.Mockito.times;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.hardware.biometrics.BiometricAuthenticator;
29 import android.hardware.biometrics.fingerprint.ISession;
30 import android.hardware.fingerprint.Fingerprint;
31 import android.platform.test.annotations.Presubmit;
32 import android.testing.TestableContext;
33 
34 import androidx.annotation.NonNull;
35 import androidx.test.filters.SmallTest;
36 import androidx.test.platform.app.InstrumentationRegistry;
37 
38 import com.android.server.biometrics.log.BiometricContext;
39 import com.android.server.biometrics.log.BiometricLogger;
40 import com.android.server.biometrics.sensors.ClientMonitorCallback;
41 import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
42 
43 import org.junit.Before;
44 import org.junit.Ignore;
45 import org.junit.Rule;
46 import org.junit.Test;
47 import org.mockito.ArgumentCaptor;
48 import org.mockito.Mock;
49 import org.mockito.junit.MockitoJUnit;
50 import org.mockito.junit.MockitoRule;
51 
52 import java.util.ArrayList;
53 import java.util.Arrays;
54 import java.util.HashMap;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.stream.Collectors;
58 
59 @Presubmit
60 @SmallTest
61 public class FingerprintInternalCleanupClientTest {
62 
63     private static final int SENSOR_ID = 22;
64 
65     @Rule
66     public final MockitoRule mockito = MockitoJUnit.rule();
67 
68     @Rule
69     public final TestableContext mContext = new TestableContext(
70             InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
71 
72     @Mock
73     private AidlSession mAidlSession;
74     @Mock
75     private ISession mSession;
76     @Mock
77     private BiometricLogger mLogger;
78     @Mock
79     private BiometricContext mBiometricContext;
80     @Mock
81     private FingerprintUtils mFingerprintUtils;
82     @Mock
83     private ClientMonitorCallback mCallback;
84 
85     private FingerprintInternalCleanupClient mClient;
86     private List<Integer> mAddedIds;
87 
88     @Before
setup()89     public void setup() {
90         when(mAidlSession.getSession()).thenReturn(mSession);
91         mAddedIds = new ArrayList<>();
92     }
93 
94     @Ignore("TODO(b/229015801): verify cleanup behavior")
95     @Test
removesUnknownTemplate()96     public void removesUnknownTemplate() throws Exception {
97         mClient = createClient();
98 
99         final List<Fingerprint> templates = List.of(
100                 new Fingerprint("one", 1, 1),
101                 new Fingerprint("two", 2, 1)
102         );
103         mClient.start(mCallback);
104         for (int i = templates.size() - 1; i >= 0; i--) {
105             mClient.getCurrentEnumerateClient().onEnumerationResult(templates.get(i), i);
106         }
107         for (int i = templates.size() - 1; i >= 0; i--) {
108             mClient.getCurrentRemoveClient().onRemoved(templates.get(i), 0);
109         }
110 
111         assertThat(mAddedIds).isEmpty();
112         final ArgumentCaptor<int[]> captor = ArgumentCaptor.forClass(int[].class);
113         verify(mSession, times(2)).removeEnrollments(captor.capture());
114         assertThat(captor.getAllValues().stream()
115                 .flatMap(x -> Arrays.stream(x).boxed())
116                 .collect(Collectors.toList()))
117                 .containsExactly(1, 2);
118         verify(mCallback).onClientFinished(eq(mClient), eq(true));
119     }
120 
121     @Test
addsUnknownTemplateWhenVirtualIsEnabled()122     public void addsUnknownTemplateWhenVirtualIsEnabled() throws Exception {
123         mClient = createClient();
124         mClient.setFavorHalEnrollments();
125 
126         final List<Fingerprint> templates = List.of(
127                 new Fingerprint("one", 1, 1),
128                 new Fingerprint("two", 2, 1)
129         );
130         mClient.start(mCallback);
131         for (int i = templates.size() - 1; i >= 0; i--) {
132             mClient.getCurrentEnumerateClient().onEnumerationResult(templates.get(i), i);
133         }
134 
135         assertThat(mAddedIds).containsExactly(1, 2);
136         verify(mSession, never()).removeEnrollments(any());
137         verify(mCallback).onClientFinished(eq(mClient), eq(true));
138     }
139 
140     @Test
cleanupUnknownHalTemplatesAfterEnumerationWhenVirtualIsDisabled()141     public void cleanupUnknownHalTemplatesAfterEnumerationWhenVirtualIsDisabled() {
142         mClient = createClient();
143 
144         final List<Fingerprint> templates = List.of(
145                 new Fingerprint("one", 1, 1),
146                 new Fingerprint("two", 2, 1),
147                 new Fingerprint("three", 3, 1)
148         );
149         mClient.start(mCallback);
150         for (int i = templates.size() - 1; i >= 0; i--) {
151             mClient.getCurrentEnumerateClient().onEnumerationResult(templates.get(i), i);
152         }
153         // The first template is removed after enumeration
154         assertThat(mClient.getUnknownHALTemplates().size()).isEqualTo(2);
155 
156         // Simulate finishing the removal of the first template.
157         // |remaining| is 0 because one FingerprintRemovalClient is associated with only one
158         // biometrics ID.
159         mClient.getCurrentRemoveClient().onRemoved(templates.get(0), 0);
160         assertThat(mClient.getUnknownHALTemplates().size()).isEqualTo(1);
161         // Simulate finishing the removal of the second template.
162         mClient.getCurrentRemoveClient().onRemoved(templates.get(1), 0);
163         assertThat(mClient.getUnknownHALTemplates()).isEmpty();
164     }
165 
createClient()166     protected FingerprintInternalCleanupClient createClient() {
167         final Map<Integer, Long> authenticatorIds = new HashMap<>();
168         return new FingerprintInternalCleanupClient(mContext, () -> mAidlSession, 2 /* userId */,
169                 "the.test.owner", SENSOR_ID, mLogger, mBiometricContext,
170                 mFingerprintUtils, authenticatorIds) {
171             @Override
172             protected void onAddUnknownTemplate(int userId,
173                     @NonNull BiometricAuthenticator.Identifier identifier) {
174                 mAddedIds.add(identifier.getBiometricId());
175             }
176         };
177     }
178 }
179