http://devarea.com/android-hidl-and-project-treble/#.WzGVeaczaUk
위의 사이트의 tutorial을 직접 추가해봤음.
두 가지를 수정하니 내가 구성한 환경에서 돌아가는 것을 확인함.
- android.hardware.simple@2.0-impl.so을 sharelib으로 링크하는 경우, /vendor/lib/hw에 위치한 해당 so를 인식하지 못함.
- *-impl.so의 경우, framework에서 direct로 링크하여 쓰는 경우가 없음.
- 따라서 tutorial 내용과 다르게 getInstance 메소드 대신, HIDL_FETCH_ISimphw을 사용하여 위의 문제들을 모두 회피 가능.
- 굳이 HIDL_FETCH_ISimphw의 내용을 따라가보진 않았으나, 해당 함수 호출시, *-impl.so 를 링크하는 부분이 hidl의 어딘가에는 구현되어 있을거라 추측함.
1. add simple directory
mkdir -p hardware/interfaces/simple/2.0/default
2. create hal file
package android.hardware.simple@2.0; interface ISimphw { simpfn(int32_t valueIn) generates (int32_t valueRet); };3. use hidl-gen to make HAL files. make hidl.sh
PACKAGE=android.hardware.simple@2.0 LOC=hardware/interfaces/simple/2.0/default/ HIDL_GEN=out/host/linux-x86/bin/hidl-gen # make hidl-gen -j64 $HIDL_GEN -o $LOC -Lc++-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE $HIDL_GEN -o $LOC -Landroidbp-impl -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport $PACKAGE#./hidl.sh
check auto gen files
hardware/interfaces/simple/2.0/ ├── ISimphw.hal └── default //auto gen ├── Android.bp ├── Simphw.cpp └── Simphw.hleej5@LeeJ5:~/workspace/sapphire/hardware/interfaces/simple/2.0/default$ cat Android.bp
cc_library_shared { name: "android.hardware.simple@2.0-impl", relative_install_path: "hw", proprietary: true, srcs: [ "Simphw.cpp", ], shared_libs: [ "libhidlbase", "libhidltransport", "libutils", "android.hardware.simple@2.0", "android.hidl.base@1.0", ], }leej5@LeeJ5:~/workspace/sapphire/hardware/interfaces/simple/2.0/default$ cat Simphw.cpp
#include "Simphw.h" namespace android { namespace hardware { namespace simple { namespace V2_0 { namespace implementation { // Methods from ::android::hardware::simple::V2_0::ISimphw follow. Returnleej5@LeeJ5:~/workspace/sapphire/hardware/interfaces/simple/2.0/default$ cat Simphw.hSimphw::simpfn(int32_t valueIn) { // TODO implement return int32_t {}; } // Methods from ::android::hidl::base::V1_0::IBase follow. ISimphw* HIDL_FETCH_ISimphw(const char* /* name */) { return new Simphw(); } } // namespace implementation } // namespace V2_0 } // namespace simple } // namespace hardware } // namespace android
#ifndef ANDROID_HARDWARE_SIMPLE_V2_0_SIMPHW_H #define ANDROID_HARDWARE_SIMPLE_V2_0_SIMPHW_H #include4. run below script to update android mk and bp export PATH=$PATH:/home/leej5/workspace/sapphire/out/host/linux-x86/bin/ ./hardware/interfaces/update-makefiles.sh#include #include namespace android { namespace hardware { namespace simple { namespace V2_0 { namespace implementation { using ::android::hardware::simple::V2_0::ISimphw; using ::android::hidl::base::V1_0::DebugInfo; using ::android::hidl::base::V1_0::IBase; using ::android::hardware::hidl_array; using ::android::hardware::hidl_memory; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; struct Simphw : public ISimphw { // Methods from ::android::hardware::simple::V2_0::ISimphw follow. Return simpfn(int32_t valueIn) override; // Methods from ::android::hidl::base::V1_0::IBase follow. }; extern "C" ISimphw* HIDL_FETCH_ISimphw(const char* name); } // namespace implementation } // namespace V2_0 } // namespace simple } // namespace hardware } // namespace android #endif // ANDROID_HARDWARE_SIMPLE_V2_0_SIMPHW_H
simple/ ├── 2.0 │ ├── Android.bp │ ├── Android.mk │ ├── ISimphw.hal │ └── default │ ├── Android.bp │ ├── Simphw.cpp │ └── Simphw.h └── Android.bpleej5@LeeJ5:~/workspace/sapphire/hardware/interfaces$ cat simple/Android.bp
// This is an autogenerated file, do not edit. subdirs = [ "2.0", "2.0/default", ]2.0/Android.bp
// This file is autogenerated by hidl-gen. Do not edit manually. filegroup { name: "android.hardware.simple@2.0_hal", srcs: [ "ISimphw.hal", ], } genrule { name: "android.hardware.simple@2.0_genc++", tools: ["hidl-gen"], cmd: "$(location hidl-gen) -o $(genDir) -Lc++-sources -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.simple@2.0", srcs: [ ":android.hardware.simple@2.0_hal", ], out: [ "android/hardware/simple/2.0/SimphwAll.cpp", ], } genrule { name: "android.hardware.simple@2.0_genc++_headers", tools: ["hidl-gen"], cmd: "$(location hidl-gen) -o $(genDir) -Lc++-headers -randroid.hardware:hardware/interfaces -randroid.hidl:system/libhidl/transport android.hardware.simple@2.0", srcs: [ ":android.hardware.simple@2.0_hal", ], out: [ "android/hardware/simple/2.0/ISimphw.h", "android/hardware/simple/2.0/IHwSimphw.h", "android/hardware/simple/2.0/BnHwSimphw.h", "android/hardware/simple/2.0/BpHwSimphw.h", "android/hardware/simple/2.0/BsSimphw.h", ], } cc_library_shared { name: "android.hardware.simple@2.0", defaults: ["hidl-module-defaults"], generated_sources: ["android.hardware.simple@2.0_genc++"], generated_headers: ["android.hardware.simple@2.0_genc++_headers"], export_generated_headers: ["android.hardware.simple@2.0_genc++_headers"], vendor_available: true, shared_libs: [ "libhidlbase", "libhidltransport", "libhwbinder", "liblog", "libutils", "libcutils", "android.hidl.base@1.0", ], export_shared_lib_headers: [ "libhidlbase", "libhidltransport", "libhwbinder", "libutils", "android.hidl.base@1.0", ], }2.0/Android.mk
# This file is autogenerated by hidl-gen. Do not edit manually. LOCAL_PATH := $(call my-dir) ################################################################################ include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.simple-V2.0-java LOCAL_MODULE_CLASS := JAVA_LIBRARIES intermediates := $(call local-generated-sources-dir, COMMON) HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX) LOCAL_JAVA_LIBRARIES := \ android.hidl.base-V1.0-java \ # # Build ISimphw.hal # GEN := $(intermediates)/android/hardware/simple/V2_0/ISimphw.java $(GEN): $(HIDL) $(GEN): PRIVATE_HIDL := $(HIDL) $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISimphw.hal $(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) $(GEN): PRIVATE_CUSTOM_TOOL = \ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport \ android.hardware.simple@2.0::ISimphw $(GEN): $(LOCAL_PATH)/ISimphw.hal $(transform-generated-source) LOCAL_GENERATED_SOURCES += $(GEN) include $(BUILD_JAVA_LIBRARY) ################################################################################ include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.simple-V2.0-java-static LOCAL_MODULE_CLASS := JAVA_LIBRARIES intermediates := $(call local-generated-sources-dir, COMMON) HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX) LOCAL_STATIC_JAVA_LIBRARIES := \ android.hidl.base-V1.0-java-static \ # # Build ISimphw.hal # GEN := $(intermediates)/android/hardware/simple/V2_0/ISimphw.java $(GEN): $(HIDL) $(GEN): PRIVATE_HIDL := $(HIDL) $(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/ISimphw.hal $(GEN): PRIVATE_OUTPUT_DIR := $(intermediates) $(GEN): PRIVATE_CUSTOM_TOOL = \ $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \ -Ljava \ -randroid.hardware:hardware/interfaces \ -randroid.hidl:system/libhidl/transport \ android.hardware.simple@2.0::ISimphw $(GEN): $(LOCAL_PATH)/ISimphw.hal $(transform-generated-source) LOCAL_GENERATED_SOURCES += $(GEN) include $(BUILD_STATIC_JAVA_LIBRARY) include $(call all-makefiles-under,$(LOCAL_PATH))5. add empty files to hardware/interfaces/simple/2.0/default: android.hardware.simple@2.0-service.rc service.cpp results
leej5@LeeJ5:~/workspace/sapphire/hardware/interfaces$ tree simple/ simple/ ├── 2.0 │ ├── Android.bp │ ├── Android.mk │ ├── ISimphw.hal │ └── default │ ├── Android.bp │ ├── Simphw.cpp │ ├── Simphw.h │ ├── android.hardware.simple@2.0-service.rc │ └── service.cpp └── Android.bp 2 directories, 9 files6.Implementing the HAL shared object: we need to add a new static function to return the service object (usually as a singleton) Simphw.h
#ifndef ANDROID_HARDWARE_SIMPLE_V2_0_SIMPHW_H #define ANDROID_HARDWARE_SIMPLE_V2_0_SIMPHW_H #includesimple/2.0/default/Simphw.cpp 수정#include #include namespace android { namespace hardware { namespace simple { namespace V2_0 { namespace implementation { using ::android::hardware::simple::V2_0::ISimphw; using ::android::hidl::base::V1_0::DebugInfo; using ::android::hidl::base::V1_0::IBase; using ::android::hardware::hidl_array; using ::android::hardware::hidl_memory; using ::android::hardware::hidl_string; using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::sp; struct Simphw : public ISimphw { // Methods from ::android::hardware::simple::V2_0::ISimphw follow. Return simpfn(int32_t valueIn) override; }; extern "C" ISimphw* HIDL_FETCH_ISimphw(const char* name); } // namespace implementation } // namespace V2_0 } // namespace simple } // namespace hardware } // namespace android #endif // ANDROID_HARDWARE_SIMPLE_V2_0_SIMPHW_H
#include "Simphw.h" namespace android { namespace hardware { namespace simple { namespace V2_0 { namespace implementation { // Methods from ::android::hardware::simple::V2_0::ISimphw follow. ReturnNote that if you want to support pass-through mode, you need to uncomment the HIDL_FETCH_ISimphw function In this example, we implemented the function as simple as possible (usually we will load the hardware module here) The generated Android.bp file build a shared library with the implementation – android.hardware.simple@2.0-impl Creating the Service To host the library we need to create a simple executable: service.cppSimphw::simpfn(int32_t valueIn) { // TODO implement return valueIn+100; } // Methods from ::android::hidl::base::V1_0::IBase follow. ISimphw* HIDL_FETCH_ISimphw(const char* /* name */) { return new Simphw(); } } // namespace implementation } // namespace V2_0 } // namespace simple } // namespace hardware } // namespace android
#define LOG_TAG "android.hardware.simple@2.0-service" #includeWe create an instance of our implementation, Create a thread pool for the binder and register the current process as a service Note that the function regsiterAsService() is auto-generated by hidl-gen tool To make this service run automatically add init file: android.hardware.simple@2.0-service.rc#include #include "Simphw.h" using android::hardware::simple::V2_0::ISimphw; using android::hardware::simple::V2_0::implementation::Simphw; using android::hardware::configureRpcThreadpool; using android::hardware::joinRpcThreadpool; using android::sp; using android::hardware::defaultPassthroughServiceImplementation; int main() { return defaultPassthroughServiceImplementation (); }
service simphwserv /vendor/bin/hw/android.hardware.simple@2.0-service class hal user root group root seclabel u:r:su:s0For testing purpose I set the security label to su , we need to set SE Linux rules (I wrote it in the init.te file): ./yours/sepolicy/block/init.te
allow init vendor_file:file { execute }; allow init su:process { transition };To tell the build system to build the service add the following to Android.bp (in directory default)
cc_binary { name: "android.hardware.simple@2.0-service", defaults: ["hidl_defaults"], proprietary: true, relative_install_path: "hw", srcs: ["service.cpp"], init_rc: ["android.hardware.simple@2.0-service.rc"], shared_libs: [ "android.hardware.simple@2.0", "libhidlbase", "libhidltransport", "liblog", "libutils", ], }Add the following components to build/make/target/product/emulator.mk vi build/make/target/product/emulator.mk
PRODUCT_PACKAGES += \ android.hardware.simple@2.0-impl \ android.hardware.simple@2.0-service \leej5@LeeJ5:~/android/hardware/interfaces/simple$ mm -j16 results
leej5@LeeJ5:~/workspace/sapphire/out/target/product/sapphire_tch/system$ find . -name "*simple*" ./lib/android.hardware.simple@2.0.so leej5@LeeJ5:~/workspace/sapphire/out/target/product/sapphire_tch/vendor$ find . -name "*simple*" ./lib/hw/android.hardware.simple@2.0-impl.so ./etc/init/android.hardware.simple@2.0-service.rc ./bin/hw/android.hardware.simple@2.0-servicesapphire_tch:/ # lshal
All available passthrough implementations (all -impl.so files) Interface Server Clients android.hardware.audio.effect@2.0::I*/* N/A android.hardware.audio@2.0::I*/* N/A android.hardware.bluetooth@1.0::I*/* N/A android.hardware.boot@1.0::I*/* N/A android.hardware.drm@1.0::I*/* N/A android.hardware.graphics.allocator@2.0::I*/* N/A android.hardware.graphics.composer@2.1::I*/* N/A android.hardware.graphics.mapper@2.0::I*/* N/A android.hardware.keymaster@3.0::I*/* N/A android.hardware.light@2.0::I*/* N/A android.hardware.memtrack@1.0::I*/* N/A android.hardware.power@1.0::I*/* N/A android.hardware.renderscript@1.0::I*/* N/A android.hardware.simple@2.0::I*/* N/A android.hardware.soundtrigger@2.0::I*/* N/A android.hardware.thermal@1.0::I*/* N/A android.hardware.tv.cec@1.0::I*/* N/A android.hardware.tv.input@1.0::I*/* N/A android.hidl.memory@1.0::I*/* N/Asapphire_tch:/ # ps -A | grep simp root 7315 1 7180 3376 binder_thread_read a7bed514 S android.hardware.simple@2.0-service sapphire_tch:/ # lshal
All binderized services (registered services through hwservicemanager) Interface Server Clients android.frameworks.displayservice@1.0::IDisplayService/default 3573 3394 android.frameworks.schedulerservice@1.0::ISchedulingPolicyService/default 3780 3394 android.frameworks.sensorservice@1.0::ISensorManager/default 3780 3394 android.hardware.audio.effect@2.0::IEffectsFactory/default 3554 3658 3394 android.hardware.audio@2.0::IDevicesFactory/default 3554 3658 3394 android.hardware.bluetooth@1.0::IBluetoothHci/default 3555 3888 3394 android.hardware.boot@1.0::IBootControl/default 3396 3762 3394 android.hardware.configstore@1.0::ISurfaceFlingerConfigs/default 3556 3394 android.hardware.drm@1.0::ICryptoFactory/default 3557 3394 android.hardware.drm@1.0::ICryptoFactory/widevine 3558 3394 android.hardware.drm@1.0::IDrmFactory/default 3557 3663 3394 android.hardware.drm@1.0::IDrmFactory/widevine 3558 3663 3394 android.hardware.graphics.allocator@2.0::IAllocator/default 3559 3573 3394 android.hardware.graphics.composer@2.1::IComposer/default 3560 3573 3394 android.hardware.keymaster@3.0::IKeymasterDevice/default 3397 3662 3394 android.hardware.light@2.0::ILight/default 3561 3780 3394 android.hardware.media.omx@1.0::IOmx/default 3669 3666 3394 android.hardware.media.omx@1.0::IOmxStore/default 3669 3394 android.hardware.memtrack@1.0::IMemtrack/default 3562 3780 3394 android.hardware.power@1.0::IPower/default 3563 3780 3394 android.hardware.simple@2.0::ISimphw/default 7315 3394
as a simple test, make a binary project to vendor path. vendor/[yours]/simpleTest "servtest.cpp"
#define LOG_TAG "android.hardware.simple@2.0-service" #includeAndroid.bp#include #include #include #include #include #include #include using android::hardware::simple::V2_0::ISimphw; using android::sp; int main() { int res; android::sp ser = ISimphw::getService(); res = ser->simpfn(200); printf("val=%d\n",res); return 0; }
cc_binary { name: "mysimptest", defaults: ["hidl_defaults"], proprietary: true, srcs: ["servtest.cpp"], shared_libs: [ "android.hardware.simple@2.0", "libhidlbase", "libhidltransport", "liblog", "libutils", ], }Add hal entry to the Manifest.xml file in my case~ add it here "/device/~~/treble.xml"
android.hardware.simple hwbinder 2.0 ISimphw default
# mysimptest
val=300
'android' 카테고리의 다른 글
Simple voice search test (0) | 2018.07.11 |
---|---|
NDK API는 binder를 지원하지 않는다. (0) | 2018.07.03 |
android ir to android keycode mapping (0) | 2018.06.21 |
Android Custom KeyCode 추가 (0) | 2018.06.21 |
[NDK] so 포함한 apk가 so loading 실패 (3) (0) | 2018.06.19 |