HIDL SIMPLE

原文:https://devarea.com/android-hidl-and-project-treble/#.XLgyn7Ejw4A

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

 

1

2

# cd ~/aosp

# mkdir -p hardware/interfaces/simple/2.0/default

 

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

 

1

2

3

4

5

package [email protected];

 

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:

 

1

2

3

4

5

# [email protected]

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

 

1

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

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

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

HIDL SIMPLE

Implementing the HAL shared object:

we need to add a new static function to return the service object (usually as a singleton)

Simphw.h

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

#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

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#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 – [email protected]

Creating the Service

To host the library we need to create a simple executable:

service.cpp

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

#define LOG_TAG "[email protected]"

 

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

[email protected]

 

1

2

3

4

5

service simphwserv /vendor/bin/hw/[email protected]

    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):

 

1

2

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)

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

cc_binary {

    name: "[email protected]",

    defaults: ["hidl_defaults"],

    proprietary: true,

    relative_install_path: "hw",

    srcs: ["service.cpp"],

    init_rc: ["[email protected]"],

 

    shared_libs: [

        "[email protected]",

        "[email protected]",

        "libhidlbase",

        "libhidltransport",

        "liblog",

        "libutils",

    ],

}

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

 

1

2

    [email protected] \

    [email protected] \

 

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

HIDL SIMPLE

The lshal tool list all the hardware services by categories:

 

1

# lshal

HIDL SIMPLE

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

 

1

2

3

4

5

6

7

8

9

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:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

#define LOG_TAG "[email protected]"

 

#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

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

cc_binary {

    name: "mysimptest",

    defaults: ["hidl_defaults"],

    proprietary: true,

    srcs: ["servtest.cpp"],

 

    shared_libs: [

        "[email protected]",

        "[email protected]",

        "libhidlbase",

        "libhidltransport",

        "liblog",

        "libutils",

    ],

}

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

 

1

    mysimptest \

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

 

1

2

3

4

5

6

7

8

9

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

HIDL SIMPLE

 

Google BookmarkFacebookMore

Tagged AndroidAndroid InternalsAOSP

Post navigation

← AOSP – CREATING A SYSTEM APPLICATION

UNDERSTANDING SED – PRACTICAL GUIDE  →

33 THOUGHTS ON “ANDROID HIDL AND PROJECT TREBLE”

  1. HIDL SIMPLECHRIS_CW

    This is the best DEMONSTRATION of How to get a HAL going I have found, Unfortunately When following it through on OREO my service fails to load the impl library from the ‘HW’ dir, if I push the library up a level to the lib64, it is found. I see nearly all the other standard(or BSP) HALS are lOAded from ‘HW’ but I cant see what they have different. Whats the trick ?
    I get:
    “library “[email protected]” not found”
    Although it is clearly there and it does load if I move it up to lib64

    MARCH 21, 2018

      -   REPLY

    1. HIDL SIMPLEKEN

      Hello,
      HAVE you FIGURED OUT WHY THIS IS HAPPENING? I AM CURRENTLY HAVING THIS ISSUE. PLEASE LET ME KNOW IF YOU FIND ANY SOLUTION.
      THANKS

      MAY 25, 2018

        -   REPLY

      1. HIDL SIMPLEJIHYUN

        hi

        i also have this problem.
        a simple way to avoid it, just copy so file to /system/lib. then it’s gone.
        but it seems not a good way. if anyone knows it.
        please share.

        JUNE 25, 2018

          -   REPLY

        1. HIDL SIMPLEJIHYUN

          Hi I resolved it by avoding linking *-impl.so file.
          I removed getInstance method and added below method

          ISimphw* HIDL_FETCH_ISimphw(const char* /* name */) {
          return new Simphw();
          }
          and modified service.cpp as below.

          int main() {
          return defaultPassthroughServiceImplementation();
          }
          maybe linking *-impl.so in /vendor/lib/hw is not allowed.
          instead, I’m guessing that it’s automatically loaded by using HIDL_FETCH_ISIMPHW.

          JUNE 25, 2018

            -   REPLY

          1. HIDL SIMPLERAJU KHANAL

            @JIHYUN: I followed your steps but still get the following error.
            hwservicemanager: getTransport: Cannot find entry [email protected]::ISimphw/default in either framework or device manifest.
            10-18 01:06:20.990 1577 1577 E ServiceManagement: Passthrough lookup opened [email protected] but could not find symbol HIDL_FETCH_ISimphw: undefined symbol: HIDL_FETCH_ISimphw
            10-18 01:06:20.990 1577 1577 E [email protected]: Could not get passthrough implementation for [email protected]::ISimphw/default.

            I do the the hidl fetch method but don’t know why it is coming this way. Any suggestions? I have been stuck in this.

            OCTOBER 17, 2018

              -  

          2. HIDL SIMPLERAJU KHANAL

            Please note the error is not with the naming convention.
            So the proper error would be:
            @JIHYUN: I followed your steps but still get the following error.
            hwservicemanager: getTransport: Cannot find entry [email protected]::ISimphw/default in either framework or device manifest.
            10-18 01:06:20.990 1577 1577 E ServiceManagement: Passthrough lookup opened [email protected] but could not find symbol HIDL_FETCH_ISimphw: undefined symbol: HIDL_FETCH_ISimphw
            10-18 01:06:20.990 1577 1577 E [email protected]: Could not get passthrough implementation for [email protected]::ISimphw/default.

            Kindly ignore the part where the name is [email protected] I have the correct impl file name.

            OCTOBER 17, 2018

              -  

  2. HIDL SIMPLEPHONG

    What IDE to run the code?

    MARCH 26, 2018

      -   REPLY

  3. HIDL SIMPLERAKESH VERMA

    thanks a lot, works great. Required to update dev/*/* in Android.bp in root directory to dev/*/*/* to access the Android.bp created in device/generic/goldfish/simphaltest.

    MARCH 27, 2018

      -   REPLY

  4. HIDL SIMPLEAJINATH

    hI,

    I tried steps given for “[email protected]″ HIDL interface and thats worked. I like the simple steps/command to generate HIDL impl and HIDL service, it really gives the confidence for who are new into Android HAL framework.

    Thanks a lot.

    One more change is required to build HIDL impl lib, just add “2.0/default” into Android.bp to include default dir Android.bp

    hardware/interfaces/simple/Android.bp

    subdirs = [
    “2.0”,
    “2.0/default”,
    ]

    @CHRIS_CW,

    As per hardware/interfaces/simple/2.0/default/Android.bp rule,

    name: “[email protected]”,
    relative_install_path: “hw”,
    proprietary: true,

    the impl lib should build at below location in vendor.img

    vendor/lib/hw
    vendor/lib64/hw

    can check your HIDL package name ? from error it seems to be UPPER case string issue “library “[email protected]” not found”

    and also check product packages should include in devicexx.mk

    PRODUCT_PACKAGES += \
    [email protected] \
    [email protected] \

    APRIL 9, 2018

      -   REPLY

  5. HIDL SIMPLE1STPIE

    it so good refference. thanks

    APRIL 19, 2018

      -   REPLY

  6. HIDL SIMPLEAARTI

    Hi
    I followed the steps given above but i am getting following error while trying to generate the HIDL files:

    ERROR: Unable to automatically import ‘[email protected]::IBase’ at /home/AOSP/hardware/interfaces/simple/2.0/ISimple.hal
    ERROR: Could not parse [email protected]::ISimple Aborting

    APRIL 20, 2018

      -   REPLY

  7. HIDL SIMPLE1STPIE

    hello.
    i have a question.
    i dont make android.mk files about simple directory.
    i try to execute hardware/interfaces/update-makefiels.sh
    and i got a message about this.
    Updating [email protected]

    but in the directory of simple/2.0/
    dont find a android.mk file.

    APRIL 24, 2018

      -   REPLY

  8. HIDL SIMPLEANONYMOUS

    In service.cpp, should “return 1” “if(res != 0)”, else would “joinRpcThreadpool();” without a registered instance of SimpleHardware.

    P/S: Sorry about all caps. something wrong somewhere i can’t type in lowercase.

    MAY 11, 2018

      -   REPLY

  9. HIDL SIMPLEANONYMOUS

    Also need “return 1” “if(ser == nullptr)”.

    MAY 11, 2018

      -   REPLY

  10. HIDL SIMPLEANONYMOUS

    @Rakesh Verma
    How did you get “hidl-gen” and “update-makefiles.sh” to detect your *.hal files if you put your source code under device/generic/goldfish/simphaltest? or did you generate everything under hardware/interfaces and moved them to device/generic/goldfish/simphaltest later?

    MAY 13, 2018

      -   REPLY

    1. HIDL SIMPLELIRAN B.H

      update-makefiles.sh only generates the makefiles under hardware/interfaces
      follow the instructions and create the testapp makefile manually

      MAY 13, 2018

        -   REPLY

      1. HIDL SIMPLEANONYMOUS

        Thanks! IS THERE A WAY TO IMPLEMENT A BOARD/TARGET SPECIFIC VERSION OF THIS AND ‘OVERWRITE’ (OR NOT USE) THE DEFAULT IMPLEMENTATION? E.g. using device/generic/marlin/SIMPLE rather than hardware/interfaces/SIMPLE? As you’d mentioned, update-makefiles.sh doesn’t seem to detect *.hal files under devices/*, so this has to be done manually, but how should the terms [email protected] and [email protected] AND [email protected] be renamed for the BOARD/TARGET? Thanks in advance.

        MAY 17, 2018

          -   REPLY

        1. HIDL SIMPLEANONYMOUS

          Sorry again for caps!

          MAY 17, 2018

            -   REPLY

    2. HIDL SIMPLERATNESH PAL

      Hope you resolved your error, I follow the same instruction everything is working fine but try to run test code getting error. I could not understand the mean so please help me,
      My test code path is here aosp8/device/generic/goldfish/mysimptest.
      127|generic_x86:/ $ mysimptest/
      mysimptest/
      /system/bin/sh: mysimptest/: not found
      127|generic_x86:/ $

      APRIL 13, 2019

        -   REPLY

  11. HIDL SIMPLERAJIV RANJAN

    superb link till now.

    MAY 16, 2018

      -   REPLY

  12. HIDL SIMPLESAI PHANI TEJA SREERAM

    The best tutorial of hidl so far got in the internet. Thanks

    JULY 17, 2018

      -   REPLY

  13. HIDL SIMPLEDEEPTIMAN PATTNAIK

    it’s a great tutorial to get started with HIDL implementation.

    I am just facing an issue, while build the hidl modules.

    ERROR: Could not open package path hardware/interfaces/simple/2.0/ for package [email protected]:

    AUGUST 1, 2018

      -   REPLY

  14. HIDL SIMPLEBRIAN

    Hi All,

    I am trying to implement an I2C DAC in android to allow the driving of specific voltages from an app. This isn’t a DAC for audio etc, it is an embedded application. I will also be implementing ADC, GPIO etc.

    I have found a kernel driver for the specific DAC I am using, and can control the DAC via the sysfs interface, e.g. “echo 3000 > /sys/bus/iio/devices/iio:device0/out_voltage0_raw”

    Now I am trying to understand how HIDL, HAL etc fit in to this.

    – I have found an example (https://elinux.org/images/f/fb/Android_Customization-_From_the_Kernel_to_the_Apps.pdf) which seems to create a custom service to control a hardware device, however this edits some of the internal files in android to start the service etc, and therefore I think this is NOT the “Andriod Oreo” way of doing it, since these modifications will be wiped during an upgrade.

    – Other examples I have found seem to be for sensor implementation. Since the DAC is an output, I don’t think the sensor API is compatible with what I am trying to achieve.

    As I understand it, Android Oreo 8.0 introduced the treble concept to allow the operating system to be updated while keeping the vendor specific changes intact. Am I correct in saying that this example is compatible with communicating with a custom device? e.g. instead of doing “return valueIn+100;”, I could “open(DEV, O_WRONLY);” etc and interface with my device?

    AUGUST 6, 2018

      -   REPLY

  15. HIDL SIMPLEBRIAN

    Does anyone know how I would call the function from within an Android App using Android Studio? I have generated an SDK after implementing this but I don’t know what Java API is exposed, if any?

    AUGUST 7, 2018

      -   REPLY

  16. HIDL SIMPLEANIL KUMAR

    I am not able to send data to another shared library from my HIDL server, I am sending some data form client to server, from server i am trying to send to another library which is normal C implementation, i am able to call but data is not reaching. Can you please help.

    AUGUST 16, 2018

      -   REPLY

  17. HIDL SIMPLEYUZHOU

    Hi,
    Thanks for the detailed documentation. A question regarding the init_rc file and SELinux init.te rule. As you mentioned:

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

    Could you please clarify what should be the setting for normal use case? I have tried to copy the init_rc file from audio, omx HAL and the service won’t load up unless I use your sepolicy here. Is there a formal way to tell the system to load up the hal service while booting?

    AUGUST 28, 2018

      -   REPLY

  18. HIDL SIMPLEWANG ZHIKAI

    hi
    as you said “we need to set SE Linux rules (I wrote it in the init.te file):”
    i don’t know which init.te file should config, could you tell me the location of init.te file?
    thank you very much!

    SEPTEMBER 12, 2018

      -   REPLY

  19. HIDL SIMPLERAJU KHANAL

    When I do an lshal I can see that it is getting generated as passthrough and not binderized

    All available passthrough implementations (all -impl.so files).
    These may return subclasses through their respective HIDL_FETCH_I* functions.
    R Interface
    [email protected]::I*/* (/vendor/lib/hw/)

    Should I not get this in the category binderized as default and looking something like what you have shown in the figure:
    [email protected]::ISimphw/default

    What I am missing here if anyone can help?
    Sorry for the capslock. i could not change the case

    OCTOBER 16, 2018

      -   REPLY

    1. HIDL SIMPLERAJU KHANAL

      Also i cannot see the same in ls -a. However I can see the so file in system/lib and in lshal as above.

      OCTOBER 16, 2018

        -   REPLY

  20. HIDL SIMPLEARINDAM

    IMPORTANT :

    I NEED to use an HIDL service( in CPP) while my client is in java (telephony fw).

    I need to register call backs in the service from my java module, so that i can receive notifications in telephony when there is an update in the c++ service.

    thanks

    DECEMBER 27, 2018

      -   REPLY

  21. HIDL SIMPLEANONYMOUS

    Nice post

    MARCH 27, 2019

      -   REPLY

  22. HIDL SIMPLERATNESH

    Hi,
    Thank you very much for nice tutorial, I am stuck in init.te file.
    Can you please tell me location of init.te file so i will set the given rules.
    allow init vendor_file:file { execute };
    allow init su:process { transition };
    Waiting for your response!

    APRIL 4, 2019

      -   REPLY

  23. HIDL SIMPLERATNESH

    After Adding
    allow init vendor_file:file { execute };
    allow init su:process { transition };
    at bottom of /system/sepolicy/public/init.te
    …………………………………………….
    PRODUCT_PACKAGES += \
    [email protected] \
    [email protected] \
    and also added emualtor.mk

    after build rom getting this error

    [email protected]:~/android8$ make -j4
    ============================================
    PLATFORM_VERSION_CODENAME=REL
    PLATFORM_VERSION=8.1.0
    TARGET_PRODUCT=aosp_x86_64
    TARGET_BUILD_VARIANT=eng
    TARGET_BUILD_TYPE=release
    TARGET_ARCH=x86_64
    TARGET_ARCH_VARIANT=x86_64
    TARGET_2ND_ARCH=x86
    TARGET_2ND_ARCH_VARIANT=x86_64
    HOST_ARCH=x86_64
    HOST_2ND_ARCH=x86
    HOST_OS=linux
    HOST_OS_EXTRA=Linux-4.18.0-16-generic-x86_64-with-Ubuntu-18.04-bionic
    HOST_CROSS_OS=windows
    HOST_CROSS_ARCH=x86
    HOST_CROSS_2ND_ARCH=x86_64
    HOST_BUILD_TYPE=release
    BUILD_ID=OPM7.181205.001
    OUT_DIR=out
    ============================================
    [2/2] bootstrap out/soong/.minibootstrap/build.ninja.in
    [1/1] out/soong/.bootstrap/bin/minibp out/soong/.bootstrap/build.ninja
    [78/79] glob hardware/interfaces/wifi/1.1/Android.bp
    [4/4] out/soong/.bootstrap/bin/soong_build out/soong/build.ninja
    FAILED: out/soong/build.ninja
    out/soong/.bootstrap/bin/soong_build -t -b out/soong -d out/soong/build.ninja.d -o out/soong/build.ninja Android.bp
    error: hardware/interfaces/simple/2.0/default/Android.bp:1:1: “[email protected]” depends on undefined module “[email protected]
    ninja: build stopped: subcommand failed.
    23:45:48 soong failed with: exit status 1

    APRIL 4, 2019

      -   REPLY