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