Merge "Reduce binder calls"

This commit is contained in:
Diya Bera
2023-01-26 21:35:24 +00:00
committed by Android (Google) Code Review
8 changed files with 213 additions and 14 deletions

View File

@@ -26,6 +26,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemService;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants;
@@ -87,6 +88,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
private CryptoObject mCryptoObject;
private Face mRemovalFace;
private Handler mHandler;
private List<FaceSensorPropertiesInternal> mProps = new ArrayList<>();
private final IFaceServiceReceiver mServiceReceiver = new IFaceServiceReceiver.Stub() {
@@ -168,6 +170,16 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
Slog.v(TAG, "FaceAuthenticationManagerService was null");
}
mHandler = new MyHandler(context);
if (context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
== PackageManager.PERMISSION_GRANTED) {
addAuthenticatorsRegisteredCallback(new IFaceAuthenticatorsRegisteredCallback.Stub() {
@Override
public void onAllAuthenticatorsRegistered(
@NonNull List<FaceSensorPropertiesInternal> sensors) {
mProps = sensors;
}
});
}
}
/**
@@ -664,14 +676,14 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
@NonNull
public List<FaceSensorPropertiesInternal> getSensorPropertiesInternal() {
try {
if (mService == null) {
return new ArrayList<>();
if (!mProps.isEmpty() || mService == null) {
return mProps;
}
return mService.getSensorPropertiesInternal(mContext.getOpPackageName());
} catch (RemoteException e) {
e.rethrowFromSystemServer();
}
return new ArrayList<>();
return mProps;
}
/**

View File

@@ -153,6 +153,7 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
@Nullable private RemoveTracker mRemoveTracker;
private Handler mHandler;
@Nullable private float[] mEnrollStageThresholds;
private List<FingerprintSensorPropertiesInternal> mProps = new ArrayList<>();
/**
* Retrieves a list of properties for all fingerprint sensors on the device.
@@ -1185,8 +1186,8 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
@NonNull
public List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal() {
try {
if (mService == null) {
return new ArrayList<>();
if (!mProps.isEmpty() || mService == null) {
return mProps;
}
return mService.getSensorPropertiesInternal(mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1502,6 +1503,17 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
Slog.v(TAG, "FingerprintService was null");
}
mHandler = new MyHandler(context);
if (context.checkCallingOrSelfPermission(USE_BIOMETRIC_INTERNAL)
== PackageManager.PERMISSION_GRANTED) {
addAuthenticatorsRegisteredCallback(
new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
@Override
public void onAllAuthenticatorsRegistered(
@NonNull List<FingerprintSensorPropertiesInternal> sensors) {
mProps = sensors;
}
});
}
}
private int getCurrentUserId() {

View File

@@ -929,7 +929,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@Override
public void run() {
mLogger.logRetryAfterFpHwUnavailable(mHardwareFingerprintUnavailableRetryCount);
if (mFpm.isHardwareDetected()) {
if (!mFingerprintSensorProperties.isEmpty()) {
updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
} else if (mHardwareFingerprintUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
mHardwareFingerprintUnavailableRetryCount++;
@@ -2346,14 +2346,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
}
private void updateFaceEnrolled(int userId) {
mIsFaceEnrolled = whitelistIpcs(
() -> mFaceManager != null && mFaceManager.isHardwareDetected()
&& mBiometricEnabledForUser.get(userId))
mIsFaceEnrolled = mFaceManager != null && !mFaceSensorProperties.isEmpty()
&& mBiometricEnabledForUser.get(userId)
&& mAuthController.isFaceAuthEnrolled(userId);
}
public boolean isFaceSupported() {
return mFaceManager != null && mFaceManager.isHardwareDetected();
return mFaceManager != null && !mFaceSensorProperties.isEmpty();
}
/**
@@ -2972,7 +2971,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
@VisibleForTesting
boolean isUnlockWithFingerprintPossible(int userId) {
// TODO (b/242022358), make this rely on onEnrollmentChanged event and update it only once.
mIsUnlockWithFingerprintPossible.put(userId, mFpm != null && mFpm.isHardwareDetected()
mIsUnlockWithFingerprintPossible.put(userId, mFpm != null
&& !mFingerprintSensorProperties.isEmpty()
&& !isFingerprintDisabled(userId) && mFpm.hasEnrolledTemplates(userId));
return mIsUnlockWithFingerprintPossible.get(userId);
}
@@ -3893,7 +3893,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
for (int subId : mServiceStates.keySet()) {
pw.println(" " + subId + "=" + mServiceStates.get(subId));
}
if (mFpm != null && mFpm.isHardwareDetected()) {
if (mFpm != null && !mFingerprintSensorProperties.isEmpty()) {
final int userId = mUserTracker.getUserId();
final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
@@ -3942,7 +3942,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
mFingerprintListenBuffer.toList()
).printTableData(pw);
}
if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
if (mFaceManager != null && !mFaceSensorProperties.isEmpty()) {
final int userId = mUserTracker.getUserId();
final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
BiometricAuthenticated face = mUserFaceAuthenticated.get(userId);

View File

@@ -695,7 +695,6 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
setKeyguardBouncerVisibility(true);
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
verify(mFaceManager).isHardwareDetected();
verify(mFaceManager, never()).hasEnrolledTemplates(anyInt());
}

View File

@@ -0,0 +1,86 @@
/*
* Copyright (C) 2023 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 android.hardware.face;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import android.os.RemoteException;
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.MockitoJUnitRunner;
import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@RunWith(MockitoJUnitRunner.class)
public class FaceManagerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Mock
Context mContext;
@Mock
IFaceService mService;
@Captor
ArgumentCaptor<IFaceAuthenticatorsRegisteredCallback> mCaptor;
List<FaceSensorPropertiesInternal> mProps;
FaceManager mFaceManager;
@Before
public void setUp() throws Exception {
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
mFaceManager = new FaceManager(mContext, mService);
mProps = new ArrayList<>();
mProps.add(new FaceSensorPropertiesInternal(
0 /* id */,
FaceSensorProperties.STRENGTH_STRONG,
1 /* maxTemplatesAllowed */,
new ArrayList<>() /* conponentInfo */,
FaceSensorProperties.TYPE_UNKNOWN,
true /* supportsFaceDetection */,
true /* supportsSelfIllumination */,
false /* resetLockoutRequiresChallenge */));
}
@Test
public void getSensorPropertiesInternal_noBinderCalls() throws RemoteException {
verify(mService).addAuthenticatorsRegisteredCallback(mCaptor.capture());
mCaptor.getValue().onAllAuthenticatorsRegistered(mProps);
List<FaceSensorPropertiesInternal> actual = mFaceManager.getSensorPropertiesInternal();
assertThat(actual).isEqualTo(mProps);
verify(mService, never()).getSensorPropertiesInternal(any());
}
}

View File

@@ -0,0 +1 @@
include /services/core/java/com/android/server/biometrics/OWNERS

View File

@@ -0,0 +1,88 @@
/*
* Copyright (C) 2023 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 android.hardware.fingerprint;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.os.Looper;
import android.os.RemoteException;
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.MockitoJUnitRunner;
import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.List;
@RunWith(MockitoJUnitRunner.class)
public class FingerprintManagerTest {
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Mock
Context mContext;
@Mock
IFingerprintService mService;
@Captor
ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mCaptor;
List<FingerprintSensorPropertiesInternal> mProps;
FingerprintManager mFingerprintManager;
@Before
public void setUp() throws Exception {
when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
mFingerprintManager = new FingerprintManager(mContext, mService);
mProps = new ArrayList<>();
mProps.add(new FingerprintSensorPropertiesInternal(
0 /* sensorId */,
FingerprintSensorProperties.STRENGTH_STRONG,
1 /* maxEnrollmentsPerUser */,
new ArrayList<>() /* componentInfo */,
FingerprintSensorProperties.TYPE_UNKNOWN,
true /* halControlsIllumination */,
true /* resetLockoutRequiresHardwareAuthToken */,
new ArrayList<>() /* sensorLocations */));
}
@Test
public void getSensorPropertiesInternal_noBinderCalls() throws RemoteException {
verify(mService).addAuthenticatorsRegisteredCallback(mCaptor.capture());
mCaptor.getValue().onAllAuthenticatorsRegistered(mProps);
List<FingerprintSensorPropertiesInternal> actual =
mFingerprintManager.getSensorPropertiesInternal();
assertThat(actual).isEqualTo(mProps);
verify(mService, never()).getSensorPropertiesInternal(any());
}
}

View File

@@ -0,0 +1 @@
include /services/core/java/com/android/server/biometrics/OWNERS