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