binder LAZY 模式介绍
2020-04-21 本文已影响0人
Little熊猫
一简介
从android 10开始,hwbinder引入了lazy service模式,android R正式引入到binder中。使用lazy方式注册的binder或者hidl servicer在client退出后确认相关service没有client调用后会自动退出,让出系统资源,节省内存占用。比较智能。
二 原理
1) hidl service lazy 注册接口
class LazyServiceRegistrarImpl {
public:
LazyServiceRegistrarImpl() : mClientCallback(new ClientCounterCallback) {}
status_t registerService(const sp<::android::hidl::base::V1_0::IBase>& service,
const std::string& name);
private:
sp<ClientCounterCallback> mClientCallback;
};
注册hidl service成功后多了个onClients回调,在client连接数为0时退出service
/**
* onClients is oneway, so no need to worry about multi-threading. Note that this means multiple
* invocations could occur on different threads however.
*/
Return<void> ClientCounterCallback::onClients(const sp<::android::hidl::base::V1_0::IBase>& service,
bool clients) {
if (clients) {
mNumConnectedServices++;
} else {
mNumConnectedServices--;
}
LOG(INFO) << "Process has " << mNumConnectedServices << " (of " << mRegisteredServices.size()
<< " available) client(s) in use after notification " << getDescriptor(service.get())
<< " has clients: " << clients;
if (mNumConnectedServices == 0) {
tryShutdown();
}
return Status::ok();
}
在hwservicemanager侧注册的Hidl service会判断当前的client数,如果有client那么就发送sendClientCallbackNotifications(true);通知对应的hidl service。如果client为空的话sendClientCallbackNotifications(false)通知hidl service client为空了。
ssize_t HidlService::forceHandleClientCallbacks(bool isCalledOnInterval) {
ssize_t count = getNodeStrongRefCount();
// binder driver doesn't support this feature
if (count == -1) return count;
bool hasClients = count > 1; // this process holds a strong count
if (mGuaranteeClient) {
// we have no record of this client
if (!mHasClients && !hasClients) {
sendClientCallbackNotifications(true);
}
// guarantee is temporary
mGuaranteeClient = false;
}
if (hasClients && !mHasClients) {
// client was retrieved in some other way
sendClientCallbackNotifications(true);
}
// there are no more clients, but the callback has not been called yet
if (!hasClients && mHasClients && isCalledOnInterval) {
mNoClientsCounter++;
if (mNoClientsCounter >= kNoClientRepeatLimit) {
sendClientCallbackNotifications(false);
}
}
return count;
}
forceHandleClientCallbacks调用的几个时机:
1) 在client get service时通知hidl servie mNumConnectedServices++
- 取消注册时tryUnregister
3) ClientCallbackCallback 调用mManager->handleClientCallbacks();interval是5秒钟
三 总结
从android R开始,binder借鉴了hidl也引入了lazy模式,具体见frameworks/native/libs/binder/LazyServiceRegistrar.cpp,原理同HIDL方式