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

Commit 65331ae8 authored by Ilya Matyukhin's avatar Ilya Matyukhin
Browse files

Implement NativeHandle conversion for enrollment

Bug: 172593521
Test: pending
Change-Id: I18615757b09c28c21f597e2898ce25baaf76b37a
parent 961f7375
Loading
Loading
Loading
Loading
+77 −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 com.android.server.biometrics.sensors.face.aidl;

import android.annotation.Nullable;
import android.os.ParcelFileDescriptor;

import java.io.FileDescriptor;
import java.io.IOException;

/**
 * A utility class for the AIDL implementation of NativeHandle - {@link
 * android.hardware.common.NativeHandle}.
 */
public final class AidlNativeHandleUtils {

    /**
     * Converts a {@link android.os.NativeHandle} to a {@link android.hardware.common.NativeHandle}
     * by duplicating the underlying file descriptors.
     *
     * Both the original and new handle must be closed after use.
     *
     * @param handle {@link android.os.NativeHandle}. Can be null.
     * @return a {@link android.hardware.common.NativeHandle} representation of {@code handle}.
     * Returns null if {@code handle} is null.
     * @throws IOException if any of the underlying calls to {@code dup} fail.
     */
    public static @Nullable android.hardware.common.NativeHandle dup(
            @Nullable android.os.NativeHandle handle) throws IOException {
        if (handle == null) {
            return null;
        }
        android.hardware.common.NativeHandle res = new android.hardware.common.NativeHandle();
        final FileDescriptor[] fds = handle.getFileDescriptors();
        res.ints = handle.getInts().clone();
        res.fds = new ParcelFileDescriptor[fds.length];
        for (int i = 0; i < fds.length; ++i) {
            res.fds[i] = ParcelFileDescriptor.dup(fds[i]);
        }
        return res;
    }

    /**
     * Closes the file descriptors contained within a {@link android.hardware.common.NativeHandle}.
     * This is a no-op if the handle is null.
     *
     * This should only be used for handles that own their file descriptors, for example handles
     * obtained using {@link #dup(android.os.NativeHandle)}.
     *
     * @param handle {@link android.hardware.common.NativeHandle}. Can be null.
     * @throws IOException if any of the underlying calls to {@code close} fail.
     */
    public static void close(@Nullable android.hardware.common.NativeHandle handle)
            throws IOException {
        if (handle != null) {
            for (ParcelFileDescriptor fd : handle.fds) {
                if (fd != null) {
                    fd.close();
                }
            }
        }
    }
}
+21 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnrollClient;
import com.android.server.biometrics.sensors.face.FaceUtils;

import java.io.IOException;
import java.util.ArrayList;

/**
@@ -51,6 +52,7 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
    @NonNull private final int[] mEnrollIgnoreList;
    @NonNull private final int[] mEnrollIgnoreListVendor;
    @Nullable private ICancellationSignal mCancellationSignal;
    @Nullable private android.hardware.common.NativeHandle mPreviewSurface;
    private final int mMaxTemplatesPerUser;

    FaceEnrollClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
@@ -66,6 +68,24 @@ public class FaceEnrollClient extends EnrollClient<ISession> {
        mEnrollIgnoreListVendor = getContext().getResources()
                .getIntArray(R.array.config_face_acquire_vendor_enroll_ignorelist);
        mMaxTemplatesPerUser = maxTemplatesPerUser;
        try {
            // We must manually close the duplicate handle after it's no longer needed.
            // The caller is responsible for closing the original handle.
            mPreviewSurface = AidlNativeHandleUtils.dup(previewSurface);
        } catch (IOException e) {
            mPreviewSurface = null;
            Slog.e(TAG, "Failed to dup previewSurface", e);
        }
    }

    @Override
    public void destroy() {
        try {
            AidlNativeHandleUtils.close(mPreviewSurface);
        } catch (IOException e) {
            Slog.e(TAG, "Failed to close mPreviewSurface", e);
        }
        super.destroy();
    }

    @Override
@@ -94,10 +114,9 @@ public class FaceEnrollClient extends EnrollClient<ISession> {

        try {
            // TODO(b/172593978): Pass features.
            // TODO(b/172593521): Pass mPreviewSurface as android.hardware.common.NativeHandle.
            mCancellationSignal = getFreshDaemon().enroll(mSequentialId,
                    HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken),
                    null /* mPreviewSurface */);
                    mPreviewSurface);
        } catch (RemoteException e) {
            Slog.e(TAG, "Remote exception when requesting enroll", e);
            onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);