android_device_motorola_milanf/fingerprint/BiometricsFingerprint.cpp
electimon 904a71bb02
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
2025-04-07 23:22:27 +03:00

159 lines
4.7 KiB
C++

/*
* Copyright (C) 2017 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.
*/
#define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service.bangkk"
#include "BiometricsFingerprint.h"
#include <android-base/file.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 <fstream>
#include <thread>
#include <display/drm/sde_drm.h>
enum HBM_STATE { OFF = 0, ON = 2 };
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, &param_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 hardware {
namespace biometrics {
namespace fingerprint {
namespace V2_3 {
namespace implementation {
BiometricsFingerprint::BiometricsFingerprint() {
biometrics_2_1_service = IBiometricsFingerprint_2_1::getService();
rbs_4_0_service = IBiometricsFingerprintRbs::getService();
}
Return<uint64_t> BiometricsFingerprint::setNotify(
const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
return biometrics_2_1_service->setNotify(clientCallback);
}
Return<uint64_t> BiometricsFingerprint::preEnroll() {
return biometrics_2_1_service->preEnroll();
}
Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat,
uint32_t gid, uint32_t timeoutSec) {
return biometrics_2_1_service->enroll(hat, gid, timeoutSec);
}
Return<RequestStatus> BiometricsFingerprint::postEnroll() {
return biometrics_2_1_service->postEnroll();
}
Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
return biometrics_2_1_service->getAuthenticatorId();
}
Return<RequestStatus> BiometricsFingerprint::cancel() {
setHbmState(OFF);
return biometrics_2_1_service->cancel();
}
Return<RequestStatus> BiometricsFingerprint::enumerate() {
return biometrics_2_1_service->enumerate();
}
Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
return biometrics_2_1_service->remove(gid, fid);
}
Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
const hidl_string& storePath) {
return biometrics_2_1_service->setActiveGroup(gid, storePath);
}
Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) {
setHbmState(OFF);
return biometrics_2_1_service->authenticate(operationId, gid);
}
Return<bool> BiometricsFingerprint::isUdfps(uint32_t) {
return true;
}
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> 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();
}
} // namespace implementation
} // namespace V2_3
} // namespace fingerprint
} // namespace biometrics
} // namespace hardware
} // namespace android