Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbd9d418 authored by Kevin Chyn's avatar Kevin Chyn
Browse files

Update biometric test paths

1) Test HALs should always respond to enumerate with no enrollments.
   CTS tests use this path to consciously remove (framework)
   enrollments when cleaning up.
2) Removes unnecessary TestSession classes from AIDL providers. These
   are redundant with the existing sessions returned from the TestHals
   themselves. We just need the framework to retrieve a new HAL session
   (from either the real HAL or the test HAL) whenever changing between
   test and non-test modes

Test: atest CtsBiometricsTestCases
Test: atest com.android.server.biometrics
Fixes: 179949545
Fixes: 179856730

Change-Id: I1bbf0b77c69a36c9065193d10be32e942af8db70
parent 630229f0
Loading
Loading
Loading
Loading
+5 −7
Original line number Diff line number Diff line
@@ -436,13 +436,7 @@ public class Sensor implements IBinder.DeathRecipient {
        mScheduler = new BiometricScheduler(tag, null /* gestureAvailabilityDispatcher */);
        mLockoutCache = new LockoutCache();
        mAuthenticatorIds = new HashMap<>();
        mLazySession = () -> {
            if (mTestHalEnabled) {
                return new TestSession(mCurrentSession.mHalSessionCallback);
            } else {
                return mCurrentSession != null ? mCurrentSession.mSession : null;
            }
        };
        mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
    }

    @NonNull HalClientMonitor.LazyDaemon<ISession> getLazySession() {
@@ -499,6 +493,10 @@ public class Sensor implements IBinder.DeathRecipient {

    void setTestHalEnabled(boolean enabled) {
        Slog.w(mTag, "setTestHalEnabled: " + enabled);
        if (enabled != mTestHalEnabled) {
            // The framework should retrieve a new session from the HAL.
            mCurrentSession = null;
        }
        mTestHalEnabled = enabled;
    }

+40 −12
Original line number Diff line number Diff line
@@ -17,12 +17,14 @@
package com.android.server.biometrics.sensors.face.aidl;

import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.face.Error;
import android.hardware.biometrics.face.IFace;
import android.hardware.biometrics.face.ISession;
import android.hardware.biometrics.face.ISessionCallback;
import android.hardware.biometrics.face.SensorProps;
import android.hardware.common.NativeHandle;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.RemoteException;
import android.util.Slog;

/**
@@ -38,70 +40,96 @@ public class TestHal extends IFace.Stub {

    @Override
    public ISession createSession(int sensorId, int userId, ISessionCallback cb) {
        Slog.w(TAG, "createSession, sensorId: " + sensorId + " userId: " + userId);

        return new ISession.Stub() {
            @Override
            public void generateChallenge(int cookie, int timeoutSec) {
            public void generateChallenge(int cookie, int timeoutSec) throws RemoteException {
                Slog.w(TAG, "generateChallenge, cookie: " + cookie);
                cb.onChallengeGenerated(0L);
            }

            @Override
            public void revokeChallenge(int cookie, long challenge) {
            public void revokeChallenge(int cookie, long challenge) throws RemoteException {
                Slog.w(TAG, "revokeChallenge: " + challenge + ", cookie: " + cookie);
                cb.onChallengeRevoked(challenge);
            }

            @Override
            public ICancellationSignal enroll(int cookie, HardwareAuthToken hat,
                    byte enrollmentType, byte[] features, NativeHandle previewSurface) {
                Slog.w(TAG, "enroll, cookie: " + cookie);
                return null;
                return new ICancellationSignal.Stub() {
                    @Override
                    public void cancel() throws RemoteException {
                        cb.onError(Error.CANCELED, 0 /* vendorCode */);
                    }
                };
            }

            @Override
            public ICancellationSignal authenticate(int cookie, long operationId) {
                Slog.w(TAG, "authenticate, cookie: " + cookie);
                return null;
                return new ICancellationSignal.Stub() {
                    @Override
                    public void cancel() throws RemoteException {
                        cb.onError(Error.CANCELED, 0 /* vendorCode */);
                    }
                };
            }

            @Override
            public ICancellationSignal detectInteraction(int cookie) {
                Slog.w(TAG, "detectInteraction, cookie: " + cookie);
                return null;
                return new ICancellationSignal.Stub() {
                    @Override
                    public void cancel() throws RemoteException {
                        cb.onError(Error.CANCELED, 0 /* vendorCode */);
                    }
                };
            }

            @Override
            public void enumerateEnrollments(int cookie) {
            public void enumerateEnrollments(int cookie) throws RemoteException {
                Slog.w(TAG, "enumerateEnrollments, cookie: " + cookie);
                cb.onEnrollmentsEnumerated(new int[0]);
            }

            @Override
            public void removeEnrollments(int cookie, int[] enrollmentIds) {
            public void removeEnrollments(int cookie, int[] enrollmentIds) throws RemoteException {
                Slog.w(TAG, "removeEnrollments, cookie: " + cookie);
                cb.onEnrollmentsRemoved(enrollmentIds);
            }

            @Override
            public void getFeatures(int cookie, int enrollmentId) {
            public void getFeatures(int cookie, int enrollmentId) throws RemoteException {
                Slog.w(TAG, "getFeatures, cookie: " + cookie);
                cb.onFeaturesRetrieved(new byte[0], enrollmentId);
            }

            @Override
            public void setFeature(int cookie, HardwareAuthToken hat, int enrollmentId,
                    byte feature, boolean enabled) {
                    byte feature, boolean enabled) throws RemoteException {
                Slog.w(TAG, "setFeature, cookie: " + cookie);
                cb.onFeatureSet(enrollmentId, feature);
            }

            @Override
            public void getAuthenticatorId(int cookie) {
            public void getAuthenticatorId(int cookie) throws RemoteException {
                Slog.w(TAG, "getAuthenticatorId, cookie: " + cookie);
                cb.onAuthenticatorIdRetrieved(0L);
            }

            @Override
            public void invalidateAuthenticatorId(int cookie) {
            public void invalidateAuthenticatorId(int cookie) throws RemoteException {
                Slog.w(TAG, "invalidateAuthenticatorId, cookie: " + cookie);
                cb.onAuthenticatorIdInvalidated(0L);
            }

            @Override
            public void resetLockout(int cookie, HardwareAuthToken hat) {
            public void resetLockout(int cookie, HardwareAuthToken hat) throws RemoteException {
                Slog.w(TAG, "resetLockout, cookie: " + cookie);
                cb.onLockoutCleared();
            }
        };
    }
+0 −117
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.server.biometrics.sensors.face.aidl;

import android.annotation.NonNull;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.face.Error;
import android.hardware.biometrics.face.ISession;
import android.hardware.common.NativeHandle;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.Binder;
import android.os.IBinder;
import android.util.Slog;

/**
 * Test session that provides mostly no-ops.
 */
public class TestSession extends ISession.Stub {
    private static final String TAG = "FaceTestSession";

    @NonNull
    private final Sensor.HalSessionCallback mHalSessionCallback;

    TestSession(@NonNull Sensor.HalSessionCallback halSessionCallback) {
        mHalSessionCallback = halSessionCallback;
    }

    @Override
    public void generateChallenge(int cookie, int timeoutSec) {
        mHalSessionCallback.onChallengeGenerated(0 /* challenge */);
    }

    @Override
    public void revokeChallenge(int cookie, long challenge) {
        mHalSessionCallback.onChallengeRevoked(challenge);
    }

    @Override
    public ICancellationSignal enroll(int cookie, HardwareAuthToken hat, byte enrollmentType,
            byte[] features, NativeHandle previewSurface) {
        return null;
    }

    @Override
    public ICancellationSignal authenticate(int cookie, long operationId) {
        return new ICancellationSignal() {
            @Override
            public void cancel() {
                mHalSessionCallback.onError(Error.CANCELED, 0 /* vendorCode */);
            }

            @Override
            public IBinder asBinder() {
                return new Binder();
            }
        };
    }

    @Override
    public ICancellationSignal detectInteraction(int cookie) {
        return null;
    }

    @Override
    public void enumerateEnrollments(int cookie) {

    }

    @Override
    public void removeEnrollments(int cookie, int[] enrollmentIds) {

    }

    @Override
    public void getFeatures(int cookie, int enrollmentId) {

    }

    @Override
    public void setFeature(int cookie, HardwareAuthToken hat, int enrollmentId, byte feature,
            boolean enabled) {

    }

    @Override
    public void getAuthenticatorId(int cookie) {
        Slog.d(TAG, "getAuthenticatorId");
        // Immediately return a value so the framework can continue with subsequent requests.
        mHalSessionCallback.onAuthenticatorIdRetrieved(0);
    }

    @Override
    public void invalidateAuthenticatorId(int cookie) {
        Slog.d(TAG, "invalidateAuthenticatorId");
        // Immediately return a value so the framework can continue with subsequent requests.
        mHalSessionCallback.onAuthenticatorIdInvalidated(0);
    }

    @Override
    public void resetLockout(int cookie, HardwareAuthToken hat) {
        mHalSessionCallback.onLockoutCleared();
    }
}
+4 −1
Original line number Diff line number Diff line
@@ -98,8 +98,11 @@ public class TestHal extends IBiometricsFace.Stub {
    }

    @Override
    public int enumerate() {
    public int enumerate() throws RemoteException {
        Slog.w(TAG, "enumerate");
        if (mCallback != null) {
            mCallback.onEnumerate(0 /* deviceId */, new ArrayList<>(), 0 /* userId */);
        }
        return 0;
    }

+6 −8
Original line number Diff line number Diff line
@@ -416,13 +416,7 @@ class Sensor implements IBinder.DeathRecipient {
        mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher);
        mLockoutCache = new LockoutCache();
        mAuthenticatorIds = new HashMap<>();
        mLazySession = () -> {
            if (mTestHalEnabled) {
                return new TestSession(mCurrentSession.mHalSessionCallback);
            } else {
                return mCurrentSession != null ? mCurrentSession.mSession : null;
            }
        };
        mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
    }

    @NonNull HalClientMonitor.LazyDaemon<ISession> getLazySession() {
@@ -478,7 +472,11 @@ class Sensor implements IBinder.DeathRecipient {
    }

    void setTestHalEnabled(boolean enabled) {
        Slog.w(mTag, "setTestHalEnabled, enabled");
        Slog.w(mTag, "setTestHalEnabled: " + enabled);
        if (enabled != mTestHalEnabled) {
            // The framework should retrieve a new session from the HAL.
            mCurrentSession = null;
        }
        mTestHalEnabled = enabled;
    }

Loading