HIDL safe_union类型介绍

一简介

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之间数据传递得到了统一,无需再进行切换。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容