1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "vibrator_service_client.h"
17
18 #include <climits>
19 #include <thread>
20
21 #include "hisysevent.h"
22 #include "hitrace_meter.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25
26 #include "death_recipient_template.h"
27 #include "sensors_errors.h"
28 #include "vibrator_decoder_creator.h"
29
30 #undef LOG_TAG
31 #define LOG_TAG "VibratorServiceClient"
32
33 namespace OHOS {
34 namespace Sensors {
35 using namespace OHOS::HiviewDFX;
36
37 namespace {
38 constexpr int32_t GET_SERVICE_MAX_COUNT = 3;
39 constexpr uint32_t WAIT_MS = 200;
40 #ifdef __aarch64__
41 static const std::string DECODER_LIBRARY_PATH = "/system/lib64/libvibrator_decoder.z.so";
42 #else
43 static const std::string DECODER_LIBRARY_PATH = "/system/lib/libvibrator_decoder.z.so";
44 #endif
45 } // namespace
46
~VibratorServiceClient()47 VibratorServiceClient::~VibratorServiceClient()
48 {
49 if (miscdeviceProxy_ != nullptr && serviceDeathObserver_ != nullptr) {
50 auto remoteObject = miscdeviceProxy_->AsObject();
51 if (remoteObject != nullptr) {
52 remoteObject->RemoveDeathRecipient(serviceDeathObserver_);
53 }
54 }
55 std::lock_guard<std::mutex> decodeLock(decodeMutex_);
56 if (decodeHandle_.destroy != nullptr && decodeHandle_.handle != nullptr) {
57 decodeHandle_.destroy(decodeHandle_.decoder);
58 decodeHandle_.decoder = nullptr;
59 decodeHandle_.Free();
60 }
61 }
62
InitServiceClient()63 int32_t VibratorServiceClient::InitServiceClient()
64 {
65 CALL_LOG_ENTER;
66 std::lock_guard<std::mutex> clientLock(clientMutex_);
67 if (miscdeviceProxy_ != nullptr) {
68 MISC_HILOGD("miscdeviceProxy_ already init");
69 return ERR_OK;
70 }
71 auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
72 if (sm == nullptr) {
73 MISC_HILOGE("sm cannot be null");
74 return MISC_NATIVE_SAM_ERR;
75 }
76 int32_t retry = 0;
77 while (retry < GET_SERVICE_MAX_COUNT) {
78 miscdeviceProxy_ = iface_cast<IMiscdeviceService>(sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID));
79 if (miscdeviceProxy_ != nullptr) {
80 MISC_HILOGD("Get service success, retry:%{public}d", retry);
81 serviceDeathObserver_ =
82 new (std::nothrow) DeathRecipientTemplate(*const_cast<VibratorServiceClient *>(this));
83 CHKPR(serviceDeathObserver_, MISC_NATIVE_GET_SERVICE_ERR);
84 auto remoteObject = miscdeviceProxy_->AsObject();
85 CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
86 remoteObject->AddDeathRecipient(serviceDeathObserver_);
87 return ERR_OK;
88 }
89 MISC_HILOGW("Get service failed, retry:%{public}d", retry);
90 std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
91 retry++;
92 }
93 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_EXCEPTION",
94 HiSysEvent::EventType::FAULT, "PKG_NAME", "InitServiceClient", "ERROR_CODE", MISC_NATIVE_GET_SERVICE_ERR);
95 MISC_HILOGE("Get service failed");
96 return MISC_NATIVE_GET_SERVICE_ERR;
97 }
98
Vibrate(int32_t vibratorId,int32_t timeOut,int32_t usage)99 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage)
100 {
101 MISC_HILOGD("Vibrate begin, time:%{public}d, usage:%{public}d", timeOut, usage);
102 int32_t ret = InitServiceClient();
103 if (ret != ERR_OK) {
104 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
105 return MISC_NATIVE_GET_SERVICE_ERR;
106 }
107 CHKPR(miscdeviceProxy_, ERROR);
108 StartTrace(HITRACE_TAG_SENSORS, "VibrateTime");
109 ret = miscdeviceProxy_->Vibrate(vibratorId, timeOut, usage);
110 FinishTrace(HITRACE_TAG_SENSORS);
111 if (ret != ERR_OK) {
112 MISC_HILOGE("Vibrate time failed, ret:%{public}d, time:%{public}d, usage:%{public}d", ret, timeOut, usage);
113 }
114 return ret;
115 }
116
Vibrate(int32_t vibratorId,const std::string & effect,int32_t loopCount,int32_t usage)117 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, const std::string &effect,
118 int32_t loopCount, int32_t usage)
119 {
120 MISC_HILOGD("Vibrate begin, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
121 effect.c_str(), loopCount, usage);
122 int32_t ret = InitServiceClient();
123 if (ret != ERR_OK) {
124 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
125 return MISC_NATIVE_GET_SERVICE_ERR;
126 }
127 CHKPR(miscdeviceProxy_, ERROR);
128 StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
129 ret = miscdeviceProxy_->PlayVibratorEffect(vibratorId, effect, loopCount, usage);
130 FinishTrace(HITRACE_TAG_SENSORS);
131 if (ret != ERR_OK) {
132 MISC_HILOGE("Vibrate effect failed, ret:%{public}d, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
133 ret, effect.c_str(), loopCount, usage);
134 }
135 return ret;
136 }
137
138 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId,const RawFileDescriptor & rawFd,int32_t usage,const VibratorParameter & parameter)139 int32_t VibratorServiceClient::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
140 const VibratorParameter ¶meter)
141 {
142 MISC_HILOGD("Vibrate begin, fd:%{public}d, offset:%{public}lld, length:%{public}lld, usage:%{public}d",
143 rawFd.fd, static_cast<long long>(rawFd.offset), static_cast<long long>(rawFd.length), usage);
144 int32_t ret = InitServiceClient();
145 if (ret != ERR_OK) {
146 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
147 return MISC_NATIVE_GET_SERVICE_ERR;
148 }
149 CHKPR(miscdeviceProxy_, ERROR);
150 StartTrace(HITRACE_TAG_SENSORS, "PlayVibratorCustom");
151 VibrateParameter vibateParameter = {
152 .intensity = parameter.intensity,
153 .frequency = parameter.frequency
154 };
155 ret = miscdeviceProxy_->PlayVibratorCustom(vibratorId, rawFd, usage, vibateParameter);
156 FinishTrace(HITRACE_TAG_SENSORS);
157 if (ret != ERR_OK) {
158 MISC_HILOGE("PlayVibratorCustom failed, ret:%{public}d, usage:%{public}d", ret, usage);
159 }
160 return ret;
161 }
162 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
163
StopVibrator(int32_t vibratorId,const std::string & mode)164 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId, const std::string &mode)
165 {
166 MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d, mode:%{public}s", vibratorId, mode.c_str());
167 int32_t ret = InitServiceClient();
168 if (ret != ERR_OK) {
169 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
170 return MISC_NATIVE_GET_SERVICE_ERR;
171 }
172 CHKPR(miscdeviceProxy_, ERROR);
173 StartTrace(HITRACE_TAG_SENSORS, "StopVibratorByMode");
174 ret = miscdeviceProxy_->StopVibrator(vibratorId, mode);
175 FinishTrace(HITRACE_TAG_SENSORS);
176 if (ret != ERR_OK) {
177 MISC_HILOGD("StopVibrator by mode failed, ret:%{public}d, mode:%{public}s", ret, mode.c_str());
178 }
179 return ret;
180 }
181
StopVibrator(int32_t vibratorId)182 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId)
183 {
184 MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d", vibratorId);
185 int32_t ret = InitServiceClient();
186 if (ret != ERR_OK) {
187 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
188 return MISC_NATIVE_GET_SERVICE_ERR;
189 }
190 CHKPR(miscdeviceProxy_, ERROR);
191 StartTrace(HITRACE_TAG_SENSORS, "StopVibratorAll");
192 ret = miscdeviceProxy_->StopVibrator(vibratorId);
193 FinishTrace(HITRACE_TAG_SENSORS);
194 if (ret != ERR_OK) {
195 MISC_HILOGD("StopVibrator failed, ret:%{public}d", ret);
196 }
197 return ret;
198 }
199
IsSupportEffect(const std::string & effect,bool & state)200 int32_t VibratorServiceClient::IsSupportEffect(const std::string &effect, bool &state)
201 {
202 MISC_HILOGD("IsSupportEffect begin, effect:%{public}s", effect.c_str());
203 int32_t ret = InitServiceClient();
204 if (ret != ERR_OK) {
205 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
206 return MISC_NATIVE_GET_SERVICE_ERR;
207 }
208 CHKPR(miscdeviceProxy_, ERROR);
209 StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
210 ret = miscdeviceProxy_->IsSupportEffect(effect, state);
211 FinishTrace(HITRACE_TAG_SENSORS);
212 if (ret != ERR_OK) {
213 MISC_HILOGE("Query effect support failed, ret:%{public}d, effect:%{public}s", ret, effect.c_str());
214 }
215 return ret;
216 }
217
ProcessDeathObserver(const wptr<IRemoteObject> & object)218 void VibratorServiceClient::ProcessDeathObserver(const wptr<IRemoteObject> &object)
219 {
220 CALL_LOG_ENTER;
221 (void)object;
222 miscdeviceProxy_ = nullptr;
223 int32_t ret = InitServiceClient();
224 if (ret != ERR_OK) {
225 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
226 return;
227 }
228 }
229
LoadDecoderLibrary(const std::string & path)230 int32_t VibratorServiceClient::LoadDecoderLibrary(const std::string& path)
231 {
232 std::lock_guard<std::mutex> decodeLock(decodeMutex_);
233 if (decodeHandle_.handle != nullptr) {
234 MISC_HILOGD("The library has already been loaded");
235 return ERR_OK;
236 }
237 char libRealPath[PATH_MAX] = {};
238 if (realpath(path.c_str(), libRealPath) == nullptr) {
239 MISC_HILOGE("Get file real path fail");
240 return ERROR;
241 }
242 decodeHandle_.handle = dlopen(libRealPath, RTLD_LAZY);
243 if (decodeHandle_.handle == nullptr) {
244 MISC_HILOGE("dlopen failed, reason:%{public}s", dlerror());
245 return ERROR;
246 }
247 decodeHandle_.create = reinterpret_cast<IVibratorDecoder *(*)(const RawFileDescriptor &)>(
248 dlsym(decodeHandle_.handle, "Create"));
249 if (decodeHandle_.create == nullptr) {
250 MISC_HILOGE("dlsym create failed: error: %{public}s", dlerror());
251 decodeHandle_.Free();
252 return ERROR;
253 }
254 decodeHandle_.destroy = reinterpret_cast<void (*)(IVibratorDecoder *)>
255 (dlsym(decodeHandle_.handle, "Destroy"));
256 if (decodeHandle_.destroy == nullptr) {
257 MISC_HILOGE("dlsym destroy failed: error: %{public}s", dlerror());
258 decodeHandle_.Free();
259 return ERROR;
260 }
261 return ERR_OK;
262 }
263
PreProcess(const VibratorFileDescription & fd,VibratorPackage & package)264 int32_t VibratorServiceClient::PreProcess(const VibratorFileDescription &fd, VibratorPackage &package)
265 {
266 if (LoadDecoderLibrary(DECODER_LIBRARY_PATH) != 0) {
267 MISC_HILOGE("LoadDecoderLibrary fail");
268 return ERROR;
269 }
270 RawFileDescriptor rawFd = {
271 .fd = fd.fd,
272 .offset = fd.offset,
273 .length = fd.length
274 };
275 decodeHandle_.decoder = decodeHandle_.create(rawFd);
276 CHKPR(decodeHandle_.decoder, ERROR);
277 VibratePackage pkg = {};
278 if (decodeHandle_.decoder->DecodeEffect(rawFd, pkg) != 0) {
279 MISC_HILOGE("DecodeEffect fail");
280 decodeHandle_.destroy(decodeHandle_.decoder);
281 decodeHandle_.decoder = nullptr;
282 return ERROR;
283 }
284 decodeHandle_.destroy(decodeHandle_.decoder);
285 decodeHandle_.decoder = nullptr;
286 return ConvertVibratePackage(pkg, package);
287 }
288
GetDelayTime(int32_t & delayTime)289 int32_t VibratorServiceClient::GetDelayTime(int32_t &delayTime)
290 {
291 int32_t ret = InitServiceClient();
292 if (ret != ERR_OK) {
293 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
294 return MISC_NATIVE_GET_SERVICE_ERR;
295 }
296 CHKPR(miscdeviceProxy_, ERROR);
297 StartTrace(HITRACE_TAG_SENSORS, "GetDelayTime");
298 ret = miscdeviceProxy_->GetDelayTime(delayTime);
299 FinishTrace(HITRACE_TAG_SENSORS);
300 if (ret != ERR_OK) {
301 MISC_HILOGE("GetDelayTime failed, ret:%{public}d", ret);
302 }
303 return ret;
304 }
305
PlayPattern(const VibratorPattern & pattern,int32_t usage,const VibratorParameter & parameter)306 int32_t VibratorServiceClient::PlayPattern(const VibratorPattern &pattern, int32_t usage,
307 const VibratorParameter ¶meter)
308 {
309 MISC_HILOGD("Vibrate begin, usage:%{public}d", usage);
310 int32_t ret = InitServiceClient();
311 if (ret != ERR_OK) {
312 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
313 return MISC_NATIVE_GET_SERVICE_ERR;
314 }
315 CHKPR(miscdeviceProxy_, ERROR);
316 StartTrace(HITRACE_TAG_SENSORS, "PlayPattern");
317 VibratePattern vibratePattern = {};
318 vibratePattern.startTime = pattern.time;
319 for (int32_t i = 0; i < pattern.eventNum; ++i) {
320 if (pattern.events == nullptr) {
321 MISC_HILOGE("VibratorPattern's events is null");
322 return ERROR;
323 }
324 VibrateEvent event;
325 event.tag = static_cast<VibrateTag>(pattern.events[i].type);
326 event.time = pattern.events[i].time;
327 event.duration = pattern.events[i].duration;
328 event.intensity = pattern.events[i].intensity;
329 event.frequency = pattern.events[i].frequency;
330 event.index = pattern.events[i].index;
331 for (int32_t j = 0; j < pattern.events[i].pointNum; ++j) {
332 if (pattern.events[i].points == nullptr) {
333 MISC_HILOGE("VibratorEvent's points is null");
334 continue;
335 }
336 VibrateCurvePoint point;
337 point.time = pattern.events[i].points[j].time;
338 point.intensity = pattern.events[i].points[j].intensity;
339 point.frequency = pattern.events[i].points[j].frequency;
340 event.points.emplace_back(point);
341 }
342 vibratePattern.events.emplace_back(event);
343 }
344 VibrateParameter vibateParameter = {
345 .intensity = parameter.intensity,
346 .frequency = parameter.frequency
347 };
348 ret = miscdeviceProxy_->PlayPattern(vibratePattern, usage, vibateParameter);
349 FinishTrace(HITRACE_TAG_SENSORS);
350 if (ret != ERR_OK) {
351 MISC_HILOGE("PlayPattern failed, ret:%{public}d, usage:%{public}d", ret, usage);
352 }
353 return ret;
354 }
355
ConvertVibratePackage(const VibratePackage & inPkg,VibratorPackage & outPkg)356 int32_t VibratorServiceClient::ConvertVibratePackage(const VibratePackage& inPkg,
357 VibratorPackage &outPkg)
358 {
359 inPkg.Dump();
360 int32_t patternSize = static_cast<int32_t>(inPkg.patterns.size());
361 VibratorPattern *patterns = (VibratorPattern *)malloc(sizeof(VibratorPattern) * patternSize);
362 CHKPR(patterns, ERROR);
363 outPkg.patternNum = patternSize;
364 for (int32_t i = 0; i < patternSize; ++i) {
365 patterns[i].time = inPkg.patterns[i].startTime;
366 auto vibrateEvents = inPkg.patterns[i].events;
367 int32_t eventSize = static_cast<int32_t>(vibrateEvents.size());
368 patterns[i].eventNum = eventSize;
369 VibratorEvent *events = (VibratorEvent *)malloc(sizeof(VibratorEvent) * eventSize);
370 if (events == nullptr) {
371 free(patterns);
372 patterns = nullptr;
373 return ERROR;
374 }
375 for (int32_t j = 0; j < eventSize; ++j) {
376 events[j].type = static_cast<VibratorEventType >(vibrateEvents[j].tag);
377 events[j].time = vibrateEvents[j].time;
378 events[j].duration = vibrateEvents[j].duration;
379 events[j].intensity = vibrateEvents[j].intensity;
380 events[j].frequency = vibrateEvents[j].frequency;
381 events[j].index = vibrateEvents[j].index;
382 auto vibratePoints = vibrateEvents[j].points;
383 events[j].pointNum = static_cast<int32_t>(vibratePoints.size());
384 VibratorCurvePoint *points = (VibratorCurvePoint *)malloc(sizeof(VibratorCurvePoint) * events[j].pointNum);
385 if (points == nullptr) {
386 free(patterns);
387 patterns = nullptr;
388 free(events);
389 events = nullptr;
390 return ERROR;
391 }
392 for (int32_t k = 0; k < events[j].pointNum; ++k) {
393 points[k].time = vibratePoints[k].time;
394 points[k].intensity = vibratePoints[k].intensity;
395 points[k].frequency = vibratePoints[k].frequency;
396 }
397 events[j].points = points;
398 }
399 patterns[i].events = events;
400 }
401 outPkg.patterns = patterns;
402 return ERR_OK;
403 }
404
FreeVibratorPackage(VibratorPackage & package)405 int32_t VibratorServiceClient::FreeVibratorPackage(VibratorPackage &package)
406 {
407 int32_t patternSize = package.patternNum;
408 if ((patternSize <= 0) || (package.patterns == nullptr)) {
409 MISC_HILOGW("Patterns is not need to free, pattern size:%{public}d", patternSize);
410 return ERROR;
411 }
412 auto patterns = package.patterns;
413 for (int32_t i = 0; i < patternSize; ++i) {
414 int32_t eventNum = patterns[i].eventNum;
415 if ((eventNum <= 0) || (patterns[i].events == nullptr)) {
416 MISC_HILOGW("Events is not need to free, event size:%{public}d", eventNum);
417 continue;
418 }
419 auto events = patterns[i].events;
420 for (int32_t j = 0; j < eventNum; ++j) {
421 if (events[j].points != nullptr) {
422 free(events[j].points);
423 events[j].points = nullptr;
424 }
425 }
426 free(events);
427 events = nullptr;
428 }
429 free(patterns);
430 patterns = nullptr;
431 return ERR_OK;
432 }
433 } // namespace Sensors
434 } // namespace OHOS
435