158ec469eSopenharmony_ci/* 258ec469eSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 358ec469eSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 458ec469eSopenharmony_ci * you may not use this file except in compliance with the License. 558ec469eSopenharmony_ci * You may obtain a copy of the License at 658ec469eSopenharmony_ci * 758ec469eSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 858ec469eSopenharmony_ci * 958ec469eSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1058ec469eSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1158ec469eSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1258ec469eSopenharmony_ci * See the License for the specific language governing permissions and 1358ec469eSopenharmony_ci * limitations under the License. 1458ec469eSopenharmony_ci */ 1558ec469eSopenharmony_ci 1658ec469eSopenharmony_ci#include "miscdevice_service.h" 1758ec469eSopenharmony_ci 1858ec469eSopenharmony_ci#include <algorithm> 1958ec469eSopenharmony_ci#include <map> 2058ec469eSopenharmony_ci#include <string_ex.h> 2158ec469eSopenharmony_ci 2258ec469eSopenharmony_ci#include "death_recipient_template.h" 2358ec469eSopenharmony_ci#ifdef MEMMGR_ENABLE 2458ec469eSopenharmony_ci#include "iservice_registry.h" 2558ec469eSopenharmony_ci#include "mem_mgr_client.h" 2658ec469eSopenharmony_ci#endif // MEMMGR_ENABLE 2758ec469eSopenharmony_ci#include "system_ability_definition.h" 2858ec469eSopenharmony_ci 2958ec469eSopenharmony_ci#include "sensors_errors.h" 3058ec469eSopenharmony_ci#include "vibration_priority_manager.h" 3158ec469eSopenharmony_ci 3258ec469eSopenharmony_ci#ifdef HDF_DRIVERS_INTERFACE_LIGHT 3358ec469eSopenharmony_ci#include "v1_0/light_interface_proxy.h" 3458ec469eSopenharmony_ci#endif // HDF_DRIVERS_INTERFACE_LIGHT 3558ec469eSopenharmony_ci 3658ec469eSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 3758ec469eSopenharmony_ci#include "parameters.h" 3858ec469eSopenharmony_ci#include "default_vibrator_decoder.h" 3958ec469eSopenharmony_ci#include "default_vibrator_decoder_factory.h" 4058ec469eSopenharmony_ci#include "vibrator_decoder_creator.h" 4158ec469eSopenharmony_ci#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 4258ec469eSopenharmony_ci 4358ec469eSopenharmony_ci#undef LOG_TAG 4458ec469eSopenharmony_ci#define LOG_TAG "MiscdeviceService" 4558ec469eSopenharmony_ci 4658ec469eSopenharmony_cinamespace OHOS { 4758ec469eSopenharmony_cinamespace Sensors { 4858ec469eSopenharmony_cinamespace { 4958ec469eSopenharmony_ciauto g_miscdeviceService = MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance(); 5058ec469eSopenharmony_ciconst bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_miscdeviceService.GetRefPtr()); 5158ec469eSopenharmony_ciconstexpr int32_t MIN_VIBRATOR_TIME = 0; 5258ec469eSopenharmony_ciconstexpr int32_t MAX_VIBRATOR_TIME = 1800000; 5358ec469eSopenharmony_ciconstexpr int32_t MIN_VIBRATOR_COUNT = 1; 5458ec469eSopenharmony_ciconstexpr int32_t MAX_VIBRATOR_COUNT = 1000; 5558ec469eSopenharmony_ciconstexpr int32_t INTENSITY_MIN = 0; 5658ec469eSopenharmony_ciconstexpr int32_t INTENSITY_MAX = 100; 5758ec469eSopenharmony_ciconstexpr int32_t FREQUENCY_MIN = 0; 5858ec469eSopenharmony_ciconstexpr int32_t FREQUENCY_MAX = 100; 5958ec469eSopenharmony_ciconstexpr int32_t INTENSITY_ADJUST_MIN = 0; 6058ec469eSopenharmony_ciconstexpr int32_t INTENSITY_ADJUST_MAX = 100; 6158ec469eSopenharmony_ciconstexpr int32_t FREQUENCY_ADJUST_MIN = -100; 6258ec469eSopenharmony_ciconstexpr int32_t FREQUENCY_ADJUST_MAX = 100; 6358ec469eSopenharmony_ciconstexpr int32_t INVALID_PID = -1; 6458ec469eSopenharmony_ciconstexpr int32_t VIBRATOR_ID = 0; 6558ec469eSopenharmony_ciconstexpr int32_t BASE_YEAR = 1900; 6658ec469eSopenharmony_ciconstexpr int32_t BASE_MON = 1; 6758ec469eSopenharmony_ciconstexpr int32_t CONVERSION_RATE = 1000; 6858ec469eSopenharmony_ciVibratorCapacity g_capacity; 6958ec469eSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 7058ec469eSopenharmony_ciconst std::string PHONE_TYPE = "phone"; 7158ec469eSopenharmony_ci#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 7258ec469eSopenharmony_ci} // namespace 7358ec469eSopenharmony_ci 7458ec469eSopenharmony_cibool MiscdeviceService::isVibrationPriorityReady_ = false; 7558ec469eSopenharmony_ci 7658ec469eSopenharmony_ciMiscdeviceService::MiscdeviceService() 7758ec469eSopenharmony_ci : SystemAbility(MISCDEVICE_SERVICE_ABILITY_ID, true), 7858ec469eSopenharmony_ci lightExist_(false), 7958ec469eSopenharmony_ci vibratorExist_(false), 8058ec469eSopenharmony_ci state_(MiscdeviceServiceState::STATE_STOPPED), 8158ec469eSopenharmony_ci vibratorThread_(nullptr) 8258ec469eSopenharmony_ci{ 8358ec469eSopenharmony_ci MISC_HILOGD("Add SystemAbility"); 8458ec469eSopenharmony_ci} 8558ec469eSopenharmony_ci 8658ec469eSopenharmony_ciMiscdeviceService::~MiscdeviceService() 8758ec469eSopenharmony_ci{ 8858ec469eSopenharmony_ci StopVibrateThread(); 8958ec469eSopenharmony_ci} 9058ec469eSopenharmony_ci 9158ec469eSopenharmony_civoid MiscdeviceService::OnDump() 9258ec469eSopenharmony_ci{ 9358ec469eSopenharmony_ci MISC_HILOGI("Ondump is invoked"); 9458ec469eSopenharmony_ci} 9558ec469eSopenharmony_ci 9658ec469eSopenharmony_ciint32_t MiscdeviceService::SubscribeCommonEvent(const std::string &eventName, 9758ec469eSopenharmony_ci EventReceiver receiver) __attribute__((no_sanitize("cfi"))) 9858ec469eSopenharmony_ci{ 9958ec469eSopenharmony_ci if (receiver == nullptr) { 10058ec469eSopenharmony_ci MISC_HILOGE("receiver is nullptr"); 10158ec469eSopenharmony_ci return ERROR; 10258ec469eSopenharmony_ci } 10358ec469eSopenharmony_ci EventFwk::MatchingSkills matchingSkills; 10458ec469eSopenharmony_ci matchingSkills.AddEvent(eventName); 10558ec469eSopenharmony_ci EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); 10658ec469eSopenharmony_ci auto subscribePtr = std::make_shared<MiscdeviceCommonEventSubscriber>(subscribeInfo, receiver); 10758ec469eSopenharmony_ci if (!EventFwk::CommonEventManager::SubscribeCommonEvent(subscribePtr)) { 10858ec469eSopenharmony_ci MISC_HILOGE("Subscribe common event fail"); 10958ec469eSopenharmony_ci return ERROR; 11058ec469eSopenharmony_ci } 11158ec469eSopenharmony_ci return ERR_OK; 11258ec469eSopenharmony_ci} 11358ec469eSopenharmony_ci 11458ec469eSopenharmony_civoid MiscdeviceService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) 11558ec469eSopenharmony_ci{ 11658ec469eSopenharmony_ci MISC_HILOGI("OnAddSystemAbility systemAbilityId:%{public}d", systemAbilityId); 11758ec469eSopenharmony_ci switch (systemAbilityId) { 11858ec469eSopenharmony_ci case MEMORY_MANAGER_SA_ID: { 11958ec469eSopenharmony_ci MISC_HILOGI("Memory manager service start"); 12058ec469eSopenharmony_ci#ifdef MEMMGR_ENABLE 12158ec469eSopenharmony_ci Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 12258ec469eSopenharmony_ci PROCESS_TYPE_SA, PROCESS_STATUS_STARTED, MISCDEVICE_SERVICE_ABILITY_ID); 12358ec469eSopenharmony_ci#endif // MEMMGR_ENABLE 12458ec469eSopenharmony_ci break; 12558ec469eSopenharmony_ci } 12658ec469eSopenharmony_ci case COMMON_EVENT_SERVICE_ID: { 12758ec469eSopenharmony_ci MISC_HILOGI("Common event service start"); 12858ec469eSopenharmony_ci int32_t ret = SubscribeCommonEvent("usual.event.DATA_SHARE_READY", 12958ec469eSopenharmony_ci std::bind(&MiscdeviceService::OnReceiveEvent, this, std::placeholders::_1)); 13058ec469eSopenharmony_ci if (ret != ERR_OK) { 13158ec469eSopenharmony_ci MISC_HILOGE("Subscribe usual.event.DATA_SHARE_READY fail"); 13258ec469eSopenharmony_ci } 13358ec469eSopenharmony_ci AddSystemAbilityListener(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID); 13458ec469eSopenharmony_ci break; 13558ec469eSopenharmony_ci } 13658ec469eSopenharmony_ci case DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID: { 13758ec469eSopenharmony_ci MISC_HILOGI("Distributed kv data service start"); 13858ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_); 13958ec469eSopenharmony_ci if (PriorityManager->Init()) { 14058ec469eSopenharmony_ci MISC_HILOGI("PriorityManager init"); 14158ec469eSopenharmony_ci isVibrationPriorityReady_ = true; 14258ec469eSopenharmony_ci } else { 14358ec469eSopenharmony_ci MISC_HILOGE("PriorityManager init fail"); 14458ec469eSopenharmony_ci } 14558ec469eSopenharmony_ci break; 14658ec469eSopenharmony_ci } 14758ec469eSopenharmony_ci default: { 14858ec469eSopenharmony_ci MISC_HILOGI("Unknown service, systemAbilityId:%{public}d", systemAbilityId); 14958ec469eSopenharmony_ci break; 15058ec469eSopenharmony_ci } 15158ec469eSopenharmony_ci } 15258ec469eSopenharmony_ci} 15358ec469eSopenharmony_ci 15458ec469eSopenharmony_civoid MiscdeviceService::OnReceiveEvent(const EventFwk::CommonEventData &data) 15558ec469eSopenharmony_ci{ 15658ec469eSopenharmony_ci const auto &want = data.GetWant(); 15758ec469eSopenharmony_ci std::string action = want.GetAction(); 15858ec469eSopenharmony_ci if (action == "usual.event.DATA_SHARE_READY") { 15958ec469eSopenharmony_ci MISC_HILOGI("On receive usual.event.DATA_SHARE_READY"); 16058ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_); 16158ec469eSopenharmony_ci if (isVibrationPriorityReady_) { 16258ec469eSopenharmony_ci MISC_HILOGI("PriorityManager already init"); 16358ec469eSopenharmony_ci return; 16458ec469eSopenharmony_ci } 16558ec469eSopenharmony_ci if (PriorityManager->Init()) { 16658ec469eSopenharmony_ci MISC_HILOGI("PriorityManager init"); 16758ec469eSopenharmony_ci isVibrationPriorityReady_ = true; 16858ec469eSopenharmony_ci } else { 16958ec469eSopenharmony_ci MISC_HILOGE("PriorityManager init fail"); 17058ec469eSopenharmony_ci } 17158ec469eSopenharmony_ci } 17258ec469eSopenharmony_ci} 17358ec469eSopenharmony_ci 17458ec469eSopenharmony_civoid MiscdeviceService::OnStart() 17558ec469eSopenharmony_ci{ 17658ec469eSopenharmony_ci CALL_LOG_ENTER; 17758ec469eSopenharmony_ci if (state_ == MiscdeviceServiceState::STATE_RUNNING) { 17858ec469eSopenharmony_ci MISC_HILOGW("state_ already started"); 17958ec469eSopenharmony_ci return; 18058ec469eSopenharmony_ci } 18158ec469eSopenharmony_ci if (!InitInterface()) { 18258ec469eSopenharmony_ci MISC_HILOGE("Init interface error"); 18358ec469eSopenharmony_ci } 18458ec469eSopenharmony_ci if (!InitLightInterface()) { 18558ec469eSopenharmony_ci MISC_HILOGE("InitLightInterface failed"); 18658ec469eSopenharmony_ci } 18758ec469eSopenharmony_ci if (!SystemAbility::Publish(MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance())) { 18858ec469eSopenharmony_ci MISC_HILOGE("Publish MiscdeviceService failed"); 18958ec469eSopenharmony_ci return; 19058ec469eSopenharmony_ci } 19158ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(miscDeviceIdMapMutex_); 19258ec469eSopenharmony_ci auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_)); 19358ec469eSopenharmony_ci if (!ret.second) { 19458ec469eSopenharmony_ci MISC_HILOGI("Light exist in miscDeviceIdMap_"); 19558ec469eSopenharmony_ci ret.first->second = lightExist_; 19658ec469eSopenharmony_ci } 19758ec469eSopenharmony_ci ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_)); 19858ec469eSopenharmony_ci if (!ret.second) { 19958ec469eSopenharmony_ci MISC_HILOGI("Vibrator exist in miscDeviceIdMap_"); 20058ec469eSopenharmony_ci ret.first->second = vibratorExist_; 20158ec469eSopenharmony_ci } 20258ec469eSopenharmony_ci state_ = MiscdeviceServiceState::STATE_RUNNING; 20358ec469eSopenharmony_ci#ifdef MEMMGR_ENABLE 20458ec469eSopenharmony_ci AddSystemAbilityListener(MEMORY_MANAGER_SA_ID); 20558ec469eSopenharmony_ci#endif // MEMMGR_ENABLE 20658ec469eSopenharmony_ci AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID); 20758ec469eSopenharmony_ci} 20858ec469eSopenharmony_ci 20958ec469eSopenharmony_civoid MiscdeviceService::OnStartFuzz() 21058ec469eSopenharmony_ci{ 21158ec469eSopenharmony_ci CALL_LOG_ENTER; 21258ec469eSopenharmony_ci if (state_ == MiscdeviceServiceState::STATE_RUNNING) { 21358ec469eSopenharmony_ci MISC_HILOGW("state_ already started"); 21458ec469eSopenharmony_ci return; 21558ec469eSopenharmony_ci } 21658ec469eSopenharmony_ci if (!InitInterface()) { 21758ec469eSopenharmony_ci MISC_HILOGE("Init interface error"); 21858ec469eSopenharmony_ci } 21958ec469eSopenharmony_ci if (!InitLightInterface()) { 22058ec469eSopenharmony_ci MISC_HILOGE("InitLightInterface failed"); 22158ec469eSopenharmony_ci } 22258ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(miscDeviceIdMapMutex_); 22358ec469eSopenharmony_ci auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_)); 22458ec469eSopenharmony_ci if (!ret.second) { 22558ec469eSopenharmony_ci MISC_HILOGI("Light exist in miscDeviceIdMap_"); 22658ec469eSopenharmony_ci ret.first->second = lightExist_; 22758ec469eSopenharmony_ci } 22858ec469eSopenharmony_ci ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_)); 22958ec469eSopenharmony_ci if (!ret.second) { 23058ec469eSopenharmony_ci MISC_HILOGI("Vibrator exist in miscDeviceIdMap_"); 23158ec469eSopenharmony_ci ret.first->second = vibratorExist_; 23258ec469eSopenharmony_ci } 23358ec469eSopenharmony_ci state_ = MiscdeviceServiceState::STATE_RUNNING; 23458ec469eSopenharmony_ci} 23558ec469eSopenharmony_ci 23658ec469eSopenharmony_cibool MiscdeviceService::InitInterface() 23758ec469eSopenharmony_ci{ 23858ec469eSopenharmony_ci auto ret = vibratorHdiConnection_.ConnectHdi(); 23958ec469eSopenharmony_ci if (ret != ERR_OK) { 24058ec469eSopenharmony_ci MISC_HILOGE("InitVibratorServiceImpl failed"); 24158ec469eSopenharmony_ci return false; 24258ec469eSopenharmony_ci } 24358ec469eSopenharmony_ci if (vibratorHdiConnection_.GetVibratorCapacity(g_capacity) != ERR_OK) { 24458ec469eSopenharmony_ci MISC_HILOGE("GetVibratorCapacity failed"); 24558ec469eSopenharmony_ci } 24658ec469eSopenharmony_ci return true; 24758ec469eSopenharmony_ci} 24858ec469eSopenharmony_ci 24958ec469eSopenharmony_cibool MiscdeviceService::InitLightInterface() 25058ec469eSopenharmony_ci{ 25158ec469eSopenharmony_ci auto ret = lightHdiConnection_.ConnectHdi(); 25258ec469eSopenharmony_ci if (ret != ERR_OK) { 25358ec469eSopenharmony_ci MISC_HILOGE("ConnectHdi failed"); 25458ec469eSopenharmony_ci return false; 25558ec469eSopenharmony_ci } 25658ec469eSopenharmony_ci return true; 25758ec469eSopenharmony_ci} 25858ec469eSopenharmony_ci 25958ec469eSopenharmony_cibool MiscdeviceService::IsValid(int32_t lightId) 26058ec469eSopenharmony_ci{ 26158ec469eSopenharmony_ci CALL_LOG_ENTER; 26258ec469eSopenharmony_ci for (const auto &item : lightInfos_) { 26358ec469eSopenharmony_ci if (lightId == item.GetLightId()) { 26458ec469eSopenharmony_ci return true; 26558ec469eSopenharmony_ci } 26658ec469eSopenharmony_ci } 26758ec469eSopenharmony_ci return false; 26858ec469eSopenharmony_ci} 26958ec469eSopenharmony_ci 27058ec469eSopenharmony_cibool MiscdeviceService::IsLightAnimationValid(const LightAnimationIPC &animation) 27158ec469eSopenharmony_ci{ 27258ec469eSopenharmony_ci CALL_LOG_ENTER; 27358ec469eSopenharmony_ci int32_t mode = animation.GetMode(); 27458ec469eSopenharmony_ci int32_t onTime = animation.GetOnTime(); 27558ec469eSopenharmony_ci int32_t offTime = animation.GetOffTime(); 27658ec469eSopenharmony_ci if ((mode < 0) || (mode >= LIGHT_MODE_BUTT)) { 27758ec469eSopenharmony_ci MISC_HILOGE("animation mode is invalid, mode:%{public}d", mode); 27858ec469eSopenharmony_ci return false; 27958ec469eSopenharmony_ci } 28058ec469eSopenharmony_ci if ((onTime < 0) || (offTime < 0)) { 28158ec469eSopenharmony_ci MISC_HILOGE("animation onTime or offTime is invalid, onTime:%{public}d, offTime:%{public}d", 28258ec469eSopenharmony_ci onTime, offTime); 28358ec469eSopenharmony_ci return false; 28458ec469eSopenharmony_ci } 28558ec469eSopenharmony_ci return true; 28658ec469eSopenharmony_ci} 28758ec469eSopenharmony_ci 28858ec469eSopenharmony_civoid MiscdeviceService::OnStop() 28958ec469eSopenharmony_ci{ 29058ec469eSopenharmony_ci CALL_LOG_ENTER; 29158ec469eSopenharmony_ci if (state_ == MiscdeviceServiceState::STATE_STOPPED) { 29258ec469eSopenharmony_ci MISC_HILOGW("MiscdeviceService stopped already"); 29358ec469eSopenharmony_ci return; 29458ec469eSopenharmony_ci } 29558ec469eSopenharmony_ci state_ = MiscdeviceServiceState::STATE_STOPPED; 29658ec469eSopenharmony_ci int32_t ret = vibratorHdiConnection_.DestroyHdiConnection(); 29758ec469eSopenharmony_ci if (ret != ERR_OK) { 29858ec469eSopenharmony_ci MISC_HILOGE("Destroy hdi connection fail"); 29958ec469eSopenharmony_ci } 30058ec469eSopenharmony_ci#ifdef MEMMGR_ENABLE 30158ec469eSopenharmony_ci Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), PROCESS_TYPE_SA, PROCESS_STATUS_DIED, 30258ec469eSopenharmony_ci MISCDEVICE_SERVICE_ABILITY_ID); 30358ec469eSopenharmony_ci#endif // MEMMGR_ENABLE 30458ec469eSopenharmony_ci} 30558ec469eSopenharmony_ci 30658ec469eSopenharmony_cibool MiscdeviceService::ShouldIgnoreVibrate(const VibrateInfo &info) 30758ec469eSopenharmony_ci{ 30858ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_); 30958ec469eSopenharmony_ci if (!isVibrationPriorityReady_) { 31058ec469eSopenharmony_ci MISC_HILOGE("Vibraion priority manager not ready"); 31158ec469eSopenharmony_ci return VIBRATION; 31258ec469eSopenharmony_ci } 31358ec469eSopenharmony_ci return (PriorityManager->ShouldIgnoreVibrate(info, vibratorThread_) != VIBRATION); 31458ec469eSopenharmony_ci} 31558ec469eSopenharmony_ci 31658ec469eSopenharmony_ciint32_t MiscdeviceService::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage, bool systemUsage) 31758ec469eSopenharmony_ci{ 31858ec469eSopenharmony_ci if ((timeOut <= MIN_VIBRATOR_TIME) || (timeOut > MAX_VIBRATOR_TIME) 31958ec469eSopenharmony_ci || (usage >= USAGE_MAX) || (usage < 0)) { 32058ec469eSopenharmony_ci MISC_HILOGE("Invalid parameter"); 32158ec469eSopenharmony_ci return PARAMETER_ERROR; 32258ec469eSopenharmony_ci } 32358ec469eSopenharmony_ci VibrateInfo info = { 32458ec469eSopenharmony_ci .mode = VIBRATE_TIME, 32558ec469eSopenharmony_ci .packageName = GetPackageName(GetCallingTokenID()), 32658ec469eSopenharmony_ci .pid = GetCallingPid(), 32758ec469eSopenharmony_ci .uid = GetCallingUid(), 32858ec469eSopenharmony_ci .usage = usage, 32958ec469eSopenharmony_ci .systemUsage = systemUsage, 33058ec469eSopenharmony_ci .duration = timeOut 33158ec469eSopenharmony_ci }; 33258ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 33358ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 33458ec469eSopenharmony_ci if (ShouldIgnoreVibrate(info)) { 33558ec469eSopenharmony_ci MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 33658ec469eSopenharmony_ci return ERROR; 33758ec469eSopenharmony_ci } 33858ec469eSopenharmony_ci StartVibrateThread(info); 33958ec469eSopenharmony_ci MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 34058ec469eSopenharmony_ci "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, 34158ec469eSopenharmony_ci info.usage, vibratorId, info.duration); 34258ec469eSopenharmony_ci return NO_ERROR; 34358ec469eSopenharmony_ci} 34458ec469eSopenharmony_ci 34558ec469eSopenharmony_ciint32_t MiscdeviceService::StopVibrator(int32_t vibratorId) 34658ec469eSopenharmony_ci{ 34758ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 34858ec469eSopenharmony_ci#if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR) 34958ec469eSopenharmony_ci if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() && 35058ec469eSopenharmony_ci !vibratorHdiConnection_.IsVibratorRunning())) { 35158ec469eSopenharmony_ci MISC_HILOGD("No vibration, no need to stop"); 35258ec469eSopenharmony_ci return ERROR; 35358ec469eSopenharmony_ci } 35458ec469eSopenharmony_ci if (vibratorHdiConnection_.IsVibratorRunning()) { 35558ec469eSopenharmony_ci vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET); 35658ec469eSopenharmony_ci vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC); 35758ec469eSopenharmony_ci } 35858ec469eSopenharmony_ci#else 35958ec469eSopenharmony_ci if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) { 36058ec469eSopenharmony_ci MISC_HILOGD("No vibration, no need to stop"); 36158ec469eSopenharmony_ci return ERROR; 36258ec469eSopenharmony_ci } 36358ec469eSopenharmony_ci#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR 36458ec469eSopenharmony_ci StopVibrateThread(); 36558ec469eSopenharmony_ci std::string packageName = GetPackageName(GetCallingTokenID()); 36658ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 36758ec469eSopenharmony_ci MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d", 36858ec469eSopenharmony_ci curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId); 36958ec469eSopenharmony_ci return NO_ERROR; 37058ec469eSopenharmony_ci} 37158ec469eSopenharmony_ci 37258ec469eSopenharmony_ciint32_t MiscdeviceService::PlayVibratorEffect(int32_t vibratorId, const std::string &effect, 37358ec469eSopenharmony_ci int32_t count, int32_t usage, bool systemUsage) 37458ec469eSopenharmony_ci{ 37558ec469eSopenharmony_ci if ((count < MIN_VIBRATOR_COUNT) || (count > MAX_VIBRATOR_COUNT) || (usage >= USAGE_MAX) || (usage < 0)) { 37658ec469eSopenharmony_ci MISC_HILOGE("Invalid parameter"); 37758ec469eSopenharmony_ci return PARAMETER_ERROR; 37858ec469eSopenharmony_ci } 37958ec469eSopenharmony_ci#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 38058ec469eSopenharmony_ci std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect); 38158ec469eSopenharmony_ci if (!effectInfo) { 38258ec469eSopenharmony_ci MISC_HILOGE("GetEffectInfo fail"); 38358ec469eSopenharmony_ci return ERROR; 38458ec469eSopenharmony_ci } 38558ec469eSopenharmony_ci if (!(effectInfo->isSupportEffect)) { 38658ec469eSopenharmony_ci MISC_HILOGE("Effect not supported"); 38758ec469eSopenharmony_ci return PARAMETER_ERROR; 38858ec469eSopenharmony_ci } 38958ec469eSopenharmony_ci#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 39058ec469eSopenharmony_ci VibrateInfo info = { 39158ec469eSopenharmony_ci .mode = VIBRATE_PRESET, 39258ec469eSopenharmony_ci .packageName = GetPackageName(GetCallingTokenID()), 39358ec469eSopenharmony_ci .pid = GetCallingPid(), 39458ec469eSopenharmony_ci .uid = GetCallingUid(), 39558ec469eSopenharmony_ci .usage = usage, 39658ec469eSopenharmony_ci .systemUsage = systemUsage, 39758ec469eSopenharmony_ci#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 39858ec469eSopenharmony_ci .duration = effectInfo->duration, 39958ec469eSopenharmony_ci#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 40058ec469eSopenharmony_ci .effect = effect, 40158ec469eSopenharmony_ci .count = count, 40258ec469eSopenharmony_ci .intensity = INTENSITY_ADJUST_MAX 40358ec469eSopenharmony_ci }; 40458ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 40558ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 40658ec469eSopenharmony_ci if (ShouldIgnoreVibrate(info)) { 40758ec469eSopenharmony_ci MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 40858ec469eSopenharmony_ci return ERROR; 40958ec469eSopenharmony_ci } 41058ec469eSopenharmony_ci StartVibrateThread(info); 41158ec469eSopenharmony_ci MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 41258ec469eSopenharmony_ci "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s, count:%{public}d", curVibrateTime.c_str(), 41358ec469eSopenharmony_ci info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str(), info.count); 41458ec469eSopenharmony_ci return NO_ERROR; 41558ec469eSopenharmony_ci} 41658ec469eSopenharmony_ci 41758ec469eSopenharmony_civoid MiscdeviceService::StartVibrateThread(VibrateInfo info) 41858ec469eSopenharmony_ci{ 41958ec469eSopenharmony_ci if (vibratorThread_ == nullptr) { 42058ec469eSopenharmony_ci vibratorThread_ = std::make_shared<VibratorThread>(); 42158ec469eSopenharmony_ci } 42258ec469eSopenharmony_ci StopVibrateThread(); 42358ec469eSopenharmony_ci#if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR) 42458ec469eSopenharmony_ci if (vibratorHdiConnection_.IsVibratorRunning()) { 42558ec469eSopenharmony_ci vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET); 42658ec469eSopenharmony_ci vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC); 42758ec469eSopenharmony_ci } 42858ec469eSopenharmony_ci#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR 42958ec469eSopenharmony_ci vibratorThread_->UpdateVibratorEffect(info); 43058ec469eSopenharmony_ci vibratorThread_->Start("VibratorThread"); 43158ec469eSopenharmony_ci DumpHelper->SaveVibrateRecord(info); 43258ec469eSopenharmony_ci} 43358ec469eSopenharmony_ci 43458ec469eSopenharmony_civoid MiscdeviceService::StopVibrateThread() 43558ec469eSopenharmony_ci{ 43658ec469eSopenharmony_ci if ((vibratorThread_ != nullptr) && (vibratorThread_->IsRunning())) { 43758ec469eSopenharmony_ci vibratorThread_->SetExitStatus(true); 43858ec469eSopenharmony_ci vibratorThread_->WakeUp(); 43958ec469eSopenharmony_ci vibratorThread_->NotifyExitSync(); 44058ec469eSopenharmony_ci vibratorThread_->SetExitStatus(false); 44158ec469eSopenharmony_ci } 44258ec469eSopenharmony_ci} 44358ec469eSopenharmony_ci 44458ec469eSopenharmony_ciint32_t MiscdeviceService::StopVibrator(int32_t vibratorId, const std::string &mode) 44558ec469eSopenharmony_ci{ 44658ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 44758ec469eSopenharmony_ci if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) { 44858ec469eSopenharmony_ci MISC_HILOGD("No vibration, no need to stop"); 44958ec469eSopenharmony_ci return ERROR; 45058ec469eSopenharmony_ci } 45158ec469eSopenharmony_ci const VibrateInfo info = vibratorThread_->GetCurrentVibrateInfo(); 45258ec469eSopenharmony_ci if (info.mode != mode) { 45358ec469eSopenharmony_ci MISC_HILOGD("Stop vibration information mismatch"); 45458ec469eSopenharmony_ci return ERROR; 45558ec469eSopenharmony_ci } 45658ec469eSopenharmony_ci StopVibrateThread(); 45758ec469eSopenharmony_ci std::string packageName = GetPackageName(GetCallingTokenID()); 45858ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 45958ec469eSopenharmony_ci MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d," 46058ec469eSopenharmony_ci "mode:%{public}s", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId, mode.c_str()); 46158ec469eSopenharmony_ci return NO_ERROR; 46258ec469eSopenharmony_ci} 46358ec469eSopenharmony_ci 46458ec469eSopenharmony_ciint32_t MiscdeviceService::IsSupportEffect(const std::string &effect, bool &state) 46558ec469eSopenharmony_ci{ 46658ec469eSopenharmony_ci#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 46758ec469eSopenharmony_ci std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect); 46858ec469eSopenharmony_ci if (!effectInfo) { 46958ec469eSopenharmony_ci MISC_HILOGE("GetEffectInfo fail"); 47058ec469eSopenharmony_ci return ERROR; 47158ec469eSopenharmony_ci } 47258ec469eSopenharmony_ci state = effectInfo->isSupportEffect; 47358ec469eSopenharmony_ci std::string packageName = GetPackageName(GetCallingTokenID()); 47458ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 47558ec469eSopenharmony_ci MISC_HILOGI("IsSupportEffect, currentTime:%{public}s, package:%{public}s, pid:%{public}d, effect:%{public}s," 47658ec469eSopenharmony_ci "state:%{public}d", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), effect.c_str(), state); 47758ec469eSopenharmony_ci#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 47858ec469eSopenharmony_ci return NO_ERROR; 47958ec469eSopenharmony_ci} 48058ec469eSopenharmony_ci 48158ec469eSopenharmony_cistd::string MiscdeviceService::GetCurrentTime() 48258ec469eSopenharmony_ci{ 48358ec469eSopenharmony_ci timespec curTime; 48458ec469eSopenharmony_ci clock_gettime(CLOCK_REALTIME, &curTime); 48558ec469eSopenharmony_ci struct tm *timeinfo = localtime(&(curTime.tv_sec)); 48658ec469eSopenharmony_ci std::string currentTime; 48758ec469eSopenharmony_ci if (timeinfo == nullptr) { 48858ec469eSopenharmony_ci MISC_HILOGE("timeinfo is null"); 48958ec469eSopenharmony_ci return currentTime; 49058ec469eSopenharmony_ci } 49158ec469eSopenharmony_ci currentTime.append(std::to_string(timeinfo->tm_year + BASE_YEAR)).append("-") 49258ec469eSopenharmony_ci .append(std::to_string(timeinfo->tm_mon + BASE_MON)).append("-").append(std::to_string(timeinfo->tm_mday)) 49358ec469eSopenharmony_ci .append(" ").append(std::to_string(timeinfo->tm_hour)).append(":").append(std::to_string(timeinfo->tm_min)) 49458ec469eSopenharmony_ci .append(":").append(std::to_string(timeinfo->tm_sec)).append(".") 49558ec469eSopenharmony_ci .append(std::to_string(curTime.tv_nsec / (CONVERSION_RATE * CONVERSION_RATE))); 49658ec469eSopenharmony_ci return currentTime; 49758ec469eSopenharmony_ci} 49858ec469eSopenharmony_ci 49958ec469eSopenharmony_ci#ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 50058ec469eSopenharmony_ciint32_t MiscdeviceService::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage, 50158ec469eSopenharmony_ci bool systemUsage, const VibrateParameter ¶meter) 50258ec469eSopenharmony_ci{ 50358ec469eSopenharmony_ci if (!(g_capacity.isSupportHdHaptic || g_capacity.isSupportPresetMapping || g_capacity.isSupportTimeDelay)) { 50458ec469eSopenharmony_ci MISC_HILOGE("The device does not support this operation"); 50558ec469eSopenharmony_ci return IS_NOT_SUPPORTED; 50658ec469eSopenharmony_ci } 50758ec469eSopenharmony_ci if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) { 50858ec469eSopenharmony_ci MISC_HILOGE("Invalid parameter, usage:%{public}d", usage); 50958ec469eSopenharmony_ci return PARAMETER_ERROR; 51058ec469eSopenharmony_ci } 51158ec469eSopenharmony_ci JsonParser parser(rawFd); 51258ec469eSopenharmony_ci VibratorDecoderCreator creator; 51358ec469eSopenharmony_ci std::unique_ptr<IVibratorDecoder> decoder(creator.CreateDecoder(parser)); 51458ec469eSopenharmony_ci CHKPR(decoder, ERROR); 51558ec469eSopenharmony_ci VibratePackage package; 51658ec469eSopenharmony_ci int32_t ret = decoder->DecodeEffect(rawFd, parser, package); 51758ec469eSopenharmony_ci if (ret != SUCCESS || package.patterns.empty()) { 51858ec469eSopenharmony_ci MISC_HILOGE("Decode effect error"); 51958ec469eSopenharmony_ci return ERROR; 52058ec469eSopenharmony_ci } 52158ec469eSopenharmony_ci MergeVibratorParmeters(parameter, package); 52258ec469eSopenharmony_ci package.Dump(); 52358ec469eSopenharmony_ci VibrateInfo info = { 52458ec469eSopenharmony_ci .packageName = GetPackageName(GetCallingTokenID()), 52558ec469eSopenharmony_ci .pid = GetCallingPid(), 52658ec469eSopenharmony_ci .uid = GetCallingUid(), 52758ec469eSopenharmony_ci .usage = usage, 52858ec469eSopenharmony_ci .systemUsage = systemUsage, 52958ec469eSopenharmony_ci .package = package, 53058ec469eSopenharmony_ci }; 53158ec469eSopenharmony_ci if (g_capacity.isSupportHdHaptic) { 53258ec469eSopenharmony_ci info.mode = VIBRATE_CUSTOM_HD; 53358ec469eSopenharmony_ci } else if (g_capacity.isSupportPresetMapping) { 53458ec469eSopenharmony_ci info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT; 53558ec469eSopenharmony_ci } else if (g_capacity.isSupportTimeDelay) { 53658ec469eSopenharmony_ci info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME; 53758ec469eSopenharmony_ci } 53858ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 53958ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 54058ec469eSopenharmony_ci if (ShouldIgnoreVibrate(info)) { 54158ec469eSopenharmony_ci MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 54258ec469eSopenharmony_ci return ERROR; 54358ec469eSopenharmony_ci } 54458ec469eSopenharmony_ci StartVibrateThread(info); 54558ec469eSopenharmony_ci MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 54658ec469eSopenharmony_ci "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, 54758ec469eSopenharmony_ci info.usage, vibratorId, package.packageDuration); 54858ec469eSopenharmony_ci return NO_ERROR; 54958ec469eSopenharmony_ci} 55058ec469eSopenharmony_ci#endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM 55158ec469eSopenharmony_ci 55258ec469eSopenharmony_cistd::string MiscdeviceService::GetPackageName(AccessTokenID tokenId) 55358ec469eSopenharmony_ci{ 55458ec469eSopenharmony_ci std::string packageName; 55558ec469eSopenharmony_ci int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId); 55658ec469eSopenharmony_ci switch (tokenType) { 55758ec469eSopenharmony_ci case ATokenTypeEnum::TOKEN_HAP: { 55858ec469eSopenharmony_ci HapTokenInfo hapInfo; 55958ec469eSopenharmony_ci if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) { 56058ec469eSopenharmony_ci MISC_HILOGE("Get hap token info fail"); 56158ec469eSopenharmony_ci return {}; 56258ec469eSopenharmony_ci } 56358ec469eSopenharmony_ci packageName = hapInfo.bundleName; 56458ec469eSopenharmony_ci break; 56558ec469eSopenharmony_ci } 56658ec469eSopenharmony_ci case ATokenTypeEnum::TOKEN_NATIVE: 56758ec469eSopenharmony_ci case ATokenTypeEnum::TOKEN_SHELL: { 56858ec469eSopenharmony_ci NativeTokenInfo tokenInfo; 56958ec469eSopenharmony_ci if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) { 57058ec469eSopenharmony_ci MISC_HILOGE("Get native token info fail"); 57158ec469eSopenharmony_ci return {}; 57258ec469eSopenharmony_ci } 57358ec469eSopenharmony_ci packageName = tokenInfo.processName; 57458ec469eSopenharmony_ci break; 57558ec469eSopenharmony_ci } 57658ec469eSopenharmony_ci default: { 57758ec469eSopenharmony_ci MISC_HILOGW("Token type not match"); 57858ec469eSopenharmony_ci break; 57958ec469eSopenharmony_ci } 58058ec469eSopenharmony_ci } 58158ec469eSopenharmony_ci return packageName; 58258ec469eSopenharmony_ci} 58358ec469eSopenharmony_ci 58458ec469eSopenharmony_cistd::vector<LightInfoIPC> MiscdeviceService::GetLightList() 58558ec469eSopenharmony_ci{ 58658ec469eSopenharmony_ci std::string packageName = GetPackageName(GetCallingTokenID()); 58758ec469eSopenharmony_ci MISC_HILOGI("GetLightList, package:%{public}s", packageName.c_str()); 58858ec469eSopenharmony_ci if (!InitLightList()) { 58958ec469eSopenharmony_ci MISC_HILOGE("InitLightList init failed"); 59058ec469eSopenharmony_ci return lightInfos_; 59158ec469eSopenharmony_ci } 59258ec469eSopenharmony_ci return lightInfos_; 59358ec469eSopenharmony_ci} 59458ec469eSopenharmony_ci 59558ec469eSopenharmony_cibool MiscdeviceService::InitLightList() 59658ec469eSopenharmony_ci{ 59758ec469eSopenharmony_ci int32_t ret = lightHdiConnection_.GetLightList(lightInfos_); 59858ec469eSopenharmony_ci if (ret != ERR_OK) { 59958ec469eSopenharmony_ci MISC_HILOGE("InitLightList failed, ret:%{public}d", ret); 60058ec469eSopenharmony_ci return false; 60158ec469eSopenharmony_ci } 60258ec469eSopenharmony_ci return true; 60358ec469eSopenharmony_ci} 60458ec469eSopenharmony_ci 60558ec469eSopenharmony_ciint32_t MiscdeviceService::TurnOn(int32_t lightId, const LightColor &color, const LightAnimationIPC &animation) 60658ec469eSopenharmony_ci{ 60758ec469eSopenharmony_ci std::string packageName = GetPackageName(GetCallingTokenID()); 60858ec469eSopenharmony_ci MISC_HILOGI("TurnOn, package:%{public}s", packageName.c_str()); 60958ec469eSopenharmony_ci if (!IsValid(lightId)) { 61058ec469eSopenharmony_ci MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId); 61158ec469eSopenharmony_ci return MISCDEVICE_NATIVE_SAM_ERR; 61258ec469eSopenharmony_ci } 61358ec469eSopenharmony_ci if (!IsLightAnimationValid(animation)) { 61458ec469eSopenharmony_ci MISC_HILOGE("animation is invalid"); 61558ec469eSopenharmony_ci return MISCDEVICE_NATIVE_SAM_ERR; 61658ec469eSopenharmony_ci } 61758ec469eSopenharmony_ci int32_t ret = lightHdiConnection_.TurnOn(lightId, color, animation); 61858ec469eSopenharmony_ci if (ret != ERR_OK) { 61958ec469eSopenharmony_ci MISC_HILOGE("TurnOn failed, error:%{public}d", ret); 62058ec469eSopenharmony_ci return ERROR; 62158ec469eSopenharmony_ci } 62258ec469eSopenharmony_ci return ret; 62358ec469eSopenharmony_ci} 62458ec469eSopenharmony_ci 62558ec469eSopenharmony_ciint32_t MiscdeviceService::TurnOff(int32_t lightId) 62658ec469eSopenharmony_ci{ 62758ec469eSopenharmony_ci std::string packageName = GetPackageName(GetCallingTokenID()); 62858ec469eSopenharmony_ci MISC_HILOGI("TurnOff, package:%{public}s", packageName.c_str()); 62958ec469eSopenharmony_ci if (!IsValid(lightId)) { 63058ec469eSopenharmony_ci MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId); 63158ec469eSopenharmony_ci return MISCDEVICE_NATIVE_SAM_ERR; 63258ec469eSopenharmony_ci } 63358ec469eSopenharmony_ci int32_t ret = lightHdiConnection_.TurnOff(lightId); 63458ec469eSopenharmony_ci if (ret != ERR_OK) { 63558ec469eSopenharmony_ci MISC_HILOGE("TurnOff failed, error:%{public}d", ret); 63658ec469eSopenharmony_ci return ERROR; 63758ec469eSopenharmony_ci } 63858ec469eSopenharmony_ci return ret; 63958ec469eSopenharmony_ci} 64058ec469eSopenharmony_ci 64158ec469eSopenharmony_ciint32_t MiscdeviceService::Dump(int32_t fd, const std::vector<std::u16string> &args) 64258ec469eSopenharmony_ci{ 64358ec469eSopenharmony_ci CALL_LOG_ENTER; 64458ec469eSopenharmony_ci if (fd < 0) { 64558ec469eSopenharmony_ci MISC_HILOGE("Invalid fd"); 64658ec469eSopenharmony_ci return DUMP_PARAM_ERR; 64758ec469eSopenharmony_ci } 64858ec469eSopenharmony_ci if (args.empty()) { 64958ec469eSopenharmony_ci MISC_HILOGE("args cannot be empty"); 65058ec469eSopenharmony_ci dprintf(fd, "args cannot be empty\n"); 65158ec469eSopenharmony_ci DumpHelper->DumpHelp(fd); 65258ec469eSopenharmony_ci return DUMP_PARAM_ERR; 65358ec469eSopenharmony_ci } 65458ec469eSopenharmony_ci std::vector<std::string> argList = { "" }; 65558ec469eSopenharmony_ci std::transform(args.begin(), args.end(), std::back_inserter(argList), 65658ec469eSopenharmony_ci [](const std::u16string &arg) { 65758ec469eSopenharmony_ci return Str16ToStr8(arg); 65858ec469eSopenharmony_ci }); 65958ec469eSopenharmony_ci DumpHelper->ParseCommand(fd, argList); 66058ec469eSopenharmony_ci return ERR_OK; 66158ec469eSopenharmony_ci} 66258ec469eSopenharmony_ci 66358ec469eSopenharmony_ciint32_t MiscdeviceService::PlayPattern(const VibratePattern &pattern, int32_t usage, 66458ec469eSopenharmony_ci bool systemUsage, const VibrateParameter ¶meter) 66558ec469eSopenharmony_ci{ 66658ec469eSopenharmony_ci if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) { 66758ec469eSopenharmony_ci MISC_HILOGE("Invalid parameter, usage:%{public}d", usage); 66858ec469eSopenharmony_ci return PARAMETER_ERROR; 66958ec469eSopenharmony_ci } 67058ec469eSopenharmony_ci VibratePattern vibratePattern = { 67158ec469eSopenharmony_ci .startTime = 0, 67258ec469eSopenharmony_ci .events = pattern.events 67358ec469eSopenharmony_ci }; 67458ec469eSopenharmony_ci std::vector<VibratePattern> patterns = {vibratePattern}; 67558ec469eSopenharmony_ci VibratePackage package = { 67658ec469eSopenharmony_ci .patterns = patterns 67758ec469eSopenharmony_ci }; 67858ec469eSopenharmony_ci MergeVibratorParmeters(parameter, package); 67958ec469eSopenharmony_ci package.Dump(); 68058ec469eSopenharmony_ci VibrateInfo info = { 68158ec469eSopenharmony_ci .mode = VIBRATE_BUTT, 68258ec469eSopenharmony_ci .packageName = GetPackageName(GetCallingTokenID()), 68358ec469eSopenharmony_ci .pid = GetCallingPid(), 68458ec469eSopenharmony_ci .uid = GetCallingUid(), 68558ec469eSopenharmony_ci .usage = usage, 68658ec469eSopenharmony_ci .systemUsage = systemUsage 68758ec469eSopenharmony_ci }; 68858ec469eSopenharmony_ci if (g_capacity.isSupportHdHaptic) { 68958ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 69058ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 69158ec469eSopenharmony_ci if (ShouldIgnoreVibrate(info)) { 69258ec469eSopenharmony_ci MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 69358ec469eSopenharmony_ci return ERROR; 69458ec469eSopenharmony_ci } 69558ec469eSopenharmony_ci StartVibrateThread(info); 69658ec469eSopenharmony_ci return vibratorHdiConnection_.PlayPattern(package.patterns.front()); 69758ec469eSopenharmony_ci } else if (g_capacity.isSupportPresetMapping) { 69858ec469eSopenharmony_ci info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT; 69958ec469eSopenharmony_ci } else if (g_capacity.isSupportTimeDelay) { 70058ec469eSopenharmony_ci info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME; 70158ec469eSopenharmony_ci } 70258ec469eSopenharmony_ci info.package = package; 70358ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 70458ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 70558ec469eSopenharmony_ci if (ShouldIgnoreVibrate(info)) { 70658ec469eSopenharmony_ci MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 70758ec469eSopenharmony_ci return ERROR; 70858ec469eSopenharmony_ci } 70958ec469eSopenharmony_ci StartVibrateThread(info); 71058ec469eSopenharmony_ci MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 71158ec469eSopenharmony_ci "duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage, 71258ec469eSopenharmony_ci pattern.patternDuration); 71358ec469eSopenharmony_ci return ERR_OK; 71458ec469eSopenharmony_ci} 71558ec469eSopenharmony_ci 71658ec469eSopenharmony_ciint32_t MiscdeviceService::GetDelayTime(int32_t &delayTime) 71758ec469eSopenharmony_ci{ 71858ec469eSopenharmony_ci std::string packageName = GetPackageName(GetCallingTokenID()); 71958ec469eSopenharmony_ci MISC_HILOGD("GetDelayTime, package:%{public}s", packageName.c_str()); 72058ec469eSopenharmony_ci return vibratorHdiConnection_.GetDelayTime(g_capacity.GetVibrateMode(), delayTime); 72158ec469eSopenharmony_ci} 72258ec469eSopenharmony_ci 72358ec469eSopenharmony_cibool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter ¶meter) 72458ec469eSopenharmony_ci{ 72558ec469eSopenharmony_ci if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) || 72658ec469eSopenharmony_ci (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) { 72758ec469eSopenharmony_ci MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d", 72858ec469eSopenharmony_ci parameter.intensity, parameter.frequency); 72958ec469eSopenharmony_ci return false; 73058ec469eSopenharmony_ci } 73158ec469eSopenharmony_ci return true; 73258ec469eSopenharmony_ci} 73358ec469eSopenharmony_ci 73458ec469eSopenharmony_civoid MiscdeviceService::MergeVibratorParmeters(const VibrateParameter ¶meter, VibratePackage &package) 73558ec469eSopenharmony_ci{ 73658ec469eSopenharmony_ci if ((parameter.intensity == INTENSITY_ADJUST_MAX) && (parameter.frequency == 0)) { 73758ec469eSopenharmony_ci MISC_HILOGD("The adjust parameter is not need to merge"); 73858ec469eSopenharmony_ci return; 73958ec469eSopenharmony_ci } 74058ec469eSopenharmony_ci parameter.Dump(); 74158ec469eSopenharmony_ci for (VibratePattern &pattern : package.patterns) { 74258ec469eSopenharmony_ci for (VibrateEvent &event : pattern.events) { 74358ec469eSopenharmony_ci float intensityScale = static_cast<float>(parameter.intensity) / INTENSITY_ADJUST_MAX; 74458ec469eSopenharmony_ci if ((event.tag == EVENT_TAG_TRANSIENT) || (event.points.empty())) { 74558ec469eSopenharmony_ci event.intensity = static_cast<int32_t>(event.intensity * intensityScale); 74658ec469eSopenharmony_ci event.intensity = std::max(std::min(event.intensity, INTENSITY_MAX), INTENSITY_MIN); 74758ec469eSopenharmony_ci event.frequency = event.frequency + parameter.frequency; 74858ec469eSopenharmony_ci event.frequency = std::max(std::min(event.frequency, FREQUENCY_MAX), FREQUENCY_MIN); 74958ec469eSopenharmony_ci } else { 75058ec469eSopenharmony_ci for (VibrateCurvePoint &point : event.points) { 75158ec469eSopenharmony_ci point.intensity = static_cast<int32_t>(point.intensity * intensityScale); 75258ec469eSopenharmony_ci point.intensity = std::max(std::min(point.intensity, INTENSITY_ADJUST_MAX), INTENSITY_ADJUST_MIN); 75358ec469eSopenharmony_ci point.frequency = point.frequency + parameter.frequency; 75458ec469eSopenharmony_ci point.frequency = std::max(std::min(point.frequency, FREQUENCY_ADJUST_MAX), FREQUENCY_ADJUST_MIN); 75558ec469eSopenharmony_ci } 75658ec469eSopenharmony_ci } 75758ec469eSopenharmony_ci } 75858ec469eSopenharmony_ci } 75958ec469eSopenharmony_ci} 76058ec469eSopenharmony_ci 76158ec469eSopenharmony_ciint32_t MiscdeviceService::TransferClientRemoteObject(const sptr<IRemoteObject> &vibratorServiceClient) 76258ec469eSopenharmony_ci{ 76358ec469eSopenharmony_ci auto clientPid = GetCallingPid(); 76458ec469eSopenharmony_ci if (clientPid < 0) { 76558ec469eSopenharmony_ci MISC_HILOGE("ClientPid is invalid, clientPid:%{public}d", clientPid); 76658ec469eSopenharmony_ci return ERROR; 76758ec469eSopenharmony_ci } 76858ec469eSopenharmony_ci RegisterClientDeathRecipient(vibratorServiceClient, clientPid); 76958ec469eSopenharmony_ci return ERR_OK; 77058ec469eSopenharmony_ci} 77158ec469eSopenharmony_ci 77258ec469eSopenharmony_civoid MiscdeviceService::ProcessDeathObserver(const wptr<IRemoteObject> &object) 77358ec469eSopenharmony_ci{ 77458ec469eSopenharmony_ci CALL_LOG_ENTER; 77558ec469eSopenharmony_ci sptr<IRemoteObject> client = object.promote(); 77658ec469eSopenharmony_ci int32_t clientPid = FindClientPid(client); 77758ec469eSopenharmony_ci VibrateInfo info; 77858ec469eSopenharmony_ci { 77958ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 78058ec469eSopenharmony_ci if (vibratorThread_ == nullptr) { 78158ec469eSopenharmony_ci vibratorThread_ = std::make_shared<VibratorThread>(); 78258ec469eSopenharmony_ci } 78358ec469eSopenharmony_ci info = vibratorThread_->GetCurrentVibrateInfo(); 78458ec469eSopenharmony_ci } 78558ec469eSopenharmony_ci int32_t vibratePid = info.pid; 78658ec469eSopenharmony_ci MISC_HILOGI("ClientPid:%{public}d, VibratePid:%{public}d", clientPid, vibratePid); 78758ec469eSopenharmony_ci if ((clientPid != INVALID_PID) && (clientPid == vibratePid)) { 78858ec469eSopenharmony_ci StopVibrator(VIBRATOR_ID); 78958ec469eSopenharmony_ci } 79058ec469eSopenharmony_ci UnregisterClientDeathRecipient(client); 79158ec469eSopenharmony_ci} 79258ec469eSopenharmony_ci 79358ec469eSopenharmony_civoid MiscdeviceService::RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient, int32_t pid) 79458ec469eSopenharmony_ci{ 79558ec469eSopenharmony_ci if (vibratorServiceClient == nullptr) { 79658ec469eSopenharmony_ci MISC_HILOGE("VibratorServiceClient is nullptr"); 79758ec469eSopenharmony_ci return; 79858ec469eSopenharmony_ci } 79958ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(clientDeathObserverMutex_); 80058ec469eSopenharmony_ci if (clientDeathObserver_ == nullptr) { 80158ec469eSopenharmony_ci clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MiscdeviceService *>(this)); 80258ec469eSopenharmony_ci if (clientDeathObserver_ == nullptr) { 80358ec469eSopenharmony_ci MISC_HILOGE("ClientDeathObserver_ is nullptr"); 80458ec469eSopenharmony_ci return; 80558ec469eSopenharmony_ci } 80658ec469eSopenharmony_ci } 80758ec469eSopenharmony_ci vibratorServiceClient->AddDeathRecipient(clientDeathObserver_); 80858ec469eSopenharmony_ci SaveClientPid(vibratorServiceClient, pid); 80958ec469eSopenharmony_ci} 81058ec469eSopenharmony_ci 81158ec469eSopenharmony_civoid MiscdeviceService::UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient) 81258ec469eSopenharmony_ci{ 81358ec469eSopenharmony_ci if (vibratorServiceClient == nullptr) { 81458ec469eSopenharmony_ci MISC_HILOGE("vibratorServiceClient is nullptr"); 81558ec469eSopenharmony_ci return; 81658ec469eSopenharmony_ci } 81758ec469eSopenharmony_ci int32_t clientPid = FindClientPid(vibratorServiceClient); 81858ec469eSopenharmony_ci if (clientPid == INVALID_PID) { 81958ec469eSopenharmony_ci MISC_HILOGE("Pid is invalid"); 82058ec469eSopenharmony_ci return; 82158ec469eSopenharmony_ci } 82258ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(clientDeathObserverMutex_); 82358ec469eSopenharmony_ci vibratorServiceClient->RemoveDeathRecipient(clientDeathObserver_); 82458ec469eSopenharmony_ci DestroyClientPid(vibratorServiceClient); 82558ec469eSopenharmony_ci} 82658ec469eSopenharmony_ci 82758ec469eSopenharmony_civoid MiscdeviceService::SaveClientPid(const sptr<IRemoteObject> &vibratorServiceClient, int32_t pid) 82858ec469eSopenharmony_ci{ 82958ec469eSopenharmony_ci if (vibratorServiceClient == nullptr) { 83058ec469eSopenharmony_ci MISC_HILOGE("VibratorServiceClient is nullptr"); 83158ec469eSopenharmony_ci return; 83258ec469eSopenharmony_ci } 83358ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(clientPidMapMutex_); 83458ec469eSopenharmony_ci clientPidMap_.insert(std::make_pair(vibratorServiceClient, pid)); 83558ec469eSopenharmony_ci} 83658ec469eSopenharmony_ci 83758ec469eSopenharmony_ciint32_t MiscdeviceService::FindClientPid(const sptr<IRemoteObject> &vibratorServiceClient) 83858ec469eSopenharmony_ci{ 83958ec469eSopenharmony_ci if (vibratorServiceClient == nullptr) { 84058ec469eSopenharmony_ci MISC_HILOGE("VibratorServiceClient is nullptr"); 84158ec469eSopenharmony_ci return INVALID_PID; 84258ec469eSopenharmony_ci } 84358ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(clientPidMapMutex_); 84458ec469eSopenharmony_ci auto it = clientPidMap_.find(vibratorServiceClient); 84558ec469eSopenharmony_ci if (it == clientPidMap_.end()) { 84658ec469eSopenharmony_ci MISC_HILOGE("Cannot find client pid"); 84758ec469eSopenharmony_ci return INVALID_PID; 84858ec469eSopenharmony_ci } 84958ec469eSopenharmony_ci return it->second; 85058ec469eSopenharmony_ci} 85158ec469eSopenharmony_ci 85258ec469eSopenharmony_civoid MiscdeviceService::DestroyClientPid(const sptr<IRemoteObject> &vibratorServiceClient) 85358ec469eSopenharmony_ci{ 85458ec469eSopenharmony_ci if (vibratorServiceClient == nullptr) { 85558ec469eSopenharmony_ci MISC_HILOGD("VibratorServiceClient is nullptr"); 85658ec469eSopenharmony_ci return; 85758ec469eSopenharmony_ci } 85858ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(clientPidMapMutex_); 85958ec469eSopenharmony_ci auto it = clientPidMap_.find(vibratorServiceClient); 86058ec469eSopenharmony_ci if (it == clientPidMap_.end()) { 86158ec469eSopenharmony_ci MISC_HILOGE("Cannot find client pid"); 86258ec469eSopenharmony_ci return; 86358ec469eSopenharmony_ci } 86458ec469eSopenharmony_ci clientPidMap_.erase(it); 86558ec469eSopenharmony_ci} 86658ec469eSopenharmony_ci 86758ec469eSopenharmony_ciint32_t MiscdeviceService::PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect, 86858ec469eSopenharmony_ci int32_t intensity, int32_t usage, bool systemUsage, int32_t count) 86958ec469eSopenharmony_ci{ 87058ec469eSopenharmony_ci if ((intensity <= INTENSITY_MIN) || (intensity > INTENSITY_MAX) || (usage >= USAGE_MAX) || (usage < 0)) { 87158ec469eSopenharmony_ci MISC_HILOGE("Invalid parameter"); 87258ec469eSopenharmony_ci return PARAMETER_ERROR; 87358ec469eSopenharmony_ci } 87458ec469eSopenharmony_ci#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 87558ec469eSopenharmony_ci std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect); 87658ec469eSopenharmony_ci if (!effectInfo) { 87758ec469eSopenharmony_ci MISC_HILOGE("GetEffectInfo fail"); 87858ec469eSopenharmony_ci return ERROR; 87958ec469eSopenharmony_ci } 88058ec469eSopenharmony_ci if (!(effectInfo->isSupportEffect)) { 88158ec469eSopenharmony_ci MISC_HILOGE("Effect not supported"); 88258ec469eSopenharmony_ci return PARAMETER_ERROR; 88358ec469eSopenharmony_ci } 88458ec469eSopenharmony_ci#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 88558ec469eSopenharmony_ci VibrateInfo info = { 88658ec469eSopenharmony_ci .mode = VIBRATE_PRESET, 88758ec469eSopenharmony_ci .packageName = GetPackageName(GetCallingTokenID()), 88858ec469eSopenharmony_ci .pid = GetCallingPid(), 88958ec469eSopenharmony_ci .uid = GetCallingUid(), 89058ec469eSopenharmony_ci .usage = usage, 89158ec469eSopenharmony_ci .systemUsage = systemUsage, 89258ec469eSopenharmony_ci#ifdef HDF_DRIVERS_INTERFACE_VIBRATOR 89358ec469eSopenharmony_ci .duration = effectInfo->duration, 89458ec469eSopenharmony_ci#endif // HDF_DRIVERS_INTERFACE_VIBRATOR 89558ec469eSopenharmony_ci .effect = effect, 89658ec469eSopenharmony_ci .count = count, 89758ec469eSopenharmony_ci .intensity = intensity 89858ec469eSopenharmony_ci }; 89958ec469eSopenharmony_ci std::lock_guard<std::mutex> lock(vibratorThreadMutex_); 90058ec469eSopenharmony_ci std::string curVibrateTime = GetCurrentTime(); 90158ec469eSopenharmony_ci if (ShouldIgnoreVibrate(info)) { 90258ec469eSopenharmony_ci MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str()); 90358ec469eSopenharmony_ci return ERROR; 90458ec469eSopenharmony_ci } 90558ec469eSopenharmony_ci StartVibrateThread(info); 90658ec469eSopenharmony_ci MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d," 90758ec469eSopenharmony_ci "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s", curVibrateTime.c_str(), 90858ec469eSopenharmony_ci info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str()); 90958ec469eSopenharmony_ci return NO_ERROR; 91058ec469eSopenharmony_ci} 91158ec469eSopenharmony_ci 91258ec469eSopenharmony_ciint32_t MiscdeviceService::GetVibratorCapacity(VibratorCapacity &capacity) 91358ec469eSopenharmony_ci{ 91458ec469eSopenharmony_ci capacity = g_capacity; 91558ec469eSopenharmony_ci return ERR_OK; 91658ec469eSopenharmony_ci} 91758ec469eSopenharmony_ci} // namespace Sensors 91858ec469eSopenharmony_ci} // namespace OHOS 919