1 /*
2 * Copyright (c) 2021-2024 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 #if (defined(__aarch64__) || defined(__x86_64__))
39 static const std::string DECODER_LIBRARY_PATH = "/system/lib64/platformsdk/libvibrator_decoder.z.so";
40 #else
41 static const std::string DECODER_LIBRARY_PATH = "/system/lib/platformsdk/libvibrator_decoder.z.so";
42 #endif
43 } // namespace
44
~VibratorServiceClient()45 VibratorServiceClient::~VibratorServiceClient()
46 {
47 if (miscdeviceProxy_ != nullptr && serviceDeathObserver_ != nullptr) {
48 auto remoteObject = miscdeviceProxy_->AsObject();
49 if (remoteObject != nullptr) {
50 remoteObject->RemoveDeathRecipient(serviceDeathObserver_);
51 }
52 }
53 std::lock_guard<std::mutex> decodeLock(decodeMutex_);
54 if (decodeHandle_.destroy != nullptr && decodeHandle_.handle != nullptr) {
55 decodeHandle_.destroy(decodeHandle_.decoder);
56 decodeHandle_.decoder = nullptr;
57 decodeHandle_.Free();
58 }
59 }
60
InitServiceClient()61 int32_t VibratorServiceClient::InitServiceClient()
62 {
63 CALL_LOG_ENTER;
64 std::lock_guard<std::mutex> clientLock(clientMutex_);
65 if (miscdeviceProxy_ != nullptr) {
66 MISC_HILOGD("miscdeviceProxy_ already init");
67 return ERR_OK;
68 }
69 if (vibratorClient_ == nullptr) {
70 vibratorClient_ = new (std::nothrow) VibratorClientStub();
71 }
72 auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
73 if (sm == nullptr) {
74 MISC_HILOGE("sm cannot be null");
75 return MISC_NATIVE_SAM_ERR;
76 }
77 miscdeviceProxy_ = iface_cast<IMiscdeviceService>(sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID));
78 if (miscdeviceProxy_ != nullptr) {
79 serviceDeathObserver_ =
80 new (std::nothrow) DeathRecipientTemplate(*const_cast<VibratorServiceClient *>(this));
81 CHKPR(serviceDeathObserver_, MISC_NATIVE_GET_SERVICE_ERR);
82 auto remoteObject = miscdeviceProxy_->AsObject();
83 CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
84 remoteObject->AddDeathRecipient(serviceDeathObserver_);
85 int32_t ret = TransferClientRemoteObject();
86 if (ret != ERR_OK) {
87 MISC_HILOGE("TransferClientRemoteObject failed, ret:%{public}d", ret);
88 return ERROR;
89 }
90 ret = GetVibratorCapacity();
91 if (ret != ERR_OK) {
92 MISC_HILOGE("GetVibratorCapacity failed, ret:%{public}d", ret);
93 return ERROR;
94 }
95 return ERR_OK;
96 }
97 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_EXCEPTION",
98 HiSysEvent::EventType::FAULT, "PKG_NAME", "InitServiceClient", "ERROR_CODE", MISC_NATIVE_GET_SERVICE_ERR);
99 MISC_HILOGE("Get service failed");
100 return MISC_NATIVE_GET_SERVICE_ERR;
101 }
102
TransferClientRemoteObject()103 int32_t VibratorServiceClient::TransferClientRemoteObject()
104 {
105 auto remoteObject = vibratorClient_->AsObject();
106 CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
107 CHKPR(miscdeviceProxy_, ERROR);
108 StartTrace(HITRACE_TAG_SENSORS, "TransferClientRemoteObject");
109 int32_t ret = miscdeviceProxy_->TransferClientRemoteObject(remoteObject);
110 FinishTrace(HITRACE_TAG_SENSORS);
111 return ret;
112 }
113
Vibrate(int32_t vibratorId,int32_t timeOut,int32_t usage,bool systemUsage)114 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage, bool systemUsage)
115 {
116 MISC_HILOGD("Vibrate begin, time:%{public}d, usage:%{public}d", timeOut, usage);
117 int32_t ret = InitServiceClient();
118 if (ret != ERR_OK) {
119 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
120 return MISC_NATIVE_GET_SERVICE_ERR;
121 }
122 std::lock_guard<std::mutex> clientLock(clientMutex_);
123 CHKPR(miscdeviceProxy_, ERROR);
124 StartTrace(HITRACE_TAG_SENSORS, "VibrateTime");
125 ret = miscdeviceProxy_->Vibrate(vibratorId, timeOut, usage, systemUsage);
126 FinishTrace(HITRACE_TAG_SENSORS);
127 if (ret != ERR_OK) {
128 MISC_HILOGE("Vibrate time failed, ret:%{public}d, time:%{public}d, usage:%{public}d", ret, timeOut, usage);
129 }
130 return ret;
131 }
132
Vibrate(int32_t vibratorId,const std::string & effect,int32_t loopCount,int32_t usage,bool systemUsage)133 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, const std::string &effect,
134 int32_t loopCount, int32_t usage, bool systemUsage)
135 {
136 MISC_HILOGD("Vibrate begin, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
137 effect.c_str(), loopCount, usage);
138 int32_t ret = InitServiceClient();
139 if (ret != ERR_OK) {
140 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
141 return MISC_NATIVE_GET_SERVICE_ERR;
142 }
143 std::lock_guard<std::mutex> clientLock(clientMutex_);
144 CHKPR(miscdeviceProxy_, ERROR);
145 StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
146 ret = miscdeviceProxy_->PlayVibratorEffect(vibratorId, effect, loopCount, usage, systemUsage);
147 FinishTrace(HITRACE_TAG_SENSORS);
148 if (ret != ERR_OK) {
149 MISC_HILOGE("Vibrate effect failed, ret:%{public}d, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
150 ret, effect.c_str(), loopCount, usage);
151 }
152 return ret;
153 }
154
155 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId,const RawFileDescriptor & rawFd,int32_t usage,bool systemUsage,const VibratorParameter & parameter)156 int32_t VibratorServiceClient::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
157 bool systemUsage, const VibratorParameter ¶meter)
158 {
159 MISC_HILOGD("Vibrate begin, fd:%{public}d, offset:%{public}lld, length:%{public}lld, usage:%{public}d",
160 rawFd.fd, static_cast<long long>(rawFd.offset), static_cast<long long>(rawFd.length), usage);
161 int32_t ret = InitServiceClient();
162 if (ret != ERR_OK) {
163 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
164 return MISC_NATIVE_GET_SERVICE_ERR;
165 }
166 std::lock_guard<std::mutex> clientLock(clientMutex_);
167 CHKPR(miscdeviceProxy_, ERROR);
168 StartTrace(HITRACE_TAG_SENSORS, "PlayVibratorCustom");
169 VibrateParameter vibateParameter = {
170 .intensity = parameter.intensity,
171 .frequency = parameter.frequency
172 };
173 ret = miscdeviceProxy_->PlayVibratorCustom(vibratorId, rawFd, usage, systemUsage, vibateParameter);
174 FinishTrace(HITRACE_TAG_SENSORS);
175 if (ret != ERR_OK) {
176 MISC_HILOGE("PlayVibratorCustom failed, ret:%{public}d, usage:%{public}d", ret, usage);
177 }
178 return ret;
179 }
180 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
181
StopVibrator(int32_t vibratorId,const std::string & mode)182 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId, const std::string &mode)
183 {
184 MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d, mode:%{public}s", vibratorId, mode.c_str());
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 std::lock_guard<std::mutex> clientLock(clientMutex_);
191 CHKPR(miscdeviceProxy_, ERROR);
192 StartTrace(HITRACE_TAG_SENSORS, "StopVibratorByMode");
193 ret = miscdeviceProxy_->StopVibrator(vibratorId, mode);
194 FinishTrace(HITRACE_TAG_SENSORS);
195 if (ret != ERR_OK) {
196 MISC_HILOGD("StopVibrator by mode failed, ret:%{public}d, mode:%{public}s", ret, mode.c_str());
197 }
198 return ret;
199 }
200
StopVibrator(int32_t vibratorId)201 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId)
202 {
203 MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d", vibratorId);
204 int32_t ret = InitServiceClient();
205 if (ret != ERR_OK) {
206 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
207 return MISC_NATIVE_GET_SERVICE_ERR;
208 }
209 std::lock_guard<std::mutex> clientLock(clientMutex_);
210 CHKPR(miscdeviceProxy_, ERROR);
211 StartTrace(HITRACE_TAG_SENSORS, "StopVibratorAll");
212 ret = miscdeviceProxy_->StopVibrator(vibratorId);
213 FinishTrace(HITRACE_TAG_SENSORS);
214 if (ret != ERR_OK) {
215 MISC_HILOGD("StopVibrator failed, ret:%{public}d", ret);
216 }
217 return ret;
218 }
219
IsHdHapticSupported()220 bool VibratorServiceClient::IsHdHapticSupported()
221 {
222 CALL_LOG_ENTER;
223 int32_t ret = InitServiceClient();
224 if (ret != ERR_OK) {
225 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
226 return MISC_NATIVE_GET_SERVICE_ERR;
227 }
228 return capacity_.isSupportHdHaptic;
229 }
230
IsSupportEffect(const std::string & effect,bool & state)231 int32_t VibratorServiceClient::IsSupportEffect(const std::string &effect, bool &state)
232 {
233 MISC_HILOGD("IsSupportEffect begin, effect:%{public}s", effect.c_str());
234 int32_t ret = InitServiceClient();
235 if (ret != ERR_OK) {
236 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
237 return MISC_NATIVE_GET_SERVICE_ERR;
238 }
239 std::lock_guard<std::mutex> clientLock(clientMutex_);
240 CHKPR(miscdeviceProxy_, ERROR);
241 StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
242 ret = miscdeviceProxy_->IsSupportEffect(effect, state);
243 FinishTrace(HITRACE_TAG_SENSORS);
244 if (ret != ERR_OK) {
245 MISC_HILOGE("Query effect support failed, ret:%{public}d, effect:%{public}s", ret, effect.c_str());
246 }
247 return ret;
248 }
249
ProcessDeathObserver(const wptr<IRemoteObject> & object)250 void VibratorServiceClient::ProcessDeathObserver(const wptr<IRemoteObject> &object)
251 {
252 CALL_LOG_ENTER;
253 (void)object;
254 {
255 std::lock_guard<std::mutex> clientLock(clientMutex_);
256 miscdeviceProxy_ = nullptr;
257 }
258 int32_t ret = InitServiceClient();
259 if (ret != ERR_OK) {
260 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
261 return;
262 }
263 }
264
LoadDecoderLibrary(const std::string & path)265 int32_t VibratorServiceClient::LoadDecoderLibrary(const std::string& path)
266 {
267 std::lock_guard<std::mutex> decodeLock(decodeMutex_);
268 if (decodeHandle_.handle != nullptr) {
269 MISC_HILOGD("The library has already been loaded");
270 return ERR_OK;
271 }
272 char libRealPath[PATH_MAX] = {};
273 if (realpath(path.c_str(), libRealPath) == nullptr) {
274 MISC_HILOGE("Get file real path fail");
275 return ERROR;
276 }
277 decodeHandle_.handle = dlopen(libRealPath, RTLD_LAZY);
278 if (decodeHandle_.handle == nullptr) {
279 MISC_HILOGE("dlopen failed, reason:%{public}s", dlerror());
280 return ERROR;
281 }
282 decodeHandle_.create = reinterpret_cast<IVibratorDecoder *(*)(const JsonParser &)>(
283 dlsym(decodeHandle_.handle, "Create"));
284 if (decodeHandle_.create == nullptr) {
285 MISC_HILOGE("dlsym create failed: error: %{public}s", dlerror());
286 decodeHandle_.Free();
287 return ERROR;
288 }
289 decodeHandle_.destroy = reinterpret_cast<void (*)(IVibratorDecoder *)>
290 (dlsym(decodeHandle_.handle, "Destroy"));
291 if (decodeHandle_.destroy == nullptr) {
292 MISC_HILOGE("dlsym destroy failed: error: %{public}s", dlerror());
293 decodeHandle_.Free();
294 return ERROR;
295 }
296 return ERR_OK;
297 }
298
PreProcess(const VibratorFileDescription & fd,VibratorPackage & package)299 int32_t VibratorServiceClient::PreProcess(const VibratorFileDescription &fd, VibratorPackage &package)
300 {
301 if (LoadDecoderLibrary(DECODER_LIBRARY_PATH) != 0) {
302 MISC_HILOGE("LoadDecoderLibrary fail");
303 return ERROR;
304 }
305 RawFileDescriptor rawFd = {
306 .fd = fd.fd,
307 .offset = fd.offset,
308 .length = fd.length
309 };
310 JsonParser parser(rawFd);
311 decodeHandle_.decoder = decodeHandle_.create(parser);
312 CHKPR(decodeHandle_.decoder, ERROR);
313 VibratePackage pkg = {};
314 if (decodeHandle_.decoder->DecodeEffect(rawFd, parser, pkg) != 0) {
315 MISC_HILOGE("DecodeEffect fail");
316 decodeHandle_.destroy(decodeHandle_.decoder);
317 decodeHandle_.decoder = nullptr;
318 return ERROR;
319 }
320 decodeHandle_.destroy(decodeHandle_.decoder);
321 decodeHandle_.decoder = nullptr;
322 return ConvertVibratePackage(pkg, package);
323 }
324
GetDelayTime(int32_t & delayTime)325 int32_t VibratorServiceClient::GetDelayTime(int32_t &delayTime)
326 {
327 int32_t ret = InitServiceClient();
328 if (ret != ERR_OK) {
329 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
330 return MISC_NATIVE_GET_SERVICE_ERR;
331 }
332 std::lock_guard<std::mutex> clientLock(clientMutex_);
333 CHKPR(miscdeviceProxy_, ERROR);
334 StartTrace(HITRACE_TAG_SENSORS, "GetDelayTime");
335 ret = miscdeviceProxy_->GetDelayTime(delayTime);
336 FinishTrace(HITRACE_TAG_SENSORS);
337 if (ret != ERR_OK) {
338 MISC_HILOGE("GetDelayTime failed, ret:%{public}d", ret);
339 }
340 return ret;
341 }
342
PlayPattern(const VibratorPattern & pattern,int32_t usage,bool systemUsage,const VibratorParameter & parameter)343 int32_t VibratorServiceClient::PlayPattern(const VibratorPattern &pattern, int32_t usage,
344 bool systemUsage, const VibratorParameter ¶meter)
345 {
346 MISC_HILOGD("Vibrate begin, usage:%{public}d", usage);
347 int32_t ret = InitServiceClient();
348 if (ret != ERR_OK) {
349 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
350 return MISC_NATIVE_GET_SERVICE_ERR;
351 }
352 StartTrace(HITRACE_TAG_SENSORS, "PlayPattern");
353 VibratePattern vibratePattern = {};
354 vibratePattern.startTime = pattern.time;
355 for (int32_t i = 0; i < pattern.eventNum; ++i) {
356 if (pattern.events == nullptr) {
357 MISC_HILOGE("VibratorPattern's events is null");
358 return ERROR;
359 }
360 VibrateEvent event;
361 event.tag = static_cast<VibrateTag>(pattern.events[i].type);
362 event.time = pattern.events[i].time;
363 event.duration = pattern.events[i].duration;
364 event.intensity = pattern.events[i].intensity;
365 event.frequency = pattern.events[i].frequency;
366 event.index = pattern.events[i].index;
367 for (int32_t j = 0; j < pattern.events[i].pointNum; ++j) {
368 if (pattern.events[i].points == nullptr) {
369 MISC_HILOGE("VibratorEvent's points is null");
370 continue;
371 }
372 VibrateCurvePoint point;
373 point.time = pattern.events[i].points[j].time;
374 point.intensity = pattern.events[i].points[j].intensity;
375 point.frequency = pattern.events[i].points[j].frequency;
376 event.points.emplace_back(point);
377 }
378 vibratePattern.events.emplace_back(event);
379 vibratePattern.patternDuration = pattern.patternDuration;
380 }
381 VibrateParameter vibateParameter = {
382 .intensity = parameter.intensity,
383 .frequency = parameter.frequency
384 };
385 std::lock_guard<std::mutex> clientLock(clientMutex_);
386 CHKPR(miscdeviceProxy_, ERROR);
387 ret = miscdeviceProxy_->PlayPattern(vibratePattern, usage, systemUsage, vibateParameter);
388 FinishTrace(HITRACE_TAG_SENSORS);
389 if (ret != ERR_OK) {
390 MISC_HILOGE("PlayPattern failed, ret:%{public}d, usage:%{public}d", ret, usage);
391 }
392 return ret;
393 }
394
ConvertVibratePackage(const VibratePackage & inPkg,VibratorPackage & outPkg)395 int32_t VibratorServiceClient::ConvertVibratePackage(const VibratePackage& inPkg,
396 VibratorPackage &outPkg)
397 {
398 inPkg.Dump();
399 int32_t patternSize = static_cast<int32_t>(inPkg.patterns.size());
400 VibratorPattern *patterns = (VibratorPattern *)malloc(sizeof(VibratorPattern) * patternSize);
401 CHKPR(patterns, ERROR);
402 outPkg.patternNum = patternSize;
403 int32_t clientPatternDuration = 0;
404 for (int32_t i = 0; i < patternSize; ++i) {
405 patterns[i].time = inPkg.patterns[i].startTime;
406 auto vibrateEvents = inPkg.patterns[i].events;
407 int32_t eventSize = static_cast<int32_t>(vibrateEvents.size());
408 patterns[i].eventNum = eventSize;
409 VibratorEvent *events = (VibratorEvent *)malloc(sizeof(VibratorEvent) * eventSize);
410 if (events == nullptr) {
411 free(patterns);
412 patterns = nullptr;
413 return ERROR;
414 }
415 for (int32_t j = 0; j < eventSize; ++j) {
416 events[j].type = static_cast<VibratorEventType >(vibrateEvents[j].tag);
417 events[j].time = vibrateEvents[j].time;
418 events[j].duration = vibrateEvents[j].duration;
419 events[j].intensity = vibrateEvents[j].intensity;
420 events[j].frequency = vibrateEvents[j].frequency;
421 events[j].index = vibrateEvents[j].index;
422 auto vibratePoints = vibrateEvents[j].points;
423 events[j].pointNum = static_cast<int32_t>(vibratePoints.size());
424 VibratorCurvePoint *points = (VibratorCurvePoint *)malloc(sizeof(VibratorCurvePoint) * events[j].pointNum);
425 if (points == nullptr) {
426 free(patterns);
427 patterns = nullptr;
428 free(events);
429 events = nullptr;
430 return ERROR;
431 }
432 for (int32_t k = 0; k < events[j].pointNum; ++k) {
433 points[k].time = vibratePoints[k].time;
434 points[k].intensity = vibratePoints[k].intensity;
435 points[k].frequency = vibratePoints[k].frequency;
436 }
437 events[j].points = points;
438 clientPatternDuration += events[j].duration;
439 }
440 patterns[i].events = events;
441 patterns[i].patternDuration = clientPatternDuration;
442 }
443 outPkg.patterns = patterns;
444 outPkg.packageDuration = inPkg.packageDuration;
445 return ERR_OK;
446 }
447
FreeVibratorPackage(VibratorPackage & package)448 int32_t VibratorServiceClient::FreeVibratorPackage(VibratorPackage &package)
449 {
450 int32_t patternSize = package.patternNum;
451 if ((patternSize <= 0) || (package.patterns == nullptr)) {
452 MISC_HILOGW("Patterns is not need to free, pattern size:%{public}d", patternSize);
453 return ERROR;
454 }
455 auto patterns = package.patterns;
456 for (int32_t i = 0; i < patternSize; ++i) {
457 int32_t eventNum = patterns[i].eventNum;
458 if ((eventNum <= 0) || (patterns[i].events == nullptr)) {
459 MISC_HILOGW("Events is not need to free, event size:%{public}d", eventNum);
460 continue;
461 }
462 auto events = patterns[i].events;
463 for (int32_t j = 0; j < eventNum; ++j) {
464 if (events[j].points != nullptr) {
465 free(events[j].points);
466 events[j].points = nullptr;
467 }
468 }
469 free(events);
470 events = nullptr;
471 }
472 free(patterns);
473 patterns = nullptr;
474 return ERR_OK;
475 }
476
PlayPrimitiveEffect(int32_t vibratorId,const std::string & effect,int32_t intensity,int32_t usage,bool systemUsage,int32_t count)477 int32_t VibratorServiceClient::PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect, int32_t intensity,
478 int32_t usage, bool systemUsage, int32_t count)
479 {
480 MISC_HILOGD("Vibrate begin, effect:%{public}s, intensity:%{public}d, usage:%{public}d, count:%{public}d",
481 effect.c_str(), intensity, usage, count);
482 int32_t ret = InitServiceClient();
483 if (ret != ERR_OK) {
484 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
485 return MISC_NATIVE_GET_SERVICE_ERR;
486 }
487 std::lock_guard<std::mutex> clientLock(clientMutex_);
488 CHKPR(miscdeviceProxy_, ERROR);
489 StartTrace(HITRACE_TAG_SENSORS, "PlayPrimitiveEffect");
490 ret = miscdeviceProxy_->PlayPrimitiveEffect(vibratorId, effect, intensity, usage, systemUsage, count);
491 FinishTrace(HITRACE_TAG_SENSORS);
492 if (ret != ERR_OK) {
493 MISC_HILOGE("Play primitive effect failed, ret:%{public}d, effect:%{public}s, intensity:%{public}d,"
494 "usage:%{public}d, count:%{public}d", ret, effect.c_str(), intensity, usage, count);
495 }
496 return ret;
497 }
498
GetVibratorCapacity()499 int32_t VibratorServiceClient::GetVibratorCapacity()
500 {
501 CHKPR(miscdeviceProxy_, ERROR);
502 StartTrace(HITRACE_TAG_SENSORS, "GetVibratorCapacity");
503 int32_t ret = miscdeviceProxy_->GetVibratorCapacity(capacity_);
504 FinishTrace(HITRACE_TAG_SENSORS);
505 capacity_.Dump();
506 return ret;
507 }
508
IsSupportVibratorCustom()509 bool VibratorServiceClient::IsSupportVibratorCustom()
510 {
511 int32_t ret = InitServiceClient();
512 if (ret != ERR_OK) {
513 MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
514 }
515 return (capacity_.isSupportHdHaptic || capacity_.isSupportPresetMapping || capacity_.isSupportTimeDelay);
516 }
517 } // namespace Sensors
518 } // namespace OHOS
519