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