blob: 8a08e5b678e17db555cc8b87938e911022949f45 [file] [log] [blame]
Lais Andrade24b5b8f2020-08-27 15:55:54 +00001/*
2 * Copyright (C) 2020 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#define LOG_TAG "VibratorManagerHalWrapper"
18
19#include <utils/Log.h>
20
21#include <vibratorservice/VibratorManagerHalWrapper.h>
22
Lais Andrade98c97032020-11-17 19:23:01 +000023namespace Aidl = android::hardware::vibrator;
24
Lais Andrade24b5b8f2020-08-27 15:55:54 +000025namespace android {
26
27namespace vibrator {
28
29constexpr int32_t SINGLE_VIBRATOR_ID = 0;
Lais Andrade98c97032020-11-17 19:23:01 +000030const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id=";
Lais Andrade24b5b8f2020-08-27 15:55:54 +000031
32HalResult<void> LegacyManagerHalWrapper::ping() {
33 return mController->ping();
34}
35
36void LegacyManagerHalWrapper::tryReconnect() {
37 mController->tryReconnect();
38}
39
Lais Andrade98c97032020-11-17 19:23:01 +000040HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() {
41 return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE);
42}
43
Lais Andrade24b5b8f2020-08-27 15:55:54 +000044HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() {
45 if (mController->init()) {
46 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID));
47 }
48 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
49 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>());
50}
51
52HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(int32_t id) {
53 if (id == SINGLE_VIBRATOR_ID && mController->init()) {
54 return HalResult<std::shared_ptr<HalController>>::ok(mController);
55 }
56 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
Lais Andrade98c97032020-11-17 19:23:01 +000057 return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX +
Lais Andrade24b5b8f2020-08-27 15:55:54 +000058 std::to_string(id));
59}
60
61HalResult<void> LegacyManagerHalWrapper::prepareSynced(const std::vector<int32_t>&) {
62 return HalResult<void>::unsupported();
63}
64
65HalResult<void> LegacyManagerHalWrapper::triggerSynced(const std::function<void()>&) {
66 return HalResult<void>::unsupported();
67}
68
69HalResult<void> LegacyManagerHalWrapper::cancelSynced() {
70 return HalResult<void>::unsupported();
71}
72
Lais Andrade98c97032020-11-17 19:23:01 +000073// -------------------------------------------------------------------------------------------------
74
Lais Andradef20b1442020-11-19 15:14:10 +000075std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator(
76 int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) {
77 std::function<HalResult<sp<Aidl::IVibrator>>()> reconnectFn = [=]() {
Lais Andrade98c97032020-11-17 19:23:01 +000078 sp<Aidl::IVibrator> vibrator;
Lais Andradef20b1442020-11-19 15:14:10 +000079 auto result = this->getHal()->getVibrator(vibratorId, &vibrator);
Lais Andrade98c97032020-11-17 19:23:01 +000080 return HalResult<sp<Aidl::IVibrator>>::fromStatus(result, vibrator);
81 };
82 auto result = reconnectFn();
83 if (!result.isOk()) {
84 return nullptr;
85 }
86 auto vibrator = result.value();
87 if (!vibrator) {
88 return nullptr;
89 }
90 return std::move(std::make_unique<AidlHalWrapper>(std::move(callbackScheduler),
91 std::move(vibrator), reconnectFn));
92}
93
94HalResult<void> AidlManagerHalWrapper::ping() {
95 return HalResult<void>::fromStatus(IInterface::asBinder(getHal())->pingBinder());
96}
97
98void AidlManagerHalWrapper::tryReconnect() {
99 sp<Aidl::IVibratorManager> newHandle = checkVintfService<Aidl::IVibratorManager>();
100 if (newHandle) {
101 std::lock_guard<std::mutex> lock(mHandleMutex);
102 mHandle = std::move(newHandle);
103 }
104}
105
106HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() {
107 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
108 if (mCapabilities.has_value()) {
109 // Return copy of cached value.
110 return HalResult<ManagerCapabilities>::ok(*mCapabilities);
111 }
112 int32_t cap = 0;
113 auto result = getHal()->getCapabilities(&cap);
114 auto ret = HalResult<ManagerCapabilities>::fromStatus(result,
115 static_cast<ManagerCapabilities>(cap));
116 if (ret.isOk()) {
117 // Cache copy of returned value.
118 mCapabilities.emplace(ret.value());
119 }
120 return ret;
121}
122
123HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() {
124 std::lock_guard<std::mutex> lock(mVibratorsMutex);
125 if (mVibratorIds.has_value()) {
126 // Return copy of cached values.
127 return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
128 }
129 std::vector<int32_t> ids;
130 auto result = getHal()->getVibratorIds(&ids);
131 auto ret = HalResult<std::vector<int32_t>>::fromStatus(result, ids);
132 if (ret.isOk()) {
133 // Cache copy of returned value and the individual controllers.
134 mVibratorIds.emplace(ret.value());
135 for (auto& id : ids) {
Lais Andradef20b1442020-11-19 15:14:10 +0000136 HalController::Connector connector = [&, id](auto scheduler) {
137 return this->connectToVibrator(id, scheduler);
138 };
139 auto controller = std::make_unique<HalController>(mCallbackScheduler, connector);
Lais Andrade98c97032020-11-17 19:23:01 +0000140 mVibrators[id] = std::move(controller);
141 }
142 }
143 return ret;
144}
145
146HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) {
147 // Make sure we cache vibrator ids and initialize the individual controllers.
148 getVibratorIds();
149 std::lock_guard<std::mutex> lock(mVibratorsMutex);
150 auto it = mVibrators.find(id);
151 if (it != mVibrators.end()) {
152 return HalResult<std::shared_ptr<HalController>>::ok(it->second);
153 }
154 return HalResult<std::shared_ptr<HalController>>::failed(MISSING_VIBRATOR_MESSAGE_PREFIX +
155 std::to_string(id));
156}
157
158HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
159 auto ret = HalResult<void>::fromStatus(getHal()->prepareSynced(ids));
160 if (ret.isOk()) {
161 // Force reload of all vibrator controllers that were prepared for a sync operation here.
162 // This will trigger calls to getVibrator(id) on each controller, so they can use the
163 // latest service provided by this manager.
164 std::lock_guard<std::mutex> lock(mVibratorsMutex);
165 for (auto& id : ids) {
166 auto it = mVibrators.find(id);
167 if (it != mVibrators.end()) {
168 it->second->tryReconnect();
169 }
170 }
171 }
172 return ret;
173}
174
175HalResult<void> AidlManagerHalWrapper::triggerSynced(
176 const std::function<void()>& completionCallback) {
177 HalResult<ManagerCapabilities> capabilities = getCapabilities();
178 bool supportsCallback = capabilities.isOk() &&
179 static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
180 auto cb = supportsCallback ? new HalCallbackWrapper(completionCallback) : nullptr;
181 return HalResult<void>::fromStatus(getHal()->triggerSynced(cb));
182}
183
184HalResult<void> AidlManagerHalWrapper::cancelSynced() {
185 auto ret = HalResult<void>::fromStatus(getHal()->cancelSynced());
186 if (ret.isOk()) {
187 // Force reload of all vibrator controllers that were prepared for a sync operation before.
188 // This will trigger calls to getVibrator(id) on each controller, so they can use the
189 // latest service provided by this manager.
190 std::lock_guard<std::mutex> lock(mVibratorsMutex);
191 for (auto& entry : mVibrators) {
192 entry.second->tryReconnect();
193 }
194 }
195 return ret;
196}
197
198sp<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
199 std::lock_guard<std::mutex> lock(mHandleMutex);
200 return mHandle;
201}
202
Lais Andrade24b5b8f2020-08-27 15:55:54 +0000203}; // namespace vibrator
204
205}; // namespace android