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