[Android][frameworks][HIDL]使用HIDL新建虛擬HAL以實現system_server與native進程雙向通信(三)——JAVA客戶端

前言

上一篇中已經完成了服務端的集成,手機軟件此時已經可以自動啓動服務端,且運行無異常。

接下來我們就要實現我們的終極目標了:system_server(JAVA端)與服務端相互通信;

預處理

首先先解釋下一個“玄學”的情況:在前兩章的操作完成後,我們不需要添加任何JAVA類,即可直接使用;

究其原因,是因爲在我們之前使用hidl-gen的時候,生成的Android.bp中包含這個字段:

hidl_interface {
    ...
    gen_java: true,
}

字段定義與實現可在這裏查到:/system/tools/hidl/build/hidl_interface.go,在此先不講解,後續有時間再補上:

JAVA代碼

添加Android.bp依賴:

    static_libs: [
        "vendor.zsui.hardware.example-V1.0-java",
    ]

核心代碼:

import vendor.zsui.hardware.example.V1_0.IExample;
...
        try {
            IExample example = IExample.getService();
            Slog.d("ZSUI", "example HELLO WORLD result = " + example.helloWorld("ZSUI"));
        } catch (Exception e) {
            e.printStackTrace();
        }
...

需要注意一點,在[email protected]中我們定義該服務的類別爲HAL(class hal),這會導致它的啓動可能比system_server中的核心服務(AMS/PowerMS等)晚,所以實際使用中需要做容錯判斷;

至此,一切似乎都處理好了,編譯也通過了,是不是可以看到Hello World了呢?

02-26 12:33:21.407   449   449 W hwservicemanager: getTransport: Cannot find entry [email protected]::IExample/default in either framework or device manifest.
02-26 12:33:21.407  1467  1574 W System.err: java.util.NoSuchElementException
02-26 12:33:21.408  1467  1574 W System.err: 	at android.os.HwBinder.getService(Native Method)
02-26 12:33:21.408  1467  1574 W System.err: 	at android.os.HwBinder.getService(HwBinder.java:91)
02-26 12:33:21.408  1467  1574 W System.err: 	at vendor.zsui.hardware.example.V1_0.IExample.getService(IExample.java:48)
02-26 12:33:21.408  1467  1574 W System.err: 	at vendor.zsui.hardware.example.V1_0.IExample.getService(IExample.java:52)
02-26 12:33:21.408  1467  1574 W System.err: 	at com.android.server.am.ActivityManagerService.bootAnimationComplete(ActivityManagerService.java:8246)
02-26 12:33:21.408  1467  1574 W System.err: 	at com.android.server.wm.WindowManagerService.performEnableScreen(WindowManagerService.java:3495)
02-26 12:33:21.408  1467  1574 W System.err: 	at com.android.server.wm.WindowManagerService.access$1100(WindowManagerService.java:272)
02-26 12:33:21.408  1467  1574 W System.err: 	at com.android.server.wm.WindowManagerService$H.handleMessage(WindowManagerService.java:4975)
02-26 12:33:21.408  1467  1574 W System.err: 	at android.os.Handler.dispatchMessage(Handler.java:106)
02-26 12:33:21.408  1467  1574 W System.err: 	at android.os.Looper.loop(Looper.java:193)
02-26 12:33:21.408  1467  1574 W System.err: 	at android.os.HandlerThread.run(HandlerThread.java:65)
02-26 12:33:21.408  1467  1574 W System.err: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

這個是由於Vintf機制要求,需要在manifest.xml中聲明這個HIDL,因此將如下內容添加到對應文件中即可:

在device/<$vendor>/<$product>/manifest.xml或等效的位置添加:

<manifest version="1.0" type="device">
    ...
    <hal format="hidl">
        <name>vendor.zsui.hardware.example</name>
        <transport>hwbinder</transport>
        <version>1.0</version>
        <interface>
            <name>IExample</name>
            <instance>default</instance>
        </interface>
    </hal>
    ...
</manifest> 

刷機,開機,一切正常:

02-26 12:46:22.879  1476  1562 D ZSUI    : example HELLO WORLD result = Hello World, ZSUI

至此,連續三章的虛擬HAL創建步驟已經完成。

這三篇主要是步驟解讀,相信按照這個一步一步來,實際使用是沒有問題的。

但是這三篇並沒有對原理方面做過多解釋,因此之後會更新一篇Q&A,主要講解部分看似“玄學”的操作;

文筆有限,若有謬誤,還請指出;

感謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章