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

Commit 1e93ca6c authored by Jeff Pu's avatar Jeff Pu
Browse files

Support configuration reset and dump

Bug: 294254230
Test: atest android.hardware.biometrics.face.* -c
      adb shell cmd android.hardware.biometrics.face.IFace/virtual resetconfig
      adb shell dumpsys face
Change-Id: I6dc5657104da103860cca133beba21e1b10cb423
parent 50d605f8
Loading
Loading
Loading
Loading
+108 −2
Original line number Diff line number Diff line
@@ -14,11 +14,23 @@
 * limitations under the License.
 */

#undef LOG_TAG
#define LOG_TAG "FaceVirtualHal"

#include "Face.h"
#include "Session.h"

#include "FakeFaceEngine.h"

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

#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/stringprintf.h>

using namespace ::android::face::virt;

namespace aidl::android::hardware::biometrics::face {

const int kSensorId = 4;
@@ -68,11 +80,105 @@ ndk::ScopedAStatus Face::getSensorProps(std::vector<SensorProps>* return_val) {
    return ndk::ScopedAStatus::ok();
}

ndk::ScopedAStatus Face::createSession(int32_t /*sensorId*/, int32_t /*userId*/,
ndk::ScopedAStatus Face::createSession(int32_t sensorId, int32_t userId,
                                       const std::shared_ptr<ISessionCallback>& cb,
                                       std::shared_ptr<ISession>* return_val) {
    *return_val = SharedRefBase::make<Session>(std::make_unique<FakeFaceEngine>(), cb);
    mSession = SharedRefBase::make<Session>(std::make_unique<FakeFaceEngine>(), cb);
    *return_val = mSession;

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

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

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

    dprintf(fd, "----- FaceVirtualHal::dump -----\n");
    std::vector<SensorProps> sps(1);
    getSensorProps(&sps);
    for (auto& sp : sps) {
        ::android::base::WriteStringToFd(sp.toString(), fd);
    }
    if (mSession != nullptr) {
        ::android::base::WriteStringToFd(mSession->toString(), fd);
    } else {
        dprintf(fd, "\nWARNING: no ISession found\n");
    }

    fsync(fd);
    return STATUS_OK;
}

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

    if (numArgs == 0) {
        LOG(INFO) << __func__ << ": available commands";
        onHelp(out);
        return STATUS_OK;
    }

    for (auto&& str : std::vector<std::string_view>(args, args + numArgs)) {
        std::string option = str.data();
        if (option.find("clearconfig") != std::string::npos ||
            option.find("resetconfig") != std::string::npos) {
            resetConfigToDefault();
        }
        if (option.find("help") != std::string::npos) {
            onHelp(out);
        }
    }

    return STATUS_OK;
}

void Face::onHelp(int fd) {
    dprintf(fd, "Virtual Face HAL commands:\n");
    dprintf(fd, "         help: print this help\n");
    dprintf(fd, "  resetconfig: reset all configuration to default\n");
    dprintf(fd, "\n");
    fsync(fd);
}

void Face::resetConfigToDefault() {
    LOG(INFO) << __func__ << ": reset virtual Face HAL configuration to default";
#define RESET_CONFIG_O(__NAME__) \
    if (FaceHalProperties::__NAME__()) FaceHalProperties::__NAME__(std::nullopt)
#define RESET_CONFIG_V(__NAME__) \
    if (!FaceHalProperties::__NAME__().empty()) FaceHalProperties::__NAME__({std::nullopt})

    RESET_CONFIG_O(type);
    RESET_CONFIG_O(strength);
    RESET_CONFIG_V(enrollments);
    RESET_CONFIG_O(enrollment_hit);
    RESET_CONFIG_V(features);
    RESET_CONFIG_O(next_enrollment);
    RESET_CONFIG_O(authenticator_id);
    RESET_CONFIG_O(challenge);
    RESET_CONFIG_O(lockout);
    RESET_CONFIG_O(operation_authenticate_fails);
    RESET_CONFIG_O(operation_detect_interaction_fails);
    RESET_CONFIG_O(operation_enroll_fails);
    RESET_CONFIG_V(operation_authenticate_latency);
    RESET_CONFIG_V(operation_detect_interaction_latency);
    RESET_CONFIG_V(operation_enroll_latency);
    RESET_CONFIG_O(operation_authenticate_duration);
    RESET_CONFIG_O(operation_authenticate_error);
    RESET_CONFIG_O(operation_authenticate_acquired);
    RESET_CONFIG_O(lockout_enable);
    RESET_CONFIG_O(lockout_timed_enable);
    RESET_CONFIG_O(lockout_timed_threshold);
    RESET_CONFIG_O(lockout_timed_duration);
    RESET_CONFIG_O(lockout_permanent_threshold);
}

}  // namespace aidl::android::hardware::biometrics::face
+10 −0
Original line number Diff line number Diff line
@@ -17,16 +17,26 @@
#pragma once

#include <aidl/android/hardware/biometrics/face/BnFace.h>
#include "Session.h"

namespace aidl::android::hardware::biometrics::face {

class Face : public BnFace {
  public:
    Face() : mSession(nullptr) {}
    ndk::ScopedAStatus getSensorProps(std::vector<SensorProps>* _aidl_return) override;

    ndk::ScopedAStatus createSession(int32_t sensorId, int32_t userId,
                                     const std::shared_ptr<ISessionCallback>& cb,
                                     std::shared_ptr<ISession>* _aidl_return) override;

    binder_status_t dump(int fd, const char** args, uint32_t numArgs);
    binder_status_t handleShellCommand(int in, int out, int err, const char** argv, uint32_t argc);

  private:
    std::shared_ptr<Session> mSession;
    void resetConfigToDefault();
    void onHelp(int);
};

}  // namespace aidl::android::hardware::biometrics::face
+1 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 */

#undef LOG_TAG
#define LOG_TAG "FaceVirtualHalEngine"

#include "FakeFaceEngine.h"
+25 −4
Original line number Diff line number Diff line
@@ -14,20 +14,38 @@
 * limitations under the License.
 */

#undef LOG_TAG
#define LOG_TAG "FaceVirtualHalSession"

#include <android-base/logging.h>

#include "Session.h"

#undef LOG_TAG
#define LOG_TAG "FaceVirtualHalSession"

namespace aidl::android::hardware::biometrics::face {

constexpr size_t MAX_WORKER_QUEUE_SIZE = 5;

void onClientDeath(void* cookie) {
    LOG(INFO) << "FaceService has died";
    Session* session = static_cast<Session*>(cookie);
    if (session && !session->isClosed()) {
        session->close();
    }
}

Session::Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb)
    : mEngine(std::move(engine)), mCb(std::move(cb)), mRandom(std::mt19937::default_seed) {
    : mEngine(std::move(engine)),
      mCb(std::move(cb)),
      mRandom(std::mt19937::default_seed),
      mStateClosed(false) {
    CHECK(mEngine);
    CHECK(mCb);
    mThread = std::make_unique<WorkerThread>(MAX_WORKER_QUEUE_SIZE);
    mDeathRecipient = AIBinder_DeathRecipient_new(onClientDeath);
}

binder_status_t Session::linkToDeath(AIBinder* binder) {
    return AIBinder_linkToDeath(binder, mDeathRecipient, this);
}

ndk::ScopedAStatus Session::generateChallenge() {
@@ -144,9 +162,12 @@ ndk::ScopedAStatus Session::resetLockout(const keymaster::HardwareAuthToken& hat
}

ndk::ScopedAStatus Session::close() {
    LOG(INFO) << "close";
    if (mCb) {
        mCb->onSessionClosed();
    }
    AIBinder_DeathRecipient_delete(mDeathRecipient);
    mStateClosed = true;
    return ndk::ScopedAStatus::ok();
}

+22 −1
Original line number Diff line number Diff line
@@ -33,6 +33,11 @@ namespace keymaster = aidl::android::hardware::keymaster;

using aidl::android::hardware::common::NativeHandle;

enum class SessionState {
    IDLING,
    CLOSED,
};

class Session : public BnSession {
  public:
    explicit Session(std::unique_ptr<FakeFaceEngine> engine, std::shared_ptr<ISessionCallback> cb);
@@ -93,12 +98,28 @@ class Session : public BnSession {
            const FaceEnrollOptions& options,
            std::shared_ptr<common::ICancellationSignal>* out) override;

    binder_status_t linkToDeath(AIBinder* binder);

    virtual std::string toString() const {
        std::ostringstream os;
        os << std::endl << "----- Face::Session:: -----" << std::endl;
        os << "mStateClosed:" << mStateClosed << std::endl;
        os << mEngine->toString();

        return os.str();
    }

    bool isClosed() { return mStateClosed; }

  private:
    std::unique_ptr<FakeFaceEngine> mEngine;
    std::shared_ptr<ISessionCallback> mCb;
    std::mt19937 mRandom;
    std::unique_ptr<WorkerThread> mThread;
    std::shared_ptr<CancellationSignal> mCancellationSignal;

    // Binder death handler.
    AIBinder_DeathRecipient* mDeathRecipient;
    bool mStateClosed;
};

}  // namespace aidl::android::hardware::biometrics::face