Quantcast
Channel: AOSP – Developers Area
Viewing all articles
Browse latest Browse all 7

Android HIDL and Project Treble

$
0
0

One of the problems in Android is the fact that when a new version is released only a few devices can be updated. Actually, if you want to enjoy the latest version, you need to buy a new smartphone every 6 months. Google solution is the Project trebel that separates the vendor implementation from the Android OS framework via a new vendor interface

HIDL

HAL interface definition language used to describe the interface between the framework and the vendor. All hardware interfaces are located in hardware/interfaces in .hal files

Let’s go over simple example

Create all the path

# cd ~/aosp
# mkdir -p hardware/interfaces/simple/2.0/default

 

Create a hal file in ISimphw.hal in  hardware/interfaces/simple/2.0

package android.hardware.simple@2.0;

interface ISimphw {
    simpfn(int32_t valueIn) generates (int32_t valueRet);
};

Generate the HAL files

To generate the HAL files you need to use the hidl-gen tool run:

# PACKAGE=android.hardware.simple@2.0
# LOC=hardware/interfaces/simple/2.0/default/
# 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

And to update all makefile (Android.mk, Android.bp) run:

# ./hardware/interfaces/update-makefiles.sh

Now add 2 empty files to hardware/interfaces/simple/2.0/default:

  • android.hardware.simple@2.0-service.rc
  • service.cpp

Now the directory hardware/interfaces/simple should look like this:

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

#include <android/hardware/simple/2.0/ISimphw.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>

namespace android {
namespace hardware {
namespace simple {
namespace V2_0 {
namespace implementation {

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 ISimphw follow.
    Return<int32_t> simpfn(int32_t valueIn) override;

    // Methods from ::android::hidl::base::V1_0::IBase follow.
    static ISimphw* getInstance(void);
};

// FIXME: most likely delete, this is only for passthrough implementations
//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

Simphw.cpp

#include "Simphw.h"

namespace android {
namespace hardware {
namespace simple {
namespace V2_0 {
namespace implementation {

// Methods from ISimphw follow.
Return<int32_t> Simphw::simpfn(int32_t valueIn) {
    // TODO implement
    return valueIn+100;
}

ISimphw *Simphw::getInstance(void){
  return new Simphw();
}

// 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

Note 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.cpp

#define LOG_TAG "android.hardware.graphics.allocator@2.0-service"

#include <android/hardware/simple/2.0/ISimphw.h>

#include <hidl/LegacySupport.h>

#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;

int main() {
      int res;
      android::sp<ISimphw> ser = Simphw::getInstance();
      ALOGE("simp main");
      configureRpcThreadpool(1, true /*callerWillJoin*/);

      if (ser != nullptr) {
          res = ser->registerAsService();
          if(res != 0)
            ALOGE("Can't register instance of SimpleHardware, nullptr");
      } else {
          ALOGE("Can't create instance of SimpleHardware, nullptr");
       }

      joinRpcThreadpool();

      return 0; // should never get here
}

We 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

service simphwserv /vendor/bin/hw/android.hardware.simple@2.0-service
    class hal
    user root
    group root
    seclabel u:r:su:s0

For testing purpose I set the security label to su , we need to set SE Linux rules (I wrote it in the init.te file):

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",
        "android.hardware.simple@2.0-impl",
        "libhidlbase",
        "libhidltransport",
        "liblog",
        "libutils",
    ],
}

Add the following components to build/make/target/product/emulator.mk

    android.hardware.simple@2.0-impl \
    android.hardware.simple@2.0-service \

 

Now build the ROM and run it, connect with adb and run ps -A to see all the hardware services:

The lshal tool list all the hardware services by categories:

# lshal

Writing the Client

To use the service we will write a simple client application. Usually, it will be part of the Android framework written by Google. For example, if the generic framework wants to access the vibrator service:

In file  frameworks/base/services/core/jni/com_android_server_VibratorService.cpp

static sp<IVibrator> mHal;

...

mHal = IVibrator::getService();
...
Status retStatus = mHal->on(timeout_ms);
...
Status retStatus = mHal->off();

Add a new directory in device/generic/goldfish – simphaltest

Add the source and Android.bp files:

#define LOG_TAG "android.hardware.graphics.allocator@2.0-service"

#include <android/hardware/simple/2.0/ISimphw.h>
#include <hidl/Status.h>
#include <hidl/LegacySupport.h>
#include <utils/misc.h>
#include <utils/Log.h>
#include <hardware/hardware.h>
#include <hidl/HidlSupport.h>


#include<stdio.h>


using android::hardware::simple::V2_0::ISimphw;
using android::sp;


int main() {
      int res;
      android::sp<ISimphw> ser = ISimphw::getService();

      res = ser->simpfn(200);

      printf("val=%d\n",res);

      return 0; 
}

Android.bp

cc_binary {
    name: "mysimptest",
    defaults: ["hidl_defaults"],
    proprietary: true,
    srcs: ["servtest.cpp"],

    shared_libs: [
        "android.hardware.simple@2.0",
        "android.hardware.simple@2.0-impl",
        "libhidlbase",
        "libhidltransport",
        "liblog",
        "libutils",
    ],
}

Add the client test to build/make/target/product/emulator.mk

    mysimptest \

Add hal entry to the Manifest.xml file of your device (device/generic/goldfish/Manifest.xml in this case)

    <hal format="hidl">
        <name>android.hardware.simple</name>
	<transport>hwbinder</transport>
        <version>2.0</version>
        <interface>
            <name>ISimphw</name>
            <instance>default</instance>
        </interface>
    </hal>

Build the ROM again and test our service:

 


Viewing all articles
Browse latest Browse all 7

Trending Articles