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 "miscdevice_service.h" 17 18#include <algorithm> 19#include <map> 20#include <string_ex.h> 21 22#include "death_recipient_template.h" 23#ifdef MEMMGR_ENABLE 24#include "iservice_registry.h" 25#include "mem_mgr_client.h" 26#endif // MEMMGR_ENABLE 27#include "system_ability_definition.h" 28 29#include "sensors_errors.h" 30#include "vibration_priority_manager.h" 31 32#ifdef HDF_DRIVERS_INTERFACE_LIGHT 33#include "v1_0/light_interface_proxy.h" 34#endif // HDF_DRIVERS_INTERFACE_LIGHT 35 36#ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 37#include "parameters.h" 38#include "default_vibrator_decoder.h" 39#include "default_vibrator_decoder_factory.h" 40#include "vibrator_decoder_creator.h" 41#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 42 43#undef LOG_TAG 44#define LOG_TAG "MiscdeviceService" 45 46namespace OHOS { 47namespace Sensors { 48namespace { 49auto g_miscdeviceService = MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance(); 50const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_miscdeviceService.GetRefPtr()); 51constexpr int32_t MIN_VIBRATOR_TIME = 0; 52constexpr int32_t MAX_VIBRATOR_TIME = 1800000; 53constexpr int32_t MIN_VIBRATOR_COUNT = 1; 54constexpr int32_t MAX_VIBRATOR_COUNT = 1000; 55constexpr int32_t INTENSITY_MIN = 0; 56constexpr int32_t INTENSITY_MAX = 100; 57constexpr int32_t FREQUENCY_MIN = 0; 58constexpr int32_t FREQUENCY_MAX = 100; 59constexpr int32_t INTENSITY_ADJUST_MIN = 0; 60constexpr int32_t INTENSITY_ADJUST_MAX = 100; 61constexpr int32_t FREQUENCY_ADJUST_MIN = -100; 62constexpr int32_t FREQUENCY_ADJUST_MAX = 100; 63constexpr int32_t INVALID_PID = -1; 64constexpr int32_t VIBRATOR_ID = 0; 65constexpr int32_t BASE_YEAR = 1900; 66constexpr int32_t BASE_MON = 1; 67constexpr int32_t CONVERSION_RATE = 1000; 68VibratorCapacity g_capacity; 69#ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 70const std::string PHONE_TYPE = "phone"; 71#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 72} // namespace 73 74bool MiscdeviceService::isVibrationPriorityReady_ = false; 75 76MiscdeviceService::MiscdeviceService() 77 : SystemAbility(MISCDEVICE_SERVICE_ABILITY_ID, true), 78 lightExist_(false), 79 vibratorExist_(false), 80 state_(MiscdeviceServiceState::STATE_STOPPED), 81 vibratorThread_(nullptr) 82{ 83 MISC_HILOGD("Add SystemAbility"); 84} 85 86MiscdeviceService::~MiscdeviceService() 87{ 88 StopVibrateThread(); 89} 90 91void MiscdeviceService::OnDump() 92{ 93 MISC_HILOGI("Ondump is invoked"); 94} 95 96int32_t MiscdeviceService::SubscribeCommonEvent(const std::string &eventName, 97 EventReceiver receiver) __attribute__((no_sanitize("cfi"))) 98{ 99 if (receiver == nullptr) { 100 MISC_HILOGE("receiver is nullptr"); 101 return ERROR; 102 } 103 EventFwk::MatchingSkills matchingSkills; 104 matchingSkills.AddEvent(eventName); 105 EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); 106 auto subscribePtr = std::make_shared<MiscdeviceCommonEventSubscriber>(subscribeInfo, receiver); 107 if (!EventFwk::CommonEventManager::SubscribeCommonEvent(subscribePtr)) { 108 MISC_HILOGE("Subscribe common event fail"); 109 return ERROR; 110 } 111 return ERR_OK; 112} 113 114void MiscdeviceService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) 115{ 116 MISC_HILOGI("OnAddSystemAbility systemAbilityId:%{public}d", systemAbilityId); 117 switch (systemAbilityId) { 118 case MEMORY_MANAGER_SA_ID: { 119 MISC_HILOGI("Memory manager service start"); 120#ifdef MEMMGR_ENABLE 121 Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 122 PROCESS_TYPE_SA, PROCESS_STATUS_STARTED, MISCDEVICE_SERVICE_ABILITY_ID); 123#endif // MEMMGR_ENABLE 124 break; 125 } 126 case COMMON_EVENT_SERVICE_ID: { 127 MISC_HILOGI("Common event service start"); 128 int32_t ret = SubscribeCommonEvent("usual.event.DATA_SHARE_READY", 129 std::bind(&MiscdeviceService::OnReceiveEvent, this, std::placeholders::_1)); 130 if (ret != ERR_OK) { 131 MISC_HILOGE("Subscribe usual.event.DATA_SHARE_READY fail"); 132 } 133 AddSystemAbilityListener(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); 134 break; 135 } 136 case DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID: { 137 MISC_HILOGI("Distributed kv data service start"); 138 std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_); 139 if (PriorityManager->Init()) { 140 MISC_HILOGI("PriorityManager init"); 141 isVibrationPriorityReady_ = true; 142 } else { 143 MISC_HILOGE("PriorityManager init fail"); 144 } 145 break; 146 } 147 default: { 148 MISC_HILOGI("Unknown service, systemAbilityId:%{public}d", systemAbilityId); 149 break; 150 } 151 } 152} 153 154void MiscdeviceService::OnReceiveEvent(const EventFwk::CommonEventData &data) 155{ 156 const auto &want = data.GetWant(); 157 std::string action = want.GetAction(); 158 if (action == "usual.event.DATA_SHARE_READY") { 159 MISC_HILOGI("On receive usual.event.DATA_SHARE_READY"); 160 std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_); 161 if (isVibrationPriorityReady_) { 162 MISC_HILOGI("PriorityManager already init"); 163 return; 164 } 165 if (PriorityManager->Init()) { 166 MISC_HILOGI("PriorityManager init"); 167 isVibrationPriorityReady_ = true; 168 } else { 169 MISC_HILOGE("PriorityManager init fail"); 170 } 171 } 172} 173 174void MiscdeviceService::OnStart() 175{ 176 CALL_LOG_ENTER; 177 if (state_ == MiscdeviceServiceState::STATE_RUNNING) { 178 MISC_HILOGW("state_ already started"); 179 return; 180 } 181 if (!InitInterface()) { 182 MISC_HILOGE("Init interface error"); 183 } 184 if (!InitLightInterface()) { 185 MISC_HILOGE("InitLightInterface failed"); 186 } 187 if (!SystemAbility::Publish(MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance())) { 188 MISC_HILOGE("Publish MiscdeviceService failed"); 189 return; 190 } 191 std::lock_guard<std::mutex> lock(miscDeviceIdMapMutex_); 192 auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_)); 193 if (!ret.second) { 194 MISC_HILOGI("Light exist in miscDeviceIdMap_"); 195 ret.first->second = lightExist_; 196 } 197 ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_)); 198 if (!ret.second) { 199 MISC_HILOGI("Vibrator exist in miscDeviceIdMap_"); 200 ret.first->second = vibratorExist_; 201 } 202 state_ = MiscdeviceServiceState::STATE_RUNNING; 203#ifdef MEMMGR_ENABLE 204 AddSystemAbilityListener(MEMORY_MANAGER_SA_ID); 205#endif // MEMMGR_ENABLE 206 AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID); 207} 208 209void MiscdeviceService::OnStartFuzz() 210{ 211 CALL_LOG_ENTER; 212 if (state_ == MiscdeviceServiceState::STATE_RUNNING) { 213 MISC_HILOGW("state_ already started"); 214 return; 215 } 216 if (!InitInterface()) { 217 MISC_HILOGE("Init interface error"); 218 } 219 if (!InitLightInterface()) { 220 MISC_HILOGE("InitLightInterface failed"); 221 } 222 std::lock_guard<std::mutex> lock(miscDeviceIdMapMutex_); 223 auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_)); 224 if (!ret.second) { 225 MISC_HILOGI("Light exist in miscDeviceIdMap_"); 226 ret.first->second = lightExist_; 227 } 228 ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_)); 229 if (!ret.second) { 230 MISC_HILOGI("Vibrator exist in miscDeviceIdMap_"); 231 ret.first->second = vibratorExist_; 232 } 233 state_ = MiscdeviceServiceState::STATE_RUNNING; 234} 235 236bool MiscdeviceService::InitInterface() 237{ 238 auto ret = vibratorHdiConnection_.ConnectHdi(); 239 if (ret != ERR_OK) { 240 MISC_HILOGE("InitVibratorServiceImpl failed"); 241 return false; 242 } 243 if (vibratorHdiConnection_.GetVibratorCapacity(g_capacity) != ERR_OK) { 244 MISC_HILOGE("GetVibratorCapacity failed"); 245 } 246 return true; 247} 248 249bool MiscdeviceService::InitLightInterface() 250{ 251 auto ret = lightHdiConnection_.ConnectHdi(); 252 if (ret != ERR_OK) { 253 MISC_HILOGE("ConnectHdi failed"); 254 return false; 255 } 256 return true; 257} 258 259bool MiscdeviceService::IsValid(int32_t lightId) 260{ 261 CALL_LOG_ENTER; 262 for (const auto &item : lightInfos_) { 263 if (lightId == item.GetLightId()) { 264 return true; 265 } 266 } 267 return false; 268} 269 270bool MiscdeviceService::IsLightAnimationValid(const LightAnimationIPC &animation) 271{ 272 CALL_LOG_ENTER; 273 int32_t mode = animation.GetMode(); 274 int32_t onTime = animation.GetOnTime(); 275 int32_t offTime = animation.GetOffTime(); 276 if ((mode < 0) || (mode >= LIGHT_MODE_BUTT)) { 277 MISC_HILOGE("animation mode is invalid, mode:%{public}d", mode); 278 return false; 279 } 280 if ((onTime < 0) || (offTime < 0)) { 281 MISC_HILOGE("animation onTime or offTime is invalid, onTime:%{public}d, offTime:%{public}d", 282 onTime, offTime); 283 return false; 284 } 285 return true; 286} 287 288void MiscdeviceService::OnStop() 289{ 290 CALL_LOG_ENTER; 291 if (state_ == MiscdeviceServiceState::STATE_STOPPED) { 292 MISC_HILOGW("MiscdeviceService stopped already"); 293 return; 294 } 295 state_ = MiscdeviceServiceState::STATE_STOPPED; 296 int32_t ret = vibratorHdiConnection_.DestroyHdiConnection(); 297 if (ret != ERR_OK) { 298 MISC_HILOGE("Destroy hdi connection fail"); 299 } 300#ifdef MEMMGR_ENABLE 301 Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), PROCESS_TYPE_SA, PROCESS_STATUS_DIED, 302 MISCDEVICE_SERVICE_ABILITY_ID); 303#endif // MEMMGR_ENABLE 304} 305 306bool MiscdeviceService::ShouldIgnoreVibrate(const VibrateInfo &info) 307{ 308 std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_); 309 if (!isVibrationPriorityReady_) { 310 MISC_HILOGE("Vibraion priority manager not ready"); 311 return VIBRATION; 312 } 313 return (PriorityManager->ShouldIgnoreVibrate(info, vibratorThread_) != VIBRATION); 314} 315 316int32_t MiscdeviceService::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage, bool systemUsage) 317{ 318 if ((timeOut <= MIN_VIBRATOR_TIME) || (timeOut > MAX_VIBRATOR_TIME) 319 || (usage >= USAGE_MAX) || (usage < 0)) { 320 MISC_HILOGE("Invalid parameter"); 321 return PARAMETER_ERROR; 322 } 323 VibrateInfo info = { 324 .mode = VIBRATE_TIME, 325 .packageName = GetPackageName(GetCallingTokenID()), 326 .pid = GetCallingPid(), 327 .uid = GetCallingUid(), 328 .usage = usage, 329 .systemUsage = systemUsage, 330 .duration = timeOut 331 }; 332 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 333 std::string curVibrateTime = GetCurrentTime(); 334 if (ShouldIgnoreVibrate(info)) { 335 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 336 return ERROR; 337 } 338 StartVibrateThread(info); 339 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 340 "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, 341 info.usage, vibratorId, info.duration); 342 return NO_ERROR; 343} 344 345int32_t MiscdeviceService::StopVibrator(int32_t vibratorId) 346{ 347 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 348#if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR) 349 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() && 350 !vibratorHdiConnection_.IsVibratorRunning())) { 351 MISC_HILOGD("No vibration, no need to stop"); 352 return ERROR; 353 } 354 if (vibratorHdiConnection_.IsVibratorRunning()) { 355 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET); 356 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC); 357 } 358#else 359 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) { 360 MISC_HILOGD("No vibration, no need to stop"); 361 return ERROR; 362 } 363#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR 364 StopVibrateThread(); 365 std::string packageName = GetPackageName(GetCallingTokenID()); 366 std::string curVibrateTime = GetCurrentTime(); 367 MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d", 368 curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId); 369 return NO_ERROR; 370} 371 372int32_t MiscdeviceService::PlayVibratorEffect(int32_t vibratorId, const std::string &effect, 373 int32_t count, int32_t usage, bool systemUsage) 374{ 375 if ((count < MIN_VIBRATOR_COUNT) || (count > MAX_VIBRATOR_COUNT) || (usage >= USAGE_MAX) || (usage < 0)) { 376 MISC_HILOGE("Invalid parameter"); 377 return PARAMETER_ERROR; 378 } 379#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 380 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect); 381 if (!effectInfo) { 382 MISC_HILOGE("GetEffectInfo fail"); 383 return ERROR; 384 } 385 if (!(effectInfo->isSupportEffect)) { 386 MISC_HILOGE("Effect not supported"); 387 return PARAMETER_ERROR; 388 } 389#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 390 VibrateInfo info = { 391 .mode = VIBRATE_PRESET, 392 .packageName = GetPackageName(GetCallingTokenID()), 393 .pid = GetCallingPid(), 394 .uid = GetCallingUid(), 395 .usage = usage, 396 .systemUsage = systemUsage, 397#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 398 .duration = effectInfo->duration, 399#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 400 .effect = effect, 401 .count = count, 402 .intensity = INTENSITY_ADJUST_MAX 403 }; 404 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 405 std::string curVibrateTime = GetCurrentTime(); 406 if (ShouldIgnoreVibrate(info)) { 407 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 408 return ERROR; 409 } 410 StartVibrateThread(info); 411 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 412 "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s, count:%{public}d", curVibrateTime.c_str(), 413 info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str(), info.count); 414 return NO_ERROR; 415} 416 417void MiscdeviceService::StartVibrateThread(VibrateInfo info) 418{ 419 if (vibratorThread_ == nullptr) { 420 vibratorThread_ = std::make_shared<VibratorThread>(); 421 } 422 StopVibrateThread(); 423#if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR) 424 if (vibratorHdiConnection_.IsVibratorRunning()) { 425 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET); 426 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC); 427 } 428#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR 429 vibratorThread_->UpdateVibratorEffect(info); 430 vibratorThread_->Start("VibratorThread"); 431 DumpHelper->SaveVibrateRecord(info); 432} 433 434void MiscdeviceService::StopVibrateThread() 435{ 436 if ((vibratorThread_ != nullptr) && (vibratorThread_->IsRunning())) { 437 vibratorThread_->SetExitStatus(true); 438 vibratorThread_->WakeUp(); 439 vibratorThread_->NotifyExitSync(); 440 vibratorThread_->SetExitStatus(false); 441 } 442} 443 444int32_t MiscdeviceService::StopVibrator(int32_t vibratorId, const std::string &mode) 445{ 446 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 447 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) { 448 MISC_HILOGD("No vibration, no need to stop"); 449 return ERROR; 450 } 451 const VibrateInfo info = vibratorThread_->GetCurrentVibrateInfo(); 452 if (info.mode != mode) { 453 MISC_HILOGD("Stop vibration information mismatch"); 454 return ERROR; 455 } 456 StopVibrateThread(); 457 std::string packageName = GetPackageName(GetCallingTokenID()); 458 std::string curVibrateTime = GetCurrentTime(); 459 MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d," 460 "mode:%{public}s", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId, mode.c_str()); 461 return NO_ERROR; 462} 463 464int32_t MiscdeviceService::IsSupportEffect(const std::string &effect, bool &state) 465{ 466#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 467 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect); 468 if (!effectInfo) { 469 MISC_HILOGE("GetEffectInfo fail"); 470 return ERROR; 471 } 472 state = effectInfo->isSupportEffect; 473 std::string packageName = GetPackageName(GetCallingTokenID()); 474 std::string curVibrateTime = GetCurrentTime(); 475 MISC_HILOGI("IsSupportEffect, currentTime:%{public}s, package:%{public}s, pid:%{public}d, effect:%{public}s," 476 "state:%{public}d", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), effect.c_str(), state); 477#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 478 return NO_ERROR; 479} 480 481std::string MiscdeviceService::GetCurrentTime() 482{ 483 timespec curTime; 484 clock_gettime(CLOCK_REALTIME, &curTime); 485 struct tm *timeinfo = localtime(&(curTime.tv_sec)); 486 std::string currentTime; 487 if (timeinfo == nullptr) { 488 MISC_HILOGE("timeinfo is null"); 489 return currentTime; 490 } 491 currentTime.append(std::to_string(timeinfo->tm_year + BASE_YEAR)).append("-") 492 .append(std::to_string(timeinfo->tm_mon + BASE_MON)).append("-").append(std::to_string(timeinfo->tm_mday)) 493 .append(" ").append(std::to_string(timeinfo->tm_hour)).append(":").append(std::to_string(timeinfo->tm_min)) 494 .append(":").append(std::to_string(timeinfo->tm_sec)).append(".") 495 .append(std::to_string(curTime.tv_nsec / (CONVERSION_RATE * CONVERSION_RATE))); 496 return currentTime; 497} 498 499#ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 500int32_t MiscdeviceService::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage, 501 bool systemUsage, const VibrateParameter ¶meter) 502{ 503 if (!(g_capacity.isSupportHdHaptic || g_capacity.isSupportPresetMapping || g_capacity.isSupportTimeDelay)) { 504 MISC_HILOGE("The device does not support this operation"); 505 return IS_NOT_SUPPORTED; 506 } 507 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) { 508 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage); 509 return PARAMETER_ERROR; 510 } 511 JsonParser parser(rawFd); 512 VibratorDecoderCreator creator; 513 std::unique_ptr<IVibratorDecoder> decoder(creator.CreateDecoder(parser)); 514 CHKPR(decoder, ERROR); 515 VibratePackage package; 516 int32_t ret = decoder->DecodeEffect(rawFd, parser, package); 517 if (ret != SUCCESS || package.patterns.empty()) { 518 MISC_HILOGE("Decode effect error"); 519 return ERROR; 520 } 521 MergeVibratorParmeters(parameter, package); 522 package.Dump(); 523 VibrateInfo info = { 524 .packageName = GetPackageName(GetCallingTokenID()), 525 .pid = GetCallingPid(), 526 .uid = GetCallingUid(), 527 .usage = usage, 528 .systemUsage = systemUsage, 529 .package = package, 530 }; 531 if (g_capacity.isSupportHdHaptic) { 532 info.mode = VIBRATE_CUSTOM_HD; 533 } else if (g_capacity.isSupportPresetMapping) { 534 info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT; 535 } else if (g_capacity.isSupportTimeDelay) { 536 info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME; 537 } 538 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 539 std::string curVibrateTime = GetCurrentTime(); 540 if (ShouldIgnoreVibrate(info)) { 541 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 542 return ERROR; 543 } 544 StartVibrateThread(info); 545 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 546 "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, 547 info.usage, vibratorId, package.packageDuration); 548 return NO_ERROR; 549} 550#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 551 552std::string MiscdeviceService::GetPackageName(AccessTokenID tokenId) 553{ 554 std::string packageName; 555 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId); 556 switch (tokenType) { 557 case ATokenTypeEnum::TOKEN_HAP: { 558 HapTokenInfo hapInfo; 559 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) { 560 MISC_HILOGE("Get hap token info fail"); 561 return {}; 562 } 563 packageName = hapInfo.bundleName; 564 break; 565 } 566 case ATokenTypeEnum::TOKEN_NATIVE: 567 case ATokenTypeEnum::TOKEN_SHELL: { 568 NativeTokenInfo tokenInfo; 569 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) { 570 MISC_HILOGE("Get native token info fail"); 571 return {}; 572 } 573 packageName = tokenInfo.processName; 574 break; 575 } 576 default: { 577 MISC_HILOGW("Token type not match"); 578 break; 579 } 580 } 581 return packageName; 582} 583 584std::vector<LightInfoIPC> MiscdeviceService::GetLightList() 585{ 586 std::string packageName = GetPackageName(GetCallingTokenID()); 587 MISC_HILOGI("GetLightList, package:%{public}s", packageName.c_str()); 588 if (!InitLightList()) { 589 MISC_HILOGE("InitLightList init failed"); 590 return lightInfos_; 591 } 592 return lightInfos_; 593} 594 595bool MiscdeviceService::InitLightList() 596{ 597 int32_t ret = lightHdiConnection_.GetLightList(lightInfos_); 598 if (ret != ERR_OK) { 599 MISC_HILOGE("InitLightList failed, ret:%{public}d", ret); 600 return false; 601 } 602 return true; 603} 604 605int32_t MiscdeviceService::TurnOn(int32_t lightId, const LightColor &color, const LightAnimationIPC &animation) 606{ 607 std::string packageName = GetPackageName(GetCallingTokenID()); 608 MISC_HILOGI("TurnOn, package:%{public}s", packageName.c_str()); 609 if (!IsValid(lightId)) { 610 MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId); 611 return MISCDEVICE_NATIVE_SAM_ERR; 612 } 613 if (!IsLightAnimationValid(animation)) { 614 MISC_HILOGE("animation is invalid"); 615 return MISCDEVICE_NATIVE_SAM_ERR; 616 } 617 int32_t ret = lightHdiConnection_.TurnOn(lightId, color, animation); 618 if (ret != ERR_OK) { 619 MISC_HILOGE("TurnOn failed, error:%{public}d", ret); 620 return ERROR; 621 } 622 return ret; 623} 624 625int32_t MiscdeviceService::TurnOff(int32_t lightId) 626{ 627 std::string packageName = GetPackageName(GetCallingTokenID()); 628 MISC_HILOGI("TurnOff, package:%{public}s", packageName.c_str()); 629 if (!IsValid(lightId)) { 630 MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId); 631 return MISCDEVICE_NATIVE_SAM_ERR; 632 } 633 int32_t ret = lightHdiConnection_.TurnOff(lightId); 634 if (ret != ERR_OK) { 635 MISC_HILOGE("TurnOff failed, error:%{public}d", ret); 636 return ERROR; 637 } 638 return ret; 639} 640 641int32_t MiscdeviceService::Dump(int32_t fd, const std::vector<std::u16string> &args) 642{ 643 CALL_LOG_ENTER; 644 if (fd < 0) { 645 MISC_HILOGE("Invalid fd"); 646 return DUMP_PARAM_ERR; 647 } 648 if (args.empty()) { 649 MISC_HILOGE("args cannot be empty"); 650 dprintf(fd, "args cannot be empty\n"); 651 DumpHelper->DumpHelp(fd); 652 return DUMP_PARAM_ERR; 653 } 654 std::vector<std::string> argList = { "" }; 655 std::transform(args.begin(), args.end(), std::back_inserter(argList), 656 [](const std::u16string &arg) { 657 return Str16ToStr8(arg); 658 }); 659 DumpHelper->ParseCommand(fd, argList); 660 return ERR_OK; 661} 662 663int32_t MiscdeviceService::PlayPattern(const VibratePattern &pattern, int32_t usage, 664 bool systemUsage, const VibrateParameter ¶meter) 665{ 666 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) { 667 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage); 668 return PARAMETER_ERROR; 669 } 670 VibratePattern vibratePattern = { 671 .startTime = 0, 672 .events = pattern.events 673 }; 674 std::vector<VibratePattern> patterns = {vibratePattern}; 675 VibratePackage package = { 676 .patterns = patterns 677 }; 678 MergeVibratorParmeters(parameter, package); 679 package.Dump(); 680 VibrateInfo info = { 681 .mode = VIBRATE_BUTT, 682 .packageName = GetPackageName(GetCallingTokenID()), 683 .pid = GetCallingPid(), 684 .uid = GetCallingUid(), 685 .usage = usage, 686 .systemUsage = systemUsage 687 }; 688 if (g_capacity.isSupportHdHaptic) { 689 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 690 std::string curVibrateTime = GetCurrentTime(); 691 if (ShouldIgnoreVibrate(info)) { 692 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 693 return ERROR; 694 } 695 StartVibrateThread(info); 696 return vibratorHdiConnection_.PlayPattern(package.patterns.front()); 697 } else if (g_capacity.isSupportPresetMapping) { 698 info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT; 699 } else if (g_capacity.isSupportTimeDelay) { 700 info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME; 701 } 702 info.package = package; 703 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 704 std::string curVibrateTime = GetCurrentTime(); 705 if (ShouldIgnoreVibrate(info)) { 706 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 707 return ERROR; 708 } 709 StartVibrateThread(info); 710 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 711 "duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage, 712 pattern.patternDuration); 713 return ERR_OK; 714} 715 716int32_t MiscdeviceService::GetDelayTime(int32_t &delayTime) 717{ 718 std::string packageName = GetPackageName(GetCallingTokenID()); 719 MISC_HILOGD("GetDelayTime, package:%{public}s", packageName.c_str()); 720 return vibratorHdiConnection_.GetDelayTime(g_capacity.GetVibrateMode(), delayTime); 721} 722 723bool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter ¶meter) 724{ 725 if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) || 726 (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) { 727 MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d", 728 parameter.intensity, parameter.frequency); 729 return false; 730 } 731 return true; 732} 733 734void MiscdeviceService::MergeVibratorParmeters(const VibrateParameter ¶meter, VibratePackage &package) 735{ 736 if ((parameter.intensity == INTENSITY_ADJUST_MAX) && (parameter.frequency == 0)) { 737 MISC_HILOGD("The adjust parameter is not need to merge"); 738 return; 739 } 740 parameter.Dump(); 741 for (VibratePattern &pattern : package.patterns) { 742 for (VibrateEvent &event : pattern.events) { 743 float intensityScale = static_cast<float>(parameter.intensity) / INTENSITY_ADJUST_MAX; 744 if ((event.tag == EVENT_TAG_TRANSIENT) || (event.points.empty())) { 745 event.intensity = static_cast<int32_t>(event.intensity * intensityScale); 746 event.intensity = std::max(std::min(event.intensity, INTENSITY_MAX), INTENSITY_MIN); 747 event.frequency = event.frequency + parameter.frequency; 748 event.frequency = std::max(std::min(event.frequency, FREQUENCY_MAX), FREQUENCY_MIN); 749 } else { 750 for (VibrateCurvePoint &point : event.points) { 751 point.intensity = static_cast<int32_t>(point.intensity * intensityScale); 752 point.intensity = std::max(std::min(point.intensity, INTENSITY_ADJUST_MAX), INTENSITY_ADJUST_MIN); 753 point.frequency = point.frequency + parameter.frequency; 754 point.frequency = std::max(std::min(point.frequency, FREQUENCY_ADJUST_MAX), FREQUENCY_ADJUST_MIN); 755 } 756 } 757 } 758 } 759} 760 761int32_t MiscdeviceService::TransferClientRemoteObject(const sptr<IRemoteObject> &vibratorServiceClient) 762{ 763 auto clientPid = GetCallingPid(); 764 if (clientPid < 0) { 765 MISC_HILOGE("ClientPid is invalid, clientPid:%{public}d", clientPid); 766 return ERROR; 767 } 768 RegisterClientDeathRecipient(vibratorServiceClient, clientPid); 769 return ERR_OK; 770} 771 772void MiscdeviceService::ProcessDeathObserver(const wptr<IRemoteObject> &object) 773{ 774 CALL_LOG_ENTER; 775 sptr<IRemoteObject> client = object.promote(); 776 int32_t clientPid = FindClientPid(client); 777 VibrateInfo info; 778 { 779 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 780 if (vibratorThread_ == nullptr) { 781 vibratorThread_ = std::make_shared<VibratorThread>(); 782 } 783 info = vibratorThread_->GetCurrentVibrateInfo(); 784 } 785 int32_t vibratePid = info.pid; 786 MISC_HILOGI("ClientPid:%{public}d, VibratePid:%{public}d", clientPid, vibratePid); 787 if ((clientPid != INVALID_PID) && (clientPid == vibratePid)) { 788 StopVibrator(VIBRATOR_ID); 789 } 790 UnregisterClientDeathRecipient(client); 791} 792 793void MiscdeviceService::RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient, int32_t pid) 794{ 795 if (vibratorServiceClient == nullptr) { 796 MISC_HILOGE("VibratorServiceClient is nullptr"); 797 return; 798 } 799 std::lock_guard<std::mutex> lock(clientDeathObserverMutex_); 800 if (clientDeathObserver_ == nullptr) { 801 clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MiscdeviceService *>(this)); 802 if (clientDeathObserver_ == nullptr) { 803 MISC_HILOGE("ClientDeathObserver_ is nullptr"); 804 return; 805 } 806 } 807 vibratorServiceClient->AddDeathRecipient(clientDeathObserver_); 808 SaveClientPid(vibratorServiceClient, pid); 809} 810 811void MiscdeviceService::UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient) 812{ 813 if (vibratorServiceClient == nullptr) { 814 MISC_HILOGE("vibratorServiceClient is nullptr"); 815 return; 816 } 817 int32_t clientPid = FindClientPid(vibratorServiceClient); 818 if (clientPid == INVALID_PID) { 819 MISC_HILOGE("Pid is invalid"); 820 return; 821 } 822 std::lock_guard<std::mutex> lock(clientDeathObserverMutex_); 823 vibratorServiceClient->RemoveDeathRecipient(clientDeathObserver_); 824 DestroyClientPid(vibratorServiceClient); 825} 826 827void MiscdeviceService::SaveClientPid(const sptr<IRemoteObject> &vibratorServiceClient, int32_t pid) 828{ 829 if (vibratorServiceClient == nullptr) { 830 MISC_HILOGE("VibratorServiceClient is nullptr"); 831 return; 832 } 833 std::lock_guard<std::mutex> lock(clientPidMapMutex_); 834 clientPidMap_.insert(std::make_pair(vibratorServiceClient, pid)); 835} 836 837int32_t MiscdeviceService::FindClientPid(const sptr<IRemoteObject> &vibratorServiceClient) 838{ 839 if (vibratorServiceClient == nullptr) { 840 MISC_HILOGE("VibratorServiceClient is nullptr"); 841 return INVALID_PID; 842 } 843 std::lock_guard<std::mutex> lock(clientPidMapMutex_); 844 auto it = clientPidMap_.find(vibratorServiceClient); 845 if (it == clientPidMap_.end()) { 846 MISC_HILOGE("Cannot find client pid"); 847 return INVALID_PID; 848 } 849 return it->second; 850} 851 852void MiscdeviceService::DestroyClientPid(const sptr<IRemoteObject> &vibratorServiceClient) 853{ 854 if (vibratorServiceClient == nullptr) { 855 MISC_HILOGD("VibratorServiceClient is nullptr"); 856 return; 857 } 858 std::lock_guard<std::mutex> lock(clientPidMapMutex_); 859 auto it = clientPidMap_.find(vibratorServiceClient); 860 if (it == clientPidMap_.end()) { 861 MISC_HILOGE("Cannot find client pid"); 862 return; 863 } 864 clientPidMap_.erase(it); 865} 866 867int32_t MiscdeviceService::PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect, 868 int32_t intensity, int32_t usage, bool systemUsage, int32_t count) 869{ 870 if ((intensity <= INTENSITY_MIN) || (intensity > INTENSITY_MAX) || (usage >= USAGE_MAX) || (usage < 0)) { 871 MISC_HILOGE("Invalid parameter"); 872 return PARAMETER_ERROR; 873 } 874#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 875 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect); 876 if (!effectInfo) { 877 MISC_HILOGE("GetEffectInfo fail"); 878 return ERROR; 879 } 880 if (!(effectInfo->isSupportEffect)) { 881 MISC_HILOGE("Effect not supported"); 882 return PARAMETER_ERROR; 883 } 884#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 885 VibrateInfo info = { 886 .mode = VIBRATE_PRESET, 887 .packageName = GetPackageName(GetCallingTokenID()), 888 .pid = GetCallingPid(), 889 .uid = GetCallingUid(), 890 .usage = usage, 891 .systemUsage = systemUsage, 892#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 893 .duration = effectInfo->duration, 894#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 895 .effect = effect, 896 .count = count, 897 .intensity = intensity 898 }; 899 std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 900 std::string curVibrateTime = GetCurrentTime(); 901 if (ShouldIgnoreVibrate(info)) { 902 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 903 return ERROR; 904 } 905 StartVibrateThread(info); 906 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 907 "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s", curVibrateTime.c_str(), 908 info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str()); 909 return NO_ERROR; 910} 911 912int32_t MiscdeviceService::GetVibratorCapacity(VibratorCapacity &capacity) 913{ 914 capacity = g_capacity; 915 return ERR_OK; 916} 917} // namespace Sensors 918} // namespace OHOS 919