1 /*
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
23 namespace Aidl = aidl::android::hardware::vibrator;
24
25 namespace android {
26
27 namespace vibrator {
28
29 constexpr int32_t SINGLE_VIBRATOR_ID = 0;
30 const constexpr char* MISSING_VIBRATOR_MESSAGE_PREFIX = "No vibrator with id=";
31
prepareSynced(const std::vector<int32_t> &)32 HalResult<void> ManagerHalWrapper::prepareSynced(const std::vector<int32_t>&) {
33 return HalResult<void>::unsupported();
34 }
35
triggerSynced(const std::function<void ()> &)36 HalResult<void> ManagerHalWrapper::triggerSynced(const std::function<void()>&) {
37 return HalResult<void>::unsupported();
38 }
39
cancelSynced()40 HalResult<void> ManagerHalWrapper::cancelSynced() {
41 return HalResult<void>::unsupported();
42 }
43
startSession(const std::vector<int32_t> &,const Aidl::VibrationSessionConfig &,const std::function<void ()> &)44 HalResult<std::shared_ptr<Aidl::IVibrationSession>> ManagerHalWrapper::startSession(
45 const std::vector<int32_t>&, const Aidl::VibrationSessionConfig&,
46 const std::function<void()>&) {
47 return HalResult<std::shared_ptr<Aidl::IVibrationSession>>::unsupported();
48 }
49
clearSessions()50 HalResult<void> ManagerHalWrapper::clearSessions() {
51 return HalResult<void>::unsupported();
52 }
53
54 // -------------------------------------------------------------------------------------------------
55
ping()56 HalResult<void> LegacyManagerHalWrapper::ping() {
57 auto pingFn = [](HalWrapper* hal) { return hal->ping(); };
58 return mController->doWithRetry<void>(pingFn, "ping");
59 }
60
tryReconnect()61 void LegacyManagerHalWrapper::tryReconnect() {
62 mController->tryReconnect();
63 }
64
getCapabilities()65 HalResult<ManagerCapabilities> LegacyManagerHalWrapper::getCapabilities() {
66 return HalResult<ManagerCapabilities>::ok(ManagerCapabilities::NONE);
67 }
68
getVibratorIds()69 HalResult<std::vector<int32_t>> LegacyManagerHalWrapper::getVibratorIds() {
70 if (mController->init()) {
71 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>(1, SINGLE_VIBRATOR_ID));
72 }
73 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
74 return HalResult<std::vector<int32_t>>::ok(std::vector<int32_t>());
75 }
76
getVibrator(int32_t id)77 HalResult<std::shared_ptr<HalController>> LegacyManagerHalWrapper::getVibrator(int32_t id) {
78 if (id == SINGLE_VIBRATOR_ID && mController->init()) {
79 return HalResult<std::shared_ptr<HalController>>::ok(mController);
80 }
81 // Controller.init did not connect to any vibrator HAL service, so the device has no vibrator.
82 return HalResult<std::shared_ptr<HalController>>::failed(
83 (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
84 }
85
86 // -------------------------------------------------------------------------------------------------
87
connectToVibrator(int32_t vibratorId,std::shared_ptr<CallbackScheduler> callbackScheduler)88 std::shared_ptr<HalWrapper> AidlManagerHalWrapper::connectToVibrator(
89 int32_t vibratorId, std::shared_ptr<CallbackScheduler> callbackScheduler) {
90 std::function<HalResult<std::shared_ptr<Aidl::IVibrator>>()> reconnectFn = [=, this]() {
91 std::shared_ptr<Aidl::IVibrator> vibrator;
92 auto status = this->getHal()->getVibrator(vibratorId, &vibrator);
93 return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrator>>(std::move(status),
94 vibrator);
95 };
96 auto result = reconnectFn();
97 if (!result.isOk()) {
98 return nullptr;
99 }
100 auto vibrator = result.value();
101 if (!vibrator) {
102 return nullptr;
103 }
104 return std::make_unique<AidlHalWrapper>(std::move(callbackScheduler), std::move(vibrator),
105 reconnectFn);
106 }
107
ping()108 HalResult<void> AidlManagerHalWrapper::ping() {
109 return HalResultFactory::fromStatus(AIBinder_ping(getHal()->asBinder().get()));
110 }
111
tryReconnect()112 void AidlManagerHalWrapper::tryReconnect() {
113 auto aidlServiceName = std::string(Aidl::IVibratorManager::descriptor) + "/default";
114 std::shared_ptr<Aidl::IVibratorManager> newHandle = Aidl::IVibratorManager::fromBinder(
115 ndk::SpAIBinder(AServiceManager_checkService(aidlServiceName.c_str())));
116 if (newHandle) {
117 std::lock_guard<std::mutex> lock(mHandleMutex);
118 mHandle = std::move(newHandle);
119 }
120 }
121
getCapabilities()122 HalResult<ManagerCapabilities> AidlManagerHalWrapper::getCapabilities() {
123 std::lock_guard<std::mutex> lock(mCapabilitiesMutex);
124 if (mCapabilities.has_value()) {
125 // Return copy of cached value.
126 return HalResult<ManagerCapabilities>::ok(*mCapabilities);
127 }
128 int32_t cap = 0;
129 auto status = getHal()->getCapabilities(&cap);
130 auto capabilities = static_cast<ManagerCapabilities>(cap);
131 auto ret = HalResultFactory::fromStatus<ManagerCapabilities>(std::move(status), capabilities);
132 if (ret.isOk()) {
133 // Cache copy of returned value.
134 mCapabilities.emplace(ret.value());
135 }
136 return ret;
137 }
138
getVibratorIds()139 HalResult<std::vector<int32_t>> AidlManagerHalWrapper::getVibratorIds() {
140 std::lock_guard<std::mutex> lock(mVibratorsMutex);
141 if (mVibratorIds.has_value()) {
142 // Return copy of cached values.
143 return HalResult<std::vector<int32_t>>::ok(*mVibratorIds);
144 }
145 std::vector<int32_t> ids;
146 auto status = getHal()->getVibratorIds(&ids);
147 auto ret = HalResultFactory::fromStatus<std::vector<int32_t>>(std::move(status), ids);
148 if (ret.isOk()) {
149 // Cache copy of returned value and the individual controllers.
150 mVibratorIds.emplace(ret.value());
151 for (auto& id : ids) {
152 HalController::Connector connector = [&, id](auto scheduler) {
153 return this->connectToVibrator(id, scheduler);
154 };
155 auto controller = std::make_unique<HalController>(mCallbackScheduler, connector);
156 mVibrators[id] = std::move(controller);
157 }
158 }
159 return ret;
160 }
161
getVibrator(int32_t id)162 HalResult<std::shared_ptr<HalController>> AidlManagerHalWrapper::getVibrator(int32_t id) {
163 // Make sure we cache vibrator ids and initialize the individual controllers.
164 getVibratorIds();
165 std::lock_guard<std::mutex> lock(mVibratorsMutex);
166 auto it = mVibrators.find(id);
167 if (it != mVibrators.end()) {
168 return HalResult<std::shared_ptr<HalController>>::ok(it->second);
169 }
170 return HalResult<std::shared_ptr<HalController>>::failed(
171 (MISSING_VIBRATOR_MESSAGE_PREFIX + std::to_string(id)).c_str());
172 }
173
prepareSynced(const std::vector<int32_t> & ids)174 HalResult<void> AidlManagerHalWrapper::prepareSynced(const std::vector<int32_t>& ids) {
175 auto ret = HalResultFactory::fromStatus(getHal()->prepareSynced(ids));
176 if (ret.isOk()) {
177 // Force reload of all vibrator controllers that were prepared for a sync operation here.
178 // This will trigger calls to getVibrator(id) on each controller, so they can use the
179 // latest service provided by this manager.
180 std::lock_guard<std::mutex> lock(mVibratorsMutex);
181 for (auto& id : ids) {
182 auto it = mVibrators.find(id);
183 if (it != mVibrators.end()) {
184 it->second->tryReconnect();
185 }
186 }
187 }
188 return ret;
189 }
190
triggerSynced(const std::function<void ()> & completionCallback)191 HalResult<void> AidlManagerHalWrapper::triggerSynced(
192 const std::function<void()>& completionCallback) {
193 HalResult<ManagerCapabilities> capabilities = getCapabilities();
194 bool supportsCallback = capabilities.isOk() &&
195 static_cast<int32_t>(capabilities.value() & ManagerCapabilities::TRIGGER_CALLBACK);
196 auto cb = supportsCallback ? ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback)
197 : nullptr;
198 return HalResultFactory::fromStatus(getHal()->triggerSynced(cb));
199 }
200
startSession(const std::vector<int32_t> & ids,const Aidl::VibrationSessionConfig & config,const std::function<void ()> & completionCallback)201 HalResult<std::shared_ptr<Aidl::IVibrationSession>> AidlManagerHalWrapper::startSession(
202 const std::vector<int32_t>& ids, const Aidl::VibrationSessionConfig& config,
203 const std::function<void()>& completionCallback) {
204 auto cb = ndk::SharedRefBase::make<HalCallbackWrapper>(completionCallback);
205 std::shared_ptr<Aidl::IVibrationSession> session;
206 auto status = getHal()->startSession(ids, config, cb, &session);
207 return HalResultFactory::fromStatus<std::shared_ptr<Aidl::IVibrationSession>>(std::move(status),
208 std::move(
209 session));
210 }
211
cancelSynced()212 HalResult<void> AidlManagerHalWrapper::cancelSynced() {
213 auto ret = HalResultFactory::fromStatus(getHal()->cancelSynced());
214 if (ret.isOk()) {
215 // Force reload of all vibrator controllers that were prepared for a sync operation before.
216 // This will trigger calls to getVibrator(id) on each controller, so they can use the
217 // latest service provided by this manager.
218 std::lock_guard<std::mutex> lock(mVibratorsMutex);
219 for (auto& entry : mVibrators) {
220 entry.second->tryReconnect();
221 }
222 }
223 return ret;
224 }
225
clearSessions()226 HalResult<void> AidlManagerHalWrapper::clearSessions() {
227 return HalResultFactory::fromStatus(getHal()->clearSessions());
228 }
229
getHal()230 std::shared_ptr<Aidl::IVibratorManager> AidlManagerHalWrapper::getHal() {
231 std::lock_guard<std::mutex> lock(mHandleMutex);
232 return mHandle;
233 }
234
235 }; // namespace vibrator
236
237 }; // namespace android
238