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 ¶meter,
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 ¶meter)
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 ¶meter)
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 ¶meter, 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