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
This commit is contained in:
Jeff Pu 2024-01-24 10:51:31 -05:00
parent 50d605f8a1
commit 1e93ca6c74
5 changed files with 166 additions and 7 deletions

View file

@ -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

View file

@ -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

View file

@ -14,6 +14,7 @@
* limitations under the License.
*/
#undef LOG_TAG
#define LOG_TAG "FaceVirtualHalEngine"
#include "FakeFaceEngine.h"

View file

@ -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();
}

View file

@ -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