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

Commit def5b048 authored by Jeff Pu's avatar Jeff Pu
Browse files

Simulate finger touch with virtual fingerprint hal

Bug: 277780272
Test: atest BiometricsE2eTests
Change-Id: I9330b3eeca52321c59d0af63782d38cd3b5f901f
parent 94734588
Loading
Loading
Loading
Loading
+70 −15
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ using ::android::base::ParseInt;

namespace aidl::android::hardware::biometrics::fingerprint {

FakeFingerprintEngine::FakeFingerprintEngine()
    : mRandom(std::mt19937::default_seed), mWorkMode(WorkMode::kIdle) {}

void FakeFingerprintEngine::generateChallengeImpl(ISessionCallback* cb) {
    BEGIN_OP(0);
    std::uniform_int_distribution<int64_t> dist;
@@ -48,6 +51,64 @@ void FakeFingerprintEngine::revokeChallengeImpl(ISessionCallback* cb, int64_t ch
void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
                                       const keymaster::HardwareAuthToken& hat,
                                       const std::future<void>& cancel) {
    BEGIN_OP(0);
    updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
}

void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t operationId,
                                             const std::future<void>& cancel) {
    BEGIN_OP(0);
    updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
                  keymaster::HardwareAuthToken());
}

void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
                                                  const std::future<void>& cancel) {
    BEGIN_OP(0);

    auto detectInteractionSupported =
            FingerprintHalProperties::detect_interaction().value_or(false);
    if (!detectInteractionSupported) {
        LOG(ERROR) << "Detect interaction is not supported";
        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
        return;
    }

    updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
                  keymaster::HardwareAuthToken());
}

void FakeFingerprintEngine::updateContext(WorkMode mode, ISessionCallback* cb,
                                          std::future<void>& cancel, int64_t operationId,
                                          const keymaster::HardwareAuthToken& hat) {
    mCancel = std::move(cancel);
    mWorkMode = mode;
    mCb = cb;
    mOperationId = operationId;
    mHat = hat;
}

void FakeFingerprintEngine::fingerDownAction() {
    LOG(INFO) << __func__;
    switch (mWorkMode) {
        case WorkMode::kAuthenticate:
            onAuthenticateFingerDown(mCb, mOperationId, mCancel);
            break;
        case WorkMode::kEnroll:
            onEnrollFingerDown(mCb, mHat, mCancel);
            break;
        case WorkMode::kDetectInteract:
            onDetectInteractFingerDown(mCb, mCancel);
            break;
        default:
            LOG(WARNING) << "unexpected mode: on fingerDownAction(), " << (int)mWorkMode;
            break;
    }
}

void FakeFingerprintEngine::onEnrollFingerDown(ISessionCallback* cb,
                                               const keymaster::HardwareAuthToken& hat,
                                               const std::future<void>& cancel) {
    BEGIN_OP(getLatency(FingerprintHalProperties::operation_enroll_latency()));

    // Do proper HAT verification in the real implementation.
@@ -116,7 +177,8 @@ void FakeFingerprintEngine::enrollImpl(ISessionCallback* cb,
    }
}

void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t /* operationId */,
void FakeFingerprintEngine::onAuthenticateFingerDown(ISessionCallback* cb,
                                                     int64_t /* operationId */,
                                                     const std::future<void>& cancel) {
    BEGIN_OP(getLatency(FingerprintHalProperties::operation_authenticate_latency()));

@@ -197,21 +259,13 @@ void FakeFingerprintEngine::authenticateImpl(ISessionCallback* cb, int64_t /* op
    }
}

void FakeFingerprintEngine::detectInteractionImpl(ISessionCallback* cb,
void FakeFingerprintEngine::onDetectInteractFingerDown(ISessionCallback* cb,
                                                       const std::future<void>& cancel) {
    BEGIN_OP(getLatency(FingerprintHalProperties::operation_detect_interaction_latency()));

    int64_t duration =
            FingerprintHalProperties::operation_detect_interaction_duration().value_or(10);

    auto detectInteractionSupported =
            FingerprintHalProperties::detect_interaction().value_or(false);
    if (!detectInteractionSupported) {
        LOG(ERROR) << "Detect interaction is not supported";
        cb->onError(Error::UNABLE_TO_PROCESS, 0 /* vendorError */);
        return;
    }

    auto acquired = FingerprintHalProperties::operation_detect_interaction_acquired().value_or("1");
    auto acquiredInfos = parseIntSequence(acquired);
    int N = acquiredInfos.size();
@@ -339,6 +393,7 @@ ndk::ScopedAStatus FakeFingerprintEngine::onPointerDownImpl(int32_t /*pointerId*
                                                            int32_t /*y*/, float /*minor*/,
                                                            float /*major*/) {
    BEGIN_OP(0);
    fingerDownAction();
    return ndk::ScopedAStatus::ok();
}

@@ -369,7 +424,8 @@ bool FakeFingerprintEngine::getSensorLocationConfig(SensorLocation& out) {
        if (dim.size() >= 4) {
            d = dim[3];
        }
        if (isValidStr) out = {0, x, y, r, d};
        if (isValidStr)
            out = {.sensorLocationX = x, .sensorLocationY = y, .sensorRadius = r, .display = d};

        return isValidStr;
    }
@@ -385,8 +441,7 @@ SensorLocation FakeFingerprintEngine::getSensorLocation() {
}

SensorLocation FakeFingerprintEngine::defaultSensorLocation() {
    return {0 /* displayId (not used) */, 0 /* sensorLocationX */, 0 /* sensorLocationY */,
            0 /* sensorRadius */, "" /* display */};
    return SensorLocation();
}

std::vector<int32_t> FakeFingerprintEngine::parseIntSequence(const std::string& str,
+3 −5
Original line number Diff line number Diff line
@@ -28,10 +28,8 @@ using namespace ::android::fingerprint::virt;
namespace aidl::android::hardware::biometrics::fingerprint {

SensorLocation FakeFingerprintEngineSide::defaultSensorLocation() {
    SensorLocation location;

    return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
            defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
            "" /* display */};
    return SensorLocation{.sensorLocationX = defaultSensorLocationX,
                          .sensorLocationY = defaultSensorLocationY,
                          .sensorRadius = defaultSensorRadius};
}
}  // namespace aidl::android::hardware::biometrics::fingerprint
+6 −57
Original line number Diff line number Diff line
@@ -31,12 +31,12 @@ using namespace ::android::fingerprint::virt;
namespace aidl::android::hardware::biometrics::fingerprint {

FakeFingerprintEngineUdfps::FakeFingerprintEngineUdfps()
    : FakeFingerprintEngine(), mWorkMode(WorkMode::kIdle), mPointerDownTime(0), mUiReadyTime(0) {}
    : FakeFingerprintEngine(), mPointerDownTime(0), mUiReadyTime(0) {}

SensorLocation FakeFingerprintEngineUdfps::defaultSensorLocation() {
    return {0 /* displayId (not used) */, defaultSensorLocationX /* sensorLocationX */,
            defaultSensorLocationY /* sensorLocationY */, defaultSensorRadius /* sensorRadius */,
            "" /* display */};
    return SensorLocation{.sensorLocationX = defaultSensorLocationX,
                          .sensorLocationY = defaultSensorLocationY,
                          .sensorRadius = defaultSensorRadius};
}

ndk::ScopedAStatus FakeFingerprintEngineUdfps::onPointerDownImpl(int32_t /*pointerId*/,
@@ -70,68 +70,17 @@ ndk::ScopedAStatus FakeFingerprintEngineUdfps::onUiReadyImpl() {
}

void FakeFingerprintEngineUdfps::fingerDownAction() {
    switch (mWorkMode) {
        case WorkMode::kAuthenticate:
            onAuthenticateFingerDown();
            break;
        case WorkMode::kEnroll:
            onEnrollFingerDown();
            break;
        case WorkMode::kDetectInteract:
            onDetectInteractFingerDown();
            break;
        default:
            LOG(WARNING) << "unexpected call: onUiReady()";
            break;
    }

    FakeFingerprintEngine::fingerDownAction();
    mUiReadyTime = 0;
    mPointerDownTime = 0;
}

void FakeFingerprintEngineUdfps::onAuthenticateFingerDown() {
    FakeFingerprintEngine::authenticateImpl(mCb, mOperationId, mCancelVec[0]);
}

void FakeFingerprintEngineUdfps::onEnrollFingerDown() {
    // Any use case to emulate display touch for each capture during enrollment?
    FakeFingerprintEngine::enrollImpl(mCb, mHat, mCancelVec[0]);
}

void FakeFingerprintEngineUdfps::onDetectInteractFingerDown() {
    FakeFingerprintEngine::detectInteractionImpl(mCb, mCancelVec[0]);
}

void FakeFingerprintEngineUdfps::enrollImpl(ISessionCallback* cb,
                                            const keymaster::HardwareAuthToken& hat,
                                            const std::future<void>& cancel) {
    updateContext(WorkMode::kEnroll, cb, const_cast<std::future<void>&>(cancel), 0, hat);
}

void FakeFingerprintEngineUdfps::authenticateImpl(ISessionCallback* cb, int64_t operationId,
                                                  const std::future<void>& cancel) {
    updateContext(WorkMode::kAuthenticate, cb, const_cast<std::future<void>&>(cancel), operationId,
                  keymaster::HardwareAuthToken());
}

void FakeFingerprintEngineUdfps::detectInteractionImpl(ISessionCallback* cb,
                                                       const std::future<void>& cancel) {
    updateContext(WorkMode::kDetectInteract, cb, const_cast<std::future<void>&>(cancel), 0,
                  keymaster::HardwareAuthToken());
}

void FakeFingerprintEngineUdfps::updateContext(WorkMode mode, ISessionCallback* cb,
                                               std::future<void>& cancel, int64_t operationId,
                                               const keymaster::HardwareAuthToken& hat) {
    FakeFingerprintEngine::updateContext(mode, cb, cancel, operationId, hat);
    mPointerDownTime = 0;
    mUiReadyTime = 0;
    mCancelVec.clear();

    mCancelVec.push_back(std::move(cancel));
    mWorkMode = mode;
    mCb = cb;
    mOperationId = operationId;
    mHat = hat;
}

}  // namespace aidl::android::hardware::biometrics::fingerprint
+8 −6
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "Fingerprint.h"
#include "Session.h"

#include <android-base/properties.h>
#include <fingerprint.sysprop.h>

#include <android-base/file.h>
@@ -59,6 +60,7 @@ Fingerprint::Fingerprint() : mWorker(MAX_WORKER_QUEUE_SIZE) {
                             << sensorTypeProp;
    }
    LOG(INFO) << "sensorTypeProp:" << sensorTypeProp;
    LOG(INFO) << "ro.product.name=" << ::android::base::GetProperty("ro.product.name", "UNKNOWN");
}

ndk::ScopedAStatus Fingerprint::getSensorProps(std::vector<SensorProps>* out) {
@@ -105,16 +107,16 @@ ndk::ScopedAStatus Fingerprint::createSession(int32_t sensorId, int32_t userId,

    mSession->linkToDeath(cb->asBinder().get());

    LOG(INFO) << "createSession: sensorId:" << sensorId << " userId:" << userId;
    LOG(INFO) << __func__ << ": sensorId:" << sensorId << " userId:" << userId;
    return ndk::ScopedAStatus::ok();
}

binder_status_t Fingerprint::dump(int fd, const char** /*args*/, uint32_t numArgs) {
    if (fd < 0) {
        LOG(ERROR) << "Fingerprint::dump fd invalid: " << fd;
        LOG(ERROR) << __func__ << "fd invalid: " << fd;
        return STATUS_BAD_VALUE;
    } else {
        LOG(INFO) << "Fingerprint::dump fd:" << fd << "numArgs:" << numArgs;
        LOG(INFO) << __func__ << " fd:" << fd << "numArgs:" << numArgs;
    }

    dprintf(fd, "----- FingerprintVirtualHal::dump -----\n");
@@ -131,11 +133,11 @@ binder_status_t Fingerprint::dump(int fd, const char** /*args*/, uint32_t numArg

binder_status_t Fingerprint::handleShellCommand(int in, int out, int err, const char** args,
                                                uint32_t numArgs) {
    LOG(INFO) << "Fingerprint::handleShellCommand in:" << in << " out:" << out << " err:" << err
    LOG(INFO) << __func__ << " in:" << in << " out:" << out << " err:" << err
              << " numArgs:" << numArgs;

    if (numArgs == 0) {
        LOG(INFO) << "Fingerprint::handleShellCommand: available commands";
        LOG(INFO) << __func__ << ": available commands";
        onHelp(out);
        return STATUS_OK;
    }
@@ -163,7 +165,7 @@ void Fingerprint::onHelp(int fd) {
}

void Fingerprint::resetConfigToDefault() {
    LOG(INFO) << "reset virtual HAL configuration to default";
    LOG(INFO) << __func__ << ": reset virtual HAL configuration to default";
#define RESET_CONFIG_O(__NAME__) \
    if (FingerprintHalProperties::__NAME__()) FingerprintHalProperties::__NAME__(std::nullopt)
#define RESET_CONFIG_V(__NAME__)                       \
+23 −1
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ namespace aidl::android::hardware::biometrics::fingerprint {
// A fake engine that is backed by system properties instead of hardware.
class FakeFingerprintEngine {
  public:
    FakeFingerprintEngine() : mRandom(std::mt19937::default_seed) {}
    FakeFingerprintEngine();
    virtual ~FakeFingerprintEngine() {}

    void generateChallengeImpl(ISessionCallback* cb);
@@ -66,6 +66,8 @@ class FakeFingerprintEngine {

    virtual SensorLocation defaultSensorLocation();

    virtual void fingerDownAction();

    std::vector<int32_t> parseIntSequence(const std::string& str, const std::string& sep = ",");

    std::vector<std::vector<int32_t>> parseEnrollmentCapture(const std::string& str);
@@ -74,15 +76,35 @@ class FakeFingerprintEngine {

    std::mt19937 mRandom;

    enum class WorkMode : int8_t { kIdle = 0, kAuthenticate, kEnroll, kDetectInteract };

    WorkMode getWorkMode() { return mWorkMode; }

    virtual std::string toString() const {
        std::ostringstream os;
        os << "----- FakeFingerprintEngine:: -----" << std::endl;
        os << "mWorkMode:" << (int)mWorkMode;
        os << "acquiredVendorInfoBase:" << FINGERPRINT_ACQUIRED_VENDOR_BASE;
        os << ", errorVendorBase:" << FINGERPRINT_ERROR_VENDOR_BASE << std::endl;
        os << mLockoutTracker.toString();
        return os.str();
    }

  protected:
    virtual void updateContext(WorkMode mode, ISessionCallback* cb, std::future<void>& cancel,
                               int64_t operationId, const keymaster::HardwareAuthToken& hat);

    void onEnrollFingerDown(ISessionCallback* cb, const keymaster::HardwareAuthToken& hat,
                            const std::future<void>& cancel);
    void onAuthenticateFingerDown(ISessionCallback* cb, int64_t, const std::future<void>& cancel);
    void onDetectInteractFingerDown(ISessionCallback* cb, const std::future<void>& cancel);

    WorkMode mWorkMode;
    ISessionCallback* mCb;
    keymaster::HardwareAuthToken mHat;
    std::future<void> mCancel;
    int64_t mOperationId;

  private:
    static constexpr int32_t FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000;
    static constexpr int32_t FINGERPRINT_ERROR_VENDOR_BASE = 1000;
Loading