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