• 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 #include "death_recipient_template.h"
19 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
20 #include "hisysevent.h"
21 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
22 #ifdef MEMMGR_ENABLE
23 #include "mem_mgr_client.h"
24 #endif // MEMMGR_ENABLE
25 #include "system_ability_definition.h"
26 
27 #include "sensors_errors.h"
28 #include "vibration_priority_manager.h"
29 
30 #ifdef HDF_DRIVERS_INTERFACE_LIGHT
31 #include "v1_0/light_interface_proxy.h"
32 #endif // HDF_DRIVERS_INTERFACE_LIGHT
33 
34 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
35 #include "permission_util.h"
36 #include "vibrator_decoder_creator.h"
37 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
38 
39 #undef LOG_TAG
40 #define LOG_TAG "MiscdeviceService"
41 
42 namespace OHOS {
43 namespace Sensors {
44 using namespace OHOS::HiviewDFX;
45 namespace {
46 auto g_miscdeviceService = MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance();
47 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_miscdeviceService.GetRefPtr());
48 const std::string VIBRATE_PERMISSION = "ohos.permission.VIBRATE";
49 const std::string LIGHT_PERMISSION = "ohos.permission.SYSTEM_LIGHT_CONTROL";
50 constexpr int32_t MAX_LIGHT_COUNT = 0XFF;
51 constexpr int32_t MIN_VIBRATOR_TIME = 0;
52 constexpr int32_t MAX_VIBRATOR_TIME = 1800000;
53 constexpr int32_t MIN_VIBRATOR_COUNT = 1;
54 constexpr int32_t MAX_VIBRATOR_COUNT = 1000;
55 constexpr int32_t INTENSITY_MIN = 0;
56 constexpr int32_t INTENSITY_MAX = 100;
57 constexpr int32_t FREQUENCY_MIN = 0;
58 constexpr int32_t FREQUENCY_MAX = 100;
59 constexpr int32_t INTENSITY_ADJUST_MIN = 0;
60 constexpr int32_t INTENSITY_ADJUST_MAX = 100;
61 constexpr int32_t FREQUENCY_ADJUST_MIN = -100;
62 constexpr int32_t FREQUENCY_ADJUST_MAX = 100;
63 constexpr int32_t INVALID_PID = -1;
64 constexpr int32_t VIBRATOR_ID = 0;
65 constexpr int32_t BASE_YEAR = 1900;
66 constexpr int32_t BASE_MON = 1;
67 constexpr int32_t CONVERSION_RATE = 1000;
68 VibratorCapacity g_capacity;
69 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
70 const std::string PHONE_TYPE = "phone";
71 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
72 }  // namespace
73 
74 bool MiscdeviceService::isVibrationPriorityReady_ = false;
75 
MiscdeviceService()76 MiscdeviceService::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 
~MiscdeviceService()86 MiscdeviceService::~MiscdeviceService()
87 {
88     StopVibrateThread();
89 }
90 
OnDump()91 void MiscdeviceService::OnDump()
92 {
93     MISC_HILOGI("Ondump is invoked");
94 }
95 
SubscribeCommonEvent(const std::string & eventName,EventReceiver receiver)96 int32_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 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)114 void 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 
OnReceiveEvent(const EventFwk::CommonEventData & data)154 void 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 
OnStart()174 void 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 
OnStartFuzz()209 void 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 
InitInterface()236 bool 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 
InitLightInterface()249 bool 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 
IsValid(int32_t lightId)259 bool MiscdeviceService::IsValid(int32_t lightId)
260 {
261     CALL_LOG_ENTER;
262     std::lock_guard<std::mutex> lightInfosLock(lightInfosMutex_);
263     for (const auto &item : lightInfos_) {
264         if (lightId == item.GetLightId()) {
265             return true;
266         }
267     }
268     return false;
269 }
270 
IsLightAnimationValid(const LightAnimationIPC & animation)271 bool MiscdeviceService::IsLightAnimationValid(const LightAnimationIPC &animation)
272 {
273     CALL_LOG_ENTER;
274     int32_t mode = animation.GetMode();
275     int32_t onTime = animation.GetOnTime();
276     int32_t offTime = animation.GetOffTime();
277     if ((mode < 0) || (mode >= LIGHT_MODE_BUTT)) {
278         MISC_HILOGE("animation mode is invalid, mode:%{public}d", mode);
279         return false;
280     }
281     if ((onTime < 0) || (offTime < 0)) {
282         MISC_HILOGE("animation onTime or offTime is invalid, onTime:%{public}d, offTime:%{public}d",
283             onTime,  offTime);
284         return false;
285     }
286     return true;
287 }
288 
OnStop()289 void MiscdeviceService::OnStop()
290 {
291     CALL_LOG_ENTER;
292     if (state_ == MiscdeviceServiceState::STATE_STOPPED) {
293         MISC_HILOGW("MiscdeviceService stopped already");
294         return;
295     }
296     state_ = MiscdeviceServiceState::STATE_STOPPED;
297     int32_t ret = vibratorHdiConnection_.DestroyHdiConnection();
298     if (ret != ERR_OK) {
299         MISC_HILOGE("Destroy hdi connection fail");
300     }
301 #ifdef MEMMGR_ENABLE
302     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), PROCESS_TYPE_SA, PROCESS_STATUS_DIED,
303         MISCDEVICE_SERVICE_ABILITY_ID);
304 #endif // MEMMGR_ENABLE
305 }
306 
ShouldIgnoreVibrate(const VibrateInfo & info)307 bool MiscdeviceService::ShouldIgnoreVibrate(const VibrateInfo &info)
308 {
309     std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_);
310     if (!isVibrationPriorityReady_) {
311         MISC_HILOGE("Vibraion priority manager not ready");
312         return VIBRATION;
313     }
314     std::string curVibrateTime = GetCurrentTime();
315     int32_t ret = PriorityManager->ShouldIgnoreVibrate(info, vibratorThread_);
316     if (ret != VIBRATION) {
317         MISC_HILOGE("ShouldIgnoreVibrate currentTime:%{public}s, ret:%{public}d", curVibrateTime.c_str(), ret);
318     }
319     return (ret != VIBRATION);
320 }
321 
Vibrate(int32_t vibratorId,int32_t timeOut,int32_t usage,bool systemUsage)322 int32_t MiscdeviceService::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage, bool systemUsage)
323 {
324     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
325     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
326     if (ret != PERMISSION_GRANTED) {
327 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
328         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
329             HiSysEvent::EventType::SECURITY, "PKG_NAME", "VibrateStub", "ERROR_CODE", ret);
330 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
331         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
332         return PERMISSION_DENIED;
333     }
334     if ((timeOut <= MIN_VIBRATOR_TIME) || (timeOut > MAX_VIBRATOR_TIME)
335         || (usage >= USAGE_MAX) || (usage < 0)) {
336         MISC_HILOGE("Invalid parameter");
337         return PARAMETER_ERROR;
338     }
339     VibrateInfo info = {
340         .mode = VIBRATE_TIME,
341         .packageName = GetPackageName(GetCallingTokenID()),
342         .pid = GetCallingPid(),
343         .uid = GetCallingUid(),
344         .usage = usage,
345         .systemUsage = systemUsage,
346         .duration = timeOut
347     };
348     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
349     std::string curVibrateTime = GetCurrentTime();
350     if (ShouldIgnoreVibrate(info)) {
351         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
352         return ERROR;
353     }
354     StartVibrateThread(info);
355     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
356         "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid,
357         info.usage, vibratorId, info.duration);
358     return NO_ERROR;
359 }
360 
StopVibrator(int32_t vibratorId)361 int32_t MiscdeviceService::StopVibrator(int32_t vibratorId)
362 {
363     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
364     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
365     if (ret != PERMISSION_GRANTED) {
366 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
367         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
368             HiSysEvent::EventType::SECURITY, "PKG_NAME", "StopVibratorStub", "ERROR_CODE", ret);
369 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
370         MISC_HILOGE("Result:%{public}d", ret);
371         return PERMISSION_DENIED;
372     }
373     return StopVibratorService(vibratorId);
374 }
375 
StopVibratorService(int32_t vibratorId)376 int32_t MiscdeviceService::StopVibratorService(int32_t vibratorId)
377 {
378     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
379 #if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR)
380     if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() &&
381         !vibratorHdiConnection_.IsVibratorRunning())) {
382         MISC_HILOGD("No vibration, no need to stop");
383         return ERROR;
384     }
385     if (vibratorHdiConnection_.IsVibratorRunning()) {
386         vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
387         vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC);
388     }
389 #else
390     if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
391         MISC_HILOGD("No vibration, no need to stop");
392         return ERROR;
393     }
394 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR
395     StopVibrateThread();
396     std::string packageName = GetPackageName(GetCallingTokenID());
397     std::string curVibrateTime = GetCurrentTime();
398     MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d",
399         curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId);
400     return NO_ERROR;
401 }
402 
PlayVibratorEffect(int32_t vibratorId,const std::string & effect,int32_t count,int32_t usage,bool systemUsage)403 int32_t MiscdeviceService::PlayVibratorEffect(int32_t vibratorId, const std::string &effect,
404     int32_t count, int32_t usage, bool systemUsage)
405 {
406     int32_t checkResult = PlayVibratorEffectCheckAuthAndParam(count, usage);
407     if (checkResult != ERR_OK) {
408         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
409         return checkResult;
410     }
411 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
412     std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
413     if (!effectInfo) {
414         MISC_HILOGE("GetEffectInfo fail");
415         return ERROR;
416     }
417     if (!(effectInfo->isSupportEffect)) {
418         MISC_HILOGE("Effect not supported");
419         return PARAMETER_ERROR;
420     }
421 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
422     VibrateInfo info = {
423         .mode = VIBRATE_PRESET,
424         .packageName = GetPackageName(GetCallingTokenID()),
425         .pid = GetCallingPid(),
426         .uid = GetCallingUid(),
427         .usage = usage,
428         .systemUsage = systemUsage,
429 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
430         .duration = effectInfo->duration,
431 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
432         .effect = effect,
433         .count = count,
434         .intensity = INTENSITY_ADJUST_MAX
435     };
436     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
437     std::string curVibrateTime = GetCurrentTime();
438     if (ShouldIgnoreVibrate(info)) {
439         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
440         return ERROR;
441     }
442     StartVibrateThread(info);
443     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
444         "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s, count:%{public}d", curVibrateTime.c_str(),
445         info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str(), info.count);
446     return NO_ERROR;
447 }
448 
PlayVibratorEffectCheckAuthAndParam(int32_t count,int32_t usage)449 int32_t MiscdeviceService::PlayVibratorEffectCheckAuthAndParam(int32_t count, int32_t usage)
450 {
451     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
452     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
453     if (ret != PERMISSION_GRANTED) {
454 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
455         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
456             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayVibratorEffectStub", "ERROR_CODE", ret);
457 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
458         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
459         return PERMISSION_DENIED;
460     }
461     if ((count < MIN_VIBRATOR_COUNT) || (count > MAX_VIBRATOR_COUNT) || (usage >= USAGE_MAX) || (usage < 0)) {
462         MISC_HILOGE("Invalid parameter");
463         return PARAMETER_ERROR;
464     }
465     return ERR_OK;
466 }
467 
StartVibrateThread(VibrateInfo info)468 void MiscdeviceService::StartVibrateThread(VibrateInfo info)
469 {
470     if (vibratorThread_ == nullptr) {
471         vibratorThread_ = std::make_shared<VibratorThread>();
472     }
473     StopVibrateThread();
474 #if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR)
475     if (vibratorHdiConnection_.IsVibratorRunning()) {
476         vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
477         vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC);
478     }
479 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR
480     vibratorThread_->UpdateVibratorEffect(info);
481     vibratorThread_->Start("VibratorThread");
482     DumpHelper->SaveVibrateRecord(info);
483 }
484 
StopVibrateThread()485 void MiscdeviceService::StopVibrateThread()
486 {
487     if ((vibratorThread_ != nullptr) && (vibratorThread_->IsRunning())) {
488         vibratorThread_->SetExitStatus(true);
489         vibratorThread_->WakeUp();
490         vibratorThread_->NotifyExitSync();
491         vibratorThread_->SetExitStatus(false);
492     }
493 }
494 
StopVibratorByMode(int32_t vibratorId,const std::string & mode)495 int32_t MiscdeviceService::StopVibratorByMode(int32_t vibratorId, const std::string &mode)
496 {
497     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
498     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
499     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
500     if (ret != PERMISSION_GRANTED) {
501 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
502         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
503             HiSysEvent::EventType::SECURITY, "PKG_NAME", "StopVibratorByModeStub", "ERROR_CODE", ret);
504 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
505         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
506         return PERMISSION_DENIED;
507     }
508     if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
509         MISC_HILOGD("No vibration, no need to stop");
510         return ERROR;
511     }
512     const VibrateInfo info = vibratorThread_->GetCurrentVibrateInfo();
513     if (info.mode != mode) {
514         MISC_HILOGD("Stop vibration information mismatch");
515         return ERROR;
516     }
517     StopVibrateThread();
518     std::string packageName = GetPackageName(GetCallingTokenID());
519     std::string curVibrateTime = GetCurrentTime();
520     MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d,"
521         "mode:%{public}s", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId, mode.c_str());
522     return NO_ERROR;
523 }
524 
IsSupportEffect(const std::string & effect,bool & state)525 int32_t MiscdeviceService::IsSupportEffect(const std::string &effect, bool &state)
526 {
527 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
528     std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
529     if (!effectInfo) {
530         MISC_HILOGE("GetEffectInfo fail");
531         return ERROR;
532     }
533     state = effectInfo->isSupportEffect;
534     std::string packageName = GetPackageName(GetCallingTokenID());
535     std::string curVibrateTime = GetCurrentTime();
536     MISC_HILOGI("IsSupportEffect, currentTime:%{public}s, package:%{public}s, pid:%{public}d, effect:%{public}s,"
537         "state:%{public}d", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), effect.c_str(), state);
538 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
539     return NO_ERROR;
540 }
541 
GetCurrentTime()542 std::string MiscdeviceService::GetCurrentTime()
543 {
544     timespec curTime;
545     clock_gettime(CLOCK_REALTIME, &curTime);
546     struct tm *timeinfo = localtime(&(curTime.tv_sec));
547     std::string currentTime;
548     if (timeinfo == nullptr) {
549         MISC_HILOGE("timeinfo is null");
550         return currentTime;
551     }
552     currentTime.append(std::to_string(timeinfo->tm_year + BASE_YEAR)).append("-")
553         .append(std::to_string(timeinfo->tm_mon + BASE_MON)).append("-").append(std::to_string(timeinfo->tm_mday))
554         .append(" ").append(std::to_string(timeinfo->tm_hour)).append(":").append(std::to_string(timeinfo->tm_min))
555         .append(":").append(std::to_string(timeinfo->tm_sec)).append(".")
556         .append(std::to_string(curTime.tv_nsec / (CONVERSION_RATE * CONVERSION_RATE)));
557     return currentTime;
558 }
559 
560 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId,int32_t fd,int64_t offset,int64_t length,int32_t usage,bool systemUsage,const VibrateParameter & parameter)561 int32_t MiscdeviceService::PlayVibratorCustom(int32_t vibratorId, int32_t fd, int64_t offset, int64_t length,
562     int32_t usage, bool systemUsage, const VibrateParameter &parameter)
563 {
564     int32_t checkResult = CheckAuthAndParam(usage, parameter);
565     if (checkResult != ERR_OK) {
566         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
567         return checkResult;
568     }
569     RawFileDescriptor rawFd;
570     rawFd.fd = fd;
571     rawFd.offset = offset;
572     rawFd.length = length;
573     JsonParser parser(rawFd);
574     VibratorDecoderCreator creator;
575     std::unique_ptr<IVibratorDecoder> decoder(creator.CreateDecoder(parser));
576     CHKPR(decoder, ERROR);
577     VibratePackage package;
578     int32_t ret = decoder->DecodeEffect(rawFd, parser, package);
579     if (ret != SUCCESS || package.patterns.empty()) {
580         MISC_HILOGE("Decode effect error");
581         return ERROR;
582     }
583     MergeVibratorParmeters(parameter, package);
584     package.Dump();
585     VibrateInfo info = {
586         .packageName = GetPackageName(GetCallingTokenID()),
587         .pid = GetCallingPid(),
588         .uid = GetCallingUid(),
589         .usage = usage,
590         .systemUsage = systemUsage,
591         .package = package,
592     };
593     if (g_capacity.isSupportHdHaptic) {
594         info.mode = VIBRATE_CUSTOM_HD;
595     } else if (g_capacity.isSupportPresetMapping) {
596         info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
597     } else if (g_capacity.isSupportTimeDelay) {
598         info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
599     }
600     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
601     std::string curVibrateTime = GetCurrentTime();
602     if (ShouldIgnoreVibrate(info)) {
603         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
604         return ERROR;
605     }
606     StartVibrateThread(info);
607     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
608         "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid,
609         info.usage, vibratorId, package.packageDuration);
610     return NO_ERROR;
611 }
612 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
613 
CheckAuthAndParam(int32_t usage,const VibrateParameter & parameter)614 int32_t MiscdeviceService::CheckAuthAndParam(int32_t usage, const VibrateParameter &parameter)
615 {
616     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
617     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
618     if (ret != PERMISSION_GRANTED) {
619 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
620         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
621             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayVibratorCustomStub", "ERROR_CODE", ret);
622 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
623         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
624         return PERMISSION_DENIED;
625     }
626     if (!(g_capacity.isSupportHdHaptic || g_capacity.isSupportPresetMapping || g_capacity.isSupportTimeDelay)) {
627         MISC_HILOGE("The device does not support this operation");
628         return IS_NOT_SUPPORTED;
629     }
630     if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
631         MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
632         return PARAMETER_ERROR;
633     }
634     return ERR_OK;
635 }
636 
GetPackageName(AccessTokenID tokenId)637 std::string MiscdeviceService::GetPackageName(AccessTokenID tokenId)
638 {
639     std::string packageName;
640     int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
641     switch (tokenType) {
642         case ATokenTypeEnum::TOKEN_HAP: {
643             HapTokenInfo hapInfo;
644             if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
645                 MISC_HILOGE("Get hap token info fail");
646                 return {};
647             }
648             packageName = hapInfo.bundleName;
649             break;
650         }
651         case ATokenTypeEnum::TOKEN_NATIVE:
652         case ATokenTypeEnum::TOKEN_SHELL: {
653             NativeTokenInfo tokenInfo;
654             if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
655                 MISC_HILOGE("Get native token info fail");
656                 return {};
657             }
658             packageName = tokenInfo.processName;
659             break;
660         }
661         default: {
662             MISC_HILOGW("Token type not match");
663             break;
664         }
665     }
666     return packageName;
667 }
668 
GetLightList(std::vector<LightInfoIPC> & lightInfoIpcList)669 int32_t MiscdeviceService::GetLightList(std::vector<LightInfoIPC> &lightInfoIpcList)
670 {
671     std::lock_guard<std::mutex> lightInfosLock(lightInfosMutex_);
672     std::string packageName = GetPackageName(GetCallingTokenID());
673     MISC_HILOGI("GetLightList, package:%{public}s", packageName.c_str());
674     int32_t ret = lightHdiConnection_.GetLightList(lightInfos_);
675     if (ret != ERR_OK) {
676         MISC_HILOGE("GetLightList failed, ret:%{public}d", ret);
677     }
678     size_t lightCount = lightInfos_.size();
679     MISC_HILOGI("lightCount:%{public}zu", lightCount);
680     if (lightCount > MAX_LIGHT_COUNT) {
681         lightCount = MAX_LIGHT_COUNT;
682     }
683     for (size_t i = 0; i < lightCount; ++i) {
684         lightInfoIpcList.push_back(lightInfos_[i]);
685     }
686     return ERR_OK;
687 }
688 
TurnOn(int32_t lightId,int32_t singleColor,const LightAnimationIPC & animation)689 int32_t MiscdeviceService::TurnOn(int32_t lightId, int32_t singleColor, const LightAnimationIPC &animation)
690 {
691     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
692     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), LIGHT_PERMISSION);
693     if (ret != PERMISSION_GRANTED) {
694 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
695         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "LIGHT_PERMISSIONS_EXCEPTION", HiSysEvent::EventType::SECURITY,
696             "PKG_NAME", "turnOnStub", "ERROR_CODE", ret);
697 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
698         MISC_HILOGE("CheckLightPermission failed, ret:%{public}d", ret);
699         return PERMISSION_DENIED;
700     }
701     LightColor color;
702     color.singleColor = singleColor;
703     std::string packageName = GetPackageName(GetCallingTokenID());
704     MISC_HILOGI("TurnOn, package:%{public}s", packageName.c_str());
705     if (!IsValid(lightId)) {
706         MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
707         return MISCDEVICE_NATIVE_SAM_ERR;
708     }
709     if (!IsLightAnimationValid(animation)) {
710         MISC_HILOGE("animation is invalid");
711         return MISCDEVICE_NATIVE_SAM_ERR;
712     }
713     ret = lightHdiConnection_.TurnOn(lightId, color, animation);
714     if (ret != ERR_OK) {
715         MISC_HILOGE("TurnOn failed, error:%{public}d", ret);
716         return ERROR;
717     }
718     return ret;
719 }
720 
TurnOff(int32_t lightId)721 int32_t MiscdeviceService::TurnOff(int32_t lightId)
722 {
723     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
724     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), LIGHT_PERMISSION);
725     if (ret != PERMISSION_GRANTED) {
726 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
727         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "LIGHT_PERMISSIONS_EXCEPTION", HiSysEvent::EventType::SECURITY,
728             "PKG_NAME", "TurnOffStub", "ERROR_CODE", ret);
729 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
730         MISC_HILOGE("CheckLightPermission failed, ret:%{public}d", ret);
731         return PERMISSION_DENIED;
732     }
733     std::string packageName = GetPackageName(GetCallingTokenID());
734     MISC_HILOGI("TurnOff, package:%{public}s", packageName.c_str());
735     if (!IsValid(lightId)) {
736         MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
737         return MISCDEVICE_NATIVE_SAM_ERR;
738     }
739     ret = lightHdiConnection_.TurnOff(lightId);
740     if (ret != ERR_OK) {
741         MISC_HILOGE("TurnOff failed, error:%{public}d", ret);
742         return ERROR;
743     }
744     return ret;
745 }
746 
Dump(int32_t fd,const std::vector<std::u16string> & args)747 int32_t MiscdeviceService::Dump(int32_t fd, const std::vector<std::u16string> &args)
748 {
749     CALL_LOG_ENTER;
750     if (fd < 0) {
751         MISC_HILOGE("Invalid fd");
752         return DUMP_PARAM_ERR;
753     }
754     if (args.empty()) {
755         MISC_HILOGE("args cannot be empty");
756         dprintf(fd, "args cannot be empty\n");
757         DumpHelper->DumpHelp(fd);
758         return DUMP_PARAM_ERR;
759     }
760     std::vector<std::string> argList = { "" };
761     std::transform(args.begin(), args.end(), std::back_inserter(argList),
762         [](const std::u16string &arg) {
763         return Str16ToStr8(arg);
764     });
765     DumpHelper->ParseCommand(fd, argList);
766     return ERR_OK;
767 }
768 
PlayPattern(const VibratePattern & pattern,int32_t usage,bool systemUsage,const VibrateParameter & parameter)769 int32_t MiscdeviceService::PlayPattern(const VibratePattern &pattern, int32_t usage,
770     bool systemUsage, const VibrateParameter &parameter)
771 {
772     int32_t checkResult = PlayPatternCheckAuthAndParam(usage, parameter);
773     if (checkResult != ERR_OK) {
774         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
775         return checkResult;
776     }
777     VibratePattern vibratePattern;
778     vibratePattern.startTime = 0;
779     vibratePattern.events = pattern.events;
780     std::vector<VibratePattern> patterns = {vibratePattern};
781     VibratePackage package = {
782         .patterns = patterns
783     };
784     MergeVibratorParmeters(parameter, package);
785     package.Dump();
786     VibrateInfo info = {
787         .mode = VIBRATE_BUTT,
788         .packageName = GetPackageName(GetCallingTokenID()),
789         .pid = GetCallingPid(),
790         .uid = GetCallingUid(),
791         .usage = usage,
792         .systemUsage = systemUsage
793     };
794     if (g_capacity.isSupportHdHaptic) {
795         std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
796         std::string curVibrateTime = GetCurrentTime();
797         if (ShouldIgnoreVibrate(info)) {
798             MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
799             return ERROR;
800         }
801         StartVibrateThread(info);
802         return vibratorHdiConnection_.PlayPattern(package.patterns.front());
803     } else if (g_capacity.isSupportPresetMapping) {
804         info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
805     } else if (g_capacity.isSupportTimeDelay) {
806         info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
807     }
808     info.package = package;
809     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
810     std::string curVibrateTime = GetCurrentTime();
811     if (ShouldIgnoreVibrate(info)) {
812         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
813         return ERROR;
814     }
815     StartVibrateThread(info);
816     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
817         "duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage,
818         pattern.patternDuration);
819     return ERR_OK;
820 }
821 
PlayPatternCheckAuthAndParam(int32_t usage,const VibrateParameter & parameter)822 int32_t MiscdeviceService::PlayPatternCheckAuthAndParam(int32_t usage, const VibrateParameter &parameter)
823 {
824     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
825     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
826     if (ret != PERMISSION_GRANTED) {
827 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
828         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
829             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayPatternStub", "ERROR_CODE", ret);
830 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
831         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
832         return PERMISSION_DENIED;
833     }
834     if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
835         MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
836         return PARAMETER_ERROR;
837     }
838     return ERR_OK;
839 }
840 
GetDelayTime(int32_t & delayTime)841 int32_t MiscdeviceService::GetDelayTime(int32_t &delayTime)
842 {
843     std::string packageName = GetPackageName(GetCallingTokenID());
844     MISC_HILOGD("GetDelayTime, package:%{public}s", packageName.c_str());
845     return vibratorHdiConnection_.GetDelayTime(g_capacity.GetVibrateMode(), delayTime);
846 }
847 
CheckVibratorParmeters(const VibrateParameter & parameter)848 bool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter &parameter)
849 {
850     if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) ||
851         (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) {
852         MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d",
853             parameter.intensity, parameter.frequency);
854         return false;
855     }
856     return true;
857 }
858 
MergeVibratorParmeters(const VibrateParameter & parameter,VibratePackage & package)859 void MiscdeviceService::MergeVibratorParmeters(const VibrateParameter &parameter, VibratePackage &package)
860 {
861     if ((parameter.intensity == INTENSITY_ADJUST_MAX) && (parameter.frequency == 0)) {
862         MISC_HILOGD("The adjust parameter is not need to merge");
863         return;
864     }
865     parameter.Dump();
866     for (VibratePattern &pattern : package.patterns) {
867         for (VibrateEvent &event : pattern.events) {
868             float intensityScale = static_cast<float>(parameter.intensity) / INTENSITY_ADJUST_MAX;
869             if ((event.tag == EVENT_TAG_TRANSIENT) || (event.points.empty())) {
870                 event.intensity = static_cast<int32_t>(event.intensity * intensityScale);
871                 event.intensity = std::max(std::min(event.intensity, INTENSITY_MAX), INTENSITY_MIN);
872                 event.frequency = event.frequency + parameter.frequency;
873                 event.frequency = std::max(std::min(event.frequency, FREQUENCY_MAX), FREQUENCY_MIN);
874             } else {
875                 for (VibrateCurvePoint &point : event.points) {
876                     point.intensity = static_cast<int32_t>(point.intensity * intensityScale);
877                     point.intensity = std::max(std::min(point.intensity, INTENSITY_ADJUST_MAX), INTENSITY_ADJUST_MIN);
878                     point.frequency = point.frequency + parameter.frequency;
879                     point.frequency = std::max(std::min(point.frequency, FREQUENCY_ADJUST_MAX), FREQUENCY_ADJUST_MIN);
880                 }
881             }
882         }
883     }
884 }
885 
TransferClientRemoteObject(const sptr<IRemoteObject> & vibratorServiceClient)886 int32_t MiscdeviceService::TransferClientRemoteObject(const sptr<IRemoteObject> &vibratorServiceClient)
887 {
888     auto clientPid = GetCallingPid();
889     if (clientPid < 0) {
890         MISC_HILOGE("ClientPid is invalid, clientPid:%{public}d", clientPid);
891         return ERROR;
892     }
893     RegisterClientDeathRecipient(vibratorServiceClient, clientPid);
894     return ERR_OK;
895 }
896 
ProcessDeathObserver(const wptr<IRemoteObject> & object)897 void MiscdeviceService::ProcessDeathObserver(const wptr<IRemoteObject> &object)
898 {
899     CALL_LOG_ENTER;
900     sptr<IRemoteObject> client = object.promote();
901     int32_t clientPid = FindClientPid(client);
902     VibrateInfo info;
903     {
904         std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
905         if (vibratorThread_ == nullptr) {
906             vibratorThread_ = std::make_shared<VibratorThread>();
907         }
908         info = vibratorThread_->GetCurrentVibrateInfo();
909     }
910     int32_t vibratePid = info.pid;
911     MISC_HILOGI("ClientPid:%{public}d, VibratePid:%{public}d", clientPid, vibratePid);
912     if ((clientPid != INVALID_PID) && (clientPid == vibratePid)) {
913         StopVibratorService(VIBRATOR_ID);
914     }
915     UnregisterClientDeathRecipient(client);
916 }
917 
RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient,int32_t pid)918 void  MiscdeviceService::RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient, int32_t pid)
919 {
920     if (vibratorServiceClient == nullptr) {
921         MISC_HILOGE("VibratorServiceClient is nullptr");
922         return;
923     }
924     std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
925     if (clientDeathObserver_ == nullptr) {
926         clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MiscdeviceService *>(this));
927         if (clientDeathObserver_ == nullptr) {
928             MISC_HILOGE("ClientDeathObserver_ is nullptr");
929             return;
930         }
931     }
932     vibratorServiceClient->AddDeathRecipient(clientDeathObserver_);
933     SaveClientPid(vibratorServiceClient, pid);
934 }
935 
UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)936 void MiscdeviceService::UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)
937 {
938     if (vibratorServiceClient == nullptr) {
939         MISC_HILOGE("vibratorServiceClient is nullptr");
940         return;
941     }
942     int32_t clientPid = FindClientPid(vibratorServiceClient);
943     if (clientPid == INVALID_PID) {
944         MISC_HILOGE("Pid is invalid");
945         return;
946     }
947     std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
948     vibratorServiceClient->RemoveDeathRecipient(clientDeathObserver_);
949     DestroyClientPid(vibratorServiceClient);
950 }
951 
SaveClientPid(const sptr<IRemoteObject> & vibratorServiceClient,int32_t pid)952 void MiscdeviceService::SaveClientPid(const sptr<IRemoteObject> &vibratorServiceClient, int32_t pid)
953 {
954     if (vibratorServiceClient == nullptr) {
955         MISC_HILOGE("VibratorServiceClient is nullptr");
956         return;
957     }
958     std::lock_guard<std::mutex> lock(clientPidMapMutex_);
959     clientPidMap_.insert(std::make_pair(vibratorServiceClient, pid));
960 }
961 
FindClientPid(const sptr<IRemoteObject> & vibratorServiceClient)962 int32_t MiscdeviceService::FindClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
963 {
964     if (vibratorServiceClient == nullptr) {
965         MISC_HILOGE("VibratorServiceClient is nullptr");
966         return INVALID_PID;
967     }
968     std::lock_guard<std::mutex> lock(clientPidMapMutex_);
969     auto it = clientPidMap_.find(vibratorServiceClient);
970     if (it == clientPidMap_.end()) {
971         MISC_HILOGE("Cannot find client pid");
972         return INVALID_PID;
973     }
974     return it->second;
975 }
976 
DestroyClientPid(const sptr<IRemoteObject> & vibratorServiceClient)977 void MiscdeviceService::DestroyClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
978 {
979     if (vibratorServiceClient == nullptr) {
980         MISC_HILOGD("VibratorServiceClient is nullptr");
981         return;
982     }
983     std::lock_guard<std::mutex> lock(clientPidMapMutex_);
984     auto it = clientPidMap_.find(vibratorServiceClient);
985     if (it == clientPidMap_.end()) {
986         MISC_HILOGE("Cannot find client pid");
987         return;
988     }
989     clientPidMap_.erase(it);
990 }
991 
PlayPrimitiveEffect(int32_t vibratorId,const std::string & effect,int32_t intensity,int32_t usage,bool systemUsage,int32_t count)992 int32_t MiscdeviceService::PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect,
993     int32_t intensity, int32_t usage, bool systemUsage, int32_t count)
994 {
995     int32_t checkResult = PlayPrimitiveEffectCheckAuthAndParam(intensity, usage);
996     if (checkResult != ERR_OK) {
997         MISC_HILOGE("CheckAuthAndParam failed, ret:%{public}d", checkResult);
998         return checkResult;
999     }
1000 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
1001     std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
1002     if (!effectInfo) {
1003         MISC_HILOGE("GetEffectInfo fail");
1004         return ERROR;
1005     }
1006     if (!(effectInfo->isSupportEffect)) {
1007         MISC_HILOGE("Effect not supported");
1008         return PARAMETER_ERROR;
1009     }
1010 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
1011     VibrateInfo info = {
1012         .mode = VIBRATE_PRESET,
1013         .packageName = GetPackageName(GetCallingTokenID()),
1014         .pid = GetCallingPid(),
1015         .uid = GetCallingUid(),
1016         .usage = usage,
1017         .systemUsage = systemUsage,
1018 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
1019         .duration = effectInfo->duration,
1020 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
1021         .effect = effect,
1022         .count = count,
1023         .intensity = intensity
1024     };
1025     std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
1026     std::string curVibrateTime = GetCurrentTime();
1027     if (ShouldIgnoreVibrate(info)) {
1028         MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
1029         return ERROR;
1030     }
1031     StartVibrateThread(info);
1032     MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
1033         "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s", curVibrateTime.c_str(),
1034         info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str());
1035     return NO_ERROR;
1036 }
1037 
PlayPrimitiveEffectCheckAuthAndParam(int32_t intensity,int32_t usage)1038 int32_t MiscdeviceService::PlayPrimitiveEffectCheckAuthAndParam(int32_t intensity, int32_t usage)
1039 {
1040     PermissionUtil &permissionUtil = PermissionUtil::GetInstance();
1041     int32_t ret = permissionUtil.CheckVibratePermission(this->GetCallingTokenID(), VIBRATE_PERMISSION);
1042     if (ret != PERMISSION_GRANTED) {
1043 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
1044         HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "VIBRATOR_PERMISSIONS_EXCEPTION",
1045             HiSysEvent::EventType::SECURITY, "PKG_NAME", "PlayPrimitiveEffectStub", "ERROR_CODE", ret);
1046 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
1047         MISC_HILOGE("CheckVibratePermission failed, ret:%{public}d", ret);
1048         return PERMISSION_DENIED;
1049     }
1050     if ((intensity <= INTENSITY_MIN) || (intensity > INTENSITY_MAX) || (usage >= USAGE_MAX) || (usage < 0)) {
1051         MISC_HILOGE("Invalid parameter");
1052         return PARAMETER_ERROR;
1053     }
1054     return ERR_OK;
1055 }
1056 
GetVibratorCapacity(VibratorCapacity & capacity)1057 int32_t MiscdeviceService::GetVibratorCapacity(VibratorCapacity &capacity)
1058 {
1059     capacity = g_capacity;
1060     return ERR_OK;
1061 }
1062 }  // namespace Sensors
1063 }  // namespace OHOS
1064