Android R(11) adds the death recipients callback of HIDL service for the client

Generally, the caller (client) of HIDL service is not in the same process with it. HIDL service generally provides hardware functions, and the caller (client) realizes characteristic functions based on this hardware function. Here, it is assumed that HIDL light service only provides the hardware function to control the on and off of specific LEDs, and client is the characteristic function to realize the flashing of LEDs every 1 second. It can be seen from the above assumptions that the client needs to call the led control interface provided by HIDL light service continuously, and the interval is 1 second. If the HIDL light service exits unexpectedly, the client will not be able to realize the feature function,
Therefore, it is necessary to know the running status of HIDL light service in the client. In the HIDL framework, a resident caller like client will register death receivers to explain the status. serviceModelClient is used here as an example of this scenario.

1.Android.bp

flagstaff@flagstaff-pc:~/aosp_r.lns/test/flagstaffTest$ cat hardware/interfaces/custom_hardware/1.0/serviceModelClient/Android.bp
cc_binary {
    name: "serviceModelClient",
    vendor: true,
    srcs: [
        "*.cpp",
        "src/*.cpp",
    ],
    shared_libs: [
        ...
        "flagstaff.hardware.custom_hardware@1.0",
    ],
    cppflags:[
        "-DLOG_TAG=\"serviceModelClient\"",
    ],
}

It belongs to c language executable program, so CC is used_ Binary is compiled, which is consistent with the implementation of hidl service.

2. Implementation of Death recipients in client

2.1 hidl_ death_ Definition of recipient

The class on the CPP side is hidl_ death_ The recipient contains only one interface servicedid. After the client implements and registers with the hidl service, the implementation will be called back after the hidl service dies. Its definition is as follows

namespace hardware {
...
//file:system\libhidl\base\include\hidl\HidlSupport.h
// hidl_death_recipient is a callback interfaced that can be used with
// linkToDeath() / unlinkToDeath()
struct hidl_death_recipient : public virtual RefBase {
    virtual void serviceDied(uint64_t cookie,
            const ::android::wp<::android::hidl::base::V1_0::IBase>& who) = 0;
};
..
}

2.2 hidl_ death_ Implementation of recipient

The following is the implementation of this interface in serviceModelClient

//file:test\flagstaffTest\hardware\interfaces\custom_hardware\1.0\serviceModelClient\serviceModelClient.cpp
static sp<hidl_death_recipient> mChd = nullptr;
static android::sp<ICustomHardware> mService = nullptr;

class CustomHardwareDeath : public hidl_death_recipient {
private:
	int mDeathCount = 1;
public:
    void serviceDied(uint64_t cookie, const wp<IBase>& who) override {
		mService = ICustomHardware::getService();
    	Return<bool> ret = mService->linkToDeath(mChd, mDeathCount++);
	}
};

After receiving the death notice of hidl service, serviceModelClient does the following three things
a) re acquire ICustomHardware services.
b) re register the death receiver of ICustomHardware service.
C) the internal flag of servicemodelclient is set. Since this is a test program, there is no flag to reset.

3. Use of death recipients

//file:test\flagstaffTest\hardware\interfaces\custom_hardware\1.0\serviceModelClient\serviceModelClient.cpp
static sp<hidl_death_recipient> mChd = nullptr;
static android::sp<ICustomHardware> mService = nullptr;
...
int main(int /* argc */, char** /* argv */) {
    ...
	android::sp<ICustomHardware> mService = ICustomHardware::getService();
	if (mService == nullptr) {
		LOG(ERROR)<<"Failed to get ICustomHardware instance of default";
		return -1;
	}

	mChd = new CustomHardwareDeath();
	Return<bool> ret = mService->linkToDeath(mChd, 0);

	joinRpcThreadpool();
	/* The following code is an example for unlinkToDeath only. Reaching here in abnormal.*/
	mService->unlinkToDeath(mChd);
	return 1;
}

The implementation steps are as follows
a) obtain ICustomHardware services.
b) instantiate customhardwareeat.
c) call the HIDL interface linkToDeath to register customhardwareeat. A death receiver supports processing multiple HIDL services. Cookies are used to distinguish HIDL services. Here, they are used to count the number of deaths.
d) after the client exits, actively call the interface unlinkToDeath to release the previously registered death callback.

4. Operation results

generic_x86_64:/ # killall flagstaff.hardware.custom_hardware@1.0-service
02-05 18:08:57.245  2112  2112 E serviceModelClient: CustomHardwareDeath:[cookie]0
generic_x86_64:/ # killall flagstaff.hardware.custom_hardware@1.0-service
02-05 18:08:59.371  2112  2112 E serviceModelClient: CustomHardwareDeath:[cookie]1
generic_x86_64:/ # killall flagstaff.hardware.custom_hardware@1.0-service
02-05 18:09:02.917  2112  2112 E serviceModelClient: CustomHardwareDeath:[cookie]2

It can be seen from the above experimental results that after each hidl service death, the client will receive the corresponding notification and the view will be restored.

5. Complete code

serviceModelClient source code

https://gitee.com/solo-king/android-rhidl-about/tree/master/hardware/interfaces/custom_hardware/1.0/serviceModelClient

In addition, if you have any questions, please leave a message or email( 836190520@qq.com )I believe that technological upgrading lies in communication~~

Keywords: Android Framework Cpp hardware aidl

Added by michaelnorth on Sat, 05 Feb 2022 12:22:31 +0200