blob: 0656318256743ffe7163da0d824be73449532991 [file] [log] [blame]
Peter Kalauskas3373cd32018-10-24 15:37:00 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <hidl/HidlLazyUtils.h>
18#include <hidl/HidlTransportSupport.h>
19
20#include <android-base/logging.h>
21
22#include <android/hidl/manager/1.2/IClientCallback.h>
23#include <android/hidl/manager/1.2/IServiceManager.h>
24
25namespace android {
26namespace hardware {
27namespace details {
28
29class ClientCounterCallback : public ::android::hidl::manager::V1_2::IClientCallback {
30 public:
31 ClientCounterCallback() : mNumConnectedServices(0), mNumRegisteredServices(0) {}
32
33 void incServiceCounter();
34
35 protected:
36 Return<void> onClients(const sp<::android::hidl::base::V1_0::IBase>& service,
37 bool clients) override;
38
39 private:
40 /**
41 * Counter of the number of services that currently have at least one client.
42 */
43 size_t mNumConnectedServices;
44
45 /**
46 * Number of services that have been registered.
47 */
48 size_t mNumRegisteredServices;
49};
50
51class LazyServiceRegistrarImpl {
52 public:
53 LazyServiceRegistrarImpl() : mClientCallback(new ClientCounterCallback) {}
54
55 status_t registerServiceWithCallback(const sp<::android::hidl::base::V1_0::IBase>& service,
56 const std::string& name);
57
58 private:
59 sp<ClientCounterCallback> mClientCallback;
60};
61
62void ClientCounterCallback::incServiceCounter() {
63 mNumRegisteredServices++;
64}
65
66/**
67 * onClients is oneway, so no need to worry about multi-threading. Note that this means multiple
68 * invocations could occur on different threads however.
69 */
70Return<void> ClientCounterCallback::onClients(const sp<::android::hidl::base::V1_0::IBase>& service,
71 bool clients) {
72 if (clients) {
73 LOG(INFO) << "HAL " << service->descriptor << " connected.";
74 mNumConnectedServices++;
75 } else {
76 LOG(INFO) << "HAL " << service->descriptor << " disconnected.";
77 mNumConnectedServices--;
78 }
79 LOG(INFO) << "HAL has " << mNumConnectedServices << " (of " << mNumRegisteredServices
80 << " available) clients in use.";
81
82 if (mNumConnectedServices == 0) {
83 LOG(INFO) << "Exiting HAL. No clients in use for any service in process.";
84 exit(EXIT_SUCCESS);
85 }
86 return Status::ok();
87}
88
89status_t LazyServiceRegistrarImpl::registerServiceWithCallback(
90 const sp<::android::hidl::base::V1_0::IBase>& service, const std::string& name) {
91 static auto manager = hardware::defaultServiceManager1_2();
92 LOG(INFO) << "Registering HAL: " << service->descriptor << " with name: " << name;
93 // TODO(b/118394906): Convert to service->registerAsService(name) when possible
94 status_t res = android::hardware::details::registerAsServiceInternal(service, name);
95 if (res == android::OK) {
96 mClientCallback->incServiceCounter();
97 bool ret = manager->registerClientCallback(service, mClientCallback);
98 if (!ret) {
99 res = android::INVALID_OPERATION;
100 LOG(ERROR) << "Failed to add client callback";
101 }
102 } else {
103 LOG(ERROR) << "Failed to register as service";
104 }
105 return res;
106}
107
108} // namespace details
109
110LazyServiceRegistrar::LazyServiceRegistrar() {
111 mImpl = std::make_shared<details::LazyServiceRegistrarImpl>();
112}
113
114status_t LazyServiceRegistrar::registerServiceWithCallback(
115 const sp<::android::hidl::base::V1_0::IBase>& service, const std::string& name) {
116 return mImpl->registerServiceWithCallback(service, name);
117}
118
119} // namespace hardware
120} // namespace android