bangkk: fingerprint: Switch to IOCTL for HBM
* On newer moto kernels it is possible to send a SET_PANEL_FEATURE ioctl to /dev/dri/card0 to set a panel feature such as HBM. Motorola has extended the HBM logic to allow FOD HBM to be set in additional to regular HBM. This is done by sending "2" with the HBM id through the ioctl. * Utilize the API provided by Egistec provides via vendor.egistec.hardware.fingerprint to send commands to the internal handler, this allows us to send the finger is on or off the sensor message directly to the HAL. Change-Id: I06ace29567900779e63b9826862964d20b267be6
This commit is contained in:
parent
b79d326b12
commit
904a71bb02
4 changed files with 67 additions and 59 deletions
|
@ -4,7 +4,4 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
soong_namespace {
|
soong_namespace {
|
||||||
imports: [
|
|
||||||
"hardware/motorola",
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ cc_binary {
|
||||||
"android.hardware.biometrics.fingerprint@2.1",
|
"android.hardware.biometrics.fingerprint@2.1",
|
||||||
"android.hardware.biometrics.fingerprint@2.2",
|
"android.hardware.biometrics.fingerprint@2.2",
|
||||||
"android.hardware.biometrics.fingerprint@2.3",
|
"android.hardware.biometrics.fingerprint@2.3",
|
||||||
"com.motorola.hardware.biometric.fingerprint@1.0",
|
"vendor.egistec.hardware.fingerprint@4.0",
|
||||||
],
|
],
|
||||||
|
header_libs: ["generated_kernel_headers"]
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,19 +17,44 @@
|
||||||
|
|
||||||
#include "BiometricsFingerprint.h"
|
#include "BiometricsFingerprint.h"
|
||||||
|
|
||||||
|
#include <android-base/file.h>
|
||||||
#include <android-base/logging.h>
|
#include <android-base/logging.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <poll.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <display/drm/sde_drm.h>
|
||||||
#include <poll.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#define NOTIFY_FINGER_UP IMotFodEventType::FINGER_UP
|
enum HBM_STATE { OFF = 0, ON = 2 };
|
||||||
#define NOTIFY_FINGER_DOWN IMotFodEventType::FINGER_DOWN
|
|
||||||
|
|
||||||
#define FOD_UI_PATH "/sys/devices/platform/soc/soc:qcom,dsi-display-primary/fod_ui"
|
void setHbmState(int state) {
|
||||||
|
struct panel_param_info param_info;
|
||||||
|
int32_t node = open("/dev/dri/card0", O_RDWR);
|
||||||
|
int32_t ret = 0;
|
||||||
|
|
||||||
|
if (node < 0) {
|
||||||
|
LOG(ERROR) << "Failed to get card0!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
param_info.param_idx = PARAM_HBM;
|
||||||
|
param_info.value = state;
|
||||||
|
|
||||||
|
ret = ioctl(node, DRM_IOCTL_SET_PANEL_FEATURE, ¶m_info);
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG(ERROR) << "IOCTL call failed with ret = " << ret;
|
||||||
|
} else {
|
||||||
|
LOG(INFO) << "HBM state set successfully. New state: " << state;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(node);
|
||||||
|
}
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace hardware {
|
namespace hardware {
|
||||||
|
@ -38,52 +63,9 @@ namespace fingerprint {
|
||||||
namespace V2_3 {
|
namespace V2_3 {
|
||||||
namespace implementation {
|
namespace implementation {
|
||||||
|
|
||||||
static bool readBool(int fd) {
|
|
||||||
char c;
|
|
||||||
int rc;
|
|
||||||
|
|
||||||
rc = lseek(fd, 0, SEEK_SET);
|
|
||||||
if (rc) {
|
|
||||||
LOG(ERROR) << "failed to seek fd, err: " << rc;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = read(fd, &c, sizeof(char));
|
|
||||||
if (rc != 1) {
|
|
||||||
LOG(ERROR) << "failed to read bool from fd, err: " << rc;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return c != '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
BiometricsFingerprint::BiometricsFingerprint() {
|
BiometricsFingerprint::BiometricsFingerprint() {
|
||||||
biometrics_2_1_service = IBiometricsFingerprint_2_1::getService();
|
biometrics_2_1_service = IBiometricsFingerprint_2_1::getService();
|
||||||
mMotoFingerprint = IMotoFingerPrint::getService();
|
rbs_4_0_service = IBiometricsFingerprintRbs::getService();
|
||||||
|
|
||||||
std::thread([this]() {
|
|
||||||
int fd = open(FOD_UI_PATH, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
|
||||||
LOG(ERROR) << "failed to open fd, err: " << fd;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pollfd fodUiPoll = {
|
|
||||||
.fd = fd,
|
|
||||||
.events = POLLERR | POLLPRI,
|
|
||||||
.revents = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
int rc = poll(&fodUiPoll, 1, -1);
|
|
||||||
if (rc < 0) {
|
|
||||||
LOG(ERROR) << "failed to poll fd, err: " << rc;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mMotoFingerprint->sendFodEvent(readBool(fd) ? NOTIFY_FINGER_DOWN : NOTIFY_FINGER_UP, {},
|
|
||||||
[](IMotFodEventResult, const hidl_vec<signed char>&) {});
|
|
||||||
}
|
|
||||||
}).detach();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<uint64_t> BiometricsFingerprint::setNotify(
|
Return<uint64_t> BiometricsFingerprint::setNotify(
|
||||||
|
@ -109,6 +91,7 @@ Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::cancel() {
|
Return<RequestStatus> BiometricsFingerprint::cancel() {
|
||||||
|
setHbmState(OFF);
|
||||||
return biometrics_2_1_service->cancel();
|
return biometrics_2_1_service->cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +109,7 @@ Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) {
|
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) {
|
||||||
|
setHbmState(OFF);
|
||||||
return biometrics_2_1_service->authenticate(operationId, gid);
|
return biometrics_2_1_service->authenticate(operationId, gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,10 +118,36 @@ Return<bool> BiometricsFingerprint::isUdfps(uint32_t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) {
|
Return<void> BiometricsFingerprint::onFingerDown(uint32_t, uint32_t, float, float) {
|
||||||
|
setHbmState(ON);
|
||||||
|
extraApiWrapper(101);
|
||||||
|
|
||||||
|
std::thread([this]() {
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
||||||
|
BiometricsFingerprint::onFingerUp();
|
||||||
|
}).detach();
|
||||||
|
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
Return<void> BiometricsFingerprint::onFingerUp() {
|
Return<void> BiometricsFingerprint::onFingerUp() {
|
||||||
|
setHbmState(OFF);
|
||||||
|
extraApiWrapper(102);
|
||||||
|
return Void();
|
||||||
|
}
|
||||||
|
|
||||||
|
Return<void> BiometricsFingerprint::extraApiWrapper(int cidValue) {
|
||||||
|
int cid[1] = {cidValue};
|
||||||
|
|
||||||
|
// Create a std::vector<uint8_t> to store the data from 'cid'
|
||||||
|
std::vector<uint8_t> cid_data(reinterpret_cast<uint8_t*>(cid),
|
||||||
|
reinterpret_cast<uint8_t*>(cid) + sizeof(cid));
|
||||||
|
|
||||||
|
// Create the hidl_vec<uint8_t> from the std::vector<uint8_t>
|
||||||
|
::android::hardware::hidl_vec<uint8_t> hidl_cid = cid_data;
|
||||||
|
|
||||||
|
// Call extra_api with the correct input buffer and an empty lambda callback
|
||||||
|
rbs_4_0_service->extra_api(7, hidl_cid, [](const ::android::hardware::hidl_vec<uint8_t>&) {});
|
||||||
|
|
||||||
return Void();
|
return Void();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,9 @@
|
||||||
#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_3_BIOMETRICSFINGERPRINT_H
|
||||||
|
|
||||||
#include <android/hardware/biometrics/fingerprint/2.3/IBiometricsFingerprint.h>
|
#include <android/hardware/biometrics/fingerprint/2.3/IBiometricsFingerprint.h>
|
||||||
#include <com/motorola/hardware/biometric/fingerprint/1.0/IMotoFingerPrint.h>
|
|
||||||
#include <hidl/MQDescriptor.h>
|
#include <hidl/MQDescriptor.h>
|
||||||
#include <hidl/Status.h>
|
#include <hidl/Status.h>
|
||||||
|
#include <vendor/egistec/hardware/fingerprint/4.0/IBiometricsFingerprintRbs.h>
|
||||||
|
|
||||||
namespace android {
|
namespace android {
|
||||||
namespace hardware {
|
namespace hardware {
|
||||||
|
@ -40,9 +40,7 @@ using ::android::hardware::Return;
|
||||||
using ::android::hardware::Void;
|
using ::android::hardware::Void;
|
||||||
using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
|
using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
|
||||||
using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
|
||||||
using ::com::motorola::hardware::biometric::fingerprint::V1_0::IMotFodEventResult;
|
using ::vendor::egistec::hardware::fingerprint::V4_0::IBiometricsFingerprintRbs;
|
||||||
using ::com::motorola::hardware::biometric::fingerprint::V1_0::IMotFodEventType;
|
|
||||||
using ::com::motorola::hardware::biometric::fingerprint::V1_0::IMotoFingerPrint;
|
|
||||||
|
|
||||||
struct BiometricsFingerprint : public IBiometricsFingerprint {
|
struct BiometricsFingerprint : public IBiometricsFingerprint {
|
||||||
BiometricsFingerprint();
|
BiometricsFingerprint();
|
||||||
|
@ -65,9 +63,11 @@ struct BiometricsFingerprint : public IBiometricsFingerprint {
|
||||||
Return<void> onFingerDown(uint32_t x, uint32_t y, float minor, float major) override;
|
Return<void> onFingerDown(uint32_t x, uint32_t y, float minor, float major) override;
|
||||||
Return<void> onFingerUp() override;
|
Return<void> onFingerUp() override;
|
||||||
|
|
||||||
|
Return<void> extraApiWrapper(int cidValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sp<IBiometricsFingerprint_2_1> biometrics_2_1_service;
|
sp<IBiometricsFingerprint_2_1> biometrics_2_1_service;
|
||||||
sp<IMotoFingerPrint> mMotoFingerprint;
|
sp<IBiometricsFingerprintRbs> rbs_4_0_service;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace implementation
|
} // namespace implementation
|
||||||
|
|
Loading…
Reference in a new issue