diff --git a/fingerprint/Android.bp b/fingerprint/Android.bp
new file mode 100644
index 0000000000000000000000000000000000000000..322bd4eb99ef09b8032e8b47fba56243ab5672ec
--- /dev/null
+++ b/fingerprint/Android.bp
@@ -0,0 +1,32 @@
+//
+// Copyright (C) 2017-2018 The LineageOS 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.
+
+cc_binary {
+    name: "android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8998",
+    relative_install_path: "hw",
+    defaults: ["hidl_defaults"],
+    init_rc: ["android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8998.rc"],
+    srcs: ["service.cpp", "BiometricsFingerprint.cpp"],
+    shared_libs: [
+        "libbase",
+        "libcutils",
+        "libhardware",
+        "libhidlbase",
+        "liblog",
+        "libutils",
+        "android.hardware.biometrics.fingerprint@2.1",
+    ],
+    proprietary: true,
+}
diff --git a/fingerprint/BiometricsFingerprint.cpp b/fingerprint/BiometricsFingerprint.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a252dae4b591846f14cfae830bd0731aa420c20d
--- /dev/null
+++ b/fingerprint/BiometricsFingerprint.cpp
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2018 The LineageOS 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.1-service.xiaomi_msm8998"
+
+#include <hardware/hw_auth_token.h>
+
+#include <hardware/hardware.h>
+#include <hardware/fingerprint.h>
+#include "BiometricsFingerprint.h"
+
+#include <cutils/properties.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+namespace android {
+namespace hardware {
+namespace biometrics {
+namespace fingerprint {
+namespace V2_1 {
+namespace implementation {
+
+// Supported fingerprint HAL version
+static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 1);
+
+using RequestStatus =
+        android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
+
+BiometricsFingerprint *BiometricsFingerprint::sInstance = nullptr;
+
+BiometricsFingerprint::BiometricsFingerprint() : mClientCallback(nullptr), mDevice(nullptr) {
+    sInstance = this; // keep track of the most recent instance
+    mDevice = openHal();
+    if (!mDevice) {
+        ALOGE("Can't open HAL module");
+    }
+}
+
+BiometricsFingerprint::~BiometricsFingerprint() {
+    ALOGV("~BiometricsFingerprint()");
+    if (mDevice == nullptr) {
+        ALOGE("No valid device");
+        return;
+    }
+    int err;
+    if (0 != (err = mDevice->common.close(
+            reinterpret_cast<hw_device_t*>(mDevice)))) {
+        ALOGE("Can't close fingerprint module, error: %d", err);
+        return;
+    }
+    mDevice = nullptr;
+}
+
+Return<RequestStatus> BiometricsFingerprint::ErrorFilter(int32_t error) {
+    switch(error) {
+        case 0: return RequestStatus::SYS_OK;
+        case -2: return RequestStatus::SYS_ENOENT;
+        case -4: return RequestStatus::SYS_EINTR;
+        case -5: return RequestStatus::SYS_EIO;
+        case -11: return RequestStatus::SYS_EAGAIN;
+        case -12: return RequestStatus::SYS_ENOMEM;
+        case -13: return RequestStatus::SYS_EACCES;
+        case -14: return RequestStatus::SYS_EFAULT;
+        case -16: return RequestStatus::SYS_EBUSY;
+        case -22: return RequestStatus::SYS_EINVAL;
+        case -28: return RequestStatus::SYS_ENOSPC;
+        case -110: return RequestStatus::SYS_ETIMEDOUT;
+        default:
+            ALOGE("An unknown error returned from fingerprint vendor library: %d", error);
+            return RequestStatus::SYS_UNKNOWN;
+    }
+}
+
+// Translate from errors returned by traditional HAL (see fingerprint.h) to
+// HIDL-compliant FingerprintError.
+FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error,
+            int32_t* vendorCode) {
+    *vendorCode = 0;
+    switch(error) {
+        case FINGERPRINT_ERROR_HW_UNAVAILABLE:
+            return FingerprintError::ERROR_HW_UNAVAILABLE;
+        case FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
+            return FingerprintError::ERROR_UNABLE_TO_PROCESS;
+        case FINGERPRINT_ERROR_TIMEOUT:
+            return FingerprintError::ERROR_TIMEOUT;
+        case FINGERPRINT_ERROR_NO_SPACE:
+            return FingerprintError::ERROR_NO_SPACE;
+        case FINGERPRINT_ERROR_CANCELED:
+            return FingerprintError::ERROR_CANCELED;
+        case FINGERPRINT_ERROR_UNABLE_TO_REMOVE:
+            return FingerprintError::ERROR_UNABLE_TO_REMOVE;
+        case FINGERPRINT_ERROR_LOCKOUT:
+            return FingerprintError::ERROR_LOCKOUT;
+        default:
+            if (error >= FINGERPRINT_ERROR_VENDOR_BASE) {
+                // vendor specific code.
+                *vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE;
+                return FingerprintError::ERROR_VENDOR;
+            }
+    }
+    ALOGE("Unknown error from fingerprint vendor library: %d", error);
+    return FingerprintError::ERROR_UNABLE_TO_PROCESS;
+}
+
+// Translate acquired messages returned by traditional HAL (see fingerprint.h)
+// to HIDL-compliant FingerprintAcquiredInfo.
+FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(
+        int32_t info, int32_t* vendorCode) {
+    *vendorCode = 0;
+    switch(info) {
+        case FINGERPRINT_ACQUIRED_GOOD:
+            return FingerprintAcquiredInfo::ACQUIRED_GOOD;
+        case FINGERPRINT_ACQUIRED_PARTIAL:
+            return FingerprintAcquiredInfo::ACQUIRED_PARTIAL;
+        case FINGERPRINT_ACQUIRED_INSUFFICIENT:
+            return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
+        case FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
+            return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY;
+        case FINGERPRINT_ACQUIRED_TOO_SLOW:
+            return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW;
+        case FINGERPRINT_ACQUIRED_TOO_FAST:
+            return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST;
+        default:
+            if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) {
+                // vendor specific code.
+                *vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE;
+                return FingerprintAcquiredInfo::ACQUIRED_VENDOR;
+            }
+    }
+    ALOGE("Unknown acquiredmsg from fingerprint vendor library: %d", info);
+    return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT;
+}
+
+Return<uint64_t> BiometricsFingerprint::setNotify(
+        const sp<IBiometricsFingerprintClientCallback>& clientCallback) {
+    std::lock_guard<std::mutex> lock(mClientCallbackMutex);
+    mClientCallback = clientCallback;
+    // This is here because HAL 2.1 doesn't have a way to propagate a
+    // unique token for its driver. Subsequent versions should send a unique
+    // token for each call to setNotify(). This is fine as long as there's only
+    // one fingerprint device on the platform.
+    return reinterpret_cast<uint64_t>(mDevice);
+}
+
+Return<uint64_t> BiometricsFingerprint::preEnroll()  {
+    return mDevice->pre_enroll(mDevice);
+}
+
+Return<RequestStatus> BiometricsFingerprint::enroll(const hidl_array<uint8_t, 69>& hat,
+        uint32_t gid, uint32_t timeoutSec) {
+    const hw_auth_token_t* authToken =
+        reinterpret_cast<const hw_auth_token_t*>(hat.data());
+    return ErrorFilter(mDevice->enroll(mDevice, authToken, gid, timeoutSec));
+}
+
+Return<RequestStatus> BiometricsFingerprint::postEnroll() {
+    return ErrorFilter(mDevice->post_enroll(mDevice));
+}
+
+Return<uint64_t> BiometricsFingerprint::getAuthenticatorId() {
+    return mDevice->get_authenticator_id(mDevice);
+}
+
+Return<RequestStatus> BiometricsFingerprint::cancel() {
+    return ErrorFilter(mDevice->cancel(mDevice));
+}
+
+Return<RequestStatus> BiometricsFingerprint::enumerate()  {
+    return ErrorFilter(mDevice->enumerate(mDevice));
+}
+
+Return<RequestStatus> BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) {
+    return ErrorFilter(mDevice->remove(mDevice, gid, fid));
+}
+
+Return<RequestStatus> BiometricsFingerprint::setActiveGroup(uint32_t gid,
+        const hidl_string& storePath) {
+    if (storePath.size() >= PATH_MAX || storePath.size() <= 0) {
+        ALOGE("Bad path length: %zd", storePath.size());
+        return RequestStatus::SYS_EINVAL;
+    }
+    if (access(storePath.c_str(), W_OK)) {
+        return RequestStatus::SYS_EINVAL;
+    }
+
+    return ErrorFilter(mDevice->set_active_group(mDevice, gid,
+                                                    storePath.c_str()));
+}
+
+Return<RequestStatus> BiometricsFingerprint::authenticate(uint64_t operationId,
+        uint32_t gid) {
+    return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid));
+}
+
+IBiometricsFingerprint* BiometricsFingerprint::getInstance() {
+    if (!sInstance) {
+      sInstance = new BiometricsFingerprint();
+    }
+    return sInstance;
+}
+
+fingerprint_device_t* getDeviceForVendor(const char *class_name)
+{
+    const hw_module_t *hw_module = nullptr;
+    int err;
+
+    err = hw_get_module_by_class(FINGERPRINT_HARDWARE_MODULE_ID, class_name, &hw_module);
+    if (err) {
+        ALOGE("Failed to get fingerprint module: class %s, error %d", class_name, err);
+        return nullptr;
+    }
+
+    if (hw_module == nullptr) {
+        ALOGE("No valid fingerprint module: class %s", class_name);
+        return nullptr;
+    }
+
+    fingerprint_module_t const *fp_module =
+            reinterpret_cast<const fingerprint_module_t*>(hw_module);
+
+    if (fp_module->common.methods->open == nullptr) {
+        ALOGE("No valid open method: class %s", class_name);
+        return nullptr;
+    }
+
+    hw_device_t *device = nullptr;
+
+    err = fp_module->common.methods->open(hw_module, nullptr, &device);
+    if (err) {
+        ALOGE("Can't open fingerprint methods, class %s, error: %d", class_name, err);
+        return nullptr;
+    }
+
+    if (kVersion != device->version) {
+        ALOGE("Wrong fingerprint version: expected %d, got %d", kVersion, device->version);
+        return nullptr;
+    }
+
+    fingerprint_device_t *fp_device =
+            reinterpret_cast<fingerprint_device_t*>(device);
+
+    ALOGI("Loaded fingerprint module: class %s", class_name);
+    return fp_device;
+}
+
+void setFpVendorProp(const char *fp_vendor) {
+    property_set("persist.vendor.sys.fp.vendor", fp_vendor);
+    property_set("ro.boot.fpsensor", fp_vendor);
+}
+
+fingerprint_device_t* getFingerprintDevice()
+{
+    fingerprint_device_t *fp_device;
+
+    fp_device = getDeviceForVendor("fpc");
+    if (fp_device == nullptr) {
+        ALOGE("Failed to load fpc fingerprint module");
+    } else {
+        setFpVendorProp("fpc");
+        return fp_device;
+    }
+
+    fp_device = getDeviceForVendor("goodix");
+    if (fp_device == nullptr) {
+        ALOGE("Failed to load goodix fingerprint module");
+    } else {
+        setFpVendorProp("goodix");
+        return fp_device;
+    }
+
+    setFpVendorProp("none");
+
+    return nullptr;
+}
+
+fingerprint_device_t* BiometricsFingerprint::openHal() {
+    int err;
+
+    fingerprint_device_t *fp_device;
+    fp_device = getFingerprintDevice();
+    if (fp_device == nullptr) {
+        return nullptr;
+    }
+
+    if (0 != (err =
+            fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) {
+        ALOGE("Can't register fingerprint module callback, error: %d", err);
+        return nullptr;
+    }
+
+    return fp_device;
+}
+
+void BiometricsFingerprint::notify(const fingerprint_msg_t *msg) {
+    BiometricsFingerprint* thisPtr = static_cast<BiometricsFingerprint*>(
+            BiometricsFingerprint::getInstance());
+    std::lock_guard<std::mutex> lock(thisPtr->mClientCallbackMutex);
+    if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) {
+        ALOGE("Receiving callbacks before the client callback is registered.");
+        return;
+    }
+    const uint64_t devId = reinterpret_cast<uint64_t>(thisPtr->mDevice);
+    switch (msg->type) {
+        case FINGERPRINT_ERROR: {
+                int32_t vendorCode = 0;
+                FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
+                ALOGD("onError(%d)", result);
+                if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
+                    ALOGE("failed to invoke fingerprint onError callback");
+                }
+            }
+            break;
+        case FINGERPRINT_ACQUIRED: {
+                int32_t vendorCode = 0;
+                FingerprintAcquiredInfo result =
+                    VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
+                ALOGD("onAcquired(%d)", result);
+                if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAcquired callback");
+                }
+            }
+            break;
+        case FINGERPRINT_TEMPLATE_ENROLLING:
+            ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)",
+                msg->data.enroll.finger.fid,
+                msg->data.enroll.finger.gid,
+                msg->data.enroll.samples_remaining);
+            if (!thisPtr->mClientCallback->onEnrollResult(devId,
+                    msg->data.enroll.finger.fid,
+                    msg->data.enroll.finger.gid,
+                    msg->data.enroll.samples_remaining).isOk()) {
+                ALOGE("failed to invoke fingerprint onEnrollResult callback");
+            }
+            break;
+        case FINGERPRINT_TEMPLATE_REMOVED:
+            ALOGD("onRemove(fid=%d, gid=%d, rem=%d)",
+                msg->data.removed.finger.fid,
+                msg->data.removed.finger.gid,
+                msg->data.removed.remaining_templates);
+            if (!thisPtr->mClientCallback->onRemoved(devId,
+                    msg->data.removed.finger.fid,
+                    msg->data.removed.finger.gid,
+                    msg->data.removed.remaining_templates).isOk()) {
+                ALOGE("failed to invoke fingerprint onRemoved callback");
+            }
+            break;
+        case FINGERPRINT_AUTHENTICATED:
+            if (msg->data.authenticated.finger.fid != 0) {
+                ALOGD("onAuthenticated(fid=%d, gid=%d)",
+                    msg->data.authenticated.finger.fid,
+                    msg->data.authenticated.finger.gid);
+                const uint8_t* hat =
+                    reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
+                const hidl_vec<uint8_t> token(
+                    std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
+                if (!thisPtr->mClientCallback->onAuthenticated(devId,
+                        msg->data.authenticated.finger.fid,
+                        msg->data.authenticated.finger.gid,
+                        token).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAuthenticated callback");
+                }
+            } else {
+                // Not a recognized fingerprint
+                if (!thisPtr->mClientCallback->onAuthenticated(devId,
+                        msg->data.authenticated.finger.fid,
+                        msg->data.authenticated.finger.gid,
+                        hidl_vec<uint8_t>()).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAuthenticated callback");
+                }
+            }
+            break;
+        case FINGERPRINT_TEMPLATE_ENUMERATING:
+            ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)",
+                msg->data.enumerated.finger.fid,
+                msg->data.enumerated.finger.gid,
+                msg->data.enumerated.remaining_templates);
+            if (!thisPtr->mClientCallback->onEnumerate(devId,
+                    msg->data.enumerated.finger.fid,
+                    msg->data.enumerated.finger.gid,
+                    msg->data.enumerated.remaining_templates).isOk()) {
+                ALOGE("failed to invoke fingerprint onEnumerate callback");
+            }
+            break;
+    }
+}
+
+} // namespace implementation
+}  // namespace V2_1
+}  // namespace fingerprint
+}  // namespace biometrics
+}  // namespace hardware
+}  // namespace android
diff --git a/fingerprint/BiometricsFingerprint.h b/fingerprint/BiometricsFingerprint.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d64e3d38db8939dc5796f93255d54028f640c43
--- /dev/null
+++ b/fingerprint/BiometricsFingerprint.h
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
+#define ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
+
+#include <log/log.h>
+#include <android/log.h>
+#include <hardware/hardware.h>
+#include <hardware/fingerprint.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+#include <android/hardware/biometrics/fingerprint/2.1/IBiometricsFingerprint.h>
+
+namespace android {
+namespace hardware {
+namespace biometrics {
+namespace fingerprint {
+namespace V2_1 {
+namespace implementation {
+
+using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
+using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback;
+using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::hidl_string;
+using ::android::sp;
+
+struct BiometricsFingerprint : public IBiometricsFingerprint {
+public:
+    BiometricsFingerprint();
+    ~BiometricsFingerprint();
+
+    // Method to wrap legacy HAL with BiometricsFingerprint class
+    static IBiometricsFingerprint* getInstance();
+
+    // Methods from ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint follow.
+    Return<uint64_t> setNotify(const sp<IBiometricsFingerprintClientCallback>& clientCallback) override;
+    Return<uint64_t> preEnroll() override;
+    Return<RequestStatus> enroll(const hidl_array<uint8_t, 69>& hat, uint32_t gid, uint32_t timeoutSec) override;
+    Return<RequestStatus> postEnroll() override;
+    Return<uint64_t> getAuthenticatorId() override;
+    Return<RequestStatus> cancel() override;
+    Return<RequestStatus> enumerate() override;
+    Return<RequestStatus> remove(uint32_t gid, uint32_t fid) override;
+    Return<RequestStatus> setActiveGroup(uint32_t gid, const hidl_string& storePath) override;
+    Return<RequestStatus> authenticate(uint64_t operationId, uint32_t gid) override;
+
+private:
+    static fingerprint_device_t* openHal();
+    static void notify(const fingerprint_msg_t *msg); /* Static callback for legacy HAL implementation */
+    static Return<RequestStatus> ErrorFilter(int32_t error);
+    static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode);
+    static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode);
+    static BiometricsFingerprint* sInstance;
+
+    std::mutex mClientCallbackMutex;
+    sp<IBiometricsFingerprintClientCallback> mClientCallback;
+    fingerprint_device_t *mDevice;
+};
+
+}  // namespace implementation
+}  // namespace V2_1
+}  // namespace fingerprint
+}  // namespace biometrics
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_BIOMETRICS_FINGERPRINT_V2_1_BIOMETRICSFINGERPRINT_H
diff --git a/fingerprint/android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8998.rc b/fingerprint/android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8998.rc
new file mode 100644
index 0000000000000000000000000000000000000000..812ea465eb29d5aee4ab39e1ca1c0071f10b66b3
--- /dev/null
+++ b/fingerprint/android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8998.rc
@@ -0,0 +1,13 @@
+service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.1-service.xiaomi_msm8998
+    class late_start
+    user system
+    group system input uhid
+    writepid /dev/cpuset/system-background/tasks
+
+on post-fs-data
+    mkdir /data/vendor/fpc 0770 system system
+    chown system system /data/vendor/fpc/calibration_image.pndat
+    chmod 0600 /data/vendor/fpc/calibration_image.pndat
+    mkdir /data/vendor/goodix 0770 system system
+    mkdir /mnt/vendor/persist/fpc 0770 system system
+    chown system system /data/vendor
diff --git a/fingerprint/service.cpp b/fingerprint/service.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e8536efb9fb68db49468a988099a7b8879edc67b
--- /dev/null
+++ b/fingerprint/service.cpp
@@ -0,0 +1,51 @@
+/*
+ * 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.1-service.xiaomi_msm8998"
+
+#include <android/log.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "BiometricsFingerprint.h"
+
+// libhwbinder:
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+
+// Generated HIDL files
+using android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint;
+using android::hardware::biometrics::fingerprint::V2_1::implementation::BiometricsFingerprint;
+
+int main() {
+    android::sp<IBiometricsFingerprint> service = BiometricsFingerprint::getInstance();
+
+    if (service == nullptr) {
+        ALOGE("Instance of BiometricsFingerprint is null");
+        return 1;
+    }
+
+    configureRpcThreadpool(1, true /*callerWillJoin*/);
+
+    android::status_t status = service->registerAsService();
+    if (status != android::OK) {
+        ALOGE("Cannot register BiometricsFingerprint service");
+        return 1;
+    }
+
+    joinRpcThreadpool();
+
+    return 0; // should never get here
+}