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 &parameter)
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 &parameter)
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