美文网首页
HIDL safe_union类型介绍

HIDL safe_union类型介绍

作者: Little熊猫 | 来源:发表于2020-04-28 19:02 被阅读0次

一简介

AIDL可以自动生成java语言,而java不像c/c++那样有union类型,因此HIDL部分的HAL语言是支持union类型的,当然这部分只限于生成c++代码,java代码不支持。从Andorid Q开始,HAL语言在java层面支持了union类型,可以使用safe_union来。那么hidl内部如何做到union的支持呢?

二 代码分析

比如我们添加一个safe_union类型,如下:

safe_union test2 {
    int32_t type1;
    int32_t type2;
};

通过hidl-gen生成test2.java,内容如下:

ublic final class test2 {
    public test2() {
        hidl_o = 0;
    }

    public static final class hidl_discriminator {
        public static final byte type1 = 0;  // int
        public static final byte type2 = 1;  // int

        public static final String getName(byte value) {
            switch (value) {
                case 0: { return "type1"; }
                case 1: { return "type2"; }
                default: { return "Unknown"; }
            }
        }

        private hidl_discriminator() {}
    }

    private byte hidl_d = 0;
    private Object hidl_o = null;
    public void type1(int type1) {
        hidl_d = hidl_discriminator.type1;
        hidl_o = type1;
    }

    public final void readFromParcel(android.os.HwParcel parcel) {
        android.os.HwBlob blob = parcel.readBuffer(8 /* size */);
        readEmbeddedFromParcel(parcel, blob, 0 /* parentOffset */);
    }

    public static final java.util.ArrayList<test2> readVectorFromParcel(android.os.HwParcel parcel) {
        java.util.ArrayList<test2> _hidl_vec = new java.util.ArrayList();
        android.os.HwBlob _hidl_blob = parcel.readBuffer(16 /* sizeof hidl_vec<T> */);

        {
            int _hidl_vec_size = _hidl_blob.getInt32(0 + 8 /* offsetof(hidl_vec<T>, mSize) */);
            android.os.HwBlob childBlob = parcel.readEmbeddedBuffer(
                    _hidl_vec_size * 8,_hidl_blob.handle(),
                    0 + 0 /* offsetof(hidl_vec<T>, mBuffer) */,true /* nullable */);

            _hidl_vec.clear();
            for (int _hidl_index_0 = 0; _hidl_index_0 < _hidl_vec_size; ++_hidl_index_0) {
                android.hardware.light.V2_0.test2 _hidl_vec_element = new android.hardware.light.V2_0.test2();
                ((android.hardware.light.V2_0.test2) _hidl_vec_element).readEmbeddedFromParcel(parcel, childBlob, _hidl_index_0 * 8);
                _hidl_vec.add(_hidl_vec_element);
            }
        }

        return _hidl_vec;
    }

    public final void readEmbeddedFromParcel(
            android.os.HwParcel parcel, android.os.HwBlob _hidl_blob, long _hidl_offset) {
        hidl_d = _hidl_blob.getInt8(_hidl_offset + 0);
        switch (this.hidl_d) {
            case hidl_discriminator.type1: {
                hidl_o = 0;
                hidl_o = _hidl_blob.getInt32(_hidl_offset + 4);
                break;
            }
            case hidl_discriminator.type2: {
                hidl_o = 0;
                hidl_o = _hidl_blob.getInt32(_hidl_offset + 4);
                break;
            }
            default: {
                throw new IllegalStateException("Unknown union discriminator (value: " + hidl_d + ").");
            }
        }
    }


};

java传输采用数组的形式,test2类型为例,里面保存两个int类型,占用4个字节,对应的数组占用16个字节,数组[0]保存类型,数组【1】保存值,数组【2】保存数组大小,剩下【3】作为padding

c++的对应实现

struct test2 final {
    enum class hidl_discriminator : uint8_t {
        type1 = 0,  // int32_t
        type2 = 1,  // int32_t
    };

    test2();
    ~test2();
    test2(test2&&);
    test2(const test2&);
    test2& operator=(test2&&);
    test2& operator=(const test2&);

    void type1(int32_t);
    int32_t& type1();
    int32_t type1() const;

    void type2(int32_t);
    int32_t& type2();
    int32_t type2() const;

    // Utility methods
    hidl_discriminator getDiscriminator() const;

    constexpr size_t hidl_getUnionOffset() const {
        return offsetof(::android::hardware::light::V2_0::test2, hidl_u);
    }

private:
    void hidl_destructUnion();

    hidl_discriminator hidl_d __attribute__ ((aligned(1))) ;
    union hidl_union final {
        int32_t type1 __attribute__ ((aligned(4)));
        int32_t type2 __attribute__ ((aligned(4)));

        hidl_union();
        ~hidl_union();
    } hidl_u;

    static_assert(sizeof(::android::hardware::light::V2_0::test2::hidl_union) == 4, "wrong size");
    static_assert(__alignof(::android::hardware::light::V2_0::test2::hidl_union) == 4, "wrong alignment");
    static_assert(sizeof(::android::hardware::light::V2_0::test2::hidl_discriminator) == 1, "wrong size");
    static_assert(__alignof(::android::hardware::light::V2_0::test2::hidl_discriminator) == 1, "wrong alignment");
};

可以看到C++对于test2类型的保存也是按照java顺序进行的,由于union是4个字节对齐,因此会给type空出3个字节,与java实现了一一对应

    hidl_discriminator hidl_d __attribute__ ((aligned(1))) ;
    union hidl_union final {
        int32_t type1 __attribute__ ((aligned(4)));
        int32_t type2 __attribute__ ((aligned(4)));

        hidl_union();
        ~hidl_union();
    } hidl_u;

三 总结

HIDL当初设计是给HAL使用的,从R开始HIDL逐渐切换成AIDL,safe_union无法在binder使用。但是binder之间数据传递得到了统一,无需再进行切换。

相关文章

  • HIDL safe_union类型介绍

    一简介 AIDL可以自动生成java语言,而java不像c/c++那样有union类型,因此HIDL部分的HAL语...

  • android HAL简介

    Android HAL(硬件抽象层)介绍以及调用 Android HIDL学习(1) ---- 简介Android...

  • HIDL实战笔记

    目录 第一篇:HIDL学习笔记之HIDL C++(第一天)第二篇:HIDL学习笔记之HIDL C++(第二天)第三...

  • CameraProvider启动流程分析

    CameraProvider进程中hidl文件 HIDL文件服务端客户端BinderNameICameraProv...

  • HIDL模型分析

    一 HIDL的结构体关系 以 Light的HIDL为例,class之间的关系如下 二 client端 sm 通过...

  • C++ struct和class区别

    一 struct继承 最近分析HIDL,在HIDL的生成中google使用了大量的struct继承,比如 首先看一...

  • Android HIDL学习(1) ---- 简介

    HIDL HAL接口定义语言(简称HIDL)适用于指定HAL和其用户之间的接口的一种接口描述语言(IDL)。HID...

  • HIDL In Telephony

    前置文章 《HIDL》 前言 在 Android 8.0(不含,下同)之前,Telephony 和 modem 之...

  • hidl 编译

  • MTK camerahalserver 层初始化流程

    看日志首先通过HIDL 调用 \vendor\mediatek\proprietary\hardware\mtkc...

网友评论

      本文标题:HIDL safe_union类型介绍

      本文链接:https://www.haomeiwen.com/subject/guvbwhtx.html