Android: Add a service

来自个人维基
2023年3月17日 (五) 21:00free6d1823讨论 | 贡献的版本

(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳转至: 导航搜索
  1. 1. aosp/hardware/interfaces/<myservice>/1.0
  • Android.bp
hidl_interface {
    name: "android.hardware.<myservice>@1.0",
    root: "android.hardware",
    vndk: {
        enabled: false,
    },
    srcs: [
        "types.hal",
        "I<Myservice>.hal",
    ],
    interfaces: [
        "android.hidl.base@1.0",
    ],
    gen_java: false,
}
  • I<Myservice>.hal
package android.hardware.<myservice>@1.0;
 
interface I<Myservice> {
    func1() generates (<Myservice>Error error);
    func2(handle h, Param1 p1) generates (<MyService>Error error);
};
  • types.hal
package android.hardware.<myservie>@1.0;
 
enum <MyService>Error : uint8_t {
    <MYSERVICE>_SUCCESS = 0,
};
struct Param1 {
    ....
};
  • default/
 - Android.bp
 - abstraction layer (@-impl) source code 
 - service.cpp
#include <sched.h>
 
#include <android/hardware/<myservice>/1.0/I<Myservice>.h>
#include <binder/ProcessState.h>
#include <hidl/HidlTransportSupport.h>
 
using android::hardware::myservice::V1_0::I<Myservice>;
 
int main() {
    // the conventional HAL might start binder services
    android::ProcessState::initWithDriver("/dev/vndbinder");
    android::ProcessState::self()->setThreadPoolMaxThreadCount(4);
    android::ProcessState::self()->startThreadPool();
 
    // same as SF main thread
    struct sched_param param = {0};
    param.sched_priority = 2;
    if (sched_setscheduler(0, SCHED_FIFO | SCHED_RESET_ON_FORK, &param) != 0) {
        ALOGE("Couldn't set SCHED_FIFO: %d", errno);
    }
 
    android::hardware::configureRpcThreadpool(4, true /* will join */);
 
    android::sp<IMyservice> service = new android::hardware::<myservice>::implementation::<Myservice>();
    if (service == nullptr) {
        ALOGE("failed to create device!");
        return -1;
    }
 
    if (service ->func1() != <Myservice>Error::<MYSERVICE>_SUCCESS) {
        ALOGE("failed to init device");
        return -1;
    }
 
    if (service->registerAsService() != android::NO_ERROR) {
        ALOGE("failed to register service");
        return 1;
    }
 
    android::hardware::joinRpcThreadpool();
 
    ALOGE("service is terminating");
    return 1;
}
- <myservice>.rc
 
  1. 2. Block diagram
  1. 3. How to register as a server
 in <vendor>/<device>/manifest.xml, add
    <hal format="hidl">
         <name>android.hardware.myservice</name>
         <transport>hwbinder</transport>
         <version>1.0</version>
         <interface>
            <name>IMyservice</name>
            <instance>default</instance>
         </interface>
    </hal>
 in <vendor>/<device>/device.mk, add
 PRODUCT_PACKAGES += \
    android.hardware.<myservice>@1.0 \
    android.hardware.<myservice>@1.0-service
    myservice.myplatform
  1. 4. How to load our implementation, e.g. myservice.myplatform.so

(1) define a global and unique hardware module id in a header file

#define <MYSERVICE>_HARDWARE_ID "myservice"

(2)<service>-imple call hw_get_module(<MYSERVICE>_HARDWARE_ID (== "myservice"))

  //it get prop from "ro.hardware.myservice", in our case, "myservice"
  //check all variants listed in property variant_keys[], start from
  // "ro.hardware", "ro.product.board", "ro.board.platform", "ro.arch"
  // in our case, ro.product.board ="myplatform"
  //now search if the file "myservice.myplatform.so" in 
/** Base path of the hal modules */
  #if defined(__LP64__)
  #define HAL_LIBRARY_PATH1 "/system/lib64/hw"
  #define HAL_LIBRARY_PATH2 "/vendor/lib64/hw"
  #define HAL_LIBRARY_PATH3 "/odm/lib64/hw"
  #else
  #define HAL_LIBRARY_PATH1 "/system/lib/hw"
  #define HAL_LIBRARY_PATH2 "/vendor/lib/hw"
  #define HAL_LIBRARY_PATH3 "/odm/lib/hw"
  #endif
   //if not exist, check the default file in above paths
   //in our case, myservice.default.so

Notes:

 1. Default lib myservice.myplatform.so is decided by ro.product.board
 2. To change default implementation, we can name our lib as
     myservice.myhardware.so
  1. 5. How to call I<Myservice>