├── Android.bp ├── sensors ├── .clang-format ├── Android.bp └── udfps_hal.cpp ├── hidl ├── touch │ ├── .clang-format │ ├── vendor.lineage.touch@1.0-service.xiaomi.rc │ ├── vendor.lineage.touch@1.0-service.xiaomi.xml │ ├── HighTouchPollingRate.h │ ├── HighTouchPollingRate.cpp │ ├── service.cpp │ └── Android.bp ├── sensors │ ├── 1.0 │ │ ├── .clang-format │ │ ├── Android.bp │ │ ├── include │ │ │ └── sensors │ │ │ │ └── convert.h │ │ ├── Sensors.h │ │ ├── Sensors.cpp │ │ └── convert.cpp │ ├── android.hardware.sensors@2.1-service.xiaomi-multihal.rc │ ├── android.hardware.sensors@2.1.xiaomi-multihal.xml │ ├── service.cpp │ ├── Android.bp │ └── HalProxyCallback.cpp ├── biometrics │ └── fingerprint │ │ ├── .clang-format │ │ ├── android.hardware.biometrics.fingerprint@2.3-service.xiaomi.rc │ │ ├── android.hardware.biometrics.fingerprint@2.3-service.xiaomi.xml │ │ ├── UdfpsExtension.cpp │ │ ├── include │ │ ├── UdfpsHandler.h │ │ └── fingerprint.h │ │ ├── UdfpsHandler.cpp │ │ ├── service.cpp │ │ ├── Android.bp │ │ ├── BiometricsFingerprint.h │ │ └── BiometricsFingerprint.cpp ├── consumerir │ ├── android.hardware.ir@1.0-service.xiaomi.rc │ ├── android.hardware.ir@1.0-service.xiaomi.xml │ ├── Android.bp │ ├── service.cpp │ ├── ConsumerIr.h │ └── ConsumerIr.cpp └── powershare │ ├── vendor.lineage.powershare@1.0-service.xiaomi.rc │ ├── vendor.lineage.powershare@1.0-service.xiaomi.xml │ ├── PowerShare.h │ ├── service.cpp │ ├── Android.bp │ └── PowerShare.cpp ├── IFAAService ├── res │ └── values │ │ └── strings.xml ├── Android.bp ├── src │ └── org │ │ └── ifaa │ │ └── aidl │ │ └── manager │ │ ├── IfaaManagerService.aidl │ │ └── IfaaService.java └── AndroidManifest.xml ├── aidl ├── light │ ├── android.hardware.light-service.xiaomi.xml │ ├── Backlight.h │ ├── LED.h │ ├── Android.bp │ ├── service.cpp │ ├── Utils.h │ ├── LED.cpp │ ├── Lights.h │ ├── android.hardware.light-service.xiaomi.rc │ ├── Utils.cpp │ ├── Backlight.cpp │ └── Lights.cpp ├── power-libperfmgr │ ├── android.hardware.power-service.xiaomi.xml │ ├── android.hardware.power-service.xiaomi-libperfmgr.rc │ ├── PowerExt.h │ ├── InteractionHandler.h │ ├── Android.mk │ ├── Power.h │ ├── service.cpp │ ├── PowerExt.cpp │ ├── PowerSessionManager.h │ ├── PowerHintSession.h │ ├── PowerSessionManager.cpp │ ├── InteractionHandler.cpp │ └── Power.cpp └── Android.mk ├── interfaces ├── Android.bp ├── updates-makefiles.sh ├── xiaomi │ ├── hardware │ │ ├── mlipay │ │ │ ├── 1.0 │ │ │ │ ├── Android.bp │ │ │ │ └── IMlipayService.hal │ │ │ └── 1.1 │ │ │ │ ├── IMlipayService.hal │ │ │ │ └── Android.bp │ │ ├── mtdservice │ │ │ ├── 1.0 │ │ │ │ ├── Android.bp │ │ │ │ └── IMTService.hal │ │ │ ├── 1.1 │ │ │ │ ├── Android.bp │ │ │ │ └── IMTService.hal │ │ │ └── 1.2 │ │ │ │ ├── Android.bp │ │ │ │ └── IMTService.hal │ │ ├── touchfeature │ │ │ └── 1.0 │ │ │ │ ├── Android.bp │ │ │ │ └── ITouchFeature.hal │ │ ├── fingerprintextension │ │ │ └── 1.0 │ │ │ │ ├── Android.bp │ │ │ │ └── IXiaomiFingerprint.hal │ │ ├── motor │ │ │ └── 1.0 │ │ │ │ ├── Android.bp │ │ │ │ ├── types.hal │ │ │ │ ├── IMotorCallback.hal │ │ │ │ └── IMotor.hal │ │ └── displayfeature │ │ │ └── 1.0 │ │ │ ├── Android.bp │ │ │ ├── IDisplayFeatureCallback.hal │ │ │ ├── types.hal │ │ │ └── IDisplayFeature.hal │ └── hw │ │ └── touchfeature │ │ └── 1.0 │ │ ├── Android.bp │ │ └── ITouchFeature.hal └── goodix │ └── hardware │ └── biometrics │ └── fingerprint │ └── 2.1 │ ├── Android.bp │ ├── IGoodixFingerprintDaemonCallback.hal │ └── IGoodixFingerprintDaemon.hal ├── megvii ├── Android.bp └── megvii.c └── Android.mk /Android.bp: -------------------------------------------------------------------------------- 1 | soong_namespace { 2 | } 3 | -------------------------------------------------------------------------------- /sensors/.clang-format: -------------------------------------------------------------------------------- 1 | ../../../build/soong/scripts/system-clang-format -------------------------------------------------------------------------------- /hidl/touch/.clang-format: -------------------------------------------------------------------------------- 1 | ../../../../build/soong/scripts/system-clang-format -------------------------------------------------------------------------------- /hidl/sensors/1.0/.clang-format: -------------------------------------------------------------------------------- 1 | ../../../../../build/soong/scripts/system-clang-format -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/.clang-format: -------------------------------------------------------------------------------- 1 | ../../../../../build/soong/scripts/system-clang-format -------------------------------------------------------------------------------- /IFAAService/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | IFAAService 4 | 5 | -------------------------------------------------------------------------------- /hidl/consumerir/android.hardware.ir@1.0-service.xiaomi.rc: -------------------------------------------------------------------------------- 1 | service ir-hal-1-0 /vendor/bin/hw/android.hardware.ir@1.0-service.xiaomi 2 | class hal 3 | user system 4 | group system 5 | -------------------------------------------------------------------------------- /hidl/powershare/vendor.lineage.powershare@1.0-service.xiaomi.rc: -------------------------------------------------------------------------------- 1 | service vendor.powershare-hal-1-0 /vendor/bin/hw/vendor.lineage.powershare@1.0-service.xiaomi 2 | class hal 3 | user system 4 | group system 5 | -------------------------------------------------------------------------------- /aidl/light/android.hardware.light-service.xiaomi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | android.hardware.light 4 | ILights/default 5 | 6 | 7 | -------------------------------------------------------------------------------- /interfaces/Android.bp: -------------------------------------------------------------------------------- 1 | hidl_package_root { 2 | name: "vendor.goodix", 3 | path: "hardware/xiaomi/interfaces/goodix", 4 | } 5 | 6 | hidl_package_root { 7 | name: "vendor.xiaomi", 8 | path: "hardware/xiaomi/interfaces/xiaomi", 9 | } 10 | -------------------------------------------------------------------------------- /hidl/touch/vendor.lineage.touch@1.0-service.xiaomi.rc: -------------------------------------------------------------------------------- 1 | service vendor.touch-hal-1-0 /vendor/bin/hw/vendor.lineage.touch@1.0-service.xiaomi 2 | interface vendor.lineage.touch@1.0::IHighTouchPollingRate default 3 | class hal 4 | user system 5 | group system 6 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/android.hardware.power-service.xiaomi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | android.hardware.power 4 | 2 5 | IPower/default 6 | 7 | 8 | -------------------------------------------------------------------------------- /interfaces/updates-makefiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | source $ANDROID_BUILD_TOP/system/tools/hidl/update-makefiles-helper.sh 4 | 5 | do_makefiles_update \ 6 | "vendor.goodix:hardware/xiaomi/interfaces/goodix" 7 | 8 | do_makefiles_update \ 9 | "vendor.xiaomi:hardware/xiaomi/interfaces/xiaomi" 10 | -------------------------------------------------------------------------------- /hidl/sensors/android.hardware.sensors@2.1-service.xiaomi-multihal.rc: -------------------------------------------------------------------------------- 1 | service vendor.sensors-hal-2-1-multihal /vendor/bin/hw/android.hardware.sensors@2.1-service.xiaomi-multihal 2 | class hal 3 | user system 4 | group system wakelock context_hub uhid 5 | writepid /dev/cpuset/system-background/tasks 6 | capabilities BLOCK_SUSPEND 7 | rlimit rtprio 10 10 8 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mlipay/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.mlipay@1.0", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IMlipayService.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | ], 13 | gen_java: true, 14 | } 15 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hw/touchfeature/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hw.touchfeature@1.0", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "ITouchFeature.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | ], 13 | gen_java: true, 14 | } 15 | -------------------------------------------------------------------------------- /hidl/consumerir/android.hardware.ir@1.0-service.xiaomi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | android.hardware.ir 4 | hwbinder 5 | 1.0 6 | 7 | IConsumerIr 8 | default 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mtdservice/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.mtdservice@1.0", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IMTService.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | ], 13 | gen_java: true, 14 | } 15 | -------------------------------------------------------------------------------- /hidl/sensors/android.hardware.sensors@2.1.xiaomi-multihal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | android.hardware.sensors 4 | hwbinder 5 | 2.1 6 | 7 | ISensors 8 | default 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hidl/touch/vendor.lineage.touch@1.0-service.xiaomi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | vendor.lineage.touch 4 | hwbinder 5 | 1.0 6 | 7 | IHighTouchPollingRate 8 | default 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/touchfeature/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.touchfeature@1.0", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "ITouchFeature.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | ], 13 | gen_java: true, 14 | } 15 | -------------------------------------------------------------------------------- /hidl/powershare/vendor.lineage.powershare@1.0-service.xiaomi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | vendor.lineage.powershare 4 | hwbinder 5 | 1.0 6 | 7 | IPowerShare 8 | default 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.xiaomi.rc: -------------------------------------------------------------------------------- 1 | service vendor.fps_hal /vendor/bin/hw/android.hardware.biometrics.fingerprint@2.3-service.xiaomi 2 | # "class hal" causes a race condition on some devices due to files created 3 | # in /data. As a workaround, postpone startup until later in boot once 4 | # /data is mounted. 5 | class late_start 6 | user system 7 | group system input uhid 8 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/fingerprintextension/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.fingerprintextension@1.0", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IXiaomiFingerprint.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | ], 13 | gen_java: true, 14 | } 15 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mlipay/1.1/IMlipayService.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vendor.xiaomi.hardware.mlipay@1.1; 8 | 9 | import @1.0::IMlipayService; 10 | 11 | interface IMlipayService extends @1.0::IMlipayService { 12 | ifaa_key_dump() generates (string hex); 13 | ifaa_get_idlist(uint32_t bioType) generates (vec idList); 14 | }; 15 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mlipay/1.1/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.mlipay@1.1", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IMlipayService.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | "vendor.xiaomi.hardware.mlipay@1.0", 13 | ], 14 | gen_java: true, 15 | } 16 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/motor/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.motor@1.0", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "types.hal", 9 | "IMotor.hal", 10 | "IMotorCallback.hal", 11 | ], 12 | interfaces: [ 13 | "android.hidl.base@1.0", 14 | ], 15 | gen_java: true, 16 | } 17 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mtdservice/1.1/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.mtdservice@1.1", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IMTService.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | "vendor.xiaomi.hardware.mtdservice@1.0", 13 | ], 14 | gen_java: true, 15 | } 16 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/android.hardware.biometrics.fingerprint@2.3-service.xiaomi.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | android.hardware.biometrics.fingerprint 4 | hwbinder 5 | 2.3 6 | 7 | IBiometricsFingerprint 8 | default 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /megvii/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2022 The LineageOS Project 3 | // 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | 7 | cc_defaults { 8 | name: "libMegviiFacepp_defaults", 9 | vendor: true, 10 | srcs: [ 11 | "megvii.c", 12 | ], 13 | } 14 | 15 | cc_library_shared { 16 | name: "libMegviiFacepp-0.5.2", 17 | defaults: ["libMegviiFacepp_defaults"], 18 | } 19 | 20 | cc_library_shared { 21 | name: "libmegface", 22 | vendor: true, 23 | } 24 | -------------------------------------------------------------------------------- /sensors/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2022 The LineageOS Project 3 | // 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | 7 | cc_library_shared { 8 | name: "sensors.udfps", 9 | defaults: ["hidl_defaults"], 10 | srcs: [ 11 | "udfps_hal.cpp", 12 | ], 13 | shared_libs: [ 14 | "libcutils", 15 | "liblog", 16 | "libutils", 17 | ], 18 | header_libs: [ 19 | "libhardware_headers", 20 | ], 21 | vendor: true, 22 | } 23 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/displayfeature/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.displayfeature@1.0", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "types.hal", 9 | "IDisplayFeature.hal", 10 | "IDisplayFeatureCallback.hal", 11 | ], 12 | interfaces: [ 13 | "android.hidl.base@1.0", 14 | ], 15 | gen_java: true, 16 | } 17 | -------------------------------------------------------------------------------- /interfaces/goodix/hardware/biometrics/fingerprint/2.1/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.goodix.hardware.biometrics.fingerprint@2.1", 5 | root: "vendor.goodix", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IGoodixFingerprintDaemon.hal", 9 | "IGoodixFingerprintDaemonCallback.hal", 10 | ], 11 | interfaces: [ 12 | "android.hidl.base@1.0", 13 | ], 14 | gen_java: true, 15 | } 16 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mtdservice/1.2/Android.bp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by hidl-gen -Landroidbp. 2 | 3 | hidl_interface { 4 | name: "vendor.xiaomi.hardware.mtdservice@1.2", 5 | root: "vendor.xiaomi", 6 | system_ext_specific: true, 7 | srcs: [ 8 | "IMTService.hal", 9 | ], 10 | interfaces: [ 11 | "android.hidl.base@1.0", 12 | "vendor.xiaomi.hardware.mtdservice@1.0", 13 | "vendor.xiaomi.hardware.mtdservice@1.1", 14 | ], 15 | gen_java: true, 16 | } 17 | -------------------------------------------------------------------------------- /aidl/light/Backlight.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "Utils.h" 8 | 9 | namespace aidl { 10 | namespace android { 11 | namespace hardware { 12 | namespace light { 13 | 14 | class BacklightDevice { 15 | public: 16 | virtual ~BacklightDevice() = default; 17 | 18 | virtual void setBacklight(uint8_t value) = 0; 19 | virtual bool exists() = 0; 20 | }; 21 | 22 | BacklightDevice *getBacklightDevice(); 23 | 24 | } // namespace light 25 | } // namespace hardware 26 | } // namespace android 27 | } // namespace aidl 28 | -------------------------------------------------------------------------------- /IFAAService/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2022 The LineageOS Project 3 | // 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | 7 | android_app { 8 | name: "IFAAService", 9 | srcs: [ 10 | "src/**/*.java", 11 | "src/**/I*.aidl", 12 | ], 13 | aidl: { 14 | local_include_dirs: ["src"], 15 | }, 16 | resource_dirs: ["res"], 17 | 18 | static_libs: [ 19 | "android.hidl.base-V1.0-java", 20 | "vendor.xiaomi.hardware.mlipay-V1.1-java", 21 | ], 22 | 23 | certificate: "platform", 24 | platform_apis: true, 25 | system_ext_specific: true, 26 | } 27 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mlipay/1.0/IMlipayService.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vendor.xiaomi.hardware.mlipay@1.0; 8 | 9 | interface IMlipayService { 10 | invoke_command(vec sbuf, uint32_t sbuf_len) generates (vec ret); 11 | ifaa_key_get_version() generates (int32_t result); 12 | ifaa_key_prepare() generates (string hex); 13 | ifaa_key_load(string data_text, string sign_text) generates (int32_t result); 14 | ifaa_key_extract(vec buf, uint32_t buf_len) generates (int32_t result); 15 | }; 16 | -------------------------------------------------------------------------------- /IFAAService/src/org/ifaa/aidl/manager/IfaaManagerService.aidl: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2022 The LineageOS Project 3 | // 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | 7 | package org.ifaa.aidl.manager; 8 | 9 | interface IfaaManagerService { 10 | int getSupportBIOTypes(); 11 | int startBIOManager(int authType); 12 | String getDeviceModel(); 13 | byte[] processCmd(inout byte[] param); 14 | int getVersion(); 15 | String getExtInfo(int authType, String keyExtInfo); 16 | void setExtInfo(int authType, String keyExtInfo, String valExtInfo); 17 | int getEnabled(int bioType); 18 | int[] getIDList(int bioType); 19 | } 20 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/UdfpsExtension.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | #if __has_include() 10 | #include 11 | #elif __has_include() 12 | #include 13 | #endif 14 | 15 | uint32_t getUdfpsZOrder(uint32_t z, bool touched) { 16 | if (touched) { 17 | z |= FOD_PRESSED_LAYER_ZORDER; 18 | } 19 | return z; 20 | } 21 | 22 | uint64_t getUdfpsUsageBits(uint64_t usageBits, bool /* touched */) { 23 | return usageBits; 24 | } 25 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mtdservice/1.1/IMTService.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vendor.xiaomi.hardware.mtdservice@1.1; 8 | 9 | import @1.0::IMTService; 10 | 11 | interface IMTService extends @1.0::IMTService { 12 | persist_read(int32_t dir_id, string file_name) generates (int32_t ret, vec rbuf); 13 | persist_write(int32_t dir_id, string file_name, vec sbuf, uint32_t sbuf_len) generates (int32_t ret); 14 | persist_remove(int32_t dir_id, string file_name) generates (int32_t ret); 15 | ifaa_key_dump() generates (string ret); 16 | }; 17 | -------------------------------------------------------------------------------- /aidl/light/LED.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace aidl { 12 | namespace android { 13 | namespace hardware { 14 | namespace light { 15 | 16 | class LED { 17 | public: 18 | LED(std::string type); 19 | 20 | bool exists(); 21 | bool setBreath(uint8_t value); 22 | bool setBrightness(uint8_t value); 23 | private: 24 | std::string mBasePath; 25 | uint32_t mMaxBrightness; 26 | bool mBreath; 27 | }; 28 | 29 | } // namespace light 30 | } // namespace hardware 31 | } // namespace android 32 | } // namespace aidl 33 | -------------------------------------------------------------------------------- /aidl/Android.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021 The LineageOS Project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | include $(call all-subdir-makefiles) 18 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021 The LineageOS Project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | ifeq ($(BOARD_VENDOR),xiaomi) 18 | 19 | include $(call all-subdir-makefiles) 20 | 21 | endif 22 | -------------------------------------------------------------------------------- /aidl/light/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2021-2022 The LineageOS Project 3 | // 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | 7 | cc_binary { 8 | name: "android.hardware.light-service.xiaomi", 9 | overrides: ["android.hardware.lights-service.qti"], 10 | relative_install_path: "hw", 11 | init_rc: ["android.hardware.light-service.xiaomi.rc"], 12 | vintf_fragments: ["android.hardware.light-service.xiaomi.xml"], 13 | srcs: [ 14 | "Backlight.cpp", 15 | "Lights.cpp", 16 | "LED.cpp", 17 | "Utils.cpp", 18 | "service.cpp", 19 | ], 20 | shared_libs: [ 21 | "libbase", 22 | "libbinder_ndk", 23 | "android.hardware.light-V1-ndk", 24 | ], 25 | vendor: true, 26 | } 27 | -------------------------------------------------------------------------------- /hidl/sensors/1.0/Android.bp: -------------------------------------------------------------------------------- 1 | package { 2 | // See: http://go/android-license-faq 3 | default_applicable_licenses: ["Android-Apache-2.0"], 4 | } 5 | 6 | cc_library_shared { 7 | name: "android.hardware.sensors@1.0-impl-xiaomi", 8 | defaults: ["hidl_defaults"], 9 | proprietary: true, 10 | relative_install_path: "hw", 11 | srcs: [ 12 | "Sensors.cpp", 13 | "convert.cpp", 14 | ], 15 | shared_libs: [ 16 | "liblog", 17 | "libcutils", 18 | "libhardware", 19 | "libbase", 20 | "libutils", 21 | "libhidlbase", 22 | "android.hardware.sensors@1.0", 23 | ], 24 | static_libs: [ 25 | "multihal", 26 | ], 27 | local_include_dirs: ["include/sensors"], 28 | } 29 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/include/UdfpsHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include "fingerprint.h" 11 | 12 | class UdfpsHandler { 13 | public: 14 | virtual ~UdfpsHandler() = default; 15 | 16 | virtual void init(fingerprint_device_t *device) = 0; 17 | virtual void onFingerDown(uint32_t x, uint32_t y, float minor, float major) = 0; 18 | virtual void onFingerUp() = 0; 19 | 20 | virtual void onAcquired(int32_t result, int32_t vendorCode) = 0; 21 | virtual void cancel() = 0; 22 | }; 23 | 24 | struct UdfpsHandlerFactory { 25 | UdfpsHandler* (*create)(); 26 | void (*destroy)(UdfpsHandler* handler); 27 | }; 28 | 29 | UdfpsHandlerFactory *getUdfpsHandlerFactory(); 30 | -------------------------------------------------------------------------------- /hidl/touch/HighTouchPollingRate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace vendor { 12 | namespace lineage { 13 | namespace touch { 14 | namespace V1_0 { 15 | namespace implementation { 16 | 17 | using ::android::hardware::Return; 18 | 19 | class HighTouchPollingRate : public IHighTouchPollingRate { 20 | public: 21 | // Methods from ::vendor::lineage::touch::V1_0::IHighTouchPollingRate follow. 22 | Return isEnabled() override; 23 | Return setEnabled(bool enabled) override; 24 | }; 25 | 26 | } // namespace implementation 27 | } // namespace V1_0 28 | } // namespace touch 29 | } // namespace lineage 30 | } // namespace vendor 31 | -------------------------------------------------------------------------------- /IFAAService/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/motor/1.0/types.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.motor@1.0; 18 | 19 | struct MotorEvent { 20 | int32_t vaalue; 21 | int32_t cookie; 22 | }; 23 | -------------------------------------------------------------------------------- /megvii/megvii.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | static int stub_fail() { 8 | return -1; 9 | } 10 | 11 | static char *stub_fail_str() { 12 | return "stub"; 13 | } 14 | 15 | void *mg_facepp[] = { 16 | &stub_fail, 17 | &stub_fail, 18 | &stub_fail, 19 | &stub_fail_str, 20 | &stub_fail_str, 21 | &stub_fail, 22 | &stub_fail, 23 | &stub_fail, 24 | &stub_fail, 25 | &stub_fail, 26 | &stub_fail, 27 | &stub_fail, 28 | &stub_fail, 29 | &stub_fail, 30 | &stub_fail, 31 | &stub_fail, 32 | &stub_fail, 33 | &stub_fail, 34 | &stub_fail, 35 | &stub_fail, 36 | &stub_fail, 37 | &stub_fail, 38 | &stub_fail, 39 | &stub_fail, 40 | &stub_fail, 41 | &stub_fail, 42 | &stub_fail, 43 | }; 44 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/motor/1.0/IMotorCallback.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.motor@1.0; 18 | 19 | interface IMotorCallback { 20 | oneway onNotify(MotorEvent event); 21 | }; 22 | -------------------------------------------------------------------------------- /aidl/light/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "Lights.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using ::aidl::android::hardware::light::Lights; 14 | 15 | int main() { 16 | ABinderProcess_setThreadPoolMaxThreadCount(0); 17 | std::shared_ptr lights = ndk::SharedRefBase::make(); 18 | if (!lights) { 19 | return EXIT_FAILURE; 20 | } 21 | 22 | const std::string instance = std::string() + Lights::descriptor + "/default"; 23 | binder_status_t status = AServiceManager_addService(lights->asBinder().get(), instance.c_str()); 24 | CHECK(status == STATUS_OK); 25 | 26 | ABinderProcess_joinThreadPool(); 27 | return EXIT_FAILURE; // should not reach 28 | } 29 | -------------------------------------------------------------------------------- /hidl/powershare/PowerShare.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020-2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace vendor { 12 | namespace lineage { 13 | namespace powershare { 14 | namespace V1_0 { 15 | namespace implementation { 16 | 17 | using ::android::sp; 18 | using ::android::hardware::Return; 19 | using ::android::hardware::Void; 20 | 21 | class PowerShare : public IPowerShare { 22 | public: 23 | Return isEnabled() override; 24 | Return setEnabled(bool enable) override; 25 | Return getMinBattery() override; 26 | Return setMinBattery(uint32_t minBattery) override; 27 | }; 28 | 29 | } // namespace implementation 30 | } // namespace V1_0 31 | } // namespace powershare 32 | } // namespace lineage 33 | } // namespace vendor 34 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/fingerprintextension/1.0/IXiaomiFingerprint.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.fingerprintextension@1.0; 18 | 19 | interface IXiaomiFingerprint { 20 | extCmd(int32_t cmd, int32_t param) generates (int32_t result); 21 | }; 22 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/UdfpsHandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "UdfpsHandler.h" 8 | #include 9 | 10 | #define UDFPS_HANDLER_LIB_NAME "libudfpshandler.so" 11 | #define UDFPS_HANDLER_FACTORY "UDFPS_HANDLER_FACTORY" 12 | 13 | UdfpsHandlerFactory* getUdfpsHandlerFactory() { 14 | void* libudfpshander; 15 | UdfpsHandlerFactory* factory_handler; 16 | 17 | libudfpshander = dlopen(UDFPS_HANDLER_LIB_NAME, RTLD_LAZY); 18 | if (!libudfpshander) { 19 | goto error; 20 | } 21 | 22 | factory_handler = (UdfpsHandlerFactory*)dlsym(libudfpshander, UDFPS_HANDLER_FACTORY); 23 | if (!factory_handler) { 24 | goto error; 25 | } 26 | 27 | return factory_handler; 28 | 29 | error: 30 | if (libudfpshander) { 31 | dlclose(libudfpshander); 32 | } 33 | 34 | return nullptr; 35 | } 36 | -------------------------------------------------------------------------------- /hidl/touch/HighTouchPollingRate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #define LOG_TAG "HighTouchPollingRateService" 8 | 9 | #include "HighTouchPollingRate.h" 10 | 11 | #include 12 | 13 | namespace vendor { 14 | namespace lineage { 15 | namespace touch { 16 | namespace V1_0 { 17 | namespace implementation { 18 | 19 | Return HighTouchPollingRate::isEnabled() { 20 | std::ifstream file(HIGH_TOUCH_POLLING_PATH); 21 | int enabled; 22 | file >> enabled; 23 | 24 | return enabled == 1; 25 | } 26 | 27 | Return HighTouchPollingRate::setEnabled(bool enabled) { 28 | std::ofstream file(HIGH_TOUCH_POLLING_PATH); 29 | file << (enabled ? "1" : "0"); 30 | return !file.fail(); 31 | } 32 | 33 | } // namespace implementation 34 | } // namespace V1_0 35 | } // namespace touch 36 | } // namespace lineage 37 | } // namespace vendor 38 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/displayfeature/1.0/IDisplayFeatureCallback.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.displayfeature@1.0; 18 | 19 | interface IDisplayFeatureCallback { 20 | oneway displayfeatureInfoChanged(uint32_t caseId, uint32_t value, float red, float green, float blue); 21 | }; 22 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/displayfeature/1.0/types.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.displayfeature@1.0; 18 | 19 | // Based on observations using Ghidra, all methods that return Status 20 | // only set the result of __android_log_print and cast it to Status. 21 | enum Status : int32_t {}; 22 | -------------------------------------------------------------------------------- /interfaces/goodix/hardware/biometrics/fingerprint/2.1/IGoodixFingerprintDaemonCallback.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.goodix.hardware.biometrics.fingerprint@2.1; 18 | 19 | interface IGoodixFingerprintDaemonCallback { 20 | onDaemonMessage(int64_t devId, int32_t msgId, int32_t cmdId, vec msgData); 21 | }; 22 | -------------------------------------------------------------------------------- /aidl/light/Utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace aidl { 12 | namespace android { 13 | namespace hardware { 14 | namespace light { 15 | 16 | typedef struct rgb { 17 | rgb(uint8_t r, uint8_t g, uint8_t b) : red(r), green(g), blue(b) {}; 18 | rgb(uint32_t color); 19 | rgb() : red(0), green(0), blue(0) {}; 20 | 21 | uint8_t red; 22 | uint8_t green; 23 | uint8_t blue; 24 | 25 | bool isLit(); 26 | uint8_t toBrightness(); 27 | } rgb_t; 28 | 29 | bool fileWriteable(const std::string& file); 30 | bool readFromFile(const std::string& file, std::string *content); 31 | bool readFromFile(const std::string& file, uint32_t *content); 32 | bool writeToFile(const std::string& file, uint32_t content); 33 | 34 | } // namespace light 35 | } // namespace hardware 36 | } // namespace android 37 | } // namespace aidl 38 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hw/touchfeature/1.0/ITouchFeature.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vendor.xiaomi.hw.touchfeature@1.0; 8 | 9 | interface ITouchFeature { 10 | getModeCurValue(int32_t touchId, int32_t ControlMode) generates (int32_t result); 11 | getModeDefaultValue(int32_t touchId, int32_t ControlMode) generates (int32_t result); 12 | getModeMaxValue(int32_t touchId, int32_t ControlMode) generates (int32_t result); 13 | getModeMinValue(int32_t touchId, int32_t ControlMode) generates (int32_t result); 14 | getModeValue(int32_t touchId, int32_t mode) generates (vec result); 15 | modeReset(int32_t touchId, int32_t ControlMode) generates (int32_t result); 16 | setModeLongValue(int32_t touchId, int32_t ControlMode, uint32_t ValueLen, vec ValueBuf) generates (int32_t result); 17 | setModeValue(int32_t touchId, int32_t ControlMode, int32_t ModeValue) generates (int32_t result); 18 | }; 19 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mtdservice/1.0/IMTService.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vendor.xiaomi.hardware.mtdservice@1.0; 8 | 9 | interface IMTService { 10 | getFid() generates (string fid); 11 | eccSign(uint32_t keyType, string text) generates (string signData); 12 | reload(string text, string sign) generates (int32_t result); 13 | enroll(string appname, int32_t enrollType) generates (string enrolldata); 14 | ifaa_key_get_version() generates (int32_t result); 15 | ifaa_key_prepare() generates (string ret); 16 | ifaa_key_load(string data_text, string sign_text) generates (int32_t result); 17 | fido_key_get_version() generates (int32_t result); 18 | fido_key_prepare() generates (string ret); 19 | fido_key_load(string data_text, string sign_text) generates (int32_t result); 20 | soter_generate() generates (string ret); 21 | soter_get_state() generates (int32_t result); 22 | soter_set_state(int32_t state); 23 | }; 24 | -------------------------------------------------------------------------------- /hidl/touch/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #define LOG_TAG "lineage.touch@1.0-service.xiaomi" 8 | 9 | #include 10 | #include 11 | 12 | #include "HighTouchPollingRate.h" 13 | 14 | using ::vendor::lineage::touch::V1_0::IHighTouchPollingRate; 15 | using ::vendor::lineage::touch::V1_0::implementation::HighTouchPollingRate; 16 | 17 | int main() { 18 | android::sp highTouchPollingRate = new HighTouchPollingRate(); 19 | 20 | android::hardware::configureRpcThreadpool(1, true); 21 | 22 | if (highTouchPollingRate->registerAsService() != android::OK) { 23 | LOG(ERROR) << "Cannot register touchscreen high polling rate HAL service."; 24 | return 1; 25 | } 26 | 27 | LOG(INFO) << "Touchscreen HAL service ready."; 28 | 29 | android::hardware::joinRpcThreadpool(); 30 | 31 | LOG(ERROR) << "Touchscreen HAL service failed to join thread pool."; 32 | return 1; 33 | } 34 | -------------------------------------------------------------------------------- /aidl/light/LED.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "LED.h" 8 | 9 | #include "Utils.h" 10 | 11 | namespace aidl { 12 | namespace android { 13 | namespace hardware { 14 | namespace light { 15 | 16 | static const uint32_t kDefaultMaxLedBrightness = 255; 17 | 18 | LED::LED(std::string type) : mBasePath("/sys/class/leds/" + type + "/") { 19 | if (!readFromFile(mBasePath + "max_brightness", &mMaxBrightness)) 20 | mMaxBrightness = kDefaultMaxLedBrightness; 21 | mBreath = fileWriteable(mBasePath + "breath"); 22 | } 23 | 24 | bool LED::exists() { 25 | return fileWriteable(mBasePath + "brightness"); 26 | } 27 | 28 | bool LED::setBreath(uint8_t value) { 29 | return writeToFile(mBasePath + (mBreath ? "breath" : "blink"), value); 30 | } 31 | 32 | bool LED::setBrightness(uint8_t value) { 33 | return writeToFile(mBasePath + "brightness", value * mMaxBrightness / 0xFF); 34 | } 35 | 36 | } // namespace light 37 | } // namespace hardware 38 | } // namespace android 39 | } // namespace aidl 40 | -------------------------------------------------------------------------------- /interfaces/goodix/hardware/biometrics/fingerprint/2.1/IGoodixFingerprintDaemon.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.goodix.hardware.biometrics.fingerprint@2.1; 18 | 19 | import vendor.goodix.hardware.biometrics.fingerprint@2.1::IGoodixFingerprintDaemonCallback; 20 | 21 | interface IGoodixFingerprintDaemon { 22 | setNotify(IGoodixFingerprintDaemonCallback Callback); 23 | sendCommand(int32_t cmd, vec data) generates (int32_t resultCode, vec data); 24 | }; 25 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/motor/1.0/IMotor.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.motor@1.0; 18 | 19 | import vendor.xiaomi.hardware.motor@1.0::IMotorCallback; 20 | 21 | interface IMotor { 22 | popupMotor(int32_t cookie); 23 | takebackMotor(int32_t cookie); 24 | setMotorCallback(IMotorCallback motorcallback); 25 | init(); 26 | release(); 27 | getMotorStatus() generates (int32_t result); 28 | calibration(); 29 | takebackMotorShortly(); 30 | }; 31 | -------------------------------------------------------------------------------- /hidl/powershare/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #define LOG_TAG "vendor.lineage.powershare@1.0-service.xiaomi" 8 | 9 | #include 10 | #include 11 | 12 | #include "PowerShare.h" 13 | 14 | using android::hardware::configureRpcThreadpool; 15 | using android::hardware::joinRpcThreadpool; 16 | 17 | using vendor::lineage::powershare::V1_0::IPowerShare; 18 | using vendor::lineage::powershare::V1_0::implementation::PowerShare; 19 | 20 | using android::OK; 21 | using android::status_t; 22 | 23 | int main() { 24 | android::sp service = new PowerShare(); 25 | 26 | configureRpcThreadpool(1, true); 27 | 28 | status_t status = service->registerAsService(); 29 | if (status != OK) { 30 | LOG(ERROR) << "Cannot register PowerShare HAL service."; 31 | return 1; 32 | } 33 | 34 | LOG(INFO) << "PowerShare HAL service ready."; 35 | 36 | joinRpcThreadpool(); 37 | 38 | LOG(ERROR) << "PowerShare HAL service failed to join thread pool."; 39 | return 1; 40 | } 41 | -------------------------------------------------------------------------------- /aidl/light/Lights.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include "Backlight.h" 12 | 13 | using ::aidl::android::hardware::light::HwLightState; 14 | using ::aidl::android::hardware::light::HwLight; 15 | 16 | namespace aidl { 17 | namespace android { 18 | namespace hardware { 19 | namespace light { 20 | 21 | class Lights : public BnLights { 22 | public: 23 | Lights(); 24 | 25 | ndk::ScopedAStatus setLightState(int32_t id, const HwLightState& state) override; 26 | ndk::ScopedAStatus getLights(std::vector *_aidl_return) override; 27 | private: 28 | void setLED(const HwLightState& state); 29 | 30 | std::vector mLights; 31 | 32 | BacklightDevice *mBacklightDevice; 33 | std::vector mButtonsPaths; 34 | bool mWhiteLED; 35 | 36 | std::mutex mLEDMutex; 37 | HwLightState mLastBatteryState; 38 | HwLightState mLastNotificationState; 39 | }; 40 | 41 | } // namespace light 42 | } // namespace hardware 43 | } // namespace android 44 | } // namespace aidl 45 | -------------------------------------------------------------------------------- /hidl/consumerir/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2017-2018,2020 The LineageOS Project 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | cc_binary { 17 | name: "android.hardware.ir@1.0-service.xiaomi", 18 | relative_install_path: "hw", 19 | defaults: ["hidl_defaults"], 20 | init_rc: ["android.hardware.ir@1.0-service.xiaomi.rc"], 21 | vintf_fragments: ["android.hardware.ir@1.0-service.xiaomi.xml"], 22 | srcs: ["service.cpp", "ConsumerIr.cpp"], 23 | shared_libs: [ 24 | "android.hardware.ir@1.0", 25 | "libbase", 26 | "libhardware", 27 | "libhidlbase", 28 | "libutils", 29 | ], 30 | proprietary: true, 31 | } 32 | -------------------------------------------------------------------------------- /hidl/touch/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2022 The LineageOS Project 3 | // 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | 7 | soong_config_module_type { 8 | name: "xiaomi_touch_hal_cc_defaults", 9 | module_type: "cc_defaults", 10 | config_namespace: "XIAOMI_TOUCH", 11 | value_variables: ["HIGH_TOUCH_POLLING_PATH"], 12 | properties: ["cppflags"], 13 | } 14 | 15 | xiaomi_touch_hal_cc_defaults { 16 | name: "xiaomi_touch_hal_defaults", 17 | soong_config_variables: { 18 | HIGH_TOUCH_POLLING_PATH: { 19 | cppflags: ["-DHIGH_TOUCH_POLLING_PATH=\"%s\""], 20 | }, 21 | }, 22 | } 23 | 24 | cc_binary { 25 | name: "vendor.lineage.touch@1.0-service.xiaomi", 26 | vintf_fragments: ["vendor.lineage.touch@1.0-service.xiaomi.xml"], 27 | init_rc: ["vendor.lineage.touch@1.0-service.xiaomi.rc"], 28 | defaults: [ 29 | "hidl_defaults", 30 | "xiaomi_touch_hal_defaults", 31 | ], 32 | relative_install_path: "hw", 33 | proprietary: true, 34 | srcs: [ 35 | "HighTouchPollingRate.cpp", 36 | "service.cpp", 37 | ], 38 | shared_libs: [ 39 | "libbase", 40 | "libbinder", 41 | "libhidlbase", 42 | "libutils", 43 | "vendor.lineage.touch@1.0", 44 | ], 45 | } 46 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/touchfeature/1.0/ITouchFeature.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2020 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.touchfeature@1.0; 18 | 19 | interface ITouchFeature { 20 | setTouchMode(int32_t mode, int32_t value) generates (int32_t result); 21 | getTouchModeCurValue(int32_t mode) generates (int32_t result); 22 | getTouchModeMaxValue(int32_t mode) generates (int32_t result); 23 | getTouchModeMinValue(int32_t mode) generates (int32_t result); 24 | getTouchModeDefValue(int32_t mode) generates (int32_t result); 25 | resetTouchMode(int32_t mode) generates (int32_t result); 26 | getModeValues(int32_t mode) generates (vec result); 27 | }; 28 | -------------------------------------------------------------------------------- /hidl/powershare/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2020 The LineageOS Project 3 | // 4 | // SPDX-License-Identifier: Apache-2.0 5 | // 6 | 7 | soong_config_module_type { 8 | name: "xiaomi_powershare_hal_cc_defaults", 9 | module_type: "cc_defaults", 10 | config_namespace: "XIAOMI_POWERSHARE", 11 | value_variables: ["WIRELESS_TX_ENABLE_PATH"], 12 | properties: ["cppflags"], 13 | } 14 | 15 | xiaomi_powershare_hal_cc_defaults { 16 | name: "xiaomi_powershare_hal_defaults", 17 | soong_config_variables: { 18 | WIRELESS_TX_ENABLE_PATH: { 19 | cppflags: ["-DWIRELESS_TX_ENABLE_PATH=\"%s\""], 20 | }, 21 | }, 22 | } 23 | 24 | cc_binary { 25 | name: "vendor.lineage.powershare@1.0-service.xiaomi", 26 | defaults: [ 27 | "hidl_defaults", 28 | "xiaomi_powershare_hal_defaults", 29 | ], 30 | relative_install_path: "hw", 31 | init_rc: ["vendor.lineage.powershare@1.0-service.xiaomi.rc"], 32 | vintf_fragments: ["vendor.lineage.powershare@1.0-service.xiaomi.xml"], 33 | srcs: [ 34 | "service.cpp", 35 | "PowerShare.cpp", 36 | ], 37 | shared_libs: [ 38 | "libbase", 39 | "libhardware", 40 | "libhidlbase", 41 | "liblog", 42 | "libutils", 43 | "vendor.lineage.powershare@1.0", 44 | ], 45 | proprietary: true, 46 | } 47 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 2022 The LineageOS Project 4 | * 5 | * SPDX-License-Identifier: Apache-2.0 6 | */ 7 | 8 | #define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service.xiaomi" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include "BiometricsFingerprint.h" 16 | 17 | using android::sp; 18 | using android::hardware::configureRpcThreadpool; 19 | using android::hardware::joinRpcThreadpool; 20 | using android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint; 21 | using android::hardware::biometrics::fingerprint::V2_3::implementation::BiometricsFingerprint; 22 | 23 | int main() { 24 | android::sp bio = BiometricsFingerprint::getInstance(); 25 | 26 | configureRpcThreadpool(1, true /*callerWillJoin*/); 27 | 28 | if (bio != nullptr) { 29 | if (::android::OK != bio->registerAsService()) { 30 | return 1; 31 | } 32 | } else { 33 | ALOGE("Can't create instance of BiometricsFingerprint, nullptr"); 34 | } 35 | 36 | joinRpcThreadpool(); 37 | 38 | return 0; // should never get here 39 | } 40 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/android.hardware.power-service.xiaomi-libperfmgr.rc: -------------------------------------------------------------------------------- 1 | service vendor.power-hal-aidl /vendor/bin/hw/android.hardware.power-service.xiaomi-libperfmgr 2 | class hal 3 | user root 4 | group system 5 | priority -20 6 | 7 | on late-fs 8 | start vendor.power-hal-aidl 9 | 10 | # Restart powerHAL when framework died 11 | on property:init.svc.zygote=restarting && property:vendor.powerhal.state=* 12 | setprop vendor.powerhal.state "" 13 | setprop vendor.powerhal.audio "" 14 | setprop vendor.powerhal.rendering "" 15 | restart vendor.power-hal-aidl 16 | 17 | # Clean up after b/163539793 resolved 18 | on property:vendor.powerhal.dalvik.vm.dex2oat-threads=* 19 | setprop dalvik.vm.dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads} 20 | setprop dalvik.vm.restore-dex2oat-threads ${vendor.powerhal.dalvik.vm.dex2oat-threads} 21 | 22 | on property:vendor.powerhal.dalvik.vm.dex2oat-cpu-set=* 23 | setprop dalvik.vm.dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set} 24 | setprop dalvik.vm.restore-dex2oat-cpu-set ${vendor.powerhal.dalvik.vm.dex2oat-cpu-set} 25 | 26 | # Restart powerHAL when debug property set 27 | on property:ro.debuggable=1 && property:vendor.powerhal.config.debug=* 28 | restart vendor.power-hal-aidl 29 | 30 | on property:persist.vendor.powerhal.config.debug=* 31 | setprop vendor.powerhal.config.debug ${persist.vendor.powerhal.config.debug} 32 | 33 | -------------------------------------------------------------------------------- /hidl/powershare/PowerShare.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #define LOG_TAG "PowerShareService" 8 | 9 | #include "PowerShare.h" 10 | #include 11 | #include 12 | 13 | namespace vendor { 14 | namespace lineage { 15 | namespace powershare { 16 | namespace V1_0 { 17 | namespace implementation { 18 | 19 | /* 20 | * Write value to path and close file. 21 | */ 22 | template 23 | static void set(const std::string& path, const T& value) { 24 | std::ofstream file(path); 25 | file << value; 26 | } 27 | 28 | template 29 | static T get(const std::string& path, const T& def) { 30 | std::ifstream file(path); 31 | T result; 32 | 33 | file >> result; 34 | return file.fail() ? def : result; 35 | } 36 | 37 | Return PowerShare::isEnabled() { 38 | const auto value = get(WIRELESS_TX_ENABLE_PATH, "0"); 39 | return !(value == "disable" || value == "0"); 40 | } 41 | 42 | Return PowerShare::setEnabled(bool enable) { 43 | set(WIRELESS_TX_ENABLE_PATH, enable ? 1 : 0); 44 | 45 | return isEnabled(); 46 | } 47 | 48 | Return PowerShare::getMinBattery() { 49 | return 0; 50 | } 51 | 52 | Return PowerShare::setMinBattery(uint32_t) { 53 | return getMinBattery(); 54 | } 55 | 56 | } // namespace implementation 57 | } // namespace V1_0 58 | } // namespace powershare 59 | } // namespace lineage 60 | } // namespace vendor 61 | -------------------------------------------------------------------------------- /hidl/sensors/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "HalProxy.h" 22 | 23 | using android::hardware::configureRpcThreadpool; 24 | using android::hardware::joinRpcThreadpool; 25 | using android::hardware::sensors::V2_1::ISensors; 26 | using android::hardware::sensors::V2_1::implementation::HalProxyV2_1; 27 | 28 | int main(int /* argc */, char** /* argv */) { 29 | configureRpcThreadpool(1, true); 30 | 31 | android::sp halProxy = new HalProxyV2_1(); 32 | if (halProxy->registerAsService() != ::android::OK) { 33 | ALOGE("Failed to register Sensors HAL instance"); 34 | return -1; 35 | } 36 | 37 | joinRpcThreadpool(); 38 | return 1; // joinRpcThreadpool shouldn't exit 39 | } 40 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/displayfeature/1.0/IDisplayFeature.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019-2022 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package vendor.xiaomi.hardware.displayfeature@1.0; 18 | 19 | import @1.0::IDisplayFeatureCallback; 20 | 21 | interface IDisplayFeature { 22 | notifyBrightness(uint32_t brightness); 23 | registerCallback(uint32_t displayId, IDisplayFeatureCallback callback) generates (Status status); 24 | sendMessage(uint32_t index, uint32_t value, string cmd); 25 | sendPanelCommand(string cmd) generates (Status status); 26 | sendPostProcCommand(uint32_t cmd, uint32_t value) generates (Status status); 27 | sendRefreshCommand() generates (Status status); 28 | setFeature(uint32_t displayId, uint32_t caseId, uint32_t modeId, uint32_t cookie) generates (Status status); 29 | setFunction(uint32_t displayId, uint32_t caseId, uint32_t modeId, uint32_t cookie) generates (Status status); 30 | }; 31 | -------------------------------------------------------------------------------- /hidl/sensors/1.0/include/sensors/convert.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | 22 | namespace android { 23 | namespace hardware { 24 | namespace sensors { 25 | namespace V1_0 { 26 | namespace implementation { 27 | 28 | void convertFromSensor(const sensor_t& src, SensorInfo* dst); 29 | void convertToSensor(const SensorInfo& src, sensor_t* dst); 30 | 31 | void convertFromSensorEvent(const sensors_event_t& src, Event* dst); 32 | void convertToSensorEvent(const Event& src, sensors_event_t* dst); 33 | 34 | bool convertFromSharedMemInfo(const SharedMemInfo& memIn, sensors_direct_mem_t* memOut); 35 | int convertFromRateLevel(RateLevel rate); 36 | 37 | bool patchXiaomiPickupSensor(SensorInfo& sensor); 38 | 39 | } // namespace implementation 40 | } // namespace V1_0 41 | } // namespace sensors 42 | } // namespace hardware 43 | } // namespace android 44 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2017 The Android Open Source Project 3 | // 2022 The LineageOS Project 4 | // 5 | // SPDX-License-Identifier: Apache-2.0 6 | // 7 | 8 | cc_binary { 9 | name: "android.hardware.biometrics.fingerprint@2.3-service.xiaomi", 10 | defaults: ["hidl_defaults"], 11 | init_rc: ["android.hardware.biometrics.fingerprint@2.3-service.xiaomi.rc"], 12 | vintf_fragments: ["android.hardware.biometrics.fingerprint@2.3-service.xiaomi.xml"], 13 | vendor: true, 14 | relative_install_path: "hw", 15 | srcs: [ 16 | "BiometricsFingerprint.cpp", 17 | "UdfpsHandler.cpp", 18 | "service.cpp", 19 | ], 20 | 21 | shared_libs: [ 22 | "libbase", 23 | "libcutils", 24 | "libdl", 25 | "liblog", 26 | "libhidlbase", 27 | "libhardware", 28 | "libutils", 29 | "android.hardware.biometrics.fingerprint@2.1", 30 | "android.hardware.biometrics.fingerprint@2.2", 31 | "android.hardware.biometrics.fingerprint@2.3", 32 | ], 33 | 34 | header_libs: ["xiaomifingerprint_headers"], 35 | } 36 | 37 | cc_library_headers { 38 | name: "xiaomifingerprint_headers", 39 | export_include_dirs: ["include"], 40 | vendor: true, 41 | header_libs: ["libhardware_headers"], 42 | export_header_lib_headers: ["libhardware_headers"], 43 | } 44 | 45 | cc_library_static { 46 | name: "libudfps_extension.xiaomi", 47 | srcs: ["UdfpsExtension.cpp"], 48 | include_dirs: [ 49 | "frameworks/native/services/surfaceflinger/CompositionEngine/include" 50 | ], 51 | header_libs: [ 52 | "generated_kernel_headers", 53 | ], 54 | } 55 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/PowerExt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | namespace aidl { 27 | namespace google { 28 | namespace hardware { 29 | namespace power { 30 | namespace impl { 31 | namespace pixel { 32 | 33 | class PowerExt : public ::aidl::google::hardware::power::extension::pixel::BnPowerExt { 34 | public: 35 | PowerExt() {} 36 | ndk::ScopedAStatus setMode(const std::string &mode, bool enabled) override; 37 | ndk::ScopedAStatus isModeSupported(const std::string &mode, bool *_aidl_return) override; 38 | ndk::ScopedAStatus setBoost(const std::string &boost, int32_t durationMs) override; 39 | ndk::ScopedAStatus isBoostSupported(const std::string &boost, bool *_aidl_return) override; 40 | 41 | private: 42 | }; 43 | 44 | } // namespace pixel 45 | } // namespace impl 46 | } // namespace power 47 | } // namespace hardware 48 | } // namespace google 49 | } // namespace aidl 50 | -------------------------------------------------------------------------------- /hidl/consumerir/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "android.hardware.ir@1.0-service.xiaomi" 18 | 19 | #include 20 | #include 21 | 22 | #include "ConsumerIr.h" 23 | 24 | // libhwbinder: 25 | using android::hardware::configureRpcThreadpool; 26 | using android::hardware::joinRpcThreadpool; 27 | 28 | // Generated HIDL files 29 | using android::hardware::ir::V1_0::IConsumerIr; 30 | using android::hardware::ir::V1_0::implementation::ConsumerIr; 31 | 32 | int main() { 33 | android::sp service = new ConsumerIr(); 34 | 35 | configureRpcThreadpool(1, true /*callerWillJoin*/); 36 | 37 | android::status_t status = service->registerAsService(); 38 | if (status != android::OK) { 39 | LOG(ERROR) << "Cannot register ConsumerIr HAL service"; 40 | return 1; 41 | } 42 | 43 | LOG(INFO) << "ConsumerIr HAL Ready."; 44 | joinRpcThreadpool(); 45 | // Under normal cases, execution will not reach this line. 46 | LOG(ERROR) << "ConsumerIr HAL failed to join thread pool."; 47 | return 1; 48 | } 49 | -------------------------------------------------------------------------------- /hidl/sensors/Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2020 The Android Open Source Project 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | cc_binary { 17 | name: "android.hardware.sensors@2.1-service.xiaomi-multihal", 18 | defaults: [ 19 | "hidl_defaults", 20 | ], 21 | vendor: true, 22 | relative_install_path: "hw", 23 | srcs: [ 24 | "service.cpp", 25 | "HalProxy.cpp", 26 | "HalProxyCallback.cpp", 27 | ], 28 | init_rc: ["android.hardware.sensors@2.1-service.xiaomi-multihal.rc"], 29 | vintf_fragments: ["android.hardware.sensors@2.1.xiaomi-multihal.xml"], 30 | header_libs: [ 31 | "android.hardware.sensors@2.X-shared-utils", 32 | ], 33 | shared_libs: [ 34 | "android.hardware.sensors@2.0", 35 | "android.hardware.sensors@2.0-ScopedWakelock", 36 | "android.hardware.sensors@2.1", 37 | "libbase", 38 | "libcutils", 39 | "libfmq", 40 | "libhidlbase", 41 | "liblog", 42 | "libpower", 43 | "libutils", 44 | ], 45 | static_libs: [ 46 | "android.hardware.sensors@1.0-convert", 47 | "android.hardware.sensors@2.X-multihal", 48 | ], 49 | } 50 | -------------------------------------------------------------------------------- /hidl/consumerir/ConsumerIr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef ANDROID_HARDWARE_IR_V1_0_IR_H 18 | #define ANDROID_HARDWARE_IR_V1_0_IR_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | namespace android { 25 | namespace hardware { 26 | namespace ir { 27 | namespace V1_0 { 28 | namespace implementation { 29 | 30 | using ::android::hardware::Return; 31 | using ::android::hardware::Void; 32 | using ::android::hardware::hidl_vec; 33 | using ::android::hardware::ir::V1_0::ConsumerIrFreqRange; 34 | using ::android::hardware::ir::V1_0::IConsumerIr; 35 | 36 | class ConsumerIr : public IConsumerIr { 37 | // Methods from ::android::hardware::ir::V1_0::IConsumerIr follow. 38 | Return transmit(int32_t carrierFreq, const hidl_vec& pattern) override; 39 | Return getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) override; 40 | }; 41 | 42 | } // namespace implementation 43 | } // namespace V1_0 44 | } // namespace ir 45 | } // namespace hardware 46 | } // namespace android 47 | 48 | #endif // ANDROID_HARDWARE_IR_V1_0_IR_H 49 | -------------------------------------------------------------------------------- /interfaces/xiaomi/hardware/mtdservice/1.2/IMTService.hal: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package vendor.xiaomi.hardware.mtdservice@1.2; 8 | 9 | import @1.1::IMTService; 10 | 11 | interface IMTService extends @1.1::IMTService { 12 | widevine_get_version() generates (int32_t ret); 13 | widevine_prepare() generates (string ret); 14 | widevine_load(string data_text, string sign_text) generates (int32_t ret); 15 | widevine_dump() generates (string ret); 16 | runExternalCmd(int32_t taType, vec ta, uint32_t cmdId, vec data) generates (int32_t ret, vec rsp); 17 | installTa(int32_t taType, vec ta, vec ta_buf) generates (int32_t ret); 18 | unInstallTa(int32_t taType, vec ta) generates (int32_t ret); 19 | loadTa(int32_t taType, vec ta) generates (int32_t ret); 20 | runTaCmd(int32_t taType, vec ta, vec data) generates (int32_t ret, vec rsp); 21 | unloadTa(int32_t taType, vec ta) generates (int32_t ret); 22 | checkPermission(vec packageName, vec signature) generates (bool ret); 23 | updateWhitelist(int32_t operation, vec whitelist) generates (int32_t ret); 24 | getWhitelistVersion() generates (int32_t ret); 25 | enrollV2(int32_t taType, vec ta, vec data) generates (int32_t ret, vec rsp); 26 | external_key_version(int32_t key_type) generates (int32_t ret); 27 | external_key_prepare(int32_t key_type) generates (string ret); 28 | external_key_load(int32_t key_type, string data_text, string sign_text) generates (int32_t ret); 29 | external_key_dump(int32_t key_type) generates (string ret); 30 | }; 31 | -------------------------------------------------------------------------------- /aidl/light/android.hardware.light-service.xiaomi.rc: -------------------------------------------------------------------------------- 1 | on early-boot 2 | # Notification LEDs 3 | chown system system /sys/class/leds/red/blink 4 | chown system system /sys/class/leds/red/breath 5 | chown system system /sys/class/leds/red/brightness 6 | chown system system /sys/class/leds/red/max_brightness 7 | 8 | chown system system /sys/class/leds/green/blink 9 | chown system system /sys/class/leds/green/breath 10 | chown system system /sys/class/leds/green/brightness 11 | chown system system /sys/class/leds/green/max_brightness 12 | 13 | chown system system /sys/class/leds/blue/blink 14 | chown system system /sys/class/leds/blue/breath 15 | chown system system /sys/class/leds/blue/brightness 16 | chown system system /sys/class/leds/blue/max_brightness 17 | 18 | chown system system /sys/class/leds/white/blink 19 | chown system system /sys/class/leds/white/breath 20 | chown system system /sys/class/leds/white/brightness 21 | chown system system /sys/class/leds/white/max_brightness 22 | 23 | # Backlight 24 | chown system system /sys/class/backlight/backlight/brightness 25 | chown system system /sys/class/backlight/backlight/max_brightness 26 | 27 | chown system system /sys/class/backlight/panel0-backlight/brightness 28 | chown system system /sys/class/backlight/panel0-backlight/max_brightness 29 | 30 | chown system system /sys/class/leds/lcd-backlight/brightness 31 | chown system system /sys/class/leds/lcd-backlight/max_brightness 32 | 33 | # Buttons 34 | chown system system /sys/class/leds/button-backlight/brightness 35 | chown system system /sys/class/leds/button-backlight1/brightness 36 | 37 | service vendor.light-default /vendor/bin/hw/android.hardware.light-service.xiaomi 38 | class hal 39 | user system 40 | group system 41 | shutdown critical 42 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/InteractionHandler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace aidl { 26 | namespace google { 27 | namespace hardware { 28 | namespace power { 29 | namespace impl { 30 | namespace pixel { 31 | 32 | enum InteractionState { 33 | INTERACTION_STATE_UNINITIALIZED, 34 | INTERACTION_STATE_IDLE, 35 | INTERACTION_STATE_INTERACTION, 36 | INTERACTION_STATE_WAITING, 37 | }; 38 | 39 | class InteractionHandler { 40 | public: 41 | InteractionHandler(); 42 | ~InteractionHandler(); 43 | bool Init(); 44 | void Exit(); 45 | void Acquire(int32_t duration); 46 | 47 | private: 48 | void Release(); 49 | void WaitForIdle(int32_t wait_ms, int32_t timeout_ms); 50 | void AbortWaitLocked(); 51 | void Routine(); 52 | 53 | void PerfLock(); 54 | void PerfRel(); 55 | 56 | enum InteractionState mState; 57 | int mIdleFd; 58 | int mEventFd; 59 | int32_t mDurationMs; 60 | struct timespec mLastTimespec; 61 | std::unique_ptr mThread; 62 | std::mutex mLock; 63 | std::condition_variable mCond; 64 | }; 65 | 66 | } // namespace pixel 67 | } // namespace impl 68 | } // namespace power 69 | } // namespace hardware 70 | } // namespace google 71 | } // namespace aidl 72 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/Android.mk: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (C) 2021 The LineageOS Project 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | ifneq (,$(findstring hardware/google/interfaces, $(PRODUCT_SOONG_NAMESPACES))) 18 | ifneq (,$(findstring hardware/google/pixel, $(PRODUCT_SOONG_NAMESPACES))) 19 | 20 | LOCAL_PATH := $(call my-dir) 21 | 22 | include $(CLEAR_VARS) 23 | 24 | LOCAL_MODULE_RELATIVE_PATH := hw 25 | 26 | LOCAL_SHARED_LIBRARIES := \ 27 | android.hardware.power-V2-ndk \ 28 | libbase \ 29 | libbinder_ndk \ 30 | libcutils \ 31 | libdl \ 32 | liblog \ 33 | libperfmgr \ 34 | libprocessgroup \ 35 | libutils \ 36 | pixel-power-ext-V1-ndk 37 | 38 | LOCAL_SRC_FILES := \ 39 | service.cpp \ 40 | InteractionHandler.cpp \ 41 | Power.cpp \ 42 | PowerExt.cpp \ 43 | PowerHintSession.cpp \ 44 | PowerSessionManager.cpp 45 | 46 | LOCAL_CFLAGS := -Wno-unused-parameter -Wno-unused-variable 47 | 48 | ifneq ($(TARGET_POWERHAL_MODE_EXT),) 49 | LOCAL_CFLAGS += -DMODE_EXT 50 | LOCAL_SRC_FILES += ../../../../$(TARGET_POWERHAL_MODE_EXT) 51 | endif 52 | 53 | ifneq ($(TARGET_TAP_TO_WAKE_NODE),) 54 | LOCAL_CFLAGS += -DTAP_TO_WAKE_NODE=\"$(TARGET_TAP_TO_WAKE_NODE)\" 55 | endif 56 | 57 | LOCAL_MODULE := android.hardware.power-service.xiaomi-libperfmgr 58 | LOCAL_INIT_RC := android.hardware.power-service.xiaomi-libperfmgr.rc 59 | LOCAL_MODULE_TAGS := optional 60 | LOCAL_VENDOR_MODULE := true 61 | LOCAL_VINTF_FRAGMENTS := android.hardware.power-service.xiaomi.xml 62 | 63 | include $(BUILD_EXECUTABLE) 64 | 65 | endif 66 | endif 67 | -------------------------------------------------------------------------------- /aidl/light/Utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "Utils.h" 8 | 9 | #define LOG_TAG "android.hardware.light-service.xiaomi" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using ::android::base::ReadFileToString; 16 | using ::android::base::WriteStringToFile; 17 | 18 | namespace aidl { 19 | namespace android { 20 | namespace hardware { 21 | namespace light { 22 | 23 | bool fileWriteable(const std::string& file) { 24 | return !access(file.c_str(), W_OK); 25 | } 26 | 27 | bool readFromFile(const std::string& file, std::string *content) { 28 | return ReadFileToString(file, content, true); 29 | } 30 | 31 | bool readFromFile(const std::string& file, uint32_t *content) { 32 | std::string content_str; 33 | if (readFromFile(file, &content_str)) 34 | *content = std::stoi(content_str); 35 | else 36 | return false; 37 | return true; 38 | } 39 | 40 | bool writeToFile(const std::string& file, std::string content) { 41 | return WriteStringToFile(content, file); 42 | } 43 | 44 | bool writeToFile(const std::string& file, uint32_t content) { 45 | return writeToFile(file, std::to_string(content)); 46 | } 47 | 48 | rgb::rgb(uint32_t color) { 49 | // Extract brightness from AARRGGBB. 50 | uint8_t alpha = (color >> 24) & 0xFF; 51 | 52 | // Retrieve each of the RGB colors 53 | red = (color >> 16) & 0xFF; 54 | green = (color >> 8) & 0xFF; 55 | blue = color & 0xFF; 56 | 57 | // Scale RGB colors if a brightness has been applied by the user 58 | if (alpha > 0 && alpha < 255) { 59 | red = red * alpha / 0xFF; 60 | green = green * alpha / 0xFF; 61 | blue = blue * alpha / 0xFF; 62 | } 63 | } 64 | 65 | bool rgb::isLit() { 66 | return !!red || !!green || !!blue; 67 | } 68 | 69 | uint8_t rgb::toBrightness() { 70 | return (77 * red + 150 * green + 29 * blue) >> 8; 71 | } 72 | 73 | } // namespace light 74 | } // namespace hardware 75 | } // namespace android 76 | } // namespace aidl 77 | -------------------------------------------------------------------------------- /aidl/light/Backlight.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "Backlight.h" 8 | 9 | #include "LED.h" 10 | 11 | namespace aidl { 12 | namespace android { 13 | namespace hardware { 14 | namespace light { 15 | 16 | class BacklightBrightness : public BacklightDevice { 17 | public: 18 | BacklightBrightness(std::string name) : mBasePath(mkBacklightBasePath + name + "/") { 19 | if (!readFromFile(mBasePath + "max_brightness", &mMaxBrightness)) { 20 | mMaxBrightness = kDefaultMaxBrightness; 21 | } 22 | }; 23 | 24 | void setBacklight(uint8_t value) { 25 | writeToFile(mBasePath + "brightness", value * mMaxBrightness / 0xFF); 26 | } 27 | 28 | bool exists() { 29 | return fileWriteable(mBasePath + "brightness"); 30 | } 31 | private: 32 | std::string mBasePath; 33 | uint32_t mMaxBrightness; 34 | 35 | inline static const std::string mkBacklightBasePath = "/sys/class/backlight/"; 36 | inline static const uint32_t kDefaultMaxBrightness = 255; 37 | }; 38 | 39 | class LEDBacklight : public BacklightDevice { 40 | public: 41 | LEDBacklight(std::string type) : mLED(type) {}; 42 | 43 | void setBacklight(uint8_t value) { 44 | mLED.setBrightness(value); 45 | } 46 | 47 | bool exists() { 48 | return mLED.exists(); 49 | } 50 | private: 51 | LED mLED; 52 | }; 53 | 54 | static const std::string kBacklightDevices[] = { 55 | "backlight", 56 | "panel0-backlight", 57 | }; 58 | 59 | static const std::string kLedDevices[] = { 60 | "lcd-backlight", 61 | }; 62 | 63 | BacklightDevice *getBacklightDevice() { 64 | for (auto &device : kBacklightDevices) { 65 | auto backlight = new BacklightBrightness(device); 66 | if (backlight->exists()) { 67 | return backlight; 68 | } 69 | delete backlight; 70 | } 71 | 72 | for (auto& device : kLedDevices) { 73 | auto backlight = new LEDBacklight(device); 74 | if (backlight->exists()) { 75 | return backlight; 76 | } 77 | delete backlight; 78 | } 79 | 80 | return nullptr; 81 | } 82 | 83 | } // namespace light 84 | } // namespace hardware 85 | } // namespace android 86 | } // namespace aidl 87 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/Power.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "InteractionHandler.h" 26 | 27 | namespace aidl { 28 | namespace google { 29 | namespace hardware { 30 | namespace power { 31 | namespace impl { 32 | namespace pixel { 33 | 34 | using ::aidl::android::hardware::power::Boost; 35 | using ::aidl::android::hardware::power::IPowerHintSession; 36 | using ::aidl::android::hardware::power::Mode; 37 | 38 | class Power : public ::aidl::android::hardware::power::BnPower { 39 | public: 40 | Power(); 41 | ndk::ScopedAStatus setMode(Mode type, bool enabled) override; 42 | ndk::ScopedAStatus isModeSupported(Mode type, bool *_aidl_return) override; 43 | ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override; 44 | ndk::ScopedAStatus isBoostSupported(Boost type, bool *_aidl_return) override; 45 | ndk::ScopedAStatus createHintSession(int32_t tgid, int32_t uid, 46 | const std::vector &threadIds, 47 | int64_t durationNanos, 48 | std::shared_ptr *_aidl_return) override; 49 | ndk::ScopedAStatus getHintSessionPreferredRate(int64_t *outNanoseconds) override; 50 | binder_status_t dump(int fd, const char **args, uint32_t numArgs) override; 51 | 52 | private: 53 | std::unique_ptr mInteractionHandler; 54 | std::atomic mSustainedPerfModeOn; 55 | }; 56 | 57 | } // namespace pixel 58 | } // namespace impl 59 | } // namespace power 60 | } // namespace hardware 61 | } // namespace google 62 | } // namespace aidl 63 | -------------------------------------------------------------------------------- /hidl/sensors/1.0/Sensors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | namespace android { 26 | namespace hardware { 27 | namespace sensors { 28 | namespace V1_0 { 29 | namespace implementation { 30 | 31 | struct Sensors : public ::android::hardware::sensors::V1_0::ISensors { 32 | Sensors(); 33 | 34 | status_t initCheck() const; 35 | 36 | Return getSensorsList(getSensorsList_cb _hidl_cb) override; 37 | 38 | Return setOperationMode(OperationMode mode) override; 39 | 40 | Return activate(int32_t sensor_handle, bool enabled) override; 41 | 42 | Return poll(int32_t maxCount, poll_cb _hidl_cb) override; 43 | 44 | Return batch(int32_t sensor_handle, int64_t sampling_period_ns, 45 | int64_t max_report_latency_ns) override; 46 | 47 | Return flush(int32_t sensor_handle) override; 48 | 49 | Return injectSensorData(const Event& event) override; 50 | 51 | Return registerDirectChannel(const SharedMemInfo& mem, 52 | registerDirectChannel_cb _hidl_cb) override; 53 | 54 | Return unregisterDirectChannel(int32_t channelHandle) override; 55 | 56 | Return configDirectReport(int32_t sensorHandle, int32_t channelHandle, RateLevel rate, 57 | configDirectReport_cb _hidl_cb) override; 58 | 59 | private: 60 | static constexpr int32_t kPollMaxBufferSize = 128; 61 | status_t mInitCheck; 62 | sensors_module_t* mSensorModule; 63 | sensors_poll_device_1_t* mSensorDevice; 64 | std::mutex mPollLock; 65 | 66 | int getHalDeviceVersion() const; 67 | std::vector getFixedUpSensorList(); 68 | 69 | static void convertFromSensorEvents(size_t count, const sensors_event_t* src, 70 | std::vector& dst, 71 | std::vector sensorsList); 72 | 73 | DISALLOW_COPY_AND_ASSIGN(Sensors); 74 | }; 75 | 76 | extern "C" ISensors* HIDL_FETCH_ISensors(const char* name); 77 | 78 | } // namespace implementation 79 | } // namespace V1_0 80 | } // namespace sensors 81 | } // namespace hardware 82 | } // namespace android 83 | -------------------------------------------------------------------------------- /hidl/consumerir/ConsumerIr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2018 The LineageOS Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "ConsumerIrService" 18 | 19 | #include 20 | #include 21 | 22 | #include 23 | 24 | #include "ConsumerIr.h" 25 | 26 | namespace android { 27 | namespace hardware { 28 | namespace ir { 29 | namespace V1_0 { 30 | namespace implementation { 31 | 32 | #define LIRC_DEV_PATH "/dev/lirc0" 33 | 34 | static const int dutyCycle = 33; 35 | 36 | static hidl_vec rangeVec{ 37 | {.min = 30000, .max = 60000}, 38 | }; 39 | 40 | static int openLircDev() { 41 | int fd = open(LIRC_DEV_PATH, O_RDWR); 42 | 43 | if (fd < 0) { 44 | LOG(ERROR) << "failed to open " << LIRC_DEV_PATH << ", error " << fd; 45 | } 46 | 47 | return fd; 48 | } 49 | 50 | // Methods from ::android::hardware::ir::V1_0::IConsumerIr follow. 51 | Return ConsumerIr::transmit(int32_t carrierFreq, const hidl_vec& pattern) { 52 | size_t entries = pattern.size(); 53 | int rc; 54 | int lircFd; 55 | 56 | lircFd = openLircDev(); 57 | if (lircFd < 0) { 58 | return lircFd; 59 | } 60 | 61 | rc = ioctl(lircFd, LIRC_SET_SEND_CARRIER, &carrierFreq); 62 | if (rc < 0) { 63 | LOG(ERROR) << "failed to set carrier " << carrierFreq << ", error: " << errno; 64 | goto out_close; 65 | } 66 | 67 | rc = ioctl(lircFd, LIRC_SET_SEND_DUTY_CYCLE, &dutyCycle); 68 | if (rc < 0) { 69 | LOG(ERROR) << "failed to set duty cycle " << dutyCycle << ", error: " << errno; 70 | goto out_close; 71 | } 72 | 73 | if ((entries & 1) != 0) { 74 | rc = write(lircFd, pattern.data(), sizeof(int32_t) * entries); 75 | } else { 76 | rc = write(lircFd, pattern.data(), sizeof(int32_t) * (entries - 1)); 77 | usleep(pattern[entries - 1]); 78 | } 79 | 80 | if (rc < 0) { 81 | LOG(ERROR) << "failed to write pattern " << pattern.size() << ", error: " << errno; 82 | goto out_close; 83 | } 84 | 85 | rc = 0; 86 | 87 | out_close: 88 | close(lircFd); 89 | 90 | return rc == 0; 91 | } 92 | 93 | Return ConsumerIr::getCarrierFreqs(getCarrierFreqs_cb _hidl_cb) { 94 | _hidl_cb(true, rangeVec); 95 | return Void(); 96 | } 97 | 98 | } // namespace implementation 99 | } // namespace V1_0 100 | } // namespace ir 101 | } // namespace hardware 102 | } // namespace android 103 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/service.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "powerhal-libperfmgr" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | #include "Power.h" 29 | #include "PowerExt.h" 30 | #include "PowerSessionManager.h" 31 | 32 | using aidl::google::hardware::power::impl::pixel::Power; 33 | using aidl::google::hardware::power::impl::pixel::PowerExt; 34 | using aidl::google::hardware::power::impl::pixel::PowerHintMonitor; 35 | using aidl::google::hardware::power::impl::pixel::PowerSessionManager; 36 | using ::android::perfmgr::HintManager; 37 | 38 | constexpr std::string_view kPowerHalInitProp("vendor.powerhal.init"); 39 | 40 | int main() { 41 | // Parse config but do not start the looper 42 | std::shared_ptr hm = HintManager::GetInstance(); 43 | if (!hm) { 44 | LOG(FATAL) << "HintManager Init failed"; 45 | } 46 | 47 | // single thread 48 | ABinderProcess_setThreadPoolMaxThreadCount(0); 49 | 50 | // core service 51 | std::shared_ptr pw = ndk::SharedRefBase::make(); 52 | ndk::SpAIBinder pwBinder = pw->asBinder(); 53 | AIBinder_setMinSchedulerPolicy(pwBinder.get(), SCHED_NORMAL, -20); 54 | 55 | // extension service 56 | std::shared_ptr pwExt = ndk::SharedRefBase::make(); 57 | auto pwExtBinder = pwExt->asBinder(); 58 | AIBinder_setMinSchedulerPolicy(pwExtBinder.get(), SCHED_NORMAL, -20); 59 | 60 | // attach the extension to the same binder we will be registering 61 | CHECK(STATUS_OK == AIBinder_setExtension(pwBinder.get(), pwExt->asBinder().get())); 62 | 63 | const std::string instance = std::string() + Power::descriptor + "/default"; 64 | binder_status_t status = AServiceManager_addService(pw->asBinder().get(), instance.c_str()); 65 | CHECK(status == STATUS_OK); 66 | LOG(INFO) << "Xiaomi Power HAL AIDL Service with Extension is started."; 67 | 68 | if (HintManager::GetInstance()->GetAdpfProfile()) { 69 | PowerHintMonitor::getInstance()->start(); 70 | } 71 | 72 | std::thread initThread([&]() { 73 | ::android::base::WaitForProperty(kPowerHalInitProp.data(), "1"); 74 | HintManager::GetInstance()->Start(); 75 | }); 76 | initThread.detach(); 77 | 78 | ABinderProcess_joinThreadPool(); 79 | 80 | // should not reach 81 | LOG(ERROR) << "Xiaomi Power HAL AIDL Service with Extension just died."; 82 | return EXIT_FAILURE; 83 | } 84 | -------------------------------------------------------------------------------- /hidl/sensors/HalProxyCallback.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2019 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "HalProxyCallback.h" 18 | 19 | #include 20 | 21 | namespace android { 22 | namespace hardware { 23 | namespace sensors { 24 | namespace V2_0 { 25 | namespace implementation { 26 | 27 | static constexpr int32_t kBitsAfterSubHalIndex = 24; 28 | 29 | /** 30 | * Set the subhal index as first byte of sensor handle and return this modified version. 31 | * 32 | * @param sensorHandle The sensor handle to modify. 33 | * @param subHalIndex The index in the hal proxy of the sub hal this sensor belongs to. 34 | * 35 | * @return The modified sensor handle. 36 | */ 37 | int32_t setSubHalIndex(int32_t sensorHandle, size_t subHalIndex) { 38 | return sensorHandle | (static_cast(subHalIndex) << kBitsAfterSubHalIndex); 39 | } 40 | 41 | void HalProxyCallbackBase::postEvents(const std::vector& events, 42 | ScopedWakelock wakelock) { 43 | if (events.empty() || !mCallback->areThreadsRunning()) return; 44 | size_t numWakeupEvents; 45 | std::vector processedEvents = processEvents(events, &numWakeupEvents); 46 | if (numWakeupEvents > 0) { 47 | ALOG_ASSERT(wakelock.isLocked(), 48 | "Wakeup events posted while wakelock unlocked for subhal" 49 | " w/ index %" PRId32 ".", 50 | mSubHalIndex); 51 | } else { 52 | ALOG_ASSERT(!wakelock.isLocked(), 53 | "No Wakeup events posted but wakelock locked for subhal" 54 | " w/ index %" PRId32 ".", 55 | mSubHalIndex); 56 | } 57 | mCallback->postEventsToMessageQueue(processedEvents, numWakeupEvents, std::move(wakelock)); 58 | } 59 | 60 | ScopedWakelock HalProxyCallbackBase::createScopedWakelock(bool lock) { 61 | ScopedWakelock wakelock(mRefCounter, lock); 62 | return wakelock; 63 | } 64 | 65 | std::vector HalProxyCallbackBase::processEvents(const std::vector& events, 66 | size_t* numWakeupEvents) const { 67 | *numWakeupEvents = 0; 68 | std::vector eventsOut; 69 | for (V2_1::Event event : events) { 70 | event.sensorHandle = setSubHalIndex(event.sensorHandle, mSubHalIndex); 71 | const V2_1::SensorInfo& sensor = mCallback->getSensorInfo(event.sensorHandle); 72 | 73 | if (sensor.type == V2_1::SensorType::PICK_UP_GESTURE 74 | && event.u.scalar != 1) { 75 | continue; 76 | } 77 | 78 | if ((sensor.flags & V1_0::SensorFlagBits::WAKE_UP) != 0) { 79 | (*numWakeupEvents)++; 80 | } 81 | eventsOut.push_back(event); 82 | } 83 | return eventsOut; 84 | } 85 | 86 | } // namespace implementation 87 | } // namespace V2_0 88 | } // namespace sensors 89 | } // namespace hardware 90 | } // namespace android 91 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/PowerExt.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "android.hardware.power-service.xiaomi.ext-libperfmgr" 18 | 19 | #include "PowerExt.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "PowerSessionManager.h" 32 | 33 | namespace aidl { 34 | namespace google { 35 | namespace hardware { 36 | namespace power { 37 | namespace impl { 38 | namespace pixel { 39 | 40 | using ::android::perfmgr::HintManager; 41 | 42 | ndk::ScopedAStatus PowerExt::setMode(const std::string &mode, bool enabled) { 43 | LOG(DEBUG) << "PowerExt setMode: " << mode << " to: " << enabled; 44 | 45 | if (enabled) { 46 | HintManager::GetInstance()->DoHint(mode); 47 | } else { 48 | HintManager::GetInstance()->EndHint(mode); 49 | } 50 | if (HintManager::GetInstance()->GetAdpfProfile() && 51 | HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) { 52 | PowerSessionManager::getInstance()->updateHintMode(mode, enabled); 53 | } 54 | 55 | return ndk::ScopedAStatus::ok(); 56 | } 57 | 58 | ndk::ScopedAStatus PowerExt::isModeSupported(const std::string &mode, bool *_aidl_return) { 59 | bool supported = HintManager::GetInstance()->IsHintSupported(mode); 60 | LOG(INFO) << "PowerExt mode " << mode << " isModeSupported: " << supported; 61 | *_aidl_return = supported; 62 | return ndk::ScopedAStatus::ok(); 63 | } 64 | 65 | ndk::ScopedAStatus PowerExt::setBoost(const std::string &boost, int32_t durationMs) { 66 | LOG(DEBUG) << "PowerExt setBoost: " << boost << " duration: " << durationMs; 67 | if (HintManager::GetInstance()->GetAdpfProfile() && 68 | HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) { 69 | PowerSessionManager::getInstance()->updateHintBoost(boost, durationMs); 70 | } 71 | 72 | if (durationMs > 0) { 73 | HintManager::GetInstance()->DoHint(boost, std::chrono::milliseconds(durationMs)); 74 | } else if (durationMs == 0) { 75 | HintManager::GetInstance()->DoHint(boost); 76 | } else { 77 | HintManager::GetInstance()->EndHint(boost); 78 | } 79 | 80 | return ndk::ScopedAStatus::ok(); 81 | } 82 | 83 | ndk::ScopedAStatus PowerExt::isBoostSupported(const std::string &boost, bool *_aidl_return) { 84 | bool supported = HintManager::GetInstance()->IsHintSupported(boost); 85 | LOG(INFO) << "PowerExt boost " << boost << " isBoostSupported: " << supported; 86 | *_aidl_return = supported; 87 | return ndk::ScopedAStatus::ok(); 88 | } 89 | 90 | } // namespace pixel 91 | } // namespace impl 92 | } // namespace power 93 | } // namespace hardware 94 | } // namespace google 95 | } // namespace aidl 96 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/BiometricsFingerprint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 2022 The LineageOS Project 4 | * 5 | * SPDX-License-Identifier: Apache-2.0 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "UdfpsHandler.h" 17 | #include "fingerprint.h" 18 | 19 | namespace android { 20 | namespace hardware { 21 | namespace biometrics { 22 | namespace fingerprint { 23 | namespace V2_3 { 24 | namespace implementation { 25 | 26 | using ::android::sp; 27 | using ::android::hardware::hidl_string; 28 | using ::android::hardware::hidl_vec; 29 | using ::android::hardware::Return; 30 | using ::android::hardware::Void; 31 | using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintAcquiredInfo; 32 | using ::android::hardware::biometrics::fingerprint::V2_1::FingerprintError; 33 | using ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprintClientCallback; 34 | using ::android::hardware::biometrics::fingerprint::V2_1::RequestStatus; 35 | using ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint; 36 | 37 | struct BiometricsFingerprint : public IBiometricsFingerprint { 38 | public: 39 | BiometricsFingerprint(); 40 | ~BiometricsFingerprint(); 41 | 42 | // Method to wrap legacy HAL with BiometricsFingerprint class 43 | static IBiometricsFingerprint* getInstance(); 44 | 45 | // Methods from ::android::hardware::biometrics::fingerprint::V2_1::IBiometricsFingerprint 46 | // follow. 47 | Return setNotify( 48 | const sp& clientCallback) override; 49 | Return preEnroll() override; 50 | Return enroll(const hidl_array& hat, uint32_t gid, 51 | uint32_t timeoutSec) override; 52 | Return postEnroll() override; 53 | Return getAuthenticatorId() override; 54 | Return cancel() override; 55 | Return enumerate() override; 56 | Return remove(uint32_t gid, uint32_t fid) override; 57 | Return setActiveGroup(uint32_t gid, const hidl_string& storePath) override; 58 | Return authenticate(uint64_t operationId, uint32_t gid) override; 59 | 60 | // Methods from ::android::hardware::biometrics::fingerprint::V2_3::IBiometricsFingerprint 61 | // follow. 62 | Return isUdfps(uint32_t sensorId) override; 63 | Return onFingerDown(uint32_t x, uint32_t y, float minor, float major) override; 64 | Return onFingerUp() override; 65 | 66 | private: 67 | static fingerprint_device_t* openHal(const char* class_name); 68 | static void notify( 69 | const fingerprint_msg_t* msg); /* Static callback for legacy HAL implementation */ 70 | static Return ErrorFilter(int32_t error); 71 | static FingerprintError VendorErrorFilter(int32_t error, int32_t* vendorCode); 72 | static FingerprintAcquiredInfo VendorAcquiredFilter(int32_t error, int32_t* vendorCode); 73 | static BiometricsFingerprint* sInstance; 74 | 75 | std::mutex mClientCallbackMutex; 76 | sp mClientCallback; 77 | fingerprint_device_t* mDevice; 78 | bool mIsUdfps; 79 | UdfpsHandlerFactory* mUdfpsHandlerFactory; 80 | UdfpsHandler* mUdfpsHandler; 81 | }; 82 | 83 | } // namespace implementation 84 | } // namespace V2_3 85 | } // namespace fingerprint 86 | } // namespace biometrics 87 | } // namespace hardware 88 | } // namespace android 89 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/PowerSessionManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "PowerHintSession.h" 28 | 29 | namespace aidl { 30 | namespace google { 31 | namespace hardware { 32 | namespace power { 33 | namespace impl { 34 | namespace pixel { 35 | 36 | using ::android::Looper; 37 | using ::android::Message; 38 | using ::android::MessageHandler; 39 | using ::android::Thread; 40 | using ::android::perfmgr::HintManager; 41 | 42 | constexpr char kPowerHalAdpfDisableTopAppBoost[] = "vendor.powerhal.adpf.disable.hint"; 43 | 44 | class PowerSessionManager : public MessageHandler { 45 | public: 46 | // current hint info 47 | void updateHintMode(const std::string &mode, bool enabled); 48 | void updateHintBoost(const std::string &boost, int32_t durationMs); 49 | int getDisplayRefreshRate(); 50 | // monitoring session status 51 | void addPowerSession(PowerHintSession *session); 52 | void removePowerSession(PowerHintSession *session); 53 | void setUclampMin(PowerHintSession *session, int min); 54 | void setUclampMinLocked(PowerHintSession *session, int min); 55 | void handleMessage(const Message &message) override; 56 | void dumpToFd(int fd); 57 | 58 | // Singleton 59 | static sp getInstance() { 60 | static sp instance = new PowerSessionManager(); 61 | return instance; 62 | } 63 | 64 | private: 65 | class WakeupHandler : public MessageHandler { 66 | public: 67 | WakeupHandler() {} 68 | void handleMessage(const Message &message) override; 69 | }; 70 | 71 | private: 72 | void wakeSessions(); 73 | std::optional isAnyAppSessionActive(); 74 | void disableSystemTopAppBoost(); 75 | void enableSystemTopAppBoost(); 76 | const std::string kDisableBoostHintName; 77 | 78 | std::unordered_set mSessions; // protected by mLock 79 | std::unordered_map mTidRefCountMap; // protected by mLock 80 | std::unordered_map> mTidSessionListMap; 81 | sp mWakeupHandler; 82 | bool mActive; // protected by mLock 83 | /** 84 | * mLock to pretect the above data objects opertions. 85 | **/ 86 | std::mutex mLock; 87 | int mDisplayRefreshRate; 88 | // Singleton 89 | PowerSessionManager() 90 | : kDisableBoostHintName(::android::base::GetProperty(kPowerHalAdpfDisableTopAppBoost, 91 | "ADPF_DISABLE_TA_BOOST")), 92 | mActive(false), 93 | mDisplayRefreshRate(60) { 94 | mWakeupHandler = sp(new WakeupHandler()); 95 | } 96 | PowerSessionManager(PowerSessionManager const &) = delete; 97 | void operator=(PowerSessionManager const &) = delete; 98 | }; 99 | 100 | class PowerHintMonitor : public Thread { 101 | public: 102 | void start(); 103 | bool threadLoop() override; 104 | sp getLooper(); 105 | // Singleton 106 | static sp getInstance() { 107 | static sp instance = new PowerHintMonitor(); 108 | return instance; 109 | } 110 | PowerHintMonitor(PowerHintMonitor const &) = delete; 111 | void operator=(PowerHintMonitor const &) = delete; 112 | 113 | private: 114 | sp mLooper; 115 | // Singleton 116 | PowerHintMonitor() : Thread(false), mLooper(new Looper(true)) {} 117 | }; 118 | 119 | } // namespace pixel 120 | } // namespace impl 121 | } // namespace power 122 | } // namespace hardware 123 | } // namespace google 124 | } // namespace aidl 125 | -------------------------------------------------------------------------------- /aidl/light/Lights.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021-2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "Lights.h" 8 | 9 | #include 10 | #include "LED.h" 11 | #include "Utils.h" 12 | 13 | namespace aidl { 14 | namespace android { 15 | namespace hardware { 16 | namespace light { 17 | 18 | static const std::string kAllButtonsPaths[] = { 19 | "/sys/class/leds/button-backlight/brightness", 20 | "/sys/class/leds/button-backlight1/brightness", 21 | }; 22 | 23 | enum led_type { 24 | RED, 25 | GREEN, 26 | BLUE, 27 | WHITE, 28 | MAX_LEDS, 29 | }; 30 | 31 | static LED kLEDs[MAX_LEDS] = { 32 | [RED] = LED("red"), 33 | [GREEN] = LED("green"), 34 | [BLUE] = LED("blue"), 35 | [WHITE] = LED("white"), 36 | }; 37 | 38 | #define AutoHwLight(light) {.id = (int32_t)light, .type = light, .ordinal = 0} 39 | 40 | static const HwLight kBacklightHwLight = AutoHwLight(LightType::BACKLIGHT); 41 | static const HwLight kBatteryHwLight = AutoHwLight(LightType::BATTERY); 42 | static const HwLight kButtonsHwLight = AutoHwLight(LightType::BUTTONS); 43 | static const HwLight kNotificationHwLight = AutoHwLight(LightType::NOTIFICATIONS); 44 | 45 | Lights::Lights() { 46 | mBacklightDevice = getBacklightDevice(); 47 | if (mBacklightDevice) { 48 | mLights.push_back(kBacklightHwLight); 49 | } 50 | 51 | for (auto& buttons : kAllButtonsPaths) { 52 | if (!fileWriteable(buttons)) 53 | continue; 54 | 55 | mButtonsPaths.push_back(buttons); 56 | } 57 | 58 | if (!mButtonsPaths.empty()) 59 | mLights.push_back(kButtonsHwLight); 60 | 61 | mWhiteLED = kLEDs[WHITE].exists(); 62 | 63 | mLights.push_back(kBatteryHwLight); 64 | mLights.push_back(kNotificationHwLight); 65 | } 66 | 67 | ndk::ScopedAStatus Lights::setLightState(int32_t id, const HwLightState& state) { 68 | rgb_t color(state.color); 69 | rgb_t batteryStateColor; 70 | 71 | LightType type = static_cast(id); 72 | switch (type) { 73 | case LightType::BACKLIGHT: 74 | if (mBacklightDevice) 75 | mBacklightDevice->setBacklight(color.toBrightness()); 76 | break; 77 | case LightType::BUTTONS: 78 | for (auto& buttons : mButtonsPaths) 79 | writeToFile(buttons, color.isLit()); 80 | break; 81 | case LightType::BATTERY: 82 | case LightType::NOTIFICATIONS: 83 | mLEDMutex.lock(); 84 | if (type == LightType::BATTERY) 85 | mLastBatteryState = state; 86 | else 87 | mLastNotificationState = state; 88 | batteryStateColor = rgb_t(mLastBatteryState.color); 89 | setLED(batteryStateColor.isLit() ? mLastBatteryState : mLastNotificationState); 90 | mLEDMutex.unlock(); 91 | break; 92 | default: 93 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 94 | break; 95 | } 96 | 97 | return ndk::ScopedAStatus::ok(); 98 | } 99 | 100 | ndk::ScopedAStatus Lights::getLights(std::vector *_aidl_return) { 101 | for (auto& light : mLights) 102 | _aidl_return->push_back(light); 103 | 104 | return ndk::ScopedAStatus::ok(); 105 | } 106 | 107 | void Lights::setLED(const HwLightState& state) { 108 | bool rc = true; 109 | rgb_t color(state.color); 110 | uint8_t blink = (state.flashOnMs != 0 && state.flashOffMs != 0); 111 | 112 | switch (state.flashMode) { 113 | case FlashMode::HARDWARE: 114 | case FlashMode::TIMED: 115 | if (mWhiteLED) { 116 | rc = kLEDs[WHITE].setBreath(blink); 117 | } else { 118 | if (!!color.red) 119 | rc &= kLEDs[RED].setBreath(blink); 120 | if (!!color.green) 121 | rc &= kLEDs[GREEN].setBreath(blink); 122 | if (!!color.blue) 123 | rc &= kLEDs[BLUE].setBreath(blink); 124 | } 125 | if (rc) 126 | break; 127 | FALLTHROUGH_INTENDED; 128 | default: 129 | if (mWhiteLED) { 130 | rc = kLEDs[WHITE].setBrightness(color.toBrightness()); 131 | } else { 132 | rc = kLEDs[RED].setBrightness(color.red); 133 | rc &= kLEDs[GREEN].setBrightness(color.green); 134 | rc &= kLEDs[BLUE].setBrightness(color.blue); 135 | } 136 | break; 137 | } 138 | 139 | return; 140 | } 141 | 142 | } // namespace light 143 | } // namespace hardware 144 | } // namespace android 145 | } // namespace aidl 146 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/PowerHintSession.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | 27 | namespace aidl { 28 | namespace google { 29 | namespace hardware { 30 | namespace power { 31 | namespace impl { 32 | namespace pixel { 33 | 34 | using aidl::android::hardware::power::BnPowerHintSession; 35 | using aidl::android::hardware::power::WorkDuration; 36 | using ::android::Message; 37 | using ::android::MessageHandler; 38 | using ::android::sp; 39 | using std::chrono::milliseconds; 40 | using std::chrono::nanoseconds; 41 | using std::chrono::steady_clock; 42 | using std::chrono::time_point; 43 | 44 | struct AppHintDesc { 45 | AppHintDesc(int32_t tgid, int32_t uid, std::vector threadIds) 46 | : tgid(tgid), 47 | uid(uid), 48 | threadIds(std::move(threadIds)), 49 | duration(0LL), 50 | current_min(0), 51 | is_active(true), 52 | update_count(0), 53 | integral_error(0), 54 | previous_error(0) {} 55 | std::string toString() const; 56 | const int32_t tgid; 57 | const int32_t uid; 58 | const std::vector threadIds; 59 | nanoseconds duration; 60 | int current_min; 61 | // status 62 | std::atomic is_active; 63 | // pid 64 | uint64_t update_count; 65 | int64_t integral_error; 66 | int64_t previous_error; 67 | }; 68 | 69 | class PowerHintSession : public BnPowerHintSession { 70 | public: 71 | explicit PowerHintSession(int32_t tgid, int32_t uid, const std::vector &threadIds, 72 | int64_t durationNanos); 73 | ~PowerHintSession(); 74 | ndk::ScopedAStatus close() override; 75 | ndk::ScopedAStatus pause() override; 76 | ndk::ScopedAStatus resume() override; 77 | ndk::ScopedAStatus updateTargetWorkDuration(int64_t targetDurationNanos) override; 78 | ndk::ScopedAStatus reportActualWorkDuration( 79 | const std::vector &actualDurations) override; 80 | bool isActive(); 81 | bool isTimeout(); 82 | void wakeup(); 83 | void setStale(); 84 | // Is this hint session for a user application 85 | bool isAppSession(); 86 | const std::vector &getTidList() const; 87 | int getUclampMin(); 88 | void dumpToStream(std::ostream &stream); 89 | 90 | void updateWorkPeriod(const std::vector &actualDurations); 91 | time_point getEarlyBoostTime(); 92 | time_point getStaleTime(); 93 | 94 | private: 95 | class StaleTimerHandler : public MessageHandler { 96 | public: 97 | StaleTimerHandler(PowerHintSession *session) 98 | : mSession(session), mIsMonitoring(false), mIsSessionDead(false) {} 99 | void updateTimer(); 100 | void updateTimer(time_point staleTime); 101 | void handleMessage(const Message &message) override; 102 | void setSessionDead(); 103 | 104 | private: 105 | PowerHintSession *mSession; 106 | std::mutex mStaleLock; 107 | std::mutex mMessageLock; 108 | std::atomic> mStaleTime; 109 | std::atomic mIsMonitoring; 110 | bool mIsSessionDead; 111 | }; 112 | 113 | class EarlyBoostHandler : public MessageHandler { 114 | public: 115 | EarlyBoostHandler(PowerHintSession *session) 116 | : mSession(session), mIsMonitoring(false), mIsSessionDead(false) {} 117 | void updateTimer(time_point boostTime); 118 | void handleMessage(const Message &message) override; 119 | void setSessionDead(); 120 | 121 | private: 122 | PowerHintSession *mSession; 123 | std::mutex mBoostLock; 124 | std::mutex mMessageLock; 125 | std::atomic> mBoostTime; 126 | std::atomic mIsMonitoring; 127 | bool mIsSessionDead; 128 | }; 129 | 130 | private: 131 | void updateUniveralBoostMode(); 132 | int setSessionUclampMin(int32_t min); 133 | std::string getIdString() const; 134 | AppHintDesc *mDescriptor = nullptr; 135 | sp mStaleTimerHandler; 136 | sp mEarlyBoostHandler; 137 | std::atomic> mLastUpdatedTime; 138 | sp mPowerManagerHandler; 139 | std::mutex mSessionLock; 140 | std::atomic mSessionClosed = false; 141 | // These 3 variables are for earlyboost work period estimation. 142 | int64_t mLastStartedTimeNs; 143 | int64_t mLastDurationNs; 144 | int64_t mWorkPeriodNs; 145 | }; 146 | 147 | } // namespace pixel 148 | } // namespace impl 149 | } // namespace power 150 | } // namespace hardware 151 | } // namespace google 152 | } // namespace aidl 153 | -------------------------------------------------------------------------------- /sensors/udfps_hal.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #define LOG_TAG "sensors.udfps" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | static const char *udfps_state_paths[] = { 20 | "/sys/devices/virtual/touch/tp_dev/fp_state", 21 | "/sys/touchpanel/fp_state", 22 | NULL, 23 | }; 24 | 25 | static struct sensor_t udfps_sensor = { 26 | .name = "UDFPS Sensor", 27 | .vendor = "The LineageOS Project", 28 | .version = 1, 29 | .handle = 0, 30 | .type = SENSOR_TYPE_DEVICE_PRIVATE_BASE + 1, 31 | .maxRange = 2048.0f, 32 | .resolution = 1.0f, 33 | .power = 0, 34 | .minDelay = -1, 35 | .fifoReservedEventCount = 0, 36 | .fifoMaxEventCount = 0, 37 | .stringType = "org.lineageos.sensor.udfps", 38 | .requiredPermission = "", 39 | .maxDelay = 0, 40 | .flags = SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP, 41 | .reserved = {}, 42 | }; 43 | 44 | struct udfps_context_t { 45 | sensors_poll_device_1_t device; 46 | int fd; 47 | }; 48 | 49 | static int udfps_read_line(int fd, char* buf, size_t len) { 50 | int rc; 51 | 52 | rc = lseek(fd, 0, SEEK_SET); 53 | if (rc < 0) { 54 | ALOGE("Failed to seek: %d", -errno); 55 | return rc; 56 | } 57 | 58 | rc = read(fd, buf, len); 59 | if (rc < 0) { 60 | ALOGE("Failed to read: %d", -errno); 61 | return rc; 62 | } 63 | 64 | return rc; 65 | } 66 | 67 | static int udfps_read_state(int fd, int& pos_x, int& pos_y) { 68 | int rc, state = 0; 69 | char buf[64]; 70 | 71 | rc = udfps_read_line(fd, buf, sizeof(buf)); 72 | if (rc > 0) { 73 | rc = sscanf(buf, "%d,%d,%d", &pos_x, &pos_y, &state); 74 | if (rc != 3) { 75 | ALOGE("Failed to parse fp_state: %d", rc); 76 | state = 0; 77 | } 78 | } 79 | 80 | return state; 81 | } 82 | 83 | static int udfps_wait_event(int fd, int timeout) { 84 | struct pollfd fds = { 85 | .fd = fd, 86 | .events = POLLERR | POLLPRI, 87 | .revents = 0, 88 | }; 89 | int rc; 90 | 91 | do { 92 | rc = poll(&fds, 1, timeout); 93 | } while (rc < 0 && errno == EINTR); 94 | 95 | return rc; 96 | } 97 | 98 | static void udfps_flush_events(int fd) { 99 | char buf[64]; 100 | 101 | while (udfps_wait_event(fd, 0) > 0) { 102 | udfps_read_line(fd, buf, sizeof(buf)); 103 | } 104 | } 105 | 106 | static int udfps_close(struct hw_device_t* dev) { 107 | udfps_context_t* ctx = reinterpret_cast(dev); 108 | 109 | if (ctx) { 110 | close(ctx->fd); 111 | delete ctx; 112 | } 113 | 114 | return 0; 115 | } 116 | 117 | static int udfps_activate(struct sensors_poll_device_t* dev, int handle, int enabled) { 118 | udfps_context_t* ctx = reinterpret_cast(dev); 119 | 120 | if (!ctx || handle) { 121 | return -EINVAL; 122 | } 123 | 124 | // Flush any pending events 125 | if (enabled) udfps_flush_events(ctx->fd); 126 | 127 | return 0; 128 | } 129 | 130 | static int udfps_setDelay(struct sensors_poll_device_t* dev, int handle, int64_t /* ns */) { 131 | udfps_context_t* ctx = reinterpret_cast(dev); 132 | 133 | if (!ctx || handle) { 134 | return -EINVAL; 135 | } 136 | 137 | return 0; 138 | } 139 | 140 | static int udfps_poll(struct sensors_poll_device_t* dev, sensors_event_t* data, int /* count */) { 141 | udfps_context_t* ctx = reinterpret_cast(dev); 142 | 143 | if (!ctx) { 144 | return -EINVAL; 145 | } 146 | 147 | int fod_x, fod_y, fod_state = 0; 148 | 149 | do { 150 | int rc = udfps_wait_event(ctx->fd, -1); 151 | if (rc < 0) { 152 | ALOGE("Failed to poll fp_state: %d", -errno); 153 | return -errno; 154 | } else if (rc > 0) { 155 | fod_state = udfps_read_state(ctx->fd, fod_x, fod_y); 156 | } 157 | } while (!fod_state); 158 | 159 | memset(data, 0, sizeof(sensors_event_t)); 160 | data->version = sizeof(sensors_event_t); 161 | data->sensor = udfps_sensor.handle; 162 | data->type = udfps_sensor.type; 163 | data->timestamp = ::android::elapsedRealtimeNano(); 164 | data->data[0] = fod_x; 165 | data->data[1] = fod_y; 166 | 167 | return 1; 168 | } 169 | 170 | static int udfps_batch(struct sensors_poll_device_1* /* dev */, int /* handle */, int /* flags */, 171 | int64_t /* period_ns */, int64_t /* max_ns */) { 172 | return 0; 173 | } 174 | 175 | static int udfps_flush(struct sensors_poll_device_1* /* dev */, int /* handle */) { 176 | return -EINVAL; 177 | } 178 | 179 | static int open_sensors(const struct hw_module_t* module, const char* /* name */, 180 | struct hw_device_t** device) { 181 | udfps_context_t* ctx = new udfps_context_t(); 182 | 183 | memset(ctx, 0, sizeof(udfps_context_t)); 184 | ctx->device.common.tag = HARDWARE_DEVICE_TAG; 185 | ctx->device.common.version = SENSORS_DEVICE_API_VERSION_1_3; 186 | ctx->device.common.module = const_cast(module); 187 | ctx->device.common.close = udfps_close; 188 | ctx->device.activate = udfps_activate; 189 | ctx->device.setDelay = udfps_setDelay; 190 | ctx->device.poll = udfps_poll; 191 | ctx->device.batch = udfps_batch; 192 | ctx->device.flush = udfps_flush; 193 | 194 | for (int i = 0; udfps_state_paths[i]; i++) { 195 | ctx->fd = open(udfps_state_paths[i], O_RDONLY); 196 | if (ctx->fd >= 0) { 197 | break; 198 | } 199 | } 200 | 201 | if (ctx->fd < 0) { 202 | ALOGE("Failed to open fp state: %d", -errno); 203 | delete ctx; 204 | 205 | return -ENODEV; 206 | } 207 | 208 | *device = &ctx->device.common; 209 | 210 | return 0; 211 | } 212 | 213 | static struct hw_module_methods_t udfps_module_methods = { 214 | .open = open_sensors, 215 | }; 216 | 217 | static int udfps_get_sensors_list(struct sensors_module_t*, struct sensor_t const** list) { 218 | *list = &udfps_sensor; 219 | 220 | return 1; 221 | } 222 | 223 | static int udfps_set_operation_mode(unsigned int mode) { 224 | return !mode ? 0 : -EINVAL; 225 | } 226 | 227 | struct sensors_module_t HAL_MODULE_INFO_SYM = { 228 | .common = {.tag = HARDWARE_MODULE_TAG, 229 | .version_major = 1, 230 | .version_minor = 0, 231 | .id = SENSORS_HARDWARE_MODULE_ID, 232 | .name = "UDFPS Sensor module", 233 | .author = "Ivan Vecera", 234 | .methods = &udfps_module_methods, 235 | .dso = NULL, 236 | .reserved = {0}}, 237 | .get_sensors_list = udfps_get_sensors_list, 238 | .set_operation_mode = udfps_set_operation_mode, 239 | }; 240 | -------------------------------------------------------------------------------- /IFAAService/src/org/ifaa/aidl/manager/IfaaService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 The LineageOS Project 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | package org.ifaa.aidl.manager; 8 | 9 | import android.app.KeyguardManager; 10 | import android.app.Service; 11 | import android.content.ActivityNotFoundException; 12 | import android.content.Context; 13 | import android.content.Intent; 14 | import android.hardware.fingerprint.Fingerprint; 15 | import android.hardware.fingerprint.FingerprintManager; 16 | import android.os.Build; 17 | import android.os.IBinder; 18 | import android.os.RemoteException; 19 | import android.os.SystemProperties; 20 | import android.util.Log; 21 | import java.lang.ref.WeakReference; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | import org.ifaa.aidl.manager.IfaaManagerService; 25 | import org.json.JSONObject; 26 | import org.json.JSONException; 27 | import vendor.xiaomi.hardware.mlipay.V1_1.IMlipayService; 28 | 29 | public class IfaaService extends Service { 30 | private static final String LOG_TAG = IfaaService.class.getSimpleName(); 31 | 32 | private static final int AUTH_TYPE_NOT_SUPPORT = 0; 33 | private static final int AUTH_TYPE_FINGERPRINT = 1; 34 | private static final int AUTH_TYPE_IRIS = 1<<1; 35 | private static final int AUTH_TYPE_OPTICAL_FINGERPRINT = 1<<4; 36 | 37 | private static final int ACTIVITY_START_SUCCESS = 0; 38 | private static final int ACTIVITY_START_FAILED = -1; 39 | 40 | private IMlipayService mMlipayService = null; 41 | 42 | private final IBinder mIFAABinder = new IfaaServiceStub(this); 43 | 44 | private final class IfaaServiceStub extends IfaaManagerService.Stub { 45 | IfaaServiceStub(IfaaService ifaaService) { 46 | new WeakReference(ifaaService); 47 | } 48 | 49 | @Override 50 | public int getSupportBIOTypes() { 51 | int ifaaProp = SystemProperties.getInt("persist.vendor.sys.pay.ifaa", 0); 52 | String fpVendor = SystemProperties.get("persist.vendor.sys.fp.vendor", ""); 53 | 54 | int res = "none".equalsIgnoreCase(fpVendor) ? 55 | ifaaProp & AUTH_TYPE_IRIS : 56 | ifaaProp & (AUTH_TYPE_FINGERPRINT | AUTH_TYPE_IRIS); 57 | 58 | if ((res & AUTH_TYPE_FINGERPRINT) == AUTH_TYPE_FINGERPRINT && 59 | SystemProperties.getBoolean("ro.hardware.fp.udfps", false)) { 60 | res |= AUTH_TYPE_OPTICAL_FINGERPRINT; 61 | } 62 | 63 | return res; 64 | } 65 | 66 | @Override 67 | public int startBIOManager(int authType) { 68 | int res = ACTIVITY_START_FAILED; 69 | 70 | if (authType == AUTH_TYPE_FINGERPRINT) { 71 | Intent intent = new Intent("android.settings.SECURITY_SETTINGS"); 72 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 73 | getApplicationContext().startActivity(intent); 74 | res = ACTIVITY_START_SUCCESS; 75 | } 76 | 77 | return res; 78 | } 79 | 80 | @Override 81 | public String getDeviceModel() { 82 | return Build.MANUFACTURER + "-" + Build.DEVICE; 83 | } 84 | 85 | @Override 86 | public byte[] processCmd(byte[] param) { 87 | IMlipayService mlipayService = getMlipayService(); 88 | if (mlipayService == null) { 89 | Log.e(LOG_TAG, "Failed to open mlipay HAL"); 90 | return null; 91 | } 92 | 93 | ArrayList paramByteArray = new ArrayList(); 94 | for (byte b : param) { 95 | paramByteArray.add(Byte.valueOf(b)); 96 | } 97 | 98 | byte[] receiveBuffer = null; 99 | 100 | try { 101 | ArrayList receiveBufferByteArray = mlipayService.invoke_command(paramByteArray, 102 | paramByteArray.size()); 103 | 104 | receiveBuffer = new byte[receiveBufferByteArray.size()]; 105 | for (int i = 0; i < receiveBufferByteArray.size(); i++) { 106 | receiveBuffer[i] = receiveBufferByteArray.get(i).byteValue(); 107 | } 108 | } catch (RemoteException e) { 109 | Log.e(LOG_TAG, "processCmdImpl: mlipay invoke_command failed", e); 110 | } 111 | 112 | return receiveBuffer; 113 | } 114 | 115 | @Override 116 | public int getVersion() { 117 | return 4; 118 | } 119 | 120 | @Override 121 | public String getExtInfo(int authType, String keyExtInfo) { 122 | return initExtString(); 123 | } 124 | 125 | @Override 126 | public void setExtInfo(int authType, String keyExtInfo, String valExtInfo) { 127 | // nothing 128 | } 129 | 130 | @Override 131 | public int getEnabled(int bioType) { 132 | return 1 == bioType ? 1000 : 1003; 133 | } 134 | 135 | @Override 136 | public int[] getIDList(int bioType) { 137 | int[] idList = new int[0]; 138 | 139 | IMlipayService mlipayService = getMlipayService(); 140 | if (mlipayService == null) { 141 | Log.e(LOG_TAG, "getIDListImpl: Failed to open mlipay HAL"); 142 | return idList; 143 | } 144 | 145 | try { 146 | ArrayList idListAL = mlipayService.ifaa_get_idlist(bioType); 147 | idList = new int[idListAL.size()]; 148 | for (int i = 0; i < idListAL.size(); i++) { 149 | idList[i] = idListAL.get(i).intValue(); 150 | } 151 | } catch (RemoteException e) { 152 | Log.e(LOG_TAG, "getIDListImpl: mlipay ifaa_get_idlist failed", e); 153 | } 154 | 155 | return idList; 156 | } 157 | }; 158 | 159 | @Override // android.app.Service 160 | public IBinder onBind(Intent intent) { 161 | return this.mIFAABinder; 162 | } 163 | 164 | // Utils 165 | 166 | private IMlipayService getMlipayService() { 167 | if (mMlipayService == null) { 168 | try { 169 | mMlipayService = IMlipayService.getService(); 170 | } catch (RemoteException e) { 171 | // do nothing 172 | } 173 | } 174 | 175 | return mMlipayService; 176 | } 177 | 178 | private String initExtString() { 179 | JSONObject obj = new JSONObject(); 180 | JSONObject keyInfo = new JSONObject(); 181 | String xy = SystemProperties.get("persist.vendor.sys.fp.udfps.location.X_Y", ""); 182 | String wh = SystemProperties.get("persist.vendor.sys.fp.udfps.size.width_height", ""); 183 | try { 184 | if (!validateVal(xy) || !validateVal(wh)) { 185 | Log.e(LOG_TAG, "initExtString: invalidate, xy: " + xy + ", wh: " + wh); 186 | return ""; 187 | } 188 | String[] split = xy.split(","); 189 | String[] split2 = wh.split(","); 190 | keyInfo.put("startX", Integer.parseInt(split[0])); 191 | keyInfo.put("startY", Integer.parseInt(split[1])); 192 | keyInfo.put("width", Integer.parseInt(split2[0])); 193 | keyInfo.put("height", Integer.parseInt(split2[1])); 194 | keyInfo.put("navConflict", true); 195 | obj.put("type", 0); 196 | obj.put("fullView", keyInfo); 197 | return obj.toString(); 198 | } catch (Exception e) { 199 | Log.e(LOG_TAG, "initExtString: Exception, xy: " + xy + ", wh: " + wh, e); 200 | return ""; 201 | } 202 | } 203 | 204 | private boolean validateVal(String str) { 205 | return !"".equalsIgnoreCase(str) && str.contains(","); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/PowerSessionManager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "powerhal-libperfmgr" 18 | #define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL) 19 | 20 | #include "PowerSessionManager.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | namespace aidl { 30 | namespace google { 31 | namespace hardware { 32 | namespace power { 33 | namespace impl { 34 | namespace pixel { 35 | 36 | using ::android::perfmgr::HintManager; 37 | 38 | namespace { 39 | /* there is no glibc or bionic wrapper */ 40 | struct sched_attr { 41 | __u32 size; 42 | __u32 sched_policy; 43 | __u64 sched_flags; 44 | __s32 sched_nice; 45 | __u32 sched_priority; 46 | __u64 sched_runtime; 47 | __u64 sched_deadline; 48 | __u64 sched_period; 49 | __u32 sched_util_min; 50 | __u32 sched_util_max; 51 | }; 52 | 53 | static int sched_setattr(int pid, struct sched_attr *attr, unsigned int flags) { 54 | if (!HintManager::GetInstance()->GetAdpfProfile()->mUclampMinOn) { 55 | ALOGV("PowerSessionManager:%s: skip", __func__); 56 | return 0; 57 | } 58 | return syscall(__NR_sched_setattr, pid, attr, flags); 59 | } 60 | 61 | static void set_uclamp_min(int tid, int min) { 62 | static constexpr int32_t kMaxUclampValue = 1024; 63 | min = std::max(0, min); 64 | min = std::min(min, kMaxUclampValue); 65 | 66 | sched_attr attr = {}; 67 | attr.size = sizeof(attr); 68 | 69 | attr.sched_flags = (SCHED_FLAG_KEEP_ALL | SCHED_FLAG_UTIL_CLAMP_MIN); 70 | attr.sched_util_min = min; 71 | 72 | int ret = sched_setattr(tid, &attr, 0); 73 | if (ret) { 74 | ALOGW("sched_setattr failed for thread %d, err=%d", tid, errno); 75 | } 76 | } 77 | } // namespace 78 | 79 | void PowerSessionManager::updateHintMode(const std::string &mode, bool enabled) { 80 | ALOGV("PowerSessionManager::updateHintMode: mode: %s, enabled: %d", mode.c_str(), enabled); 81 | if (enabled && mode.compare(0, 8, "REFRESH_") == 0) { 82 | if (mode.compare("REFRESH_120FPS") == 0) { 83 | mDisplayRefreshRate = 120; 84 | } else if (mode.compare("REFRESH_90FPS") == 0) { 85 | mDisplayRefreshRate = 90; 86 | } else if (mode.compare("REFRESH_60FPS") == 0) { 87 | mDisplayRefreshRate = 60; 88 | } 89 | } 90 | if (HintManager::GetInstance()->GetAdpfProfile()) { 91 | HintManager::GetInstance()->SetAdpfProfile(mode); 92 | } 93 | } 94 | 95 | void PowerSessionManager::updateHintBoost(const std::string &boost, int32_t durationMs) { 96 | ATRACE_CALL(); 97 | ALOGV("PowerSessionManager::updateHintBoost: boost: %s, durationMs: %d", boost.c_str(), 98 | durationMs); 99 | if (boost.compare("DISPLAY_UPDATE_IMMINENT") == 0) { 100 | PowerHintMonitor::getInstance()->getLooper()->sendMessage(mWakeupHandler, NULL); 101 | } 102 | } 103 | 104 | void PowerSessionManager::wakeSessions() { 105 | std::lock_guard guard(mLock); 106 | for (PowerHintSession *s : mSessions) { 107 | s->wakeup(); 108 | } 109 | } 110 | 111 | int PowerSessionManager::getDisplayRefreshRate() { 112 | return mDisplayRefreshRate; 113 | } 114 | 115 | void PowerSessionManager::addPowerSession(PowerHintSession *session) { 116 | std::lock_guard guard(mLock); 117 | for (auto t : session->getTidList()) { 118 | mTidSessionListMap[t].insert(session); 119 | if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) { 120 | if (!SetTaskProfiles(t, {"ResetUclampGrp"})) { 121 | ALOGW("Failed to set ResetUclampGrp task profile for tid:%d", t); 122 | } else { 123 | mTidRefCountMap[t] = 1; 124 | } 125 | continue; 126 | } 127 | if (mTidRefCountMap[t] <= 0) { 128 | ALOGE("Error! Unexpected zero/negative RefCount:%d for tid:%d", mTidRefCountMap[t], t); 129 | continue; 130 | } 131 | mTidRefCountMap[t]++; 132 | } 133 | mSessions.insert(session); 134 | } 135 | 136 | void PowerSessionManager::removePowerSession(PowerHintSession *session) { 137 | std::lock_guard guard(mLock); 138 | for (auto t : session->getTidList()) { 139 | if (mTidRefCountMap.find(t) == mTidRefCountMap.end()) { 140 | ALOGE("Unexpected Error! Failed to look up tid:%d in TidRefCountMap", t); 141 | continue; 142 | } 143 | mTidSessionListMap[t].erase(session); 144 | mTidRefCountMap[t]--; 145 | if (mTidRefCountMap[t] <= 0) { 146 | if (!SetTaskProfiles(t, {"NoResetUclampGrp"})) { 147 | ALOGW("Failed to set NoResetUclampGrp task profile for tid:%d", t); 148 | } 149 | mTidRefCountMap.erase(t); 150 | } 151 | } 152 | mSessions.erase(session); 153 | } 154 | 155 | void PowerSessionManager::setUclampMin(PowerHintSession *session, int val) { 156 | std::lock_guard guard(mLock); 157 | setUclampMinLocked(session, val); 158 | } 159 | 160 | void PowerSessionManager::setUclampMinLocked(PowerHintSession *session, int val) { 161 | for (auto t : session->getTidList()) { 162 | // Get thex max uclamp.min across sessions which include the tid. 163 | int tidMax = 0; 164 | for (PowerHintSession *s : mTidSessionListMap[t]) { 165 | if (!s->isActive() || s->isTimeout()) 166 | continue; 167 | tidMax = std::max(tidMax, s->getUclampMin()); 168 | } 169 | set_uclamp_min(t, std::max(val, tidMax)); 170 | } 171 | } 172 | 173 | std::optional PowerSessionManager::isAnyAppSessionActive() { 174 | std::lock_guard guard(mLock); 175 | bool active = false; 176 | for (PowerHintSession *s : mSessions) { 177 | // session active and not stale is actually active. 178 | if (s->isActive() && !s->isTimeout() && s->isAppSession()) { 179 | active = true; 180 | break; 181 | } 182 | } 183 | if (active == mActive) { 184 | return std::nullopt; 185 | } else { 186 | mActive = active; 187 | } 188 | 189 | return active; 190 | } 191 | 192 | void PowerSessionManager::handleMessage(const Message &) { 193 | auto active = isAnyAppSessionActive(); 194 | if (!active.has_value()) { 195 | return; 196 | } 197 | if (active.value()) { 198 | disableSystemTopAppBoost(); 199 | } else { 200 | enableSystemTopAppBoost(); 201 | } 202 | } 203 | 204 | void PowerSessionManager::WakeupHandler::handleMessage(const Message &) { 205 | PowerSessionManager::getInstance()->wakeSessions(); 206 | } 207 | 208 | void PowerSessionManager::dumpToFd(int fd) { 209 | std::ostringstream dump_buf; 210 | std::lock_guard guard(mLock); 211 | dump_buf << "========== Begin PowerSessionManager ADPF list ==========\n"; 212 | for (PowerHintSession *s : mSessions) { 213 | s->dumpToStream(dump_buf); 214 | dump_buf << " Tid:Ref["; 215 | for (size_t i = 0, len = s->getTidList().size(); i < len; i++) { 216 | int t = s->getTidList()[i]; 217 | dump_buf << t << ":" << mTidSessionListMap[t].size(); 218 | if (i < len - 1) { 219 | dump_buf << ", "; 220 | } 221 | } 222 | dump_buf << "]\n"; 223 | } 224 | dump_buf << "========== End PowerSessionManager ADPF list ==========\n"; 225 | if (!::android::base::WriteStringToFd(dump_buf.str(), fd)) { 226 | ALOGE("Failed to dump one of session list to fd:%d", fd); 227 | } 228 | } 229 | 230 | void PowerSessionManager::enableSystemTopAppBoost() { 231 | if (HintManager::GetInstance()->IsHintSupported(kDisableBoostHintName)) { 232 | ALOGV("PowerSessionManager::enableSystemTopAppBoost!!"); 233 | HintManager::GetInstance()->EndHint(kDisableBoostHintName); 234 | } 235 | } 236 | 237 | void PowerSessionManager::disableSystemTopAppBoost() { 238 | if (HintManager::GetInstance()->IsHintSupported(kDisableBoostHintName)) { 239 | ALOGV("PowerSessionManager::disableSystemTopAppBoost!!"); 240 | HintManager::GetInstance()->DoHint(kDisableBoostHintName); 241 | } 242 | } 243 | 244 | // =========== PowerHintMonitor implementation start from here =========== 245 | void PowerHintMonitor::start() { 246 | if (!isRunning()) { 247 | run("PowerHintMonitor", ::android::PRIORITY_HIGHEST); 248 | } 249 | } 250 | 251 | bool PowerHintMonitor::threadLoop() { 252 | while (true) { 253 | mLooper->pollOnce(-1); 254 | } 255 | return true; 256 | } 257 | 258 | sp PowerHintMonitor::getLooper() { 259 | return mLooper; 260 | } 261 | 262 | } // namespace pixel 263 | } // namespace impl 264 | } // namespace power 265 | } // namespace hardware 266 | } // namespace google 267 | } // namespace aidl 268 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/InteractionHandler.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define ATRACE_TAG (ATRACE_TAG_POWER | ATRACE_TAG_HAL) 18 | #define LOG_TAG "powerhal-libperfmgr" 19 | 20 | #include "InteractionHandler.h" 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #define MAX_LENGTH 64 36 | 37 | #define MSINSEC 1000L 38 | #define NSINMS 1000000L 39 | 40 | namespace aidl { 41 | namespace google { 42 | namespace hardware { 43 | namespace power { 44 | namespace impl { 45 | namespace pixel { 46 | 47 | namespace { 48 | 49 | static const bool kDisplayIdleSupport = 50 | ::android::base::GetBoolProperty("vendor.powerhal.disp.idle_support", true); 51 | static const std::array kDispIdlePath = {"/sys/class/drm/card0/device/idle_state", 52 | "/sys/class/graphics/fb0/idle_state"}; 53 | static const uint32_t kWaitMs = 54 | ::android::base::GetUintProperty("vendor.powerhal.disp.idle_wait", /*default*/ 100U); 55 | static const uint32_t kMinDurationMs = 56 | ::android::base::GetUintProperty("vendor.powerhal.interaction.min", /*default*/ 1400U); 57 | static const uint32_t kMaxDurationMs = 58 | ::android::base::GetUintProperty("vendor.powerhal.interaction.max", /*default*/ 5650U); 59 | static const uint32_t kDurationOffsetMs = 60 | ::android::base::GetUintProperty("vendor.powerhal.interaction.offset", /*default*/ 650U); 61 | 62 | static size_t CalcTimespecDiffMs(struct timespec start, struct timespec end) { 63 | size_t diff_in_ms = 0; 64 | diff_in_ms += (end.tv_sec - start.tv_sec) * MSINSEC; 65 | diff_in_ms += (end.tv_nsec - start.tv_nsec) / NSINMS; 66 | return diff_in_ms; 67 | } 68 | 69 | static int FbIdleOpen(void) { 70 | int fd; 71 | for (const auto &path : kDispIdlePath) { 72 | fd = open(path, O_RDONLY); 73 | if (fd >= 0) 74 | return fd; 75 | } 76 | ALOGE("Unable to open fb idle state path (%d)", errno); 77 | return -1; 78 | } 79 | 80 | } // namespace 81 | 82 | using ::android::perfmgr::HintManager; 83 | 84 | InteractionHandler::InteractionHandler() 85 | : mState(INTERACTION_STATE_UNINITIALIZED), mDurationMs(0) {} 86 | 87 | InteractionHandler::~InteractionHandler() { 88 | Exit(); 89 | } 90 | 91 | bool InteractionHandler::Init() { 92 | std::lock_guard lk(mLock); 93 | 94 | if (mState != INTERACTION_STATE_UNINITIALIZED) 95 | return true; 96 | 97 | int fd = FbIdleOpen(); 98 | if (fd < 0) 99 | return false; 100 | mIdleFd = fd; 101 | 102 | mEventFd = eventfd(0, EFD_NONBLOCK); 103 | if (mEventFd < 0) { 104 | ALOGE("Unable to create event fd (%d)", errno); 105 | close(mIdleFd); 106 | return false; 107 | } 108 | 109 | mState = INTERACTION_STATE_IDLE; 110 | mThread = std::unique_ptr(new std::thread(&InteractionHandler::Routine, this)); 111 | 112 | return true; 113 | } 114 | 115 | void InteractionHandler::Exit() { 116 | std::unique_lock lk(mLock); 117 | if (mState == INTERACTION_STATE_UNINITIALIZED) 118 | return; 119 | 120 | AbortWaitLocked(); 121 | mState = INTERACTION_STATE_UNINITIALIZED; 122 | lk.unlock(); 123 | 124 | mCond.notify_all(); 125 | mThread->join(); 126 | 127 | close(mEventFd); 128 | close(mIdleFd); 129 | } 130 | 131 | void InteractionHandler::PerfLock() { 132 | ALOGV("%s: acquiring perf lock", __func__); 133 | if (!HintManager::GetInstance()->DoHint("INTERACTION")) { 134 | ALOGE("%s: do hint INTERACTION failed", __func__); 135 | } 136 | } 137 | 138 | void InteractionHandler::PerfRel() { 139 | ALOGV("%s: releasing perf lock", __func__); 140 | if (!HintManager::GetInstance()->EndHint("INTERACTION")) { 141 | ALOGE("%s: end hint INTERACTION failed", __func__); 142 | } 143 | } 144 | 145 | void InteractionHandler::Acquire(int32_t duration) { 146 | ATRACE_CALL(); 147 | 148 | std::lock_guard lk(mLock); 149 | 150 | int inputDuration = duration + kDurationOffsetMs; 151 | int finalDuration; 152 | if (inputDuration > kMaxDurationMs) 153 | finalDuration = kMaxDurationMs; 154 | else if (inputDuration > kMinDurationMs) 155 | finalDuration = inputDuration; 156 | else 157 | finalDuration = kMinDurationMs; 158 | 159 | // Fallback to do boost directly 160 | // 1) override property is set OR 161 | // 2) InteractionHandler not initialized 162 | if (!kDisplayIdleSupport || mState == INTERACTION_STATE_UNINITIALIZED) { 163 | HintManager::GetInstance()->DoHint("INTERACTION", std::chrono::milliseconds(finalDuration)); 164 | return; 165 | } 166 | 167 | struct timespec cur_timespec; 168 | clock_gettime(CLOCK_MONOTONIC, &cur_timespec); 169 | if (mState != INTERACTION_STATE_IDLE && finalDuration <= mDurationMs) { 170 | size_t elapsed_time = CalcTimespecDiffMs(mLastTimespec, cur_timespec); 171 | // don't hint if previous hint's duration covers this hint's duration 172 | if (elapsed_time <= (mDurationMs - finalDuration)) { 173 | ALOGV("%s: Previous duration (%d) cover this (%d) elapsed: %lld", __func__, 174 | static_cast(mDurationMs), static_cast(finalDuration), 175 | static_cast(elapsed_time)); 176 | return; 177 | } 178 | } 179 | mLastTimespec = cur_timespec; 180 | mDurationMs = finalDuration; 181 | 182 | ALOGV("%s: input: %d final duration: %d", __func__, duration, finalDuration); 183 | 184 | if (mState == INTERACTION_STATE_WAITING) 185 | AbortWaitLocked(); 186 | else if (mState == INTERACTION_STATE_IDLE) 187 | PerfLock(); 188 | 189 | mState = INTERACTION_STATE_INTERACTION; 190 | mCond.notify_one(); 191 | } 192 | 193 | void InteractionHandler::Release() { 194 | std::lock_guard lk(mLock); 195 | if (mState == INTERACTION_STATE_WAITING) { 196 | ATRACE_CALL(); 197 | PerfRel(); 198 | mState = INTERACTION_STATE_IDLE; 199 | } else { 200 | // clear any wait aborts pending in event fd 201 | uint64_t val; 202 | ssize_t ret = read(mEventFd, &val, sizeof(val)); 203 | 204 | ALOGW_IF(ret < 0, "%s: failed to clear eventfd (%zd, %d)", __func__, ret, errno); 205 | } 206 | } 207 | 208 | // should be called while locked 209 | void InteractionHandler::AbortWaitLocked() { 210 | uint64_t val = 1; 211 | ssize_t ret = write(mEventFd, &val, sizeof(val)); 212 | if (ret != sizeof(val)) 213 | ALOGW("Unable to write to event fd (%zd)", ret); 214 | } 215 | 216 | void InteractionHandler::WaitForIdle(int32_t wait_ms, int32_t timeout_ms) { 217 | char data[MAX_LENGTH]; 218 | ssize_t ret; 219 | struct pollfd pfd[2]; 220 | 221 | ATRACE_CALL(); 222 | 223 | ALOGV("%s: wait:%d timeout:%d", __func__, wait_ms, timeout_ms); 224 | 225 | pfd[0].fd = mEventFd; 226 | pfd[0].events = POLLIN; 227 | pfd[1].fd = mIdleFd; 228 | pfd[1].events = POLLPRI | POLLERR; 229 | 230 | ret = poll(pfd, 1, wait_ms); 231 | if (ret > 0) { 232 | ALOGV("%s: wait aborted", __func__); 233 | return; 234 | } else if (ret < 0) { 235 | ALOGE("%s: error in poll while waiting", __func__); 236 | return; 237 | } 238 | 239 | ret = pread(mIdleFd, data, sizeof(data), 0); 240 | if (!ret) { 241 | ALOGE("%s: Unexpected EOF!", __func__); 242 | return; 243 | } 244 | 245 | if (!strncmp(data, "idle", 4)) { 246 | ALOGV("%s: already idle", __func__); 247 | return; 248 | } 249 | 250 | ret = poll(pfd, 2, timeout_ms); 251 | if (ret < 0) 252 | ALOGE("%s: Error on waiting for idle (%zd)", __func__, ret); 253 | else if (ret == 0) 254 | ALOGV("%s: timed out waiting for idle", __func__); 255 | else if (pfd[0].revents) 256 | ALOGV("%s: wait for idle aborted", __func__); 257 | else if (pfd[1].revents) 258 | ALOGV("%s: idle detected", __func__); 259 | } 260 | 261 | void InteractionHandler::Routine() { 262 | pthread_setname_np(pthread_self(), "DispIdle"); 263 | std::unique_lock lk(mLock, std::defer_lock); 264 | 265 | while (true) { 266 | lk.lock(); 267 | mCond.wait(lk, [&] { return mState != INTERACTION_STATE_IDLE; }); 268 | if (mState == INTERACTION_STATE_UNINITIALIZED) 269 | return; 270 | mState = INTERACTION_STATE_WAITING; 271 | lk.unlock(); 272 | 273 | WaitForIdle(kWaitMs, mDurationMs); 274 | Release(); 275 | } 276 | } 277 | 278 | } // namespace pixel 279 | } // namespace impl 280 | } // namespace power 281 | } // namespace hardware 282 | } // namespace google 283 | } // namespace aidl 284 | -------------------------------------------------------------------------------- /aidl/power-libperfmgr/Power.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define LOG_TAG "powerhal-libperfmgr" 18 | 19 | #include "Power.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "PowerHintSession.h" 32 | #include "PowerSessionManager.h" 33 | 34 | namespace aidl { 35 | namespace google { 36 | namespace hardware { 37 | namespace power { 38 | namespace impl { 39 | namespace pixel { 40 | 41 | using ::aidl::google::hardware::power::impl::pixel::PowerHintSession; 42 | using ::android::perfmgr::HintManager; 43 | 44 | #ifdef MODE_EXT 45 | extern bool isDeviceSpecificModeSupported(Mode type, bool* _aidl_return); 46 | extern bool setDeviceSpecificMode(Mode type, bool enabled); 47 | #endif 48 | 49 | constexpr char kPowerHalStateProp[] = "vendor.powerhal.state"; 50 | constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio"; 51 | constexpr char kPowerHalRenderingProp[] = "vendor.powerhal.rendering"; 52 | 53 | Power::Power() 54 | : mInteractionHandler(nullptr), 55 | mSustainedPerfModeOn(false) { 56 | mInteractionHandler = std::make_unique(); 57 | mInteractionHandler->Init(); 58 | 59 | std::string state = ::android::base::GetProperty(kPowerHalStateProp, ""); 60 | if (state == "SUSTAINED_PERFORMANCE") { 61 | LOG(INFO) << "Initialize with SUSTAINED_PERFORMANCE on"; 62 | HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE"); 63 | mSustainedPerfModeOn = true; 64 | } else { 65 | LOG(INFO) << "Initialize PowerHAL"; 66 | } 67 | 68 | state = ::android::base::GetProperty(kPowerHalAudioProp, ""); 69 | if (state == "AUDIO_STREAMING_LOW_LATENCY") { 70 | LOG(INFO) << "Initialize with AUDIO_LOW_LATENCY on"; 71 | HintManager::GetInstance()->DoHint(state); 72 | } 73 | 74 | state = ::android::base::GetProperty(kPowerHalRenderingProp, ""); 75 | if (state == "EXPENSIVE_RENDERING") { 76 | LOG(INFO) << "Initialize with EXPENSIVE_RENDERING on"; 77 | HintManager::GetInstance()->DoHint("EXPENSIVE_RENDERING"); 78 | } 79 | } 80 | 81 | ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { 82 | LOG(DEBUG) << "Power setMode: " << toString(type) << " to: " << enabled; 83 | if (HintManager::GetInstance()->GetAdpfProfile() && 84 | HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) { 85 | PowerSessionManager::getInstance()->updateHintMode(toString(type), enabled); 86 | } 87 | #ifdef MODE_EXT 88 | if (setDeviceSpecificMode(type, enabled)) { 89 | return ndk::ScopedAStatus::ok(); 90 | } 91 | #endif 92 | switch (type) { 93 | #ifdef TAP_TO_WAKE_NODE 94 | case Mode::DOUBLE_TAP_TO_WAKE: 95 | ::android::base::WriteStringToFile(enabled ? "1" : "0", TAP_TO_WAKE_NODE, true); 96 | break; 97 | #endif 98 | case Mode::SUSTAINED_PERFORMANCE: 99 | if (enabled) { 100 | HintManager::GetInstance()->DoHint("SUSTAINED_PERFORMANCE"); 101 | } 102 | mSustainedPerfModeOn = true; 103 | break; 104 | case Mode::LAUNCH: 105 | if (mSustainedPerfModeOn) { 106 | break; 107 | } 108 | [[fallthrough]]; 109 | #ifndef TAP_TO_WAKE_NODE 110 | case Mode::DOUBLE_TAP_TO_WAKE: 111 | [[fallthrough]]; 112 | #endif 113 | case Mode::FIXED_PERFORMANCE: 114 | [[fallthrough]]; 115 | case Mode::EXPENSIVE_RENDERING: 116 | [[fallthrough]]; 117 | case Mode::INTERACTIVE: 118 | [[fallthrough]]; 119 | case Mode::DEVICE_IDLE: 120 | [[fallthrough]]; 121 | case Mode::DISPLAY_INACTIVE: 122 | [[fallthrough]]; 123 | case Mode::AUDIO_STREAMING_LOW_LATENCY: 124 | [[fallthrough]]; 125 | default: 126 | if (enabled) { 127 | HintManager::GetInstance()->DoHint(toString(type)); 128 | } else { 129 | HintManager::GetInstance()->EndHint(toString(type)); 130 | } 131 | break; 132 | } 133 | 134 | return ndk::ScopedAStatus::ok(); 135 | } 136 | 137 | ndk::ScopedAStatus Power::isModeSupported(Mode type, bool *_aidl_return) { 138 | #ifdef MODE_EXT 139 | if (isDeviceSpecificModeSupported(type, _aidl_return)) { 140 | return ndk::ScopedAStatus::ok(); 141 | } 142 | #endif 143 | 144 | bool supported = HintManager::GetInstance()->IsHintSupported(toString(type)); 145 | #ifdef TAP_TO_WAKE_NODE 146 | if (type == Mode::DOUBLE_TAP_TO_WAKE) { 147 | supported = true; 148 | } 149 | #endif 150 | LOG(INFO) << "Power mode " << toString(type) << " isModeSupported: " << supported; 151 | *_aidl_return = supported; 152 | return ndk::ScopedAStatus::ok(); 153 | } 154 | 155 | ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) { 156 | LOG(DEBUG) << "Power setBoost: " << toString(type) << " duration: " << durationMs; 157 | if (HintManager::GetInstance()->GetAdpfProfile() && 158 | HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs > 0) { 159 | PowerSessionManager::getInstance()->updateHintBoost(toString(type), durationMs); 160 | } 161 | switch (type) { 162 | case Boost::INTERACTION: 163 | if (mSustainedPerfModeOn) { 164 | break; 165 | } 166 | mInteractionHandler->Acquire(durationMs); 167 | break; 168 | case Boost::DISPLAY_UPDATE_IMMINENT: 169 | [[fallthrough]]; 170 | case Boost::ML_ACC: 171 | [[fallthrough]]; 172 | case Boost::AUDIO_LAUNCH: 173 | [[fallthrough]]; 174 | default: 175 | if (mSustainedPerfModeOn) { 176 | break; 177 | } 178 | if (durationMs > 0) { 179 | HintManager::GetInstance()->DoHint(toString(type), 180 | std::chrono::milliseconds(durationMs)); 181 | } else if (durationMs == 0) { 182 | HintManager::GetInstance()->DoHint(toString(type)); 183 | } else { 184 | HintManager::GetInstance()->EndHint(toString(type)); 185 | } 186 | break; 187 | } 188 | 189 | return ndk::ScopedAStatus::ok(); 190 | } 191 | 192 | ndk::ScopedAStatus Power::isBoostSupported(Boost type, bool *_aidl_return) { 193 | bool supported = HintManager::GetInstance()->IsHintSupported(toString(type)); 194 | LOG(INFO) << "Power boost " << toString(type) << " isBoostSupported: " << supported; 195 | *_aidl_return = supported; 196 | return ndk::ScopedAStatus::ok(); 197 | } 198 | 199 | constexpr const char *boolToString(bool b) { 200 | return b ? "true" : "false"; 201 | } 202 | 203 | binder_status_t Power::dump(int fd, const char **, uint32_t) { 204 | std::string buf(::android::base::StringPrintf( 205 | "HintManager Running: %s\n" 206 | "SustainedPerformanceMode: %s\n", 207 | boolToString(HintManager::GetInstance()->IsRunning()), 208 | boolToString(mSustainedPerfModeOn))); 209 | // Dump nodes through libperfmgr 210 | HintManager::GetInstance()->DumpToFd(fd); 211 | PowerSessionManager::getInstance()->dumpToFd(fd); 212 | if (!::android::base::WriteStringToFd(buf, fd)) { 213 | PLOG(ERROR) << "Failed to dump state to fd"; 214 | } 215 | fsync(fd); 216 | return STATUS_OK; 217 | } 218 | 219 | ndk::ScopedAStatus Power::createHintSession(int32_t tgid, int32_t uid, 220 | const std::vector &threadIds, 221 | int64_t durationNanos, 222 | std::shared_ptr *_aidl_return) { 223 | if (!HintManager::GetInstance()->GetAdpfProfile() || 224 | HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs <= 0) { 225 | *_aidl_return = nullptr; 226 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 227 | } 228 | if (threadIds.size() == 0) { 229 | LOG(ERROR) << "Error: threadIds.size() shouldn't be " << threadIds.size(); 230 | *_aidl_return = nullptr; 231 | return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT); 232 | } 233 | std::shared_ptr session = ndk::SharedRefBase::make( 234 | tgid, uid, threadIds, durationNanos); 235 | *_aidl_return = session; 236 | return ndk::ScopedAStatus::ok(); 237 | } 238 | 239 | ndk::ScopedAStatus Power::getHintSessionPreferredRate(int64_t *outNanoseconds) { 240 | *outNanoseconds = HintManager::GetInstance()->GetAdpfProfile() 241 | ? HintManager::GetInstance()->GetAdpfProfile()->mReportingRateLimitNs 242 | : 0; 243 | if (*outNanoseconds <= 0) { 244 | return ndk::ScopedAStatus::fromExceptionCode(EX_UNSUPPORTED_OPERATION); 245 | } 246 | 247 | return ndk::ScopedAStatus::ok(); 248 | } 249 | 250 | } // namespace pixel 251 | } // namespace impl 252 | } // namespace power 253 | } // namespace hardware 254 | } // namespace google 255 | } // namespace aidl 256 | -------------------------------------------------------------------------------- /hidl/sensors/1.0/Sensors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "Sensors.h" 18 | #include "convert.h" 19 | #include "multihal.h" 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace android { 26 | namespace hardware { 27 | namespace sensors { 28 | namespace V1_0 { 29 | namespace implementation { 30 | 31 | /* 32 | * If a multi-hal configuration file exists in the proper location, 33 | * return true indicating we need to use multi-hal functionality. 34 | */ 35 | static bool UseMultiHal() { 36 | const std::string& name = MULTI_HAL_CONFIG_FILE_PATH; 37 | struct stat buffer; 38 | return (stat(name.c_str(), &buffer) == 0); 39 | } 40 | 41 | static Result ResultFromStatus(status_t err) { 42 | switch (err) { 43 | case OK: 44 | return Result::OK; 45 | case PERMISSION_DENIED: 46 | return Result::PERMISSION_DENIED; 47 | case NO_MEMORY: 48 | return Result::NO_MEMORY; 49 | case BAD_VALUE: 50 | return Result::BAD_VALUE; 51 | default: 52 | return Result::INVALID_OPERATION; 53 | } 54 | } 55 | 56 | Sensors::Sensors() : mInitCheck(NO_INIT), mSensorModule(nullptr), mSensorDevice(nullptr) { 57 | status_t err = OK; 58 | if (UseMultiHal()) { 59 | mSensorModule = ::get_multi_hal_module_info(); 60 | } else { 61 | err = hw_get_module(SENSORS_HARDWARE_MODULE_ID, (hw_module_t const**)&mSensorModule); 62 | } 63 | if (mSensorModule == NULL) { 64 | err = UNKNOWN_ERROR; 65 | } 66 | 67 | if (err != OK) { 68 | LOG(ERROR) << "Couldn't load " << SENSORS_HARDWARE_MODULE_ID << " module (" 69 | << strerror(-err) << ")"; 70 | 71 | mInitCheck = err; 72 | return; 73 | } 74 | 75 | err = sensors_open_1(&mSensorModule->common, &mSensorDevice); 76 | 77 | if (err != OK) { 78 | LOG(ERROR) << "Couldn't open device for module " << SENSORS_HARDWARE_MODULE_ID << " (" 79 | << strerror(-err) << ")"; 80 | 81 | mInitCheck = err; 82 | return; 83 | } 84 | 85 | // Require all the old HAL APIs to be present except for injection, which 86 | // is considered optional. 87 | CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3); 88 | 89 | if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) { 90 | if (mSensorDevice->inject_sensor_data == nullptr) { 91 | LOG(ERROR) << "HAL specifies version 1.4, but does not implement inject_sensor_data()"; 92 | } 93 | if (mSensorModule->set_operation_mode == nullptr) { 94 | LOG(ERROR) << "HAL specifies version 1.4, but does not implement set_operation_mode()"; 95 | } 96 | } 97 | 98 | mInitCheck = OK; 99 | } 100 | 101 | status_t Sensors::initCheck() const { 102 | return mInitCheck; 103 | } 104 | 105 | Return Sensors::getSensorsList(getSensorsList_cb _hidl_cb) { 106 | hidl_vec out = getFixedUpSensorList(); 107 | 108 | _hidl_cb(out); 109 | 110 | return Void(); 111 | } 112 | 113 | int Sensors::getHalDeviceVersion() const { 114 | if (!mSensorDevice) { 115 | return -1; 116 | } 117 | 118 | return mSensorDevice->common.version; 119 | } 120 | 121 | Return Sensors::setOperationMode(OperationMode mode) { 122 | if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 || 123 | mSensorModule->set_operation_mode == nullptr) { 124 | return Result::INVALID_OPERATION; 125 | } 126 | return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode)); 127 | } 128 | 129 | Return Sensors::activate(int32_t sensor_handle, bool enabled) { 130 | return ResultFromStatus(mSensorDevice->activate( 131 | reinterpret_cast(mSensorDevice), sensor_handle, enabled)); 132 | } 133 | 134 | Return Sensors::poll(int32_t maxCount, poll_cb _hidl_cb) { 135 | hidl_vec out; 136 | hidl_vec dynamicSensorsAdded; 137 | 138 | std::unique_ptr data; 139 | int err = android::NO_ERROR; 140 | 141 | { // scope of reentry lock 142 | 143 | // This enforces a single client, meaning that a maximum of one client can call poll(). 144 | // If this function is re-entred, it means that we are stuck in a state that may prevent 145 | // the system from proceeding normally. 146 | // 147 | // Exit and let the system restart the sensor-hal-implementation hidl service. 148 | // 149 | // This function must not call _hidl_cb(...) or return until there is no risk of blocking. 150 | std::unique_lock lock(mPollLock, std::try_to_lock); 151 | if (!lock.owns_lock()) { 152 | // cannot get the lock, hidl service will go into deadlock if it is not restarted. 153 | // This is guaranteed to not trigger in passthrough mode. 154 | LOG(ERROR) 155 | << "ISensors::poll() re-entry. I do not know what to do except killing myself."; 156 | ::exit(-1); 157 | } 158 | 159 | if (maxCount <= 0) { 160 | err = android::BAD_VALUE; 161 | } else { 162 | int bufferSize = maxCount <= kPollMaxBufferSize ? maxCount : kPollMaxBufferSize; 163 | data.reset(new sensors_event_t[bufferSize]); 164 | err = mSensorDevice->poll(reinterpret_cast(mSensorDevice), 165 | data.get(), bufferSize); 166 | } 167 | } 168 | 169 | if (err < 0) { 170 | _hidl_cb(ResultFromStatus(err), out, dynamicSensorsAdded); 171 | return Void(); 172 | } 173 | 174 | const size_t count = (size_t)err; 175 | 176 | for (size_t i = 0; i < count; ++i) { 177 | if (data[i].type != SENSOR_TYPE_DYNAMIC_SENSOR_META) { 178 | continue; 179 | } 180 | 181 | const dynamic_sensor_meta_event_t* dyn = &data[i].dynamic_sensor_meta; 182 | 183 | if (!dyn->connected) { 184 | continue; 185 | } 186 | 187 | CHECK(dyn->sensor != nullptr); 188 | CHECK_EQ(dyn->sensor->handle, dyn->handle); 189 | 190 | SensorInfo info; 191 | convertFromSensor(*dyn->sensor, &info); 192 | 193 | size_t numDynamicSensors = dynamicSensorsAdded.size(); 194 | dynamicSensorsAdded.resize(numDynamicSensors + 1); 195 | dynamicSensorsAdded[numDynamicSensors] = info; 196 | } 197 | 198 | std::vector events; 199 | convertFromSensorEvents(err, data.get(), events, getFixedUpSensorList()); 200 | out = events; 201 | 202 | _hidl_cb(Result::OK, out, dynamicSensorsAdded); 203 | 204 | return Void(); 205 | } 206 | 207 | Return Sensors::batch(int32_t sensor_handle, int64_t sampling_period_ns, 208 | int64_t max_report_latency_ns) { 209 | return ResultFromStatus(mSensorDevice->batch(mSensorDevice, sensor_handle, 0, /*flags*/ 210 | sampling_period_ns, max_report_latency_ns)); 211 | } 212 | 213 | Return Sensors::flush(int32_t sensor_handle) { 214 | return ResultFromStatus(mSensorDevice->flush(mSensorDevice, sensor_handle)); 215 | } 216 | 217 | Return Sensors::injectSensorData(const Event& event) { 218 | if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4 || 219 | mSensorDevice->inject_sensor_data == nullptr) { 220 | return Result::INVALID_OPERATION; 221 | } 222 | 223 | sensors_event_t out; 224 | convertToSensorEvent(event, &out); 225 | 226 | return ResultFromStatus(mSensorDevice->inject_sensor_data(mSensorDevice, &out)); 227 | } 228 | 229 | Return Sensors::registerDirectChannel(const SharedMemInfo& mem, 230 | registerDirectChannel_cb _hidl_cb) { 231 | if (mSensorDevice->register_direct_channel == nullptr || 232 | mSensorDevice->config_direct_report == nullptr) { 233 | // HAL does not support 234 | _hidl_cb(Result::INVALID_OPERATION, -1); 235 | return Void(); 236 | } 237 | 238 | sensors_direct_mem_t m; 239 | if (!convertFromSharedMemInfo(mem, &m)) { 240 | _hidl_cb(Result::BAD_VALUE, -1); 241 | return Void(); 242 | } 243 | 244 | int err = mSensorDevice->register_direct_channel(mSensorDevice, &m, -1); 245 | 246 | if (err < 0) { 247 | _hidl_cb(ResultFromStatus(err), -1); 248 | } else { 249 | int32_t channelHandle = static_cast(err); 250 | _hidl_cb(Result::OK, channelHandle); 251 | } 252 | return Void(); 253 | } 254 | 255 | Return Sensors::unregisterDirectChannel(int32_t channelHandle) { 256 | if (mSensorDevice->register_direct_channel == nullptr || 257 | mSensorDevice->config_direct_report == nullptr) { 258 | // HAL does not support 259 | return Result::INVALID_OPERATION; 260 | } 261 | 262 | mSensorDevice->register_direct_channel(mSensorDevice, nullptr, channelHandle); 263 | 264 | return Result::OK; 265 | } 266 | 267 | Return Sensors::configDirectReport(int32_t sensorHandle, int32_t channelHandle, 268 | RateLevel rate, configDirectReport_cb _hidl_cb) { 269 | if (mSensorDevice->register_direct_channel == nullptr || 270 | mSensorDevice->config_direct_report == nullptr) { 271 | // HAL does not support 272 | _hidl_cb(Result::INVALID_OPERATION, -1); 273 | return Void(); 274 | } 275 | 276 | sensors_direct_cfg_t cfg = {.rate_level = convertFromRateLevel(rate)}; 277 | if (cfg.rate_level < 0) { 278 | _hidl_cb(Result::BAD_VALUE, -1); 279 | return Void(); 280 | } 281 | 282 | int err = mSensorDevice->config_direct_report(mSensorDevice, sensorHandle, channelHandle, &cfg); 283 | 284 | if (rate == RateLevel::STOP) { 285 | _hidl_cb(ResultFromStatus(err), -1); 286 | } else { 287 | _hidl_cb(err > 0 ? Result::OK : ResultFromStatus(err), err); 288 | } 289 | return Void(); 290 | } 291 | 292 | std::vector Sensors::getFixedUpSensorList() { 293 | std::vector sensors; 294 | 295 | sensor_t const* list; 296 | size_t count = mSensorModule->get_sensors_list(mSensorModule, &list); 297 | 298 | for (size_t i = 0; i < count; ++i) { 299 | const sensor_t* src = &list[i]; 300 | SensorInfo sensor; 301 | 302 | convertFromSensor(*src, &sensor); 303 | 304 | bool keep = patchXiaomiPickupSensor(sensor); 305 | if (keep) { 306 | sensors.push_back(sensor); 307 | } 308 | } 309 | 310 | return sensors; 311 | }; 312 | 313 | // static 314 | void Sensors::convertFromSensorEvents(size_t count, const sensors_event_t* srcArray, 315 | std::vector& dstVec, 316 | std::vector sensorsList) { 317 | for (size_t i = 0; i < count; ++i) { 318 | const sensors_event_t& src = srcArray[i]; 319 | Event event; 320 | 321 | convertFromSensorEvent(src, &event); 322 | 323 | SensorInfo* sensor = nullptr; 324 | for (auto& s : sensorsList) { 325 | if (s.sensorHandle == event.sensorHandle) { 326 | sensor = &s; 327 | break; 328 | } 329 | } 330 | 331 | if (sensor && sensor->type == SensorType::PICK_UP_GESTURE) { 332 | if (event.u.scalar != 1) { 333 | continue; 334 | } 335 | event.sensorType = SensorType::PICK_UP_GESTURE; 336 | } 337 | 338 | dstVec.push_back(event); 339 | } 340 | } 341 | 342 | ISensors* HIDL_FETCH_ISensors(const char* /* hal */) { 343 | Sensors* sensors = new Sensors; 344 | if (sensors->initCheck() != OK) { 345 | delete sensors; 346 | sensors = nullptr; 347 | 348 | return nullptr; 349 | } 350 | 351 | return sensors; 352 | } 353 | 354 | } // namespace implementation 355 | } // namespace V1_0 356 | } // namespace sensors 357 | } // namespace hardware 358 | } // namespace android 359 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/include/fingerprint.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 The Android Open Source Project 3 | * 2022 The LineageOS Project 4 | * 5 | * SPDX-License-Identifier: Apache-2.0 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | #define FINGERPRINT_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) 14 | #define FINGERPRINT_MODULE_API_VERSION_2_0 HARDWARE_MODULE_API_VERSION(2, 0) 15 | #define FINGERPRINT_MODULE_API_VERSION_2_1 HARDWARE_MODULE_API_VERSION(2, 1) 16 | #define FINGERPRINT_MODULE_API_VERSION_3_0 HARDWARE_MODULE_API_VERSION(3, 0) 17 | #define FINGERPRINT_HARDWARE_MODULE_ID "fingerprint" 18 | 19 | typedef enum fingerprint_msg_type { 20 | FINGERPRINT_ERROR = -1, 21 | FINGERPRINT_ACQUIRED = 1, 22 | FINGERPRINT_TEMPLATE_ENROLLING = 3, 23 | FINGERPRINT_TEMPLATE_REMOVED = 4, 24 | FINGERPRINT_AUTHENTICATED = 5, 25 | FINGERPRINT_TEMPLATE_ENUMERATING = 6, 26 | } fingerprint_msg_type_t; 27 | 28 | /* 29 | * Fingerprint errors are meant to tell the framework to terminate the current operation and ask 30 | * for the user to correct the situation. These will almost always result in messaging and user 31 | * interaction to correct the problem. 32 | * 33 | * For example, FINGERPRINT_ERROR_CANCELED should follow any acquisition message that results in 34 | * a situation where the current operation can't continue without user interaction. For example, 35 | * if the sensor is dirty during enrollment and no further enrollment progress can be made, 36 | * send FINGERPRINT_ACQUIRED_IMAGER_DIRTY followed by FINGERPRINT_ERROR_CANCELED. 37 | */ 38 | typedef enum fingerprint_error { 39 | FINGERPRINT_ERROR_HW_UNAVAILABLE = 1, /* The hardware has an error that can't be resolved. */ 40 | FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2, /* Bad data; operation can't continue */ 41 | FINGERPRINT_ERROR_TIMEOUT = 3, /* The operation has timed out waiting for user input. */ 42 | FINGERPRINT_ERROR_NO_SPACE = 4, /* No space available to store a template */ 43 | FINGERPRINT_ERROR_CANCELED = 5, /* The current operation can't proceed. See above. */ 44 | FINGERPRINT_ERROR_UNABLE_TO_REMOVE = 6, /* fingerprint with given id can't be removed */ 45 | FINGERPRINT_ERROR_LOCKOUT = 7, /* the fingerprint hardware is in lockout due to too many attempts */ 46 | FINGERPRINT_ERROR_VENDOR_BASE = 1000 /* vendor-specific error messages start here */ 47 | } fingerprint_error_t; 48 | 49 | /* 50 | * Fingerprint acquisition info is meant as feedback for the current operation. Anything but 51 | * FINGERPRINT_ACQUIRED_GOOD will be shown to the user as feedback on how to take action on the 52 | * current operation. For example, FINGERPRINT_ACQUIRED_IMAGER_DIRTY can be used to tell the user 53 | * to clean the sensor. If this will cause the current operation to fail, an additional 54 | * FINGERPRINT_ERROR_CANCELED can be sent to stop the operation in progress (e.g. enrollment). 55 | * In general, these messages will result in a "Try again" message. 56 | */ 57 | typedef enum fingerprint_acquired_info { 58 | FINGERPRINT_ACQUIRED_GOOD = 0, 59 | FINGERPRINT_ACQUIRED_PARTIAL = 1, /* sensor needs more data, i.e. longer swipe. */ 60 | FINGERPRINT_ACQUIRED_INSUFFICIENT = 2, /* image doesn't contain enough detail for recognition*/ 61 | FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3, /* sensor needs to be cleaned */ 62 | FINGERPRINT_ACQUIRED_TOO_SLOW = 4, /* mostly swipe-type sensors; not enough data collected */ 63 | FINGERPRINT_ACQUIRED_TOO_FAST = 5, /* for swipe and area sensors; tell user to slow down*/ 64 | FINGERPRINT_ACQUIRED_DETECTED = 6, /* when the finger is first detected. Used to optimize wakeup. 65 | Should be followed by one of the above messages */ 66 | FINGERPRINT_ACQUIRED_VENDOR_BASE = 1000 /* vendor-specific acquisition messages start here */ 67 | } fingerprint_acquired_info_t; 68 | 69 | typedef struct fingerprint_finger_id { 70 | uint32_t gid; 71 | uint32_t fid; 72 | } fingerprint_finger_id_t; 73 | 74 | typedef struct fingerprint_enroll { 75 | fingerprint_finger_id_t finger; 76 | /* samples_remaining goes from N (no data collected, but N scans needed) 77 | * to 0 (no more data is needed to build a template). */ 78 | uint32_t samples_remaining; 79 | uint64_t msg; /* Vendor specific message. Used for user guidance */ 80 | } fingerprint_enroll_t; 81 | 82 | typedef struct fingerprint_iterator { 83 | fingerprint_finger_id_t finger; 84 | uint32_t remaining_templates; 85 | } fingerprint_iterator_t; 86 | 87 | typedef fingerprint_iterator_t fingerprint_enumerated_t; 88 | typedef fingerprint_iterator_t fingerprint_removed_t; 89 | 90 | typedef struct fingerprint_acquired { 91 | fingerprint_acquired_info_t acquired_info; /* information about the image */ 92 | } fingerprint_acquired_t; 93 | 94 | typedef struct fingerprint_authenticated { 95 | fingerprint_finger_id_t finger; 96 | hw_auth_token_t hat; 97 | } fingerprint_authenticated_t; 98 | 99 | typedef struct fingerprint_msg { 100 | fingerprint_msg_type_t type; 101 | union { 102 | fingerprint_error_t error; 103 | fingerprint_enroll_t enroll; 104 | fingerprint_enumerated_t enumerated; 105 | fingerprint_removed_t removed; 106 | fingerprint_acquired_t acquired; 107 | fingerprint_authenticated_t authenticated; 108 | } data; 109 | } fingerprint_msg_t; 110 | 111 | /* Callback function type */ 112 | typedef void (*fingerprint_notify_t)(const fingerprint_msg_t *msg); 113 | 114 | /* Synchronous operation */ 115 | typedef struct fingerprint_device { 116 | /** 117 | * Common methods of the fingerprint device. This *must* be the first member 118 | * of fingerprint_device as users of this structure will cast a hw_device_t 119 | * to fingerprint_device pointer in contexts where it's known 120 | * the hw_device_t references a fingerprint_device. 121 | */ 122 | struct hw_device_t common; 123 | 124 | /* 125 | * Client provided callback function to receive notifications. 126 | * Do not set by hand, use the function above instead. 127 | */ 128 | fingerprint_notify_t notify; 129 | 130 | /* 131 | * Set notification callback: 132 | * Registers a user function that would receive notifications from the HAL 133 | * The call will block if the HAL state machine is in busy state until HAL 134 | * leaves the busy state. 135 | * 136 | * Function return: 0 if callback function is successfuly registered 137 | * or a negative number in case of error, generally from the errno.h set. 138 | */ 139 | int (*set_notify)(struct fingerprint_device *dev, fingerprint_notify_t notify); 140 | 141 | /* 142 | * Fingerprint pre-enroll enroll request: 143 | * Generates a unique token to upper layers to indicate the start of an enrollment transaction. 144 | * This token will be wrapped by security for verification and passed to enroll() for 145 | * verification before enrollment will be allowed. This is to ensure adding a new fingerprint 146 | * template was preceded by some kind of credential confirmation (e.g. device password). 147 | * 148 | * Function return: 0 if function failed 149 | * otherwise, a uint64_t of token 150 | */ 151 | uint64_t (*pre_enroll)(struct fingerprint_device *dev); 152 | 153 | /* 154 | * Fingerprint enroll request: 155 | * Switches the HAL state machine to collect and store a new fingerprint 156 | * template. Switches back as soon as enroll is complete 157 | * (fingerprint_msg.type == FINGERPRINT_TEMPLATE_ENROLLING && 158 | * fingerprint_msg.data.enroll.samples_remaining == 0) 159 | * or after timeout_sec seconds. 160 | * The fingerprint template will be assigned to the group gid. User has a choice 161 | * to supply the gid or set it to 0 in which case a unique group id will be generated. 162 | * 163 | * Function return: 0 if enrollment process can be successfully started 164 | * or a negative number in case of error, generally from the errno.h set. 165 | * A notify() function may be called indicating the error condition. 166 | */ 167 | int (*enroll)(struct fingerprint_device *dev, const hw_auth_token_t *hat, 168 | uint32_t gid, uint32_t timeout_sec); 169 | 170 | /* 171 | * Finishes the enroll operation and invalidates the pre_enroll() generated challenge. 172 | * This will be called at the end of a multi-finger enrollment session to indicate 173 | * that no more fingers will be added. 174 | * 175 | * Function return: 0 if the request is accepted 176 | * or a negative number in case of error, generally from the errno.h set. 177 | */ 178 | int (*post_enroll)(struct fingerprint_device *dev); 179 | 180 | /* 181 | * get_authenticator_id: 182 | * Returns a token associated with the current fingerprint set. This value will 183 | * change whenever a new fingerprint is enrolled, thus creating a new fingerprint 184 | * set. 185 | * 186 | * Function return: current authenticator id or 0 if function failed. 187 | */ 188 | uint64_t (*get_authenticator_id)(struct fingerprint_device *dev); 189 | 190 | /* 191 | * Cancel pending enroll or authenticate, sending FINGERPRINT_ERROR_CANCELED 192 | * to all running clients. Switches the HAL state machine back to the idle state. 193 | * Unlike enroll_done() doesn't invalidate the pre_enroll() challenge. 194 | * 195 | * Function return: 0 if cancel request is accepted 196 | * or a negative number in case of error, generally from the errno.h set. 197 | */ 198 | int (*cancel)(struct fingerprint_device *dev); 199 | 200 | /* 201 | * Enumerate all the fingerprint templates found in the directory set by 202 | * set_active_group() 203 | * For each template found a notify() will be called with: 204 | * fingerprint_msg.type == FINGERPRINT_TEMPLATE_ENUMERATED 205 | * fingerprint_msg.data.enumerated.finger indicating a template id 206 | * fingerprint_msg.data.enumerated.remaining_templates indicating how many more 207 | * enumeration messages to expect. 208 | * Note: If there are no fingerprints, then this should return 0 and the first fingerprint 209 | * enumerated should have fingerid=0 and remaining=0 210 | * Function return: 0 if enumerate request is accepted 211 | * or a negative number in case of error, generally from the errno.h set. 212 | */ 213 | int (*enumerate)(struct fingerprint_device *dev); 214 | 215 | /* 216 | * Fingerprint remove request: 217 | * Deletes a fingerprint template. 218 | * Works only within the path set by set_active_group(). 219 | * The fid parameter can be used as a widcard: 220 | * * fid == 0 -- delete all the templates in the group. 221 | * * fid != 0 -- delete this specific template from the group. 222 | * For each template found a notify() will be called with: 223 | * fingerprint_msg.type == FINGERPRINT_TEMPLATE_REMOVED 224 | * fingerprint_msg.data.removed.finger indicating a template id deleted 225 | * fingerprint_msg.data.removed.remaining_templates indicating how many more 226 | * templates will be deleted by this operation. 227 | * 228 | * Function return: 0 if fingerprint template(s) can be successfully deleted 229 | * or a negative number in case of error, generally from the errno.h set. 230 | */ 231 | int (*remove)(struct fingerprint_device *dev, uint32_t gid, uint32_t fid); 232 | 233 | /* 234 | * Restricts the HAL operation to a set of fingerprints belonging to a 235 | * group provided. 236 | * The caller must provide a path to a storage location within the user's 237 | * data directory. 238 | * 239 | * Function return: 0 on success 240 | * or a negative number in case of error, generally from the errno.h set. 241 | */ 242 | int (*set_active_group)(struct fingerprint_device *dev, uint32_t gid, 243 | const char *store_path); 244 | 245 | /* 246 | * Authenticates an operation identifed by operation_id 247 | * 248 | * Function return: 0 on success 249 | * or a negative number in case of error, generally from the errno.h set. 250 | */ 251 | int (*authenticate)(struct fingerprint_device *dev, uint64_t operation_id, uint32_t gid); 252 | 253 | /* 254 | * Xiaomi fingerprint extension command. 255 | */ 256 | int (*extCmd)(struct fingerprint_device* dev, int32_t cmd, int32_t param); 257 | 258 | /* Reserved for backward binary compatibility */ 259 | void *reserved[4]; 260 | } fingerprint_device_t; 261 | 262 | typedef struct fingerprint_module { 263 | /** 264 | * Common methods of the fingerprint module. This *must* be the first member 265 | * of fingerprint_module as users of this structure will cast a hw_module_t 266 | * to fingerprint_module pointer in contexts where it's known 267 | * the hw_module_t references a fingerprint_module. 268 | */ 269 | struct hw_module_t common; 270 | } fingerprint_module_t; 271 | -------------------------------------------------------------------------------- /hidl/sensors/1.0/convert.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #include "convert.h" 18 | 19 | #include 20 | 21 | namespace android { 22 | namespace hardware { 23 | namespace sensors { 24 | namespace V1_0 { 25 | namespace implementation { 26 | 27 | void convertFromSensor(const sensor_t& src, SensorInfo* dst) { 28 | dst->name = src.name; 29 | dst->vendor = src.vendor; 30 | dst->version = src.version; 31 | dst->sensorHandle = src.handle; 32 | dst->type = (SensorType)src.type; 33 | dst->maxRange = src.maxRange; 34 | dst->resolution = src.resolution; 35 | dst->power = src.power; 36 | dst->minDelay = src.minDelay; 37 | dst->fifoReservedEventCount = src.fifoReservedEventCount; 38 | dst->fifoMaxEventCount = src.fifoMaxEventCount; 39 | dst->typeAsString = src.stringType; 40 | dst->requiredPermission = src.requiredPermission; 41 | dst->maxDelay = src.maxDelay; 42 | dst->flags = src.flags; 43 | } 44 | 45 | void convertToSensor(const ::android::hardware::sensors::V1_0::SensorInfo& src, sensor_t* dst) { 46 | dst->name = strdup(src.name.c_str()); 47 | dst->vendor = strdup(src.vendor.c_str()); 48 | dst->version = src.version; 49 | dst->handle = src.sensorHandle; 50 | dst->type = (int)src.type; 51 | dst->maxRange = src.maxRange; 52 | dst->resolution = src.resolution; 53 | dst->power = src.power; 54 | dst->minDelay = src.minDelay; 55 | dst->fifoReservedEventCount = src.fifoReservedEventCount; 56 | dst->fifoMaxEventCount = src.fifoMaxEventCount; 57 | dst->stringType = strdup(src.typeAsString.c_str()); 58 | dst->requiredPermission = strdup(src.requiredPermission.c_str()); 59 | dst->maxDelay = src.maxDelay; 60 | dst->flags = src.flags; 61 | dst->reserved[0] = dst->reserved[1] = 0; 62 | } 63 | 64 | void convertFromSensorEvent(const sensors_event_t& src, Event* dst) { 65 | typedef ::android::hardware::sensors::V1_0::SensorType SensorType; 66 | typedef ::android::hardware::sensors::V1_0::MetaDataEventType MetaDataEventType; 67 | 68 | *dst = { 69 | .timestamp = src.timestamp, 70 | .sensorHandle = src.sensor, 71 | .sensorType = (SensorType)src.type, 72 | }; 73 | 74 | switch (dst->sensorType) { 75 | case SensorType::META_DATA: { 76 | dst->u.meta.what = (MetaDataEventType)src.meta_data.what; 77 | // Legacy HALs contain the handle reference in the meta data field. 78 | // Copy that over to the handle of the event. In legacy HALs this 79 | // field was expected to be 0. 80 | dst->sensorHandle = src.meta_data.sensor; 81 | break; 82 | } 83 | 84 | case SensorType::ACCELEROMETER: 85 | case SensorType::MAGNETIC_FIELD: 86 | case SensorType::ORIENTATION: 87 | case SensorType::GYROSCOPE: 88 | case SensorType::GRAVITY: 89 | case SensorType::LINEAR_ACCELERATION: { 90 | dst->u.vec3.x = src.acceleration.x; 91 | dst->u.vec3.y = src.acceleration.y; 92 | dst->u.vec3.z = src.acceleration.z; 93 | dst->u.vec3.status = (SensorStatus)src.acceleration.status; 94 | break; 95 | } 96 | 97 | case SensorType::GAME_ROTATION_VECTOR: { 98 | dst->u.vec4.x = src.data[0]; 99 | dst->u.vec4.y = src.data[1]; 100 | dst->u.vec4.z = src.data[2]; 101 | dst->u.vec4.w = src.data[3]; 102 | break; 103 | } 104 | 105 | case SensorType::ROTATION_VECTOR: 106 | case SensorType::GEOMAGNETIC_ROTATION_VECTOR: { 107 | dst->u.data[0] = src.data[0]; 108 | dst->u.data[1] = src.data[1]; 109 | dst->u.data[2] = src.data[2]; 110 | dst->u.data[3] = src.data[3]; 111 | dst->u.data[4] = src.data[4]; 112 | break; 113 | } 114 | 115 | case SensorType::MAGNETIC_FIELD_UNCALIBRATED: 116 | case SensorType::GYROSCOPE_UNCALIBRATED: 117 | case SensorType::ACCELEROMETER_UNCALIBRATED: { 118 | dst->u.uncal.x = src.uncalibrated_gyro.x_uncalib; 119 | dst->u.uncal.y = src.uncalibrated_gyro.y_uncalib; 120 | dst->u.uncal.z = src.uncalibrated_gyro.z_uncalib; 121 | dst->u.uncal.x_bias = src.uncalibrated_gyro.x_bias; 122 | dst->u.uncal.y_bias = src.uncalibrated_gyro.y_bias; 123 | dst->u.uncal.z_bias = src.uncalibrated_gyro.z_bias; 124 | break; 125 | } 126 | 127 | case SensorType::DEVICE_ORIENTATION: 128 | case SensorType::LIGHT: 129 | case SensorType::PRESSURE: 130 | case SensorType::TEMPERATURE: 131 | case SensorType::PROXIMITY: 132 | case SensorType::RELATIVE_HUMIDITY: 133 | case SensorType::AMBIENT_TEMPERATURE: 134 | case SensorType::SIGNIFICANT_MOTION: 135 | case SensorType::STEP_DETECTOR: 136 | case SensorType::TILT_DETECTOR: 137 | case SensorType::WAKE_GESTURE: 138 | case SensorType::GLANCE_GESTURE: 139 | case SensorType::PICK_UP_GESTURE: 140 | case SensorType::WRIST_TILT_GESTURE: 141 | case SensorType::STATIONARY_DETECT: 142 | case SensorType::MOTION_DETECT: 143 | case SensorType::HEART_BEAT: 144 | case SensorType::LOW_LATENCY_OFFBODY_DETECT: { 145 | dst->u.scalar = src.data[0]; 146 | break; 147 | } 148 | 149 | case SensorType::STEP_COUNTER: { 150 | dst->u.stepCount = src.u64.step_counter; 151 | break; 152 | } 153 | 154 | case SensorType::HEART_RATE: { 155 | dst->u.heartRate.bpm = src.heart_rate.bpm; 156 | dst->u.heartRate.status = (SensorStatus)src.heart_rate.status; 157 | break; 158 | } 159 | 160 | case SensorType::POSE_6DOF: { // 15 floats 161 | for (size_t i = 0; i < 15; ++i) { 162 | dst->u.pose6DOF[i] = src.data[i]; 163 | } 164 | break; 165 | } 166 | 167 | case SensorType::DYNAMIC_SENSOR_META: { 168 | dst->u.dynamic.connected = src.dynamic_sensor_meta.connected; 169 | dst->u.dynamic.sensorHandle = src.dynamic_sensor_meta.handle; 170 | 171 | memcpy(dst->u.dynamic.uuid.data(), src.dynamic_sensor_meta.uuid, 16); 172 | 173 | break; 174 | } 175 | 176 | case SensorType::ADDITIONAL_INFO: { 177 | ::android::hardware::sensors::V1_0::AdditionalInfo* dstInfo = &dst->u.additional; 178 | 179 | const additional_info_event_t& srcInfo = src.additional_info; 180 | 181 | dstInfo->type = (::android::hardware::sensors::V1_0::AdditionalInfoType)srcInfo.type; 182 | 183 | dstInfo->serial = srcInfo.serial; 184 | 185 | CHECK_EQ(sizeof(dstInfo->u), sizeof(srcInfo.data_int32)); 186 | memcpy(&dstInfo->u, srcInfo.data_int32, sizeof(srcInfo.data_int32)); 187 | break; 188 | } 189 | 190 | default: { 191 | memcpy(dst->u.data.data(), src.data, 16 * sizeof(float)); 192 | break; 193 | } 194 | } 195 | } 196 | 197 | void convertToSensorEvent(const Event& src, sensors_event_t* dst) { 198 | *dst = {.version = sizeof(sensors_event_t), 199 | .sensor = src.sensorHandle, 200 | .type = (int32_t)src.sensorType, 201 | .reserved0 = 0, 202 | .timestamp = src.timestamp}; 203 | 204 | switch (src.sensorType) { 205 | case SensorType::META_DATA: { 206 | // Legacy HALs expect the handle reference in the meta data field. 207 | // Copy it over from the handle of the event. 208 | dst->meta_data.what = (int32_t)src.u.meta.what; 209 | dst->meta_data.sensor = src.sensorHandle; 210 | // Set the sensor handle to 0 to maintain compatibility. 211 | dst->sensor = 0; 212 | break; 213 | } 214 | 215 | case SensorType::ACCELEROMETER: 216 | case SensorType::MAGNETIC_FIELD: 217 | case SensorType::ORIENTATION: 218 | case SensorType::GYROSCOPE: 219 | case SensorType::GRAVITY: 220 | case SensorType::LINEAR_ACCELERATION: { 221 | dst->acceleration.x = src.u.vec3.x; 222 | dst->acceleration.y = src.u.vec3.y; 223 | dst->acceleration.z = src.u.vec3.z; 224 | dst->acceleration.status = (int8_t)src.u.vec3.status; 225 | break; 226 | } 227 | 228 | case SensorType::GAME_ROTATION_VECTOR: { 229 | dst->data[0] = src.u.vec4.x; 230 | dst->data[1] = src.u.vec4.y; 231 | dst->data[2] = src.u.vec4.z; 232 | dst->data[3] = src.u.vec4.w; 233 | break; 234 | } 235 | 236 | case SensorType::ROTATION_VECTOR: 237 | case SensorType::GEOMAGNETIC_ROTATION_VECTOR: { 238 | dst->data[0] = src.u.data[0]; 239 | dst->data[1] = src.u.data[1]; 240 | dst->data[2] = src.u.data[2]; 241 | dst->data[3] = src.u.data[3]; 242 | dst->data[4] = src.u.data[4]; 243 | break; 244 | } 245 | 246 | case SensorType::MAGNETIC_FIELD_UNCALIBRATED: 247 | case SensorType::GYROSCOPE_UNCALIBRATED: 248 | case SensorType::ACCELEROMETER_UNCALIBRATED: { 249 | dst->uncalibrated_gyro.x_uncalib = src.u.uncal.x; 250 | dst->uncalibrated_gyro.y_uncalib = src.u.uncal.y; 251 | dst->uncalibrated_gyro.z_uncalib = src.u.uncal.z; 252 | dst->uncalibrated_gyro.x_bias = src.u.uncal.x_bias; 253 | dst->uncalibrated_gyro.y_bias = src.u.uncal.y_bias; 254 | dst->uncalibrated_gyro.z_bias = src.u.uncal.z_bias; 255 | break; 256 | } 257 | 258 | case SensorType::DEVICE_ORIENTATION: 259 | case SensorType::LIGHT: 260 | case SensorType::PRESSURE: 261 | case SensorType::TEMPERATURE: 262 | case SensorType::PROXIMITY: 263 | case SensorType::RELATIVE_HUMIDITY: 264 | case SensorType::AMBIENT_TEMPERATURE: 265 | case SensorType::SIGNIFICANT_MOTION: 266 | case SensorType::STEP_DETECTOR: 267 | case SensorType::TILT_DETECTOR: 268 | case SensorType::WAKE_GESTURE: 269 | case SensorType::GLANCE_GESTURE: 270 | case SensorType::PICK_UP_GESTURE: 271 | case SensorType::WRIST_TILT_GESTURE: 272 | case SensorType::STATIONARY_DETECT: 273 | case SensorType::MOTION_DETECT: 274 | case SensorType::HEART_BEAT: 275 | case SensorType::LOW_LATENCY_OFFBODY_DETECT: { 276 | dst->data[0] = src.u.scalar; 277 | break; 278 | } 279 | 280 | case SensorType::STEP_COUNTER: { 281 | dst->u64.step_counter = src.u.stepCount; 282 | break; 283 | } 284 | 285 | case SensorType::HEART_RATE: { 286 | dst->heart_rate.bpm = src.u.heartRate.bpm; 287 | dst->heart_rate.status = (int8_t)src.u.heartRate.status; 288 | break; 289 | } 290 | 291 | case SensorType::POSE_6DOF: { // 15 floats 292 | for (size_t i = 0; i < 15; ++i) { 293 | dst->data[i] = src.u.pose6DOF[i]; 294 | } 295 | break; 296 | } 297 | 298 | case SensorType::DYNAMIC_SENSOR_META: { 299 | dst->dynamic_sensor_meta.connected = src.u.dynamic.connected; 300 | dst->dynamic_sensor_meta.handle = src.u.dynamic.sensorHandle; 301 | dst->dynamic_sensor_meta.sensor = NULL; // to be filled in later 302 | 303 | memcpy(dst->dynamic_sensor_meta.uuid, src.u.dynamic.uuid.data(), 16); 304 | 305 | break; 306 | } 307 | 308 | case SensorType::ADDITIONAL_INFO: { 309 | const ::android::hardware::sensors::V1_0::AdditionalInfo& srcInfo = src.u.additional; 310 | 311 | additional_info_event_t* dstInfo = &dst->additional_info; 312 | dstInfo->type = (int32_t)srcInfo.type; 313 | dstInfo->serial = srcInfo.serial; 314 | 315 | CHECK_EQ(sizeof(srcInfo.u), sizeof(dstInfo->data_int32)); 316 | 317 | memcpy(dstInfo->data_int32, &srcInfo.u, sizeof(dstInfo->data_int32)); 318 | 319 | break; 320 | } 321 | 322 | default: { 323 | memcpy(dst->data, src.u.data.data(), 16 * sizeof(float)); 324 | break; 325 | } 326 | } 327 | } 328 | 329 | bool convertFromSharedMemInfo(const SharedMemInfo& memIn, sensors_direct_mem_t* memOut) { 330 | if (memOut == nullptr) { 331 | return false; 332 | } 333 | 334 | switch (memIn.type) { 335 | case SharedMemType::ASHMEM: 336 | memOut->type = SENSOR_DIRECT_MEM_TYPE_ASHMEM; 337 | break; 338 | case SharedMemType::GRALLOC: 339 | memOut->type = SENSOR_DIRECT_MEM_TYPE_GRALLOC; 340 | break; 341 | default: 342 | return false; 343 | } 344 | 345 | switch (memIn.format) { 346 | case SharedMemFormat::SENSORS_EVENT: 347 | memOut->format = SENSOR_DIRECT_FMT_SENSORS_EVENT; 348 | break; 349 | default: 350 | return false; 351 | } 352 | 353 | if (memIn.memoryHandle == nullptr) { 354 | return false; 355 | } 356 | 357 | memOut->size = memIn.size; 358 | memOut->handle = memIn.memoryHandle; 359 | return true; 360 | } 361 | 362 | int convertFromRateLevel(RateLevel rate) { 363 | switch (rate) { 364 | case RateLevel::STOP: 365 | return SENSOR_DIRECT_RATE_STOP; 366 | case RateLevel::NORMAL: 367 | return SENSOR_DIRECT_RATE_NORMAL; 368 | case RateLevel::FAST: 369 | return SENSOR_DIRECT_RATE_FAST; 370 | case RateLevel::VERY_FAST: 371 | return SENSOR_DIRECT_RATE_VERY_FAST; 372 | default: 373 | return -1; 374 | } 375 | } 376 | 377 | bool patchXiaomiPickupSensor(SensorInfo& sensor) { 378 | if (sensor.typeAsString != "xiaomi.sensor.pickup") { 379 | return true; 380 | } 381 | 382 | /* 383 | * Implement only the wake-up version of this sensor. 384 | */ 385 | if (!(sensor.flags & SensorFlagBits::WAKE_UP)) { 386 | return false; 387 | } 388 | 389 | sensor.type = SensorType::PICK_UP_GESTURE; 390 | sensor.typeAsString = SENSOR_STRING_TYPE_PICK_UP_GESTURE; 391 | sensor.maxRange = 1; 392 | 393 | return true; 394 | } 395 | 396 | } // namespace implementation 397 | } // namespace V1_0 398 | } // namespace sensors 399 | } // namespace hardware 400 | } // namespace android 401 | -------------------------------------------------------------------------------- /hidl/biometrics/fingerprint/BiometricsFingerprint.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 2022 The LineageOS Project 4 | * 5 | * SPDX-License-Identifier: Apache-2.0 6 | */ 7 | 8 | #define LOG_TAG "android.hardware.biometrics.fingerprint@2.3-service.xiaomi" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include "BiometricsFingerprint.h" 15 | #include "UdfpsHandler.h" 16 | 17 | #include 18 | #include 19 | #include 20 | 21 | namespace { 22 | 23 | typedef struct fingerprint_hal { 24 | const char* class_name; 25 | const bool is_udfps; 26 | } fingerprint_hal_t; 27 | 28 | static const fingerprint_hal_t kModules[] = { 29 | {"fpc", false}, {"fpc_fod", true}, {"goodix", false}, {"goodix_fod", true}, 30 | {"goodix_fod6", true}, {"silead", false}, {"syna", true}, 31 | }; 32 | 33 | } // anonymous namespace 34 | 35 | namespace android { 36 | namespace hardware { 37 | namespace biometrics { 38 | namespace fingerprint { 39 | namespace V2_3 { 40 | namespace implementation { 41 | 42 | // Supported fingerprint HAL version 43 | static const uint16_t kVersion = HARDWARE_MODULE_API_VERSION(2, 1); 44 | 45 | using RequestStatus = android::hardware::biometrics::fingerprint::V2_1::RequestStatus; 46 | 47 | using ::android::base::SetProperty; 48 | using ::android::base::StartsWith; 49 | 50 | BiometricsFingerprint* BiometricsFingerprint::sInstance = nullptr; 51 | 52 | BiometricsFingerprint::BiometricsFingerprint() 53 | : mClientCallback(nullptr), 54 | mDevice(nullptr), 55 | mUdfpsHandlerFactory(nullptr), 56 | mUdfpsHandler(nullptr) { 57 | sInstance = this; // keep track of the most recent instance 58 | for (auto& [class_name, is_udfps] : kModules) { 59 | mDevice = openHal(class_name); 60 | if (!mDevice) { 61 | ALOGE("Can't open HAL module, class %s", class_name); 62 | continue; 63 | } 64 | 65 | ALOGI("Opened fingerprint HAL, class %s", class_name); 66 | mIsUdfps = is_udfps; 67 | SetProperty("persist.vendor.sys.fp.vendor", class_name); 68 | break; 69 | } 70 | if (!mDevice) { 71 | ALOGE("Can't open any HAL module"); 72 | SetProperty("persist.vendor.sys.fp.vendor", "none"); 73 | } 74 | 75 | if (mIsUdfps) { 76 | SetProperty("ro.hardware.fp.udfps", "true"); 77 | 78 | mUdfpsHandlerFactory = getUdfpsHandlerFactory(); 79 | if (!mUdfpsHandlerFactory) { 80 | ALOGE("Can't get UdfpsHandlerFactory"); 81 | } else { 82 | mUdfpsHandler = mUdfpsHandlerFactory->create(); 83 | if (!mUdfpsHandler) { 84 | ALOGE("Can't create UdfpsHandler"); 85 | } else { 86 | mUdfpsHandler->init(mDevice); 87 | } 88 | } 89 | } 90 | } 91 | 92 | BiometricsFingerprint::~BiometricsFingerprint() { 93 | ALOGV("~BiometricsFingerprint()"); 94 | if (mUdfpsHandler) { 95 | mUdfpsHandlerFactory->destroy(mUdfpsHandler); 96 | } 97 | if (mDevice == nullptr) { 98 | ALOGE("No valid device"); 99 | return; 100 | } 101 | int err; 102 | if (0 != (err = mDevice->common.close(reinterpret_cast(mDevice)))) { 103 | ALOGE("Can't close fingerprint module, error: %d", err); 104 | return; 105 | } 106 | mDevice = nullptr; 107 | } 108 | 109 | Return BiometricsFingerprint::ErrorFilter(int32_t error) { 110 | switch (error) { 111 | case 0: 112 | return RequestStatus::SYS_OK; 113 | case -2: 114 | return RequestStatus::SYS_ENOENT; 115 | case -4: 116 | return RequestStatus::SYS_EINTR; 117 | case -5: 118 | return RequestStatus::SYS_EIO; 119 | case -11: 120 | return RequestStatus::SYS_EAGAIN; 121 | case -12: 122 | return RequestStatus::SYS_ENOMEM; 123 | case -13: 124 | return RequestStatus::SYS_EACCES; 125 | case -14: 126 | return RequestStatus::SYS_EFAULT; 127 | case -16: 128 | return RequestStatus::SYS_EBUSY; 129 | case -22: 130 | return RequestStatus::SYS_EINVAL; 131 | case -28: 132 | return RequestStatus::SYS_ENOSPC; 133 | case -110: 134 | return RequestStatus::SYS_ETIMEDOUT; 135 | default: 136 | ALOGE("An unknown error returned from fingerprint vendor library: %d", error); 137 | return RequestStatus::SYS_UNKNOWN; 138 | } 139 | } 140 | 141 | // Translate from errors returned by traditional HAL (see fingerprint.h) to 142 | // HIDL-compliant FingerprintError. 143 | FingerprintError BiometricsFingerprint::VendorErrorFilter(int32_t error, int32_t* vendorCode) { 144 | *vendorCode = 0; 145 | switch (error) { 146 | case FINGERPRINT_ERROR_HW_UNAVAILABLE: 147 | return FingerprintError::ERROR_HW_UNAVAILABLE; 148 | case FINGERPRINT_ERROR_UNABLE_TO_PROCESS: 149 | return FingerprintError::ERROR_UNABLE_TO_PROCESS; 150 | case FINGERPRINT_ERROR_TIMEOUT: 151 | return FingerprintError::ERROR_TIMEOUT; 152 | case FINGERPRINT_ERROR_NO_SPACE: 153 | return FingerprintError::ERROR_NO_SPACE; 154 | case FINGERPRINT_ERROR_CANCELED: 155 | return FingerprintError::ERROR_CANCELED; 156 | case FINGERPRINT_ERROR_UNABLE_TO_REMOVE: 157 | return FingerprintError::ERROR_UNABLE_TO_REMOVE; 158 | case FINGERPRINT_ERROR_LOCKOUT: 159 | return FingerprintError::ERROR_LOCKOUT; 160 | default: 161 | if (error >= FINGERPRINT_ERROR_VENDOR_BASE) { 162 | // vendor specific code. 163 | *vendorCode = error - FINGERPRINT_ERROR_VENDOR_BASE; 164 | return FingerprintError::ERROR_VENDOR; 165 | } 166 | } 167 | ALOGE("Unknown error from fingerprint vendor library: %d", error); 168 | return FingerprintError::ERROR_UNABLE_TO_PROCESS; 169 | } 170 | 171 | // Translate acquired messages returned by traditional HAL (see fingerprint.h) 172 | // to HIDL-compliant FingerprintAcquiredInfo. 173 | FingerprintAcquiredInfo BiometricsFingerprint::VendorAcquiredFilter(int32_t info, 174 | int32_t* vendorCode) { 175 | *vendorCode = 0; 176 | switch (info) { 177 | case FINGERPRINT_ACQUIRED_GOOD: 178 | return FingerprintAcquiredInfo::ACQUIRED_GOOD; 179 | case FINGERPRINT_ACQUIRED_PARTIAL: 180 | return FingerprintAcquiredInfo::ACQUIRED_PARTIAL; 181 | case FINGERPRINT_ACQUIRED_INSUFFICIENT: 182 | return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; 183 | case FINGERPRINT_ACQUIRED_IMAGER_DIRTY: 184 | return FingerprintAcquiredInfo::ACQUIRED_IMAGER_DIRTY; 185 | case FINGERPRINT_ACQUIRED_TOO_SLOW: 186 | return FingerprintAcquiredInfo::ACQUIRED_TOO_SLOW; 187 | case FINGERPRINT_ACQUIRED_TOO_FAST: 188 | return FingerprintAcquiredInfo::ACQUIRED_TOO_FAST; 189 | default: 190 | if (info >= FINGERPRINT_ACQUIRED_VENDOR_BASE) { 191 | // vendor specific code. 192 | *vendorCode = info - FINGERPRINT_ACQUIRED_VENDOR_BASE; 193 | return FingerprintAcquiredInfo::ACQUIRED_VENDOR; 194 | } 195 | } 196 | ALOGE("Unknown acquiredmsg from fingerprint vendor library: %d", info); 197 | return FingerprintAcquiredInfo::ACQUIRED_INSUFFICIENT; 198 | } 199 | 200 | Return BiometricsFingerprint::setNotify( 201 | const sp& clientCallback) { 202 | std::lock_guard lock(mClientCallbackMutex); 203 | mClientCallback = clientCallback; 204 | // This is here because HAL 2.1 doesn't have a way to propagate a 205 | // unique token for its driver. Subsequent versions should send a unique 206 | // token for each call to setNotify(). This is fine as long as there's only 207 | // one fingerprint device on the platform. 208 | return reinterpret_cast(mDevice); 209 | } 210 | 211 | Return BiometricsFingerprint::preEnroll() { 212 | return mDevice->pre_enroll(mDevice); 213 | } 214 | 215 | Return BiometricsFingerprint::enroll(const hidl_array& hat, 216 | uint32_t gid, uint32_t timeoutSec) { 217 | const hw_auth_token_t* authToken = reinterpret_cast(hat.data()); 218 | return ErrorFilter(mDevice->enroll(mDevice, authToken, gid, timeoutSec)); 219 | } 220 | 221 | Return BiometricsFingerprint::postEnroll() { 222 | return ErrorFilter(mDevice->post_enroll(mDevice)); 223 | } 224 | 225 | Return BiometricsFingerprint::getAuthenticatorId() { 226 | return mDevice->get_authenticator_id(mDevice); 227 | } 228 | 229 | Return BiometricsFingerprint::cancel() { 230 | if (mUdfpsHandler) { 231 | mUdfpsHandler->cancel(); 232 | } 233 | return ErrorFilter(mDevice->cancel(mDevice)); 234 | } 235 | 236 | Return BiometricsFingerprint::enumerate() { 237 | return ErrorFilter(mDevice->enumerate(mDevice)); 238 | } 239 | 240 | Return BiometricsFingerprint::remove(uint32_t gid, uint32_t fid) { 241 | return ErrorFilter(mDevice->remove(mDevice, gid, fid)); 242 | } 243 | 244 | Return BiometricsFingerprint::setActiveGroup(uint32_t gid, 245 | const hidl_string& storePath) { 246 | if (storePath.size() >= PATH_MAX || storePath.size() <= 0) { 247 | ALOGE("Bad path length: %zd", storePath.size()); 248 | return RequestStatus::SYS_EINVAL; 249 | } 250 | std::string mutableStorePath = storePath; 251 | if (StartsWith(mutableStorePath, "/data/system/users/")) { 252 | mutableStorePath = "/data/vendor_de/"; 253 | mutableStorePath += 254 | static_cast(storePath).substr(strlen("/data/system/users/")); 255 | } 256 | if (access(mutableStorePath.c_str(), W_OK)) { 257 | return RequestStatus::SYS_EINVAL; 258 | } 259 | 260 | return ErrorFilter(mDevice->set_active_group(mDevice, gid, mutableStorePath.c_str())); 261 | } 262 | 263 | Return BiometricsFingerprint::authenticate(uint64_t operationId, uint32_t gid) { 264 | return ErrorFilter(mDevice->authenticate(mDevice, operationId, gid)); 265 | } 266 | 267 | Return BiometricsFingerprint::isUdfps(uint32_t /*sensorId*/) { 268 | return mIsUdfps; 269 | } 270 | 271 | Return BiometricsFingerprint::onFingerDown(uint32_t x, uint32_t y, float minor, float major) { 272 | if (mUdfpsHandler) { 273 | mUdfpsHandler->onFingerDown(x, y, minor, major); 274 | } 275 | 276 | return Void(); 277 | } 278 | 279 | Return BiometricsFingerprint::onFingerUp() { 280 | if (mUdfpsHandler) { 281 | mUdfpsHandler->onFingerUp(); 282 | } 283 | 284 | return Void(); 285 | } 286 | 287 | IBiometricsFingerprint* BiometricsFingerprint::getInstance() { 288 | if (!sInstance) { 289 | sInstance = new BiometricsFingerprint(); 290 | } 291 | return sInstance; 292 | } 293 | 294 | fingerprint_device_t* BiometricsFingerprint::openHal(const char* class_name) { 295 | int err; 296 | const hw_module_t* hw_mdl = nullptr; 297 | ALOGD("Opening fingerprint hal library..."); 298 | if (0 != (err = hw_get_module_by_class(FINGERPRINT_HARDWARE_MODULE_ID, class_name, &hw_mdl))) { 299 | ALOGE("Can't open fingerprint HW Module, error: %d", err); 300 | return nullptr; 301 | } 302 | 303 | if (hw_mdl == nullptr) { 304 | ALOGE("No valid fingerprint module"); 305 | return nullptr; 306 | } 307 | 308 | fingerprint_module_t const* module = reinterpret_cast(hw_mdl); 309 | if (module->common.methods->open == nullptr) { 310 | ALOGE("No valid open method"); 311 | return nullptr; 312 | } 313 | 314 | hw_device_t* device = nullptr; 315 | 316 | if (0 != (err = module->common.methods->open(hw_mdl, nullptr, &device))) { 317 | ALOGE("Can't open fingerprint methods, error: %d", err); 318 | return nullptr; 319 | } 320 | 321 | if (kVersion != device->version) { 322 | // enforce version on new devices because of HIDL@2.1 translation layer 323 | ALOGE("Wrong fp version. Expected %d, got %d", kVersion, device->version); 324 | return nullptr; 325 | } 326 | 327 | fingerprint_device_t* fp_device = reinterpret_cast(device); 328 | 329 | if (0 != (err = fp_device->set_notify(fp_device, BiometricsFingerprint::notify))) { 330 | ALOGE("Can't register fingerprint module callback, error: %d", err); 331 | return nullptr; 332 | } 333 | 334 | return fp_device; 335 | } 336 | 337 | void BiometricsFingerprint::notify(const fingerprint_msg_t* msg) { 338 | BiometricsFingerprint* thisPtr = 339 | static_cast(BiometricsFingerprint::getInstance()); 340 | std::lock_guard lock(thisPtr->mClientCallbackMutex); 341 | if (thisPtr == nullptr || thisPtr->mClientCallback == nullptr) { 342 | ALOGE("Receiving callbacks before the client callback is registered."); 343 | return; 344 | } 345 | const uint64_t devId = reinterpret_cast(thisPtr->mDevice); 346 | switch (msg->type) { 347 | case FINGERPRINT_ERROR: { 348 | int32_t vendorCode = 0; 349 | FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode); 350 | ALOGD("onError(%d)", result); 351 | if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) { 352 | ALOGE("failed to invoke fingerprint onError callback"); 353 | } 354 | } break; 355 | case FINGERPRINT_ACQUIRED: { 356 | int32_t vendorCode = 0; 357 | FingerprintAcquiredInfo result = 358 | VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode); 359 | ALOGD("onAcquired(%d)", result); 360 | if (thisPtr->mUdfpsHandler) { 361 | thisPtr->mUdfpsHandler->onAcquired(static_cast(result), vendorCode); 362 | } 363 | if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) { 364 | ALOGE("failed to invoke fingerprint onAcquired callback"); 365 | } 366 | } break; 367 | case FINGERPRINT_TEMPLATE_ENROLLING: 368 | ALOGD("onEnrollResult(fid=%d, gid=%d, rem=%d)", msg->data.enroll.finger.fid, 369 | msg->data.enroll.finger.gid, msg->data.enroll.samples_remaining); 370 | if (!thisPtr->mClientCallback 371 | ->onEnrollResult(devId, msg->data.enroll.finger.fid, 372 | msg->data.enroll.finger.gid, 373 | msg->data.enroll.samples_remaining) 374 | .isOk()) { 375 | ALOGE("failed to invoke fingerprint onEnrollResult callback"); 376 | } 377 | break; 378 | case FINGERPRINT_TEMPLATE_REMOVED: 379 | ALOGD("onRemove(fid=%d, gid=%d, rem=%d)", msg->data.removed.finger.fid, 380 | msg->data.removed.finger.gid, msg->data.removed.remaining_templates); 381 | if (!thisPtr->mClientCallback 382 | ->onRemoved(devId, msg->data.removed.finger.fid, 383 | msg->data.removed.finger.gid, 384 | msg->data.removed.remaining_templates) 385 | .isOk()) { 386 | ALOGE("failed to invoke fingerprint onRemoved callback"); 387 | } 388 | break; 389 | case FINGERPRINT_AUTHENTICATED: 390 | if (msg->data.authenticated.finger.fid != 0) { 391 | ALOGD("onAuthenticated(fid=%d, gid=%d)", msg->data.authenticated.finger.fid, 392 | msg->data.authenticated.finger.gid); 393 | const uint8_t* hat = reinterpret_cast(&msg->data.authenticated.hat); 394 | const hidl_vec token( 395 | std::vector(hat, hat + sizeof(msg->data.authenticated.hat))); 396 | if (!thisPtr->mClientCallback 397 | ->onAuthenticated(devId, msg->data.authenticated.finger.fid, 398 | msg->data.authenticated.finger.gid, token) 399 | .isOk()) { 400 | ALOGE("failed to invoke fingerprint onAuthenticated callback"); 401 | } 402 | } else { 403 | // Not a recognized fingerprint 404 | if (!thisPtr->mClientCallback 405 | ->onAuthenticated(devId, msg->data.authenticated.finger.fid, 406 | msg->data.authenticated.finger.gid, 407 | hidl_vec()) 408 | .isOk()) { 409 | ALOGE("failed to invoke fingerprint onAuthenticated callback"); 410 | } 411 | } 412 | break; 413 | case FINGERPRINT_TEMPLATE_ENUMERATING: 414 | ALOGD("onEnumerate(fid=%d, gid=%d, rem=%d)", msg->data.enumerated.finger.fid, 415 | msg->data.enumerated.finger.gid, msg->data.enumerated.remaining_templates); 416 | if (!thisPtr->mClientCallback 417 | ->onEnumerate(devId, msg->data.enumerated.finger.fid, 418 | msg->data.enumerated.finger.gid, 419 | msg->data.enumerated.remaining_templates) 420 | .isOk()) { 421 | ALOGE("failed to invoke fingerprint onEnumerate callback"); 422 | } 423 | break; 424 | } 425 | } 426 | 427 | } // namespace implementation 428 | } // namespace V2_3 429 | } // namespace fingerprint 430 | } // namespace biometrics 431 | } // namespace hardware 432 | } // namespace android 433 | --------------------------------------------------------------------------------