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

Commit 53c5d870 authored by Kevin Chyn's avatar Kevin Chyn Committed by Android (Google) Code Review
Browse files

Merge changes Ic26e47c1,I6c9717d1

* changes:
  Check foreground and appOps for BiometricPrompt#authenticate
  Update authentication when encrypted or lockout
parents fe5fd515 613ee92b
Loading
Loading
Loading
Loading
+93 −1
Original line number Diff line number Diff line
/**
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
@@ -70,11 +70,13 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
    private static final int MSG_GET_FEATURE_COMPLETED = 106;
    private static final int MSG_SET_FEATURE_COMPLETED = 107;
    private static final int MSG_CHALLENGE_GENERATED = 108;
    private static final int MSG_FACE_DETECTED = 109;

    private final IFaceService mService;
    private final Context mContext;
    private IBinder mToken = new Binder();
    private AuthenticationCallback mAuthenticationCallback;
    private FaceDetectionCallback mFaceDetectionCallback;
    private EnrollmentCallback mEnrollmentCallback;
    private RemovalCallback mRemovalCallback;
    private SetFeatureCallback mSetFeatureCallback;
@@ -102,6 +104,12 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
                    face).sendToTarget();
        }

        @Override // binder call
        public void onFaceDetected(int sensorId, int userId, boolean isStrongBiometric) {
            mHandler.obtainMessage(MSG_FACE_DETECTED, sensorId, userId, isStrongBiometric)
                    .sendToTarget();
        }

        @Override // binder call
        public void onAuthenticationFailed() {
            mHandler.obtainMessage(MSG_AUTHENTICATION_FAILED).sendToTarget();
@@ -250,6 +258,34 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
        }
    }

    /**
     * Uses the face hardware to detect for the presence of a face, without giving details about
     * accept/reject/lockout.
     * @hide
     */
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    public void detectFace(@NonNull CancellationSignal cancel,
            @NonNull FaceDetectionCallback callback, int userId) {
        if (mService == null) {
            return;
        }

        if (cancel.isCanceled()) {
            Slog.w(TAG, "Detection already cancelled");
            return;
        } else {
            cancel.setOnCancelListener(new OnFaceDetectionCancelListener());
        }

        mFaceDetectionCallback = callback;

        try {
            mService.detectFace(mToken, userId, mServiceReceiver, mContext.getOpPackageName());
        } catch (RemoteException e) {
            Slog.w(TAG, "Remote exception when requesting finger detect", e);
        }
    }

    /**
     * Defaults to {@link FaceManager#enroll(int, byte[], CancellationSignal, EnrollmentCallback,
     * int[], Surface)} with {@code surface} set to null.
@@ -580,6 +616,24 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
        return false;
    }

    /**
     * Get statically configured sensor properties.
     * @hide
     */
    @RequiresPermission(USE_BIOMETRIC_INTERNAL)
    @NonNull
    public FaceSensorProperties getSensorProperties() {
        try {
            if (mService == null || !mService.isHardwareDetected(mContext.getOpPackageName())) {
                return new FaceSensorProperties();
            }
            return mService.getSensorProperties(mContext.getOpPackageName());
        } catch (RemoteException e) {
            e.rethrowFromSystemServer();
        }
        return new FaceSensorProperties();
    }

    /**
     * @hide
     */
@@ -639,6 +693,18 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
        }
    }

    private void cancelFaceDetect() {
        if (mService == null) {
            return;
        }

        try {
            mService.cancelFaceDetect(mToken, mContext.getOpPackageName());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * @hide
     */
@@ -895,6 +961,13 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
        }
    }

    /**
     * @hide
     */
    public interface FaceDetectionCallback {
        void onFaceDetected(int sensorId, int userId, boolean isStrongBiometric);
    }

    /**
     * Callback structure provided to {@link FaceManager#enroll(long,
     * EnrollmentCallback, CancellationSignal, int). Users of {@link #FaceAuthenticationManager()}
@@ -1026,6 +1099,13 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
        }
    }

    private class OnFaceDetectionCancelListener implements OnCancelListener {
        @Override
        public void onCancel() {
            cancelFaceDetect();
        }
    }

    private class MyHandler extends Handler {
        private MyHandler(Context context) {
            super(context.getMainLooper());
@@ -1072,6 +1152,10 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
                case MSG_CHALLENGE_GENERATED:
                    sendChallengeGenerated((long) msg.obj /* challenge */);
                    break;
                case MSG_FACE_DETECTED:
                    sendFaceDetected(msg.arg1 /* sensorId */, msg.arg2 /* userId */,
                            (boolean) msg.obj /* isStrongBiometric */);
                    break;
                default:
                    Slog.w(TAG, "Unknown message: " + msg.what);
            }
@@ -1100,6 +1184,14 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
        mGenerateChallengeCallback.onGenerateChallengeResult(challenge);
    }

    private void sendFaceDetected(int sensorId, int userId, boolean isStrongBiometric) {
        if (mFaceDetectionCallback == null) {
            Slog.e(TAG, "sendFaceDetected, callback null");
            return;
        }
        mFaceDetectionCallback.onFaceDetected(sensorId, userId, isStrongBiometric);
    }

    private void sendRemovedResult(Face face, int remaining) {
        if (mRemovalCallback == null) {
            return;
+18 −0
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 android.hardware.face;

parcelable FaceSensorProperties;
 No newline at end of file
+70 −0
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 android.hardware.face;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Container for face sensor properties.
 * @hide
 */
public class FaceSensorProperties implements Parcelable {

    public final boolean supportsFaceDetection;

    /**
     * Creates a SensorProperties class with safe default values
     */
    public FaceSensorProperties() {
        supportsFaceDetection = false;
    }

    /**
     * Initializes SensorProperties with specified values
     */
    public FaceSensorProperties(boolean supportsFaceDetection) {
        this.supportsFaceDetection = supportsFaceDetection;
    }

    protected FaceSensorProperties(Parcel in) {
        supportsFaceDetection = in.readBoolean();
    }

    public static final Creator<FaceSensorProperties> CREATOR =
            new Creator<FaceSensorProperties>() {
        @Override
        public FaceSensorProperties createFromParcel(Parcel in) {
            return new FaceSensorProperties(in);
        }

        @Override
        public FaceSensorProperties[] newArray(int size) {
            return new FaceSensorProperties[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeBoolean(supportsFaceDetection);
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import android.hardware.biometrics.IBiometricSensorReceiver;
import android.hardware.biometrics.IBiometricServiceLockoutResetCallback;
import android.hardware.face.IFaceServiceReceiver;
import android.hardware.face.Face;
import android.hardware.face.FaceSensorProperties;
import android.view.Surface;

/**
@@ -31,6 +32,10 @@ interface IFaceService {
    void authenticate(IBinder token, long operationId, int userid, IFaceServiceReceiver receiver,
            String opPackageName);

    // Uses the face hardware to detect for the presence of a face, without giving details
    // about accept/reject/lockout.
    void detectFace(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);

    // This method prepares the service to start authenticating, but doesn't start authentication.
    // This is protected by the MANAGE_BIOMETRIC signatuer permission. This method should only be
    // called from BiometricService. The additional uid, pid, userId arguments should be determined
@@ -46,6 +51,9 @@ interface IFaceService {
    // Cancel authentication for the given sessionId
    void cancelAuthentication(IBinder token, String opPackageName);

    // Cancel face detection
    void cancelFaceDetect(IBinder token, String opPackageName);

    // Same as above, with extra arguments.
    void cancelAuthenticationFromService(IBinder token, String opPackageName,
            int callingUid, int callingPid, int callingUserId);
@@ -80,6 +88,9 @@ interface IFaceService {
    // Determine if a user has at least one enrolled face
    boolean hasEnrolledFaces(int userId, String opPackageName);

    // Retrieve static sensor properties
    FaceSensorProperties getSensorProperties(String opPackageName);

    // Return the LockoutTracker status for the specified user
    int getLockoutModeForUser(int userId);

+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ oneway interface IFaceServiceReceiver {
    void onEnrollResult(in Face face, int remaining);
    void onAcquired(int acquiredInfo, int vendorCode);
    void onAuthenticationSucceeded(in Face face, int userId, boolean isStrongBiometric);
    void onFaceDetected(int sensorId, int userId, boolean isStrongBiometric);
    void onAuthenticationFailed();
    void onError(int error, int vendorCode);
    void onRemoved(in Face face, int remaining);
Loading