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