• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
19 #include "common_event_support.h"
20 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
21 #include "death_recipient_template.h"
22 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
23 #include "hisysevent.h"
24 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
25 #ifdef MEMMGR_ENABLE
26 #include "mem_mgr_client.h"
27 #endif // MEMMGR_ENABLE
28 #include "system_ability_definition.h"
29 
30 #include "sensors_errors.h"
31 #include "vibration_priority_manager.h"
32 #include "vibrator_client_proxy.h"
33 
34 #ifdef HDF_DRIVERS_INTERFACE_LIGHT
35 #include "v1_0/light_interface_proxy.h"
36 #endif // HDF_DRIVERS_INTERFACE_LIGHT
37 
38 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
39 #include "permission_util.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 
46 namespace OHOS {
47 namespace Sensors {
48 using namespace OHOS::HiviewDFX;
49 namespace {
50 auto g_miscdeviceService = MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance();
51 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_miscdeviceService.GetRefPtr());
52 const std::string VIBRATE_PERMISSION = "ohos.permission.VIBRATE";
53 const std::string LIGHT_PERMISSION = "ohos.permission.SYSTEM_LIGHT_CONTROL";
54 constexpr int32_t MAX_LIGHT_COUNT = 0XFF;
55 constexpr int32_t MIN_VIBRATOR_TIME = 0;
56 constexpr int32_t MAX_VIBRATOR_TIME = 1800000;
57 constexpr int32_t MIN_VIBRATOR_COUNT = 1;
58 constexpr int32_t MAX_VIBRATOR_COUNT = 1000;
59 constexpr int32_t INTENSITY_MIN = 0;
60 constexpr int32_t INTENSITY_MAX = 100;
61 constexpr int32_t FREQUENCY_MIN = 0;
62 constexpr int32_t FREQUENCY_MAX = 100;
63 constexpr int32_t INTENSITY_ADJUST_MIN = 0;
64 constexpr int32_t INTENSITY_ADJUST_MAX = 100;
65 constexpr int32_t FREQUENCY_ADJUST_MIN = -100;
66 constexpr int32_t FREQUENCY_ADJUST_MAX = 100;
67 constexpr int32_t INVALID_PID = -1;
68 constexpr int32_t BASE_YEAR = 1900;
69 constexpr int32_t BASE_MON = 1;
70 constexpr int32_t CONVERSION_RATE = 1000;
71 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
72 const std::string PHONE_TYPE = "phone";
73 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
74 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
75 constexpr int32_t SHORT_VIBRATOR_DURATION = 50;
76 #endif // OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
77 }  // namespace
78 
79 bool MiscdeviceService::isVibrationPriorityReady_ = false;
80 std::map<int32_t, VibratorAllInfos> MiscdeviceService::devicesManageMap_;
81 std::map<sptr<IRemoteObject>, int32_t> MiscdeviceService::clientPidMap_;
82 
MiscdeviceService()83 MiscdeviceService::MiscdeviceService()
84     : SystemAbility(MISCDEVICE_SERVICE_ABILITY_ID, true),
85       lightExist_(false),
86       vibratorExist_(false),
87       state_(MiscdeviceServiceState::STATE_STOPPED)
88 {
89     MISC_HILOGD("Add SystemAbility");
90 }
91 
~MiscdeviceService()92 MiscdeviceService::~MiscdeviceService()
93 {
94     std::lock_guard<std::mutex> lock(devicesManageMutex_);
95     auto it = devicesManageMap_.begin();
96     while (it != devicesManageMap_.end()) {
97         int deviceId = it->first;
98         const VibratorControlInfo& vibratorControlInfo_ = it->second.controlInfo;
99         MISC_HILOGI("Device ID:%d, Motor Count:%d", deviceId, vibratorControlInfo_.motorCount);
100         VibratorIdentifierIPC identifier;
101         identifier.deviceId = deviceId;
102         identifier.vibratorId = -1;
103         StopVibratorService(identifier);
104         it = devicesManageMap_.erase(it);
105     }
106 }
107 
OnDump()108 void MiscdeviceService::OnDump()
109 {
110     MISC_HILOGI("Ondump is invoked");
111 }
112 
SubscribeCommonEvent(const std::string & eventName,EventReceiver receiver)113 int32_t MiscdeviceService::SubscribeCommonEvent(const std::string &eventName,
114     EventReceiver receiver) __attribute__((no_sanitize("cfi")))
115 {
116     if (receiver == nullptr) {
117         MISC_HILOGE("receiver is nullptr");
118         return ERROR;
119     }
120     EventFwk::MatchingSkills matchingSkills;
121     matchingSkills.AddEvent(eventName);
122     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
123     auto subscribePtr = std::make_shared<MiscdeviceCommonEventSubscriber>(subscribeInfo, receiver);
124     if (!EventFwk::CommonEventManager::SubscribeCommonEvent(subscribePtr)) {
125         MISC_HILOGE("Subscribe common event fail");
126         return ERROR;
127     }
128     return ERR_OK;
129 }
130 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)131 void MiscdeviceService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
132 {
133     MISC_HILOGI("OnAddSystemAbility systemAbilityId:%{public}d", systemAbilityId);
134     switch (systemAbilityId) {
135         case MEMORY_MANAGER_SA_ID: {
136             MISC_HILOGI("Memory manager service start");
137 #ifdef MEMMGR_ENABLE
138             Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(),
139                 PROCESS_TYPE_SA, PROCESS_STATUS_STARTED, MISCDEVICE_SERVICE_ABILITY_ID);
140 #endif // MEMMGR_ENABLE
141             break;
142         }
143         case COMMON_EVENT_SERVICE_ID: {
144             MISC_HILOGI("Common event service start");
145             int32_t ret = SubscribeCommonEvent("usual.event.DATA_SHARE_READY",
146                 [this](const EventFwk::CommonEventData &data) { this->OnReceiveEvent(data); });
147             if (ret != ERR_OK) {
148                 MISC_HILOGE("Subscribe usual.event.DATA_SHARE_READY fail");
149             }
150 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
151             ret = SubscribeCommonEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED,
152                 [this](const EventFwk::CommonEventData &data) { this->OnReceiveUserSwitchEvent(data); });
153             if (ret != ERR_OK) {
154                 MISC_HILOGE("Subscribe usual.event.USER_SWITCHED fail");
155             }
156 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
157             AddSystemAbilityListener(DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID);
158             break;
159         }
160         case DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID: {
161             MISC_HILOGI("Distributed kv data service start");
162             std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_);
163             if (isVibrationPriorityReady_) { /** Datashare will reconnect to the client and register data after alive */
164                 MISC_HILOGI("PriorityManager already init");
165                 break;
166             }
167             if (PriorityManager->Init()) {
168                 MISC_HILOGI("PriorityManager init");
169                 isVibrationPriorityReady_ = true;
170             } else {
171                 MISC_HILOGE("PriorityManager init fail");
172             }
173             break;
174         }
175         default: {
176             MISC_HILOGI("Unknown service, systemAbilityId:%{public}d", systemAbilityId);
177             break;
178         }
179     }
180 }
181 
OnReceiveEvent(const EventFwk::CommonEventData & data)182 void MiscdeviceService::OnReceiveEvent(const EventFwk::CommonEventData &data)
183 {
184     const auto &want = data.GetWant();
185     std::string action = want.GetAction();
186     if (action == "usual.event.DATA_SHARE_READY") {
187         MISC_HILOGI("On receive usual.event.DATA_SHARE_READY");
188         std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_);
189         if (isVibrationPriorityReady_) {
190             MISC_HILOGI("PriorityManager already init");
191             return;
192         }
193         if (PriorityManager->Init()) {
194             MISC_HILOGI("PriorityManager init");
195             isVibrationPriorityReady_ = true;
196         } else {
197             MISC_HILOGE("PriorityManager init fail");
198         }
199     }
200 }
201 
202 #ifdef OHOS_BUILD_ENABLE_DO_NOT_DISTURB
OnReceiveUserSwitchEvent(const EventFwk::CommonEventData & data)203 void MiscdeviceService::OnReceiveUserSwitchEvent(const EventFwk::CommonEventData &data)
204 {
205     const auto &want = data.GetWant();
206     std::string action = want.GetAction();
207     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
208         MISC_HILOGI("OnReceiveUserSwitchEvent user switched");
209         PriorityManager->ReregisterCurrentUserObserver();
210 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
211         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "USER_SWITCHED_EXCEPTION", HiSysEvent::EventType::FAULT,
212             "PKG_NAME", "OnReceiveUserSwitchEvent", "ERROR_CODE", ERR_OK);
213 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
214     }
215 }
216 #endif // OHOS_BUILD_ENABLE_DO_NOT_DISTURB
217 
OnStart()218 void MiscdeviceService::OnStart()
219 {
220     CALL_LOG_ENTER;
221     if (state_ == MiscdeviceServiceState::STATE_RUNNING) {
222         MISC_HILOGW("state_ already started");
223         return;
224     }
225     if (!InitInterface()) {
226         MISC_HILOGE("Init interface error");
227     }
228     if (!InitLightInterface()) {
229         MISC_HILOGE("InitLightInterface failed");
230     }
231     if (!SystemAbility::Publish(MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance())) {
232         MISC_HILOGE("Publish MiscdeviceService failed");
233         return;
234     }
235     std::lock_guard<std::mutex> lock(miscDeviceIdMapMutex_);
236     auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_));
237     if (!ret.second) {
238         MISC_HILOGI("Light exist in miscDeviceIdMap_");
239         ret.first->second = lightExist_;
240     }
241     ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_));
242     if (!ret.second) {
243         MISC_HILOGI("Vibrator exist in miscDeviceIdMap_");
244         ret.first->second = vibratorExist_;
245     }
246     state_ = MiscdeviceServiceState::STATE_RUNNING;
247 #ifdef MEMMGR_ENABLE
248     AddSystemAbilityListener(MEMORY_MANAGER_SA_ID);
249 #endif // MEMMGR_ENABLE
250     AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID);
251     RegisterVibratorPlugCb();
252 }
253 
RegisterVibratorPlugCb()254 int32_t MiscdeviceService::RegisterVibratorPlugCb()
255 {
256     auto ret = vibratorHdiConnection_.RegisterVibratorPlugCallback(
257         std::bind(&MiscdeviceService::SendMsgToClient, this, std::placeholders::_1));
258     if (ret != ERR_OK) {
259         MISC_HILOGE("RegisterVibratorPlugCallback failed");
260         return false;
261     }
262     MISC_HILOGI("RegisterVibratorPlugCallback success");
263     return true;
264 }
265 
OnStartFuzz()266 void MiscdeviceService::OnStartFuzz()
267 {
268     CALL_LOG_ENTER;
269     if (state_ == MiscdeviceServiceState::STATE_RUNNING) {
270         MISC_HILOGW("state_ already started");
271         return;
272     }
273     if (!InitInterface()) {
274         MISC_HILOGE("Init interface error");
275     }
276     if (!InitLightInterface()) {
277         MISC_HILOGE("InitLightInterface failed");
278     }
279     std::lock_guard<std::mutex> lock(miscDeviceIdMapMutex_);
280     auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_));
281     if (!ret.second) {
282         MISC_HILOGI("Light exist in miscDeviceIdMap_");
283         ret.first->second = lightExist_;
284     }
285     ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_));
286     if (!ret.second) {
287         MISC_HILOGI("Vibrator exist in miscDeviceIdMap_");
288         ret.first->second = vibratorExist_;
289     }
290     state_ = MiscdeviceServiceState::STATE_RUNNING;
291 }
292 
InitInterface()293 bool MiscdeviceService::InitInterface()
294 {
295     auto ret = vibratorHdiConnection_.ConnectHdi();
296     if (ret != ERR_OK) {
297         MISC_HILOGE("InitVibratorServiceImpl failed");
298         return false;
299     }
300     GetOnlineVibratorInfo();
301     return true;
302 }
303 
InitLightInterface()304 bool MiscdeviceService::InitLightInterface()
305 {
306     auto ret = lightHdiConnection_.ConnectHdi();
307     if (ret != ERR_OK) {
308         MISC_HILOGE("ConnectHdi failed");
309         return false;
310     }
311     return true;
312 }
313 
IsValid(int32_t lightId)314 bool MiscdeviceService::IsValid(int32_t lightId)
315 {
316     CALL_LOG_ENTER;
317     std::lock_guard<std::mutex> lightInfosLock(lightInfosMutex_);
318     for (const auto &item : lightInfos_) {
319         if (lightId == item.GetLightId()) {
320             return true;
321         }
322     }
323     return false;
324 }
325 
IsLightAnimationValid(const LightAnimationIPC & animation)326 bool MiscdeviceService::IsLightAnimationValid(const LightAnimationIPC &animation)
327 {
328     CALL_LOG_ENTER;
329     int32_t mode = animation.GetMode();
330     int32_t onTime = animation.GetOnTime();
331     int32_t offTime = animation.GetOffTime();
332     if ((mode < 0) || (mode >= LIGHT_MODE_BUTT)) {
333         MISC_HILOGE("animation mode is invalid, mode:%{public}d", mode);
334         return false;
335     }
336     if ((onTime < 0) || (offTime < 0)) {
337         MISC_HILOGE("animation onTime or offTime is invalid, onTime:%{public}d, offTime:%{public}d",
338             onTime,  offTime);
339         return false;
340     }
341     return true;
342 }
343 
OnStop()344 void MiscdeviceService::OnStop()
345 {
346     CALL_LOG_ENTER;
347     if (state_ == MiscdeviceServiceState::STATE_STOPPED) {
348         MISC_HILOGW("MiscdeviceService stopped already");
349         return;
350     }
351     state_ = MiscdeviceServiceState::STATE_STOPPED;
352     int32_t ret = vibratorHdiConnection_.DestroyHdiConnection();
353     if (ret != ERR_OK) {
354         MISC_HILOGE("Destroy hdi connection fail");
355     }
356 #ifdef MEMMGR_ENABLE
357     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), PROCESS_TYPE_SA, PROCESS_STATUS_DIED,
358         MISCDEVICE_SERVICE_ABILITY_ID);
359 #endif // MEMMGR_ENABLE
360 }
361 
ShouldIgnoreVibrate(const VibrateInfo & info,const VibratorIdentifierIPC & identifier)362 bool MiscdeviceService::ShouldIgnoreVibrate(const VibrateInfo &info, const VibratorIdentifierIPC& identifier)
363 {
364     std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_);
365     if (!isVibrationPriorityReady_) {
366         MISC_HILOGE("Vibraion priority manager not ready");
367         return VIBRATION;
368     }
369     std::string curVibrateTime = GetCurrentTime();
370     auto vibratorThread_ = GetVibratorThread(identifier);
371     int32_t ret = PriorityManager->ShouldIgnoreVibrate(info, vibratorThread_, identifier);
372     if (ret != VIBRATION) {
373         MISC_HILOGE("ShouldIgnoreVibrate currentTime:%{public}s, ret:%{public}d", curVibrateTime.c_str(), ret);
374     }
375     return (ret != VIBRATION);
376 }
377 
Vibrate(const VibratorIdentifierIPC & identifier,int32_t timeOut,int32_t usage,bool systemUsage)378 int32_t MiscdeviceService::Vibrate(const VibratorIdentifierIPC& identifier, int32_t timeOut, int32_t usage,
379     bool systemUsage)
380 {
381     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
382     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
383     if (ret != PERMISSION_GRANTED) {
384 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
385         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
386             HiSysEvent::EventType::SECURITY, "PKG_NAME", "VibrateStub", "ERROR_CODE", ret);
387 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
388         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
389         return PERMISSION_DENIED;
390     }
391     if ((timeOut <= MIN_VIBRATOR_TIME) || (timeOut > MAX_VIBRATOR_TIME)
392         || (usage >= USAGE_MAX) || (usage < 0)) {
393         MISC_HILOGE("Invalid parameter");
394         return PARAMETER_ERROR;
395     }
396     VibrateInfo info = {
397         .mode = VIBRATE_TIME,
398         .packageName = GetPackageName(GetCallingTokenID()),
399         .pid = GetCallingPid(),
400         .uid = GetCallingUid(),
401         .usage = usage,
402         .systemUsage = systemUsage,
403         .duration = timeOut
404     };
405     std::string curVibrateTime = GetCurrentTime();
406     if (StartVibrateThreadControl(identifier, info) != ERR_OK) {
407         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating or no vibration found",
408             curVibrateTime.c_str());
409         return ERROR;
410     }
411     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
412         "deviceId:%{public}d, vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(),
413         info.packageName.c_str(), info.pid, info.usage, identifier.deviceId, identifier.vibratorId, info.duration);
414     return NO_ERROR;
415 }
416 
StopVibrator(const VibratorIdentifierIPC & identifier)417 int32_t MiscdeviceService::StopVibrator(const VibratorIdentifierIPC& identifier)
418 {
419     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
420     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
421     if (ret != PERMISSION_GRANTED) {
422 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
423         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
424             HiSysEvent::EventType::SECURITY, "PKG_NAME", "StopVibratorStub", "ERROR_CODE", ret);
425 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
426         MISC_HILOGE("Result:%{public}d", ret);
427         return PERMISSION_DENIED;
428     }
429     std::lock_guard<std::mutex> lock(devicesManageMutex_);
430     return StopVibratorService(identifier);
431 }
432 
StopVibratorService(const VibratorIdentifierIPC & identifier)433 int32_t MiscdeviceService::StopVibratorService(const VibratorIdentifierIPC& identifier)
434 {
435     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
436     std::vector<VibratorIdentifierIPC> result = CheckDeviceIdIsValid(identifier);
437     size_t ignoreVibrateNum = 0;
438     if (result.empty()) {
439         MISC_HILOGD("result is empty, no need to stop");
440         return ERROR;
441     }
442     for (const auto& paramIt : result) {
443         auto vibratorThread_ = GetVibratorThread(paramIt);
444         #if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM)
445             if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() &&
446                 !vibratorHdiConnection_.IsVibratorRunning(paramIt))) {
447                 MISC_HILOGD("Thread is not running, no need to stop");
448                 ignoreVibrateNum ++;
449                 continue;
450             }
451             if (vibratorHdiConnection_.IsVibratorRunning(paramIt)) {
452                 vibratorHdiConnection_.Stop(paramIt, HDF_VIBRATOR_MODE_PRESET);
453                 vibratorHdiConnection_.Stop(paramIt, HDF_VIBRATOR_MODE_HDHAPTIC);
454             }
455         #else
456             if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
457                 MISC_HILOGD("Thread is not running, no need to stop");
458                 ignoreVibrateNum ++;
459                 continue;
460             }
461         #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
462             StopVibrateThread(vibratorThread_);
463     }
464     if (ignoreVibrateNum == result.size()) {
465         MISC_HILOGD("No vibration, no need to stop");
466         return NO_ERROR;
467     }
468     std::string packageName = GetPackageName(GetCallingTokenID());
469     std::string curVibrateTime = GetCurrentTime();
470     MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, deviceId:%{public}d,"
471         "vibratorId:%{public}d", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), identifier.deviceId,
472         identifier.vibratorId);
473     return NO_ERROR;
474 }
475 
PlayVibratorEffect(const VibratorIdentifierIPC & identifier,const std::string & effect,int32_t count,int32_t usage,bool systemUsage)476 int32_t MiscdeviceService::PlayVibratorEffect(const VibratorIdentifierIPC& identifier, const std::string &effect,
477     int32_t count, int32_t usage, bool systemUsage)
478 {
479     int32_t checkResult = PlayVibratorEffectCheckAuthAndParam(count, usage);
480     if (checkResult != ERR_OK) {
481         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
482         return checkResult;
483     }
484 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
485     std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(identifier, effect);
486     if (!effectInfo) {
487         MISC_HILOGE("GetEffectInfo fail");
488         return ERROR;
489     }
490     if (!(effectInfo->isSupportEffect)) {
491         MISC_HILOGE("Effect not supported");
492         return PARAMETER_ERROR;
493     }
494 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
495     VibrateInfo info = {
496         .mode = VIBRATE_PRESET,
497         .packageName = GetPackageName(GetCallingTokenID()),
498         .pid = GetCallingPid(),
499         .uid = GetCallingUid(),
500         .usage = usage,
501         .systemUsage = systemUsage,
502 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
503         .duration = effectInfo->duration,
504 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
505         .effect = effect,
506         .count = count,
507         .intensity = INTENSITY_ADJUST_MAX
508     };
509     std::string curVibrateTime = GetCurrentTime();
510     if (StartVibrateThreadControl(identifier, info) != ERR_OK) {
511         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating or no vibration found",
512             curVibrateTime.c_str());
513         return ERROR;
514     }
515     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
516         "deviceId:%{public}d, vibratorId:%{public}d, duration:%{public}d, effect:%{public}s, count:%{public}d",
517         curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage, identifier.deviceId,
518         identifier.vibratorId, info.duration, info.effect.c_str(), info.count);
519     return NO_ERROR;
520 }
521 
PlayVibratorEffectCheckAuthAndParam(int32_t count,int32_t usage)522 int32_t MiscdeviceService::PlayVibratorEffectCheckAuthAndParam(int32_t count, int32_t usage)
523 {
524     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
525     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
526     if (ret != PERMISSION_GRANTED) {
527 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
528         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
529             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayVibratorEffectStub", "ERROR_CODE", ret);
530 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
531         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
532         return PERMISSION_DENIED;
533     }
534     if ((count < MIN_VIBRATOR_COUNT) || (count > MAX_VIBRATOR_COUNT) || (usage >= USAGE_MAX) || (usage < 0)) {
535         MISC_HILOGE("Invalid parameter");
536         return PARAMETER_ERROR;
537     }
538     return ERR_OK;
539 }
540 
StartVibrateThread(VibrateInfo info,const VibratorIdentifierIPC & identifier)541 void MiscdeviceService::StartVibrateThread(VibrateInfo info, const VibratorIdentifierIPC& identifier)
542 {
543     auto vibratorThread_ = GetVibratorThread(identifier);
544     if (vibratorThread_ == nullptr) {
545         MISC_HILOGD("No effective vibrator thread");
546         return;
547     }
548     std::vector<HdfWaveInformation> waveInfo;
549     if (GetAllWaveInfo(identifier, waveInfo) != ERR_OK) {
550         MISC_HILOGE("GetAllWaveInfo failed");
551         return;
552     }
553 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
554     VibrateInfo currentVibrateInfo = vibratorThread_->GetCurrentVibrateInfo();
555     if (info.duration <= SHORT_VIBRATOR_DURATION && currentVibrateInfo.duration <= SHORT_VIBRATOR_DURATION &&
556         info.mode == VIBRATE_PRESET && currentVibrateInfo.mode == VIBRATE_PRESET && info.count == 1) {
557         vibratorThread_->UpdateVibratorEffect(info, identifier, waveInfo);
558         FastVibratorEffect(info, identifier);
559     } else {
560 #endif // OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
561     StopVibrateThread(vibratorThread_);
562 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
563     if (vibratorHdiConnection_.IsVibratorRunning(identifier)) {
564         vibratorHdiConnection_.Stop(identifier, HDF_VIBRATOR_MODE_PRESET);
565         vibratorHdiConnection_.Stop(identifier, HDF_VIBRATOR_MODE_HDHAPTIC);
566     }
567 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
568     vibratorThread_->UpdateVibratorEffect(info, identifier, waveInfo);
569     vibratorThread_->Start("VibratorThread");
570 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
571     }
572 #endif // OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
573     DumpHelper->SaveVibrateRecord(info);
574 }
575 
StopVibrateThread(std::shared_ptr<VibratorThread> vibratorThread)576 void MiscdeviceService::StopVibrateThread(std::shared_ptr<VibratorThread> vibratorThread)
577 {
578     if ((vibratorThread != nullptr) && (vibratorThread->IsRunning())) {
579         vibratorThread->SetExitStatus(true);
580         vibratorThread->WakeUp();
581         vibratorThread->NotifyExitSync();
582         vibratorThread->SetExitStatus(false);
583         vibratorThread->ResetVibrateInfo();
584     }
585 }
586 
StopVibratorByMode(const VibratorIdentifierIPC & identifier,const std::string & mode)587 int32_t MiscdeviceService::StopVibratorByMode(const VibratorIdentifierIPC& identifier, const std::string &mode)
588 {
589     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
590     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
591     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
592     if (ret != PERMISSION_GRANTED) {
593 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
594         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
595             HiSysEvent::EventType::SECURITY, "PKG_NAME", "StopVibratorByModeStub", "ERROR_CODE", ret);
596 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
597         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
598         return PERMISSION_DENIED;
599     }
600     std::vector<VibratorIdentifierIPC> result = CheckDeviceIdIsValid(identifier);
601     size_t ignoreVibrateNum = 0;
602     if (result.empty()) {
603         MISC_HILOGD("result is empty, no need to stop");
604         return ERROR;
605     }
606     for (const auto& paramIt : result) {
607         auto vibratorThread_ = GetVibratorThread(paramIt);
608         if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() &&
609             !vibratorHdiConnection_.IsVibratorRunning(paramIt))) {
610             MISC_HILOGD("Thread is not running, no need to stop");
611             ignoreVibrateNum ++;
612             continue;
613         }
614         const VibrateInfo info = vibratorThread_->GetCurrentVibrateInfo();
615         if (info.mode != mode) {
616             MISC_HILOGD("Stop vibration information mismatch");
617             continue;
618         }
619         StopVibrateThread(vibratorThread_);
620         if (vibratorHdiConnection_.IsVibratorRunning(paramIt)) {
621             vibratorHdiConnection_.Stop(paramIt, HDF_VIBRATOR_MODE_PRESET);
622         }
623     }
624     if (ignoreVibrateNum == result.size()) {
625         MISC_HILOGD("No vibration, no need to stop");
626         return NO_ERROR;
627     }
628     std::string packageName = GetPackageName(GetCallingTokenID());
629     std::string curVibrateTime = GetCurrentTime();
630     MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, deviceId:%{public}d,"
631         "vibratorId:%{public}d, mode:%{public}s", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(),
632         identifier.deviceId, identifier.vibratorId, mode.c_str());
633     return NO_ERROR;
634 }
635 
IsSupportEffect(const VibratorIdentifierIPC & identifier,const std::string & effect,bool & state)636 int32_t MiscdeviceService::IsSupportEffect(const VibratorIdentifierIPC& identifier, const std::string &effect,
637     bool &state)
638 {
639 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
640     std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(identifier, effect);
641     if (!effectInfo) {
642         MISC_HILOGE("GetEffectInfo fail");
643         return ERROR;
644     }
645     state = effectInfo->isSupportEffect;
646     std::string packageName = GetPackageName(GetCallingTokenID());
647     std::string curVibrateTime = GetCurrentTime();
648     MISC_HILOGI("IsSupportEffect, currentTime:%{public}s, package:%{public}s, pid:%{public}d, effect:%{public}s,"
649         "state:%{public}d", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), effect.c_str(), state);
650 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
651     return NO_ERROR;
652 }
653 
GetCurrentTime()654 std::string MiscdeviceService::GetCurrentTime()
655 {
656     timespec curTime;
657     clock_gettime(CLOCK_REALTIME, &curTime);
658     struct tm *timeinfo = localtime(&(curTime.tv_sec));
659     std::string currentTime;
660     if (timeinfo == nullptr) {
661         MISC_HILOGE("timeinfo is null");
662         return currentTime;
663     }
664     currentTime.append(std::to_string(timeinfo->tm_year + BASE_YEAR)).append("-")
665         .append(std::to_string(timeinfo->tm_mon + BASE_MON)).append("-").append(std::to_string(timeinfo->tm_mday))
666         .append(" ").append(std::to_string(timeinfo->tm_hour)).append(":").append(std::to_string(timeinfo->tm_min))
667         .append(":").append(std::to_string(timeinfo->tm_sec)).append(".")
668         .append(std::to_string(curTime.tv_nsec / (CONVERSION_RATE * CONVERSION_RATE)));
669     return currentTime;
670 }
671 
672 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(const VibratorIdentifierIPC & identifier,int32_t fd,int64_t offset,int64_t length,const CustomHapticInfoIPC & customHapticInfoIPC)673 int32_t MiscdeviceService::PlayVibratorCustom(const VibratorIdentifierIPC& identifier, int32_t fd,
674     int64_t offset, int64_t length, const CustomHapticInfoIPC& customHapticInfoIPC)
675 {
676     int32_t checkResult = CheckAuthAndParam(customHapticInfoIPC.usage, customHapticInfoIPC.parameter, identifier);
677     if (checkResult != ERR_OK) {
678         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
679         close(fd);
680         return checkResult;
681     }
682     RawFileDescriptor rawFd;
683     rawFd.fd = fd;
684     rawFd.offset = offset;
685     rawFd.length = length;
686     JsonParser parser(rawFd);
687     VibratorDecoderCreator creator;
688     std::unique_ptr<IVibratorDecoder> decoder(creator.CreateDecoder(parser));
689     CHKPR(decoder, ERROR);
690     VibratePackage package;
691     int32_t ret = decoder->DecodeEffect(rawFd, parser, package);
692     if (ret != SUCCESS || package.patterns.empty()) {
693         MISC_HILOGE("Decode effect error");
694         return ERROR;
695     }
696     MergeVibratorParmeters(customHapticInfoIPC.parameter, package);
697     package.Dump();
698     VibrateInfo info = {
699         .packageName = GetPackageName(GetCallingTokenID()),
700         .pid = GetCallingPid(),
701         .uid = GetCallingUid(),
702         .usage = customHapticInfoIPC.usage,
703         .systemUsage = customHapticInfoIPC.systemUsage,
704         .package = package,
705     };
706     VibratorCapacity capacity;
707     if (GetHapticCapacityInfo(identifier, capacity) != ERR_OK) {
708         MISC_HILOGE("GetVibratorCapacity failed");
709         return ERROR;
710     }
711     if (capacity.isSupportHdHaptic) {
712         info.mode = VIBRATE_CUSTOM_HD;
713     } else if (capacity.isSupportPresetMapping) {
714         info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
715     } else if (capacity.isSupportTimeDelay) {
716         info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
717     }
718     std::string curVibrateTime = GetCurrentTime();
719     if (StartVibrateThreadControl(identifier, info) != ERR_OK) {
720         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating or no vibration found",
721             curVibrateTime.c_str());
722         return ERROR;
723     }
724     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
725         "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid,
726         info.usage, identifier.vibratorId, package.packageDuration);
727     return NO_ERROR;
728 }
729 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
730 
CheckAuthAndParam(int32_t usage,const VibrateParameter & parameter,const VibratorIdentifierIPC & identifier)731 int32_t MiscdeviceService::CheckAuthAndParam(int32_t usage, const VibrateParameter &parameter,
732     const VibratorIdentifierIPC& identifier)
733 {
734     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
735     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
736     if (ret != PERMISSION_GRANTED) {
737 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
738         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
739             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayVibratorCustomStub", "ERROR_CODE", ret);
740 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
741         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
742         return PERMISSION_DENIED;
743     }
744     VibratorCapacity capacity;
745     if (GetHapticCapacityInfo(identifier, capacity) != ERR_OK) {
746         MISC_HILOGE("GetVibratorCapacity failed");
747         return ERROR;
748     }
749     if (!(capacity.isSupportHdHaptic || capacity.isSupportPresetMapping || capacity.isSupportTimeDelay)) {
750         MISC_HILOGE("The device does not support this operation");
751         return IS_NOT_SUPPORTED;
752     }
753     if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
754         MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
755         return PARAMETER_ERROR;
756     }
757     return ERR_OK;
758 }
759 
GetPackageName(AccessTokenID tokenId)760 std::string MiscdeviceService::GetPackageName(AccessTokenID tokenId)
761 {
762     std::string packageName;
763     int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
764     switch (tokenType) {
765         case ATokenTypeEnum::TOKEN_HAP: {
766             HapTokenInfo hapInfo;
767             if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
768                 MISC_HILOGE("Get hap token info fail");
769                 return {};
770             }
771             packageName = hapInfo.bundleName;
772             break;
773         }
774         case ATokenTypeEnum::TOKEN_NATIVE:
775         case ATokenTypeEnum::TOKEN_SHELL: {
776             NativeTokenInfo tokenInfo;
777             if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
778                 MISC_HILOGE("Get native token info fail");
779                 return {};
780             }
781             packageName = tokenInfo.processName;
782             break;
783         }
784         default: {
785             MISC_HILOGW("Token type not match");
786             break;
787         }
788     }
789     return packageName;
790 }
791 
GetLightList(std::vector<LightInfoIPC> & lightInfoIpcList)792 int32_t MiscdeviceService::GetLightList(std::vector<LightInfoIPC> &lightInfoIpcList)
793 {
794     std::lock_guard<std::mutex> lightInfosLock(lightInfosMutex_);
795     std::string packageName = GetPackageName(GetCallingTokenID());
796     MISC_HILOGI("GetLightList, package:%{public}s", packageName.c_str());
797     int32_t ret = lightHdiConnection_.GetLightList(lightInfos_);
798     if (ret != ERR_OK) {
799         MISC_HILOGE("GetLightList failed, ret:%{public}d", ret);
800     }
801     size_t lightCount = lightInfos_.size();
802     MISC_HILOGI("lightCount:%{public}zu", lightCount);
803     if (lightCount > MAX_LIGHT_COUNT) {
804         lightCount = MAX_LIGHT_COUNT;
805     }
806     for (size_t i = 0; i < lightCount; ++i) {
807         lightInfoIpcList.push_back(lightInfos_[i]);
808     }
809     return ERR_OK;
810 }
811 
TurnOn(int32_t lightId,int32_t singleColor,const LightAnimationIPC & animation)812 int32_t MiscdeviceService::TurnOn(int32_t lightId, int32_t singleColor, const LightAnimationIPC &animation)
813 {
814     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
815     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), LIGHT_PERMISSION);
816     if (ret != PERMISSION_GRANTED) {
817 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
818         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "LIGHT_PERMISSIONS_EXCEPTION", HiSysEvent::EventType::SECURITY,
819             "PKG_NAME", "turnOnStub", "ERROR_CODE", ret);
820 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
821         MISC_HILOGE("CheckLightPermission failed, ret:%{public}d", ret);
822         return PERMISSION_DENIED;
823     }
824     LightColor color;
825     color.singleColor = singleColor;
826     std::string packageName = GetPackageName(GetCallingTokenID());
827     MISC_HILOGI("TurnOn, package:%{public}s", packageName.c_str());
828     if (!IsValid(lightId)) {
829         MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
830         return MISCDEVICE_NATIVE_SAM_ERR;
831     }
832     if (!IsLightAnimationValid(animation)) {
833         MISC_HILOGE("animation is invalid");
834         return MISCDEVICE_NATIVE_SAM_ERR;
835     }
836     ret = lightHdiConnection_.TurnOn(lightId, color, animation);
837     if (ret != ERR_OK) {
838         MISC_HILOGE("TurnOn failed, error:%{public}d", ret);
839         return ERROR;
840     }
841     return ret;
842 }
843 
TurnOff(int32_t lightId)844 int32_t MiscdeviceService::TurnOff(int32_t lightId)
845 {
846     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
847     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), LIGHT_PERMISSION);
848     if (ret != PERMISSION_GRANTED) {
849 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
850         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "LIGHT_PERMISSIONS_EXCEPTION", HiSysEvent::EventType::SECURITY,
851             "PKG_NAME", "TurnOffStub", "ERROR_CODE", ret);
852 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
853         MISC_HILOGE("CheckLightPermission failed, ret:%{public}d", ret);
854         return PERMISSION_DENIED;
855     }
856     std::string packageName = GetPackageName(GetCallingTokenID());
857     MISC_HILOGI("TurnOff, package:%{public}s", packageName.c_str());
858     if (!IsValid(lightId)) {
859         MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
860         return MISCDEVICE_NATIVE_SAM_ERR;
861     }
862     ret = lightHdiConnection_.TurnOff(lightId);
863     if (ret != ERR_OK) {
864         MISC_HILOGE("TurnOff failed, error:%{public}d", ret);
865         return ERROR;
866     }
867     return ret;
868 }
869 
Dump(int32_t fd,const std::vector<std::u16string> & args)870 int32_t MiscdeviceService::Dump(int32_t fd, const std::vector<std::u16string> &args)
871 {
872     CALL_LOG_ENTER;
873     if (fd < 0) {
874         MISC_HILOGE("Invalid fd");
875         return DUMP_PARAM_ERR;
876     }
877     if (args.empty()) {
878         MISC_HILOGE("args cannot be empty");
879         dprintf(fd, "args cannot be empty\n");
880         DumpHelper->DumpHelp(fd);
881         return DUMP_PARAM_ERR;
882     }
883     std::vector<std::string> argList = { "" };
884     std::transform(args.begin(), args.end(), std::back_inserter(argList),
885         [](const std::u16string &arg) {
886         return Str16ToStr8(arg);
887     });
888     DumpHelper->ParseCommand(fd, argList);
889     return ERR_OK;
890 }
891 
PerformVibrationControl(const VibratorIdentifierIPC & identifier,int32_t duration,VibrateInfo & info)892 int32_t MiscdeviceService::PerformVibrationControl(const VibratorIdentifierIPC& identifier,
893     int32_t duration, VibrateInfo& info)
894 {
895     std::string curVibrateTime = GetCurrentTime();
896     if (StartVibrateThreadControl(identifier, info) != ERR_OK) {
897         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating or no vibration found",
898             curVibrateTime.c_str());
899         return ERROR;
900     }
901     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
902         "duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage, duration);
903     return ERR_OK;
904 }
905 
PlayPattern(const VibratorIdentifierIPC & identifier,const VibratePattern & pattern,const CustomHapticInfoIPC & customHapticInfoIPC)906 int32_t MiscdeviceService::PlayPattern(const VibratorIdentifierIPC& identifier, const VibratePattern &pattern,
907     const CustomHapticInfoIPC& customHapticInfoIPC)
908 {
909     int32_t checkResult = PlayPatternCheckAuthAndParam(customHapticInfoIPC.usage, customHapticInfoIPC.parameter);
910     if (checkResult != ERR_OK) {
911         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
912         return checkResult;
913     }
914     VibratePattern vibratePattern;
915     uint32_t sessionId = customHapticInfoIPC.parameter.sessionId;
916     vibratePattern.startTime = ((sessionId > 0) ? pattern.startTime : 0);
917     vibratePattern.events = pattern.events;
918     std::vector<VibratePattern> patterns = {vibratePattern};
919     VibratePackage package = {
920         .patterns = patterns
921     };
922     MergeVibratorParmeters(customHapticInfoIPC.parameter, package);
923     package.Dump();
924     VibrateInfo info = {
925         .mode = VIBRATE_BUTT,
926         .packageName = GetPackageName(GetCallingTokenID()),
927         .pid = GetCallingPid(),
928         .uid = GetCallingUid(),
929         .usage = customHapticInfoIPC.usage,
930         .systemUsage = customHapticInfoIPC.systemUsage,
931         .sessionId = sessionId
932     };
933     VibratorCapacity capacity;
934     if (GetHapticCapacityInfo(identifier, capacity) != ERR_OK) {
935         MISC_HILOGE("GetVibratorCapacity failed");
936         return ERROR;
937     }
938     if (capacity.isSupportHdHaptic) {
939         int32_t result = PerformVibrationControl(identifier, pattern.patternDuration, info);
940         if (result != ERR_OK) {
941             MISC_HILOGE("PerformVibrationControl failed");
942             return result;
943         }
944         if (sessionId > 0) {
945             return vibratorHdiConnection_.PlayPatternBySessionId(identifier, sessionId, package.patterns.front());
946         }
947         return vibratorHdiConnection_.PlayPattern(identifier, package.patterns.front());
948     } else if (capacity.isSupportPresetMapping) {
949         info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
950     } else if (capacity.isSupportTimeDelay) {
951         info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
952     }
953     info.package = package;
954     return PerformVibrationControl(identifier, pattern.patternDuration, info);
955 }
956 
PlayPackageBySessionId(const VibratorIdentifierIPC & identifier,const VibratePackageIPC & package,const CustomHapticInfoIPC & customHapticInfoIPC)957 int32_t MiscdeviceService::PlayPackageBySessionId(const VibratorIdentifierIPC &identifier,
958     const VibratePackageIPC &package, const CustomHapticInfoIPC &customHapticInfoIPC)
959 {
960     CALL_LOG_ENTER;
961     int32_t checkResult = PlayPatternCheckAuthAndParam(customHapticInfoIPC.usage, customHapticInfoIPC.parameter);
962     if (checkResult != ERR_OK) {
963         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
964         return checkResult;
965     }
966     package.Dump();
967     VibrateInfo info = {
968         .mode = VIBRATE_BUTT,
969         .packageName = GetPackageName(GetCallingTokenID()),
970         .pid = GetCallingPid(),
971         .uid = GetCallingUid(),
972         .usage = customHapticInfoIPC.usage,
973         .systemUsage = customHapticInfoIPC.systemUsage,
974         .sessionId = customHapticInfoIPC.parameter.sessionId
975     };
976     VibratorCapacity capacity;
977     if (GetHapticCapacityInfo(identifier, capacity) != ERR_OK) {
978         MISC_HILOGE("GetVibratorCapacity failed");
979         return ERROR;
980     }
981     if (capacity.isSupportHdHaptic) {
982         int32_t result = PerformVibrationControl(identifier, package.packageDuration, info);
983         if (result != ERR_OK) {
984             MISC_HILOGE("PerformVibrationControl failed");
985             return result;
986         }
987         uint32_t sessionId = customHapticInfoIPC.parameter.sessionId;
988         return vibratorHdiConnection_.PlayPackageBySessionId(identifier, sessionId, package);
989     } else if (capacity.isSupportPresetMapping) {
990         info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
991     } else if (capacity.isSupportTimeDelay) {
992         info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
993     }
994     info.packageIPC = package;
995     return PerformVibrationControl(identifier, package.packageDuration, info);
996 }
997 
StopVibrateBySessionId(const VibratorIdentifierIPC & identifier,uint32_t sessionId)998 int32_t MiscdeviceService::StopVibrateBySessionId(const VibratorIdentifierIPC &identifier, uint32_t sessionId)
999 {
1000     CALL_LOG_ENTER;
1001     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
1002     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
1003     if (ret != PERMISSION_GRANTED) {
1004 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
1005         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
1006             HiSysEvent::EventType::SECURITY, "PKG_NAME", "StopVibrateBySessionId", "ERROR_CODE", ret);
1007 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
1008         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
1009         return PERMISSION_DENIED;
1010     }
1011     std::vector<VibratorIdentifierIPC> result = CheckDeviceIdIsValid(identifier);
1012     size_t ignoreVibrateNum = 0;
1013     if (result.empty()) {
1014         MISC_HILOGE("result is empty, no need to stop");
1015         return ERROR;
1016     }
1017     for (const auto& paramIt : result) {
1018         auto vibratorThread_ = GetVibratorThread(paramIt);
1019         if (!vibratorHdiConnection_.IsVibratorRunning(paramIt)) {
1020             MISC_HILOGD("Thread is not running, no need to stop");
1021             ignoreVibrateNum++;
1022             continue;
1023         }
1024         if (vibratorHdiConnection_.IsVibratorRunning(paramIt)) {
1025             vibratorHdiConnection_.StopVibrateBySessionId(paramIt, sessionId);
1026         }
1027     }
1028     if (ignoreVibrateNum == result.size()) {
1029         MISC_HILOGE("No need to stop, ignoreVibrateNum:%{public}zu", ignoreVibrateNum);
1030         return NO_ERROR;
1031     }
1032     std::string packageName = GetPackageName(GetCallingTokenID());
1033     std::string curVibrateTime = GetCurrentTime();
1034     MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, deviceId:%{public}d,"
1035         "vibratorId:%{public}d, sessionId:%{public}d", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(),
1036         identifier.deviceId, identifier.vibratorId, sessionId);
1037     return NO_ERROR;
1038 }
1039 
PlayPatternCheckAuthAndParam(int32_t usage,const VibrateParameter & parameter)1040 int32_t MiscdeviceService::PlayPatternCheckAuthAndParam(int32_t usage, const VibrateParameter &parameter)
1041 {
1042     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
1043     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
1044     if (ret != PERMISSION_GRANTED) {
1045 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
1046         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
1047             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayPatternStub", "ERROR_CODE", ret);
1048 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
1049         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
1050         return PERMISSION_DENIED;
1051     }
1052     if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
1053         MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
1054         return PARAMETER_ERROR;
1055     }
1056     return ERR_OK;
1057 }
1058 
GetDelayTime(const VibratorIdentifierIPC & identifier,int32_t & delayTime)1059 int32_t MiscdeviceService::GetDelayTime(const VibratorIdentifierIPC& identifier, int32_t &delayTime)
1060 {
1061     std::string packageName = GetPackageName(GetCallingTokenID());
1062     MISC_HILOGD("GetDelayTime, package:%{public}s", packageName.c_str());
1063     VibratorCapacity capacity;
1064     if (GetHapticCapacityInfo(identifier, capacity) != ERR_OK) {
1065         MISC_HILOGE("GetVibratorCapacity failed");
1066         return ERROR;
1067     }
1068     return vibratorHdiConnection_.GetDelayTime(identifier, capacity.GetVibrateMode(), delayTime);
1069 }
1070 
CheckVibratorParmeters(const VibrateParameter & parameter)1071 bool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter &parameter)
1072 {
1073     if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) ||
1074         (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) {
1075         MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d",
1076             parameter.intensity, parameter.frequency);
1077         return false;
1078     }
1079     return true;
1080 }
1081 
MergeVibratorParmeters(const VibrateParameter & parameter,VibratePackage & package)1082 void MiscdeviceService::MergeVibratorParmeters(const VibrateParameter &parameter, VibratePackage &package)
1083 {
1084     if ((parameter.intensity == INTENSITY_ADJUST_MAX) && (parameter.frequency == 0)) {
1085         MISC_HILOGD("The adjust parameter is not need to merge");
1086         return;
1087     }
1088     MISC_HILOGI("intensity:%{public}d, frequency:%{public}d", parameter.intensity, parameter.frequency);
1089     for (VibratePattern &pattern : package.patterns) {
1090         for (VibrateEvent &event : pattern.events) {
1091             float intensityScale = static_cast<float>(parameter.intensity) / INTENSITY_ADJUST_MAX;
1092             if ((event.tag == EVENT_TAG_TRANSIENT) || (event.points.empty())) {
1093                 event.intensity = static_cast<int32_t>(event.intensity * intensityScale);
1094                 event.intensity = std::max(std::min(event.intensity, INTENSITY_MAX), INTENSITY_MIN);
1095                 event.frequency = event.frequency + parameter.frequency;
1096                 event.frequency = std::max(std::min(event.frequency, FREQUENCY_MAX), FREQUENCY_MIN);
1097             } else {
1098                 for (VibrateCurvePoint &point : event.points) {
1099                     point.intensity = static_cast<int32_t>(point.intensity * intensityScale);
1100                     point.intensity = std::max(std::min(point.intensity, INTENSITY_ADJUST_MAX), INTENSITY_ADJUST_MIN);
1101                     point.frequency = point.frequency + parameter.frequency;
1102                     point.frequency = std::max(std::min(point.frequency, FREQUENCY_ADJUST_MAX), FREQUENCY_ADJUST_MIN);
1103                 }
1104             }
1105         }
1106     }
1107 }
1108 
SendMsgToClient(const HdfVibratorPlugInfo & info)1109 void MiscdeviceService::SendMsgToClient(const HdfVibratorPlugInfo &info)
1110 {
1111     MISC_HILOGI("Device:%{public}d state change, state:%{public}d, deviceName:%{public}s", info.deviceId, info.status,
1112         info.deviceName.c_str());
1113     std::lock_guard<std::mutex> lockManage(devicesManageMutex_);
1114     if (info.status == 0) {
1115         auto it = devicesManageMap_.find(info.deviceId);
1116         if (it != devicesManageMap_.end()) {
1117             VibratorIdentifierIPC identifier;
1118             for (auto &value : it->second.baseInfo) {
1119                 identifier.deviceId = info.deviceId;
1120                 identifier.vibratorId = value.vibratorId;
1121                 StopVibratorService(identifier);
1122             }
1123             devicesManageMap_.erase(it);
1124             MISC_HILOGI("Device %{public}d is offline and removed from the map.", info.deviceId);
1125         }
1126     } else {
1127         std::vector<HdfVibratorInfo> vibratorInfo;
1128         auto ret = vibratorHdiConnection_.GetVibratorInfo(vibratorInfo);
1129         if (ret != NO_ERROR || vibratorInfo.empty()) {
1130             MISC_HILOGE("Device not contain the local vibrator");
1131         }
1132         if (InsertVibratorInfo(info.deviceId, info.deviceName, vibratorInfo) != NO_ERROR) {
1133             MISC_HILOGE("Insert vibrator of device %{public}d fail", info.deviceId);
1134         }
1135     }
1136 
1137     std::lock_guard<std::mutex> lock(clientPidMapMutex_);
1138     MISC_HILOGI("Device:%{public}d state change,state:%{public}d, clientPidMap_.size::%{public}zu",
1139         info.deviceId, info.status, clientPidMap_.size());
1140     for (auto it = clientPidMap_.begin(); it != clientPidMap_.end(); ++it) {
1141         const sptr<IRemoteObject>& key = it->first;
1142 
1143         sptr<IVibratorClient> clientProxy = iface_cast<IVibratorClient>(key);
1144         if (clientProxy != nullptr) {
1145             MISC_HILOGI("Device:%{public}d state change,state:%{public}d, ProcessPlugEvent",
1146                         info.deviceId, info.status);
1147             clientProxy->ProcessPlugEvent(info.status, info.deviceId, info.vibratorCnt);
1148         }
1149     }
1150 }
1151 
TransferClientRemoteObject(const sptr<IRemoteObject> & vibratorServiceClient)1152 int32_t MiscdeviceService::TransferClientRemoteObject(const sptr<IRemoteObject> &vibratorServiceClient)
1153 {
1154     auto clientPid = GetCallingPid();
1155     if (clientPid < 0) {
1156         MISC_HILOGE("ClientPid is invalid, clientPid:%{public}d", clientPid);
1157         return ERROR;
1158     }
1159     RegisterClientDeathRecipient(vibratorServiceClient, clientPid);
1160     return ERR_OK;
1161 }
1162 
ProcessDeathObserver(const wptr<IRemoteObject> & object)1163 void MiscdeviceService::ProcessDeathObserver(const wptr<IRemoteObject> &object)
1164 {
1165     CALL_LOG_ENTER;
1166     sptr<IRemoteObject> client = object.promote();
1167     int32_t clientPid = FindClientPid(client);
1168     VibrateInfo info;
1169     std::lock_guard<std::mutex> lock(devicesManageMutex_);
1170     for (const auto& pair : devicesManageMap_) {
1171         int deviceId = pair.first;
1172         const VibratorControlInfo& vibratorControlInfo_ = pair.second.controlInfo;
1173         MISC_HILOGI("Device ID:%{public}d, , Motor Count:%{public}d", deviceId, vibratorControlInfo_.motorCount);
1174         for (const auto& motorPair : vibratorControlInfo_.vibratorThreads) {
1175             int motorId = motorPair.first;
1176             {
1177                 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
1178                 auto vibratorThread_ = motorPair.second;
1179                 if (vibratorThread_ == nullptr) {
1180                     MISC_HILOGE("MotorId:%{public}d, Vibrate thread no found in devicesManageMap_", motorId);
1181                     vibratorThread_ = std::make_shared<VibratorThread>();
1182                 }
1183                 info = vibratorThread_->GetCurrentVibrateInfo();
1184             }
1185             int32_t vibratePid = info.pid;
1186             MISC_HILOGI("ClientPid:%{public}d, VibratePid:%{public}d", clientPid, vibratePid);
1187             if ((clientPid != INVALID_PID) && (clientPid == vibratePid)) {
1188                 VibratorIdentifierIPC identifier;
1189                 identifier.deviceId = deviceId;
1190                 identifier.vibratorId = motorId;
1191                 StopVibratorService(identifier);
1192             }
1193         }
1194     }
1195     UnregisterClientDeathRecipient(client);
1196 }
1197 
RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient,int32_t pid)1198 void  MiscdeviceService::RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient, int32_t pid)
1199 {
1200     if (vibratorServiceClient == nullptr) {
1201         MISC_HILOGE("VibratorServiceClient is nullptr");
1202         return;
1203     }
1204     std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
1205     if (clientDeathObserver_ == nullptr) {
1206         clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MiscdeviceService *>(this));
1207         if (clientDeathObserver_ == nullptr) {
1208             MISC_HILOGE("ClientDeathObserver_ is nullptr");
1209             return;
1210         }
1211     }
1212     vibratorServiceClient->AddDeathRecipient(clientDeathObserver_);
1213     SaveClientPid(vibratorServiceClient, pid);
1214 }
1215 
UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)1216 void MiscdeviceService::UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)
1217 {
1218     if (vibratorServiceClient == nullptr) {
1219         MISC_HILOGE("vibratorServiceClient is nullptr");
1220         return;
1221     }
1222     int32_t clientPid = FindClientPid(vibratorServiceClient);
1223     if (clientPid == INVALID_PID) {
1224         MISC_HILOGE("Pid is invalid");
1225         return;
1226     }
1227     std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
1228     vibratorServiceClient->RemoveDeathRecipient(clientDeathObserver_);
1229     DestroyClientPid(vibratorServiceClient);
1230 }
1231 
SaveClientPid(const sptr<IRemoteObject> & vibratorServiceClient,int32_t pid)1232 void MiscdeviceService::SaveClientPid(const sptr<IRemoteObject> &vibratorServiceClient, int32_t pid)
1233 {
1234     if (vibratorServiceClient == nullptr) {
1235         MISC_HILOGE("VibratorServiceClient is nullptr");
1236         return;
1237     }
1238     std::lock_guard<std::mutex> lock(clientPidMapMutex_);
1239     clientPidMap_.insert(std::make_pair(vibratorServiceClient, pid));
1240 }
1241 
FindClientPid(const sptr<IRemoteObject> & vibratorServiceClient)1242 int32_t MiscdeviceService::FindClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
1243 {
1244     if (vibratorServiceClient == nullptr) {
1245         MISC_HILOGE("VibratorServiceClient is nullptr");
1246         return INVALID_PID;
1247     }
1248     std::lock_guard<std::mutex> lock(clientPidMapMutex_);
1249     auto it = clientPidMap_.find(vibratorServiceClient);
1250     if (it == clientPidMap_.end()) {
1251         MISC_HILOGE("Cannot find client pid");
1252         return INVALID_PID;
1253     }
1254     return it->second;
1255 }
1256 
DestroyClientPid(const sptr<IRemoteObject> & vibratorServiceClient)1257 void MiscdeviceService::DestroyClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
1258 {
1259     if (vibratorServiceClient == nullptr) {
1260         MISC_HILOGD("VibratorServiceClient is nullptr");
1261         return;
1262     }
1263     std::lock_guard<std::mutex> lock(clientPidMapMutex_);
1264     auto it = clientPidMap_.find(vibratorServiceClient);
1265     if (it == clientPidMap_.end()) {
1266         MISC_HILOGE("Cannot find client pid");
1267         return;
1268     }
1269     clientPidMap_.erase(it);
1270 }
1271 
PlayPrimitiveEffect(const VibratorIdentifierIPC & identifier,const std::string & effect,const PrimitiveEffectIPC & primitiveEffectIPC)1272 int32_t MiscdeviceService::PlayPrimitiveEffect(const VibratorIdentifierIPC& identifier,
1273     const std::string &effect, const PrimitiveEffectIPC& primitiveEffectIPC)
1274 {
1275     int32_t checkResult = PlayPrimitiveEffectCheckAuthAndParam(primitiveEffectIPC.intensity, primitiveEffectIPC.usage);
1276     if (checkResult != ERR_OK) {
1277         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
1278         return checkResult;
1279     }
1280 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
1281     std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(identifier, effect);
1282     if (!effectInfo) {
1283         MISC_HILOGE("GetEffectInfo fail");
1284         return ERROR;
1285     }
1286     if (!(effectInfo->isSupportEffect)) {
1287         MISC_HILOGE("Effect not supported");
1288         return PARAMETER_ERROR;
1289     }
1290 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
1291     VibrateInfo info = {
1292         .mode = VIBRATE_PRESET,
1293         .packageName = GetPackageName(GetCallingTokenID()),
1294         .pid = GetCallingPid(),
1295         .uid = GetCallingUid(),
1296         .usage = primitiveEffectIPC.usage,
1297         .systemUsage = primitiveEffectIPC.systemUsage,
1298 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
1299         .duration = effectInfo->duration,
1300 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
1301         .effect = effect,
1302         .count = primitiveEffectIPC.count,
1303         .intensity = primitiveEffectIPC.intensity
1304     };
1305     std::string curVibrateTime = GetCurrentTime();
1306     if (StartVibrateThreadControl(identifier, info) != ERR_OK) {
1307         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating or no vibration found",
1308             curVibrateTime.c_str());
1309         return ERROR;
1310     }
1311     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
1312         "deviceId:%{public}d, vibratorId:%{public}d, duration:%{public}d, effect:%{public}s, intensity:%{public}d",
1313         curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage, identifier.deviceId,
1314         identifier.vibratorId, info.duration, info.effect.c_str(), info.intensity);
1315     return NO_ERROR;
1316 }
1317 
PlayPrimitiveEffectCheckAuthAndParam(int32_t intensity,int32_t usage)1318 int32_t MiscdeviceService::PlayPrimitiveEffectCheckAuthAndParam(int32_t intensity, int32_t usage)
1319 {
1320     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
1321     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
1322     if (ret != PERMISSION_GRANTED) {
1323 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
1324         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
1325             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayPrimitiveEffectStub", "ERROR_CODE", ret);
1326 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
1327         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
1328         return PERMISSION_DENIED;
1329     }
1330     if ((intensity <= INTENSITY_MIN) || (intensity > INTENSITY_MAX) || (usage >= USAGE_MAX) || (usage < 0)) {
1331         MISC_HILOGE("Invalid parameter");
1332         return PARAMETER_ERROR;
1333     }
1334     return ERR_OK;
1335 }
1336 
GetLocalDeviceId(int32_t & deviceId)1337 int32_t MiscdeviceService::GetLocalDeviceId(int32_t &deviceId)
1338 {
1339     for (const auto& device : devicesManageMap_) {
1340         for (const auto& info : device.second.baseInfo) {
1341             if (info.isLocalVibrator) {
1342                 deviceId = info.deviceId;
1343                 return NO_ERROR;
1344             }
1345         }
1346     }
1347 
1348     return ERROR;
1349 }
1350 
GetOneVibrator(const VibratorIdentifierIPC & actIdentifier,std::vector<VibratorInfoIPC> & vibratorInfoIPC)1351 int32_t MiscdeviceService::GetOneVibrator(const VibratorIdentifierIPC& actIdentifier,
1352     std::vector<VibratorInfoIPC>& vibratorInfoIPC)
1353 {
1354     if (devicesManageMap_.empty()) {
1355         MISC_HILOGE("No vibrator device online");
1356         return ERROR;
1357     }
1358 
1359     auto it = devicesManageMap_.find(actIdentifier.deviceId);
1360     if (it == devicesManageMap_.end()) {
1361         MISC_HILOGE("Device manager map has no vibrator info");
1362         return ERROR;
1363     }
1364     for (auto &value : it->second.baseInfo) {
1365         if (actIdentifier.vibratorId == value.vibratorId) {
1366             vibratorInfoIPC.emplace_back(value);
1367             break;
1368         }
1369     }
1370     return NO_ERROR;
1371 }
1372 
GetVibratorList(const VibratorIdentifierIPC & identifier,std::vector<VibratorInfoIPC> & vibratorInfoIPC)1373 int32_t MiscdeviceService::GetVibratorList(const VibratorIdentifierIPC& identifier,
1374     std::vector<VibratorInfoIPC>& vibratorInfoIPC)
1375 {
1376     CALL_LOG_ENTER;
1377     identifier.Dump();
1378     if (devicesManageMap_.empty()) {
1379         GetOnlineVibratorInfo();
1380     }
1381     std::lock_guard<std::mutex> lockManage(devicesManageMutex_);
1382     if ((identifier.deviceId == -1) && (identifier.vibratorId == -1)) {
1383         for (auto &value : devicesManageMap_) {
1384             vibratorInfoIPC.insert(vibratorInfoIPC.end(), value.second.baseInfo.begin(),
1385                 value.second.baseInfo.end());
1386         }
1387     } else if ((identifier.deviceId == -1) && (identifier.vibratorId != -1)) {
1388         VibratorIdentifierIPC actIdentifier;
1389         actIdentifier.vibratorId = identifier.vibratorId;
1390         int32_t ret = GetLocalDeviceId(actIdentifier.deviceId);
1391         if (ret == NO_ERROR) {
1392             ret = GetOneVibrator(actIdentifier, vibratorInfoIPC);
1393             if (ret != NO_ERROR) {
1394                 MISC_HILOGI("Local deviceId %{public}d has no vibratorId %{public}d info",
1395                     actIdentifier.deviceId, actIdentifier.vibratorId);
1396             }
1397         }
1398     } else if ((identifier.deviceId != -1) && (identifier.vibratorId == -1)) {
1399         auto it = devicesManageMap_.find(identifier.deviceId);
1400         if (it == devicesManageMap_.end()) {
1401             MISC_HILOGD("Device manager map has no vibrator info");
1402             return NO_ERROR;
1403         }
1404         vibratorInfoIPC = it->second.baseInfo;
1405     } else { // ((identifier.deviceId != -1) && (identifier.vibratorId != -1))
1406         if (GetOneVibrator(identifier, vibratorInfoIPC) != NO_ERROR) {
1407             MISC_HILOGI("DeviceId %{public}d has no vibratorId %{public}d info",
1408                 identifier.deviceId, identifier.vibratorId);
1409         }
1410     }
1411     return NO_ERROR;
1412 }
1413 
GetEffectInfo(const VibratorIdentifierIPC & identifier,const std::string & effectType,EffectInfoIPC & effectInfoIPC)1414 int32_t MiscdeviceService::GetEffectInfo(const VibratorIdentifierIPC& identifier, const std::string& effectType,
1415     EffectInfoIPC& effectInfoIPC)
1416 {
1417     CALL_LOG_ENTER;
1418     identifier.Dump();
1419     if (devicesManageMap_.empty()) {
1420         MISC_HILOGI("No vibrator device online");
1421         return NO_ERROR;
1422     }
1423     VibratorIdentifierIPC localIdentifier;
1424     if (identifier.deviceId == -1) {
1425         for (const auto& pair : devicesManageMap_) {
1426             for (const auto& info : pair.second.baseInfo) {
1427                 info.isLocalVibrator ? (localIdentifier.deviceId = info.deviceId) : 0;
1428             }
1429         }
1430     }
1431     HdfEffectInfo hdfEffectInfo;
1432     int32_t ret = vibratorHdiConnection_.GetEffectInfo((identifier.deviceId == -1) ? localIdentifier : identifier,
1433         effectType, hdfEffectInfo);
1434     if (ret != NO_ERROR) {
1435         MISC_HILOGE("HDI::GetEffectInfo return error");
1436         return ERROR;
1437     }
1438     effectInfoIPC.duration = hdfEffectInfo.duration;
1439     effectInfoIPC.isSupportEffect = hdfEffectInfo.isSupportEffect;
1440     effectInfoIPC.Dump();
1441     return NO_ERROR;
1442 }
1443 
SubscribeVibratorPlugInfo(const sptr<IRemoteObject> & vibratorServiceClient)1444 int32_t MiscdeviceService::SubscribeVibratorPlugInfo(const sptr<IRemoteObject> &vibratorServiceClient)
1445 {
1446     auto clientPid = GetCallingPid();
1447     if (clientPid < 0) {
1448         MISC_HILOGE("ClientPid is invalid, clientPid:%{public}d", clientPid);
1449         return ERROR;
1450     }
1451     if (vibratorServiceClient == nullptr) {
1452         MISC_HILOGD("VibratorServiceClient is nullptr");
1453         return ERROR;
1454     }
1455     return ERR_OK;
1456 }
1457 
GetVibratorCapacity(const VibratorIdentifierIPC & identifier,VibratorCapacity & vibratorCapacity)1458 int32_t MiscdeviceService::GetVibratorCapacity(const VibratorIdentifierIPC& identifier,
1459     VibratorCapacity &vibratorCapacity)
1460 {
1461     CALL_LOG_ENTER;
1462     VibratorCapacity capacity;
1463     if (GetHapticCapacityInfo(identifier, capacity) != ERR_OK) {
1464         MISC_HILOGE("GetVibratorCapacity failed");
1465         return ERROR;
1466     }
1467     vibratorCapacity = capacity;
1468     return ERR_OK;
1469 }
1470 
1471 // 手表短振快速下发不启动线程
1472 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
FastVibratorEffect(const VibrateInfo & info,const VibratorIdentifierIPC & identifier)1473 int32_t MiscdeviceService::FastVibratorEffect(const VibrateInfo &info, const VibratorIdentifierIPC& identifier)
1474 {
1475     int32_t ret = VibratorDevice.StartByIntensity(identifier, info.effect, info.intensity);
1476     if (ret != SUCCESS) {
1477         MISC_HILOGE("Vibrate effect %{public}s failed.", info.effect.c_str());
1478     }
1479     return NO_ERROR;
1480 }
1481 #endif // OHOS_BUILD_ENABLE_VIBRATOR_PRESET_INFO
1482 
GetVibratorThread(const VibratorIdentifierIPC & identifier)1483 std::shared_ptr<VibratorThread> MiscdeviceService::GetVibratorThread(const VibratorIdentifierIPC& identifier)
1484 {
1485     CALL_LOG_ENTER;
1486     auto deviceIt = devicesManageMap_.find(identifier.deviceId);
1487     if (deviceIt != devicesManageMap_.end()) {
1488         auto thread = deviceIt->second.controlInfo.GetVibratorThread(identifier.vibratorId);
1489         if (thread) {
1490             MISC_HILOGI("Success: Vibrate thread found.");
1491             return thread;
1492         } else {
1493             MISC_HILOGE("Failed: Vibrate thread no found.");
1494             return nullptr;
1495         }
1496     }
1497     return nullptr;
1498 }
1499 
GetHapticCapacityInfo(const VibratorIdentifierIPC & identifier,VibratorCapacity & capacityInfo)1500 int32_t MiscdeviceService::GetHapticCapacityInfo(const VibratorIdentifierIPC& identifier,
1501     VibratorCapacity& capacityInfo)
1502 {
1503     CALL_LOG_ENTER;
1504     std::lock_guard<std::mutex> lock(devicesManageMutex_);
1505     if (identifier.deviceId != -1) {
1506         auto deviceIt = devicesManageMap_.find(identifier.deviceId);
1507         if (deviceIt != devicesManageMap_.end()) {
1508             capacityInfo = deviceIt->second.capacityInfo;
1509             return ERR_OK;
1510         }
1511         MISC_HILOGW("No vibrator capacity information found for device ID: %{public}d", identifier.deviceId);
1512         return ERR_OK;
1513     }
1514     for (const auto& pair : devicesManageMap_) {
1515         for (const auto& info : pair.second.baseInfo) {
1516             if (info.isLocalVibrator) {
1517                 capacityInfo = pair.second.capacityInfo;
1518                 return ERR_OK;
1519             }
1520         }
1521     }
1522     MISC_HILOGW("No local vibrator capacity information found for device ID: %{public}d", identifier.deviceId);
1523     return ERR_OK;
1524 }
1525 
GetAllWaveInfo(const VibratorIdentifierIPC & identifier,std::vector<HdfWaveInformation> & waveInfo)1526 int32_t MiscdeviceService::GetAllWaveInfo(const VibratorIdentifierIPC& identifier,
1527     std::vector<HdfWaveInformation>& waveInfo)
1528 {
1529     CALL_LOG_ENTER;
1530     if (identifier.deviceId != -1) {
1531         auto deviceIt = devicesManageMap_.find(identifier.deviceId);
1532         if (deviceIt != devicesManageMap_.end()) {
1533             waveInfo = deviceIt->second.waveInfo;
1534             return ERR_OK;
1535         }
1536         MISC_HILOGE("Device ID %{public}d not found", identifier.deviceId);
1537         return ERR_OK;
1538     }
1539     for (const auto& [deviceId, deviceInfo] : devicesManageMap_) {
1540         for (const auto& baseInfo : deviceInfo.baseInfo) {
1541             if (baseInfo.isLocalVibrator) {
1542                 waveInfo = deviceInfo.waveInfo;
1543                 return ERR_OK;
1544             }
1545         }
1546     }
1547     MISC_HILOGW("No vibrator information found for device ID: %{public}d", identifier.deviceId);
1548     return ERR_OK;
1549 }
1550 
GetHapticStartUpTime(const VibratorIdentifierIPC & identifier,int32_t mode,int32_t & startUpTime)1551 int32_t MiscdeviceService::GetHapticStartUpTime(const VibratorIdentifierIPC& identifier, int32_t mode,
1552     int32_t &startUpTime)
1553 {
1554     CALL_LOG_ENTER;
1555     auto ret = vibratorHdiConnection_.GetDelayTime(identifier, mode, startUpTime);
1556     if (ret != NO_ERROR) {
1557         MISC_HILOGE("HDI::GetHapticStartUpTime return error");
1558         return ERROR;
1559     }
1560     return NO_ERROR;
1561 }
1562 
ConvertToServerInfos(const std::vector<HdfVibratorInfo> & baseVibratorInfo,const VibratorCapacity & vibratorCapacity,const std::vector<HdfWaveInformation> & waveInfomation,const HdfVibratorPlugInfo & info,VibratorAllInfos & vibratorAllInfos)1563 void MiscdeviceService::ConvertToServerInfos(const std::vector<HdfVibratorInfo> &baseVibratorInfo,
1564     const VibratorCapacity &vibratorCapacity, const std::vector<HdfWaveInformation> &waveInfomation,
1565     const HdfVibratorPlugInfo &info, VibratorAllInfos& vibratorAllInfos)
1566 {
1567     CALL_LOG_ENTER;
1568     VibratorInfoIPC vibratorInfo;
1569     for (auto infos : baseVibratorInfo) {
1570         vibratorInfo.deviceId = infos.deviceId;
1571         vibratorInfo.vibratorId = infos.vibratorId;
1572         vibratorInfo.deviceName = info.deviceName;
1573         vibratorInfo.isSupportHdHaptic = vibratorCapacity.isSupportHdHaptic;
1574         vibratorInfo.isLocalVibrator = infos.isLocal;
1575         vibratorAllInfos.baseInfo.emplace_back(vibratorInfo);
1576         MISC_HILOGI("HDI::HdfVibratorInfo deviceName:%{public}s, deviceId:%{public}d, vibratorId:%{public}d,"
1577             " isLocalVibrator:%{public}d", info.deviceName.c_str(), vibratorInfo.deviceId, vibratorInfo.vibratorId,
1578             vibratorInfo.isLocalVibrator);
1579     }
1580     vibratorAllInfos.capacityInfo = vibratorCapacity;
1581     vibratorAllInfos.waveInfo = waveInfomation;
1582 }
1583 
GetOnlineVibratorInfo()1584 void MiscdeviceService::GetOnlineVibratorInfo()
1585 {
1586     CALL_LOG_ENTER;
1587     std::vector<HdfVibratorInfo> vibratorInfo;
1588     auto ret = vibratorHdiConnection_.GetVibratorInfo(vibratorInfo);
1589     if (ret != NO_ERROR || vibratorInfo.empty()) {
1590         MISC_HILOGW("Device does not contain any vibrators");
1591         return;
1592     }
1593 
1594     std::lock_guard<std::mutex> lockManage(devicesManageMutex_);
1595     const std::string deviceName = "";
1596     for (auto &info : vibratorInfo) {
1597         const auto it = devicesManageMap_.find(info.deviceId);
1598         if (it != devicesManageMap_.end()) {
1599             continue;
1600         }
1601         if (InsertVibratorInfo(info.deviceId, deviceName, vibratorInfo) != NO_ERROR) {
1602             MISC_HILOGW("Insert vibrator of device %{public}d fail", info.deviceId);
1603         }
1604     }
1605 }
1606 
InsertVibratorInfo(int deviceId,const std::string & deviceName,const std::vector<HdfVibratorInfo> & vibratorInfo)1607 int32_t MiscdeviceService::InsertVibratorInfo(int deviceId, const std::string &deviceName,
1608     const std::vector<HdfVibratorInfo> &vibratorInfo)
1609 {
1610     CALL_LOG_ENTER;
1611     std::vector<HdfVibratorInfo> infos;
1612     std::vector<int> vibratorIdList;
1613     for (auto &info : vibratorInfo) {
1614         const auto it = devicesManageMap_.find(info.deviceId);
1615         if (it != devicesManageMap_.end()) {
1616             MISC_HILOGW("The deviceId already exists in devicesManageMap_, deviceId: %{public}d", info.deviceId);
1617             continue;
1618         }
1619         if (info.deviceId == deviceId) {
1620             infos.emplace_back(info);
1621             vibratorIdList.push_back(info.vibratorId);
1622         }
1623     }
1624     if (infos.empty()) {
1625         MISC_HILOGW("Device %{public}d does not contain any vibrators", deviceId);
1626         return NO_ERROR;
1627     }
1628 
1629     VibratorIdentifierIPC param;
1630     param.deviceId = infos[0].deviceId;
1631     param.vibratorId = infos[0].vibratorId;
1632     VibratorCapacity capacity;
1633     int32_t ret = vibratorHdiConnection_.GetVibratorCapacity(param, capacity);
1634     if (ret != NO_ERROR) {
1635         MISC_HILOGW("Get capacity fail from HDI, then use the default capacity, deviceId: %{public}d", param.deviceId);
1636     }
1637     std::vector<HdfWaveInformation> waveInfo;
1638     ret = vibratorHdiConnection_.GetAllWaveInfo(param, waveInfo);
1639     if (ret != NO_ERROR) {
1640         MISC_HILOGW("Get waveInfo fail from HDI, deviceId: %{public}d", param.deviceId);
1641     }
1642 
1643     HdfVibratorPlugInfo mockInfo;
1644     mockInfo.deviceName = deviceName;
1645     VibratorAllInfos localVibratorInfo(vibratorIdList);
1646     (void)ConvertToServerInfos(infos, capacity, waveInfo, mockInfo, localVibratorInfo);
1647     devicesManageMap_.insert(std::make_pair(param.deviceId, localVibratorInfo));
1648     return NO_ERROR;
1649 }
1650 
StartVibrateThreadControl(const VibratorIdentifierIPC & identifier,VibrateInfo & info)1651 int32_t MiscdeviceService::StartVibrateThreadControl(const VibratorIdentifierIPC& identifier, VibrateInfo& info)
1652 {
1653     std::lock_guard<std::mutex> lockManage(devicesManageMutex_);
1654     std::string curVibrateTime = GetCurrentTime();
1655     std::vector<VibratorIdentifierIPC> result = CheckDeviceIdIsValid(identifier);
1656     if (result.empty()) {
1657         MISC_HILOGE("No vibration found");
1658         return ERROR;
1659     }
1660 
1661     size_t ignoreVibrateNum = 0;
1662 
1663     const std::vector<std::string> specialModes = {
1664         VIBRATE_CUSTOM_HD, VIBRATE_CUSTOM_COMPOSITE_EFFECT,
1665         VIBRATE_CUSTOM_COMPOSITE_TIME, VIBRATE_BUTT
1666     };
1667 
1668     std::unordered_set<int32_t> uniqueIndices;
1669     if (std::find(specialModes.begin(), specialModes.end(), info.mode) != specialModes.end()) {
1670         for (const auto& pattern : info.package.patterns) {
1671             for (const auto& event : pattern.events) {
1672                 uniqueIndices.insert(event.index);
1673             }
1674         }
1675         for (const auto& index : uniqueIndices) {
1676             MISC_HILOGD("Info mode:%{public}s, vibratorIndex:%{public}d", info.mode.c_str(), index);
1677         }
1678     }
1679     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
1680     for (const auto& paramIt : result) {
1681         bool shouldProcess = uniqueIndices.empty() ||
1682         uniqueIndices.find(0) != uniqueIndices.end() ||
1683         uniqueIndices.find(paramIt.position) != uniqueIndices.end();
1684 
1685         if (paramIt.isLocalVibrator && ShouldIgnoreVibrate(info, paramIt)) {
1686             if (shouldProcess) {
1687                 ignoreVibrateNum++;
1688                 continue;
1689             }
1690         }
1691         if (shouldProcess) {
1692             StartVibrateThread(info, paramIt);
1693         }
1694     }
1695 
1696     return (ignoreVibrateNum == result.size()) ? ERROR : ERR_OK;
1697 }
1698 
CheckDeviceIdIsValid(const VibratorIdentifierIPC & identifier)1699 std::vector<VibratorIdentifierIPC> MiscdeviceService::CheckDeviceIdIsValid(const VibratorIdentifierIPC& identifier)
1700 {
1701     CALL_LOG_ENTER;
1702     std::vector<VibratorIdentifierIPC> result;
1703 
1704     auto addToResult = [&](const auto& info) {
1705         VibratorIdentifierIPC newIdentifier;
1706         newIdentifier.deviceId = info.deviceId;
1707         newIdentifier.vibratorId = info.vibratorId;
1708         newIdentifier.position = info.position;
1709         newIdentifier.isLocalVibrator = info.isLocalVibrator;
1710         result.push_back(newIdentifier);
1711         MISC_HILOGD("Push result in list,:%{public}d,:%{public}d", newIdentifier.deviceId, newIdentifier.vibratorId);
1712     };
1713 
1714     auto processDevice = [&](const auto& device) {
1715         for (const auto& info : device.second.baseInfo) {
1716             bool shouldAdd = false;
1717             if (identifier.deviceId == -1 && identifier.vibratorId != -1) {
1718                 shouldAdd = info.isLocalVibrator && info.vibratorId == identifier.vibratorId;
1719             } else if (identifier.deviceId != -1 && identifier.vibratorId != -1) {
1720                 shouldAdd = info.vibratorId == identifier.vibratorId;
1721             } else if (identifier.deviceId == -1 && identifier.vibratorId == -1) {
1722                 shouldAdd = info.isLocalVibrator;
1723             } else { // (identifier.deviceId != -1 && identifier.vibratorId == -1)
1724                 shouldAdd = true;
1725             }
1726 
1727             if (shouldAdd) {
1728                 addToResult(info);
1729             }
1730         }
1731     };
1732 
1733     if (identifier.deviceId != -1) {
1734         auto deviceIt = devicesManageMap_.find(identifier.deviceId);
1735         if (deviceIt != devicesManageMap_.end()) {
1736             processDevice(*deviceIt);
1737         }
1738     } else {
1739         for (const auto& pair : devicesManageMap_) {
1740             processDevice(pair);
1741         }
1742     }
1743     return result;
1744 }
1745 }  // namespace Sensors
1746 }  // namespace OHOS
1747