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