一簡介
從android 10開始,hwbinder引入了lazy service模式,android R正式引入到binder中。使用lazy方式注冊的binder或者hidl servicer在client退出后確認相關service沒有client調用后會自動退出,讓出系統資源,節(jié)省內存占用。比較智能。
二 原理
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那么就發(fā)送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方式