1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "miscdevice_service.h"
17
18 #include <algorithm>
19 #include <map>
20 #include <string_ex.h>
21
22 #include "death_recipient_template.h"
23 #ifdef MEMMGR_ENABLE
24 #include "iservice_registry.h"
25 #include "mem_mgr_client.h"
26 #endif // MEMMGR_ENABLE
27 #include "system_ability_definition.h"
28
29 #include "sensors_errors.h"
30 #include "vibration_priority_manager.h"
31
32 #ifdef HDF_DRIVERS_INTERFACE_LIGHT
33 #include "v1_0/light_interface_proxy.h"
34 #endif // HDF_DRIVERS_INTERFACE_LIGHT
35
36 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
37 #include "parameters.h"
38 #include "default_vibrator_decoder.h"
39 #include "default_vibrator_decoder_factory.h"
40 #include "vibrator_decoder_creator.h"
41 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
42
43 #undef LOG_TAG
44 #define LOG_TAG "MiscdeviceService"
45
46 namespace OHOS {
47 namespace Sensors {
48 namespace {
49 auto g_miscdeviceService = MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance();
50 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_miscdeviceService.GetRefPtr());
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 for (const auto &item : lightInfos_) {
263 if (lightId == item.GetLightId()) {
264 return true;
265 }
266 }
267 return false;
268 }
269
IsLightAnimationValid(const LightAnimationIPC & animation)270 bool MiscdeviceService::IsLightAnimationValid(const LightAnimationIPC &animation)
271 {
272 CALL_LOG_ENTER;
273 int32_t mode = animation.GetMode();
274 int32_t onTime = animation.GetOnTime();
275 int32_t offTime = animation.GetOffTime();
276 if ((mode < 0) || (mode >= LIGHT_MODE_BUTT)) {
277 MISC_HILOGE("animation mode is invalid, mode:%{public}d", mode);
278 return false;
279 }
280 if ((onTime < 0) || (offTime < 0)) {
281 MISC_HILOGE("animation onTime or offTime is invalid, onTime:%{public}d, offTime:%{public}d",
282 onTime, offTime);
283 return false;
284 }
285 return true;
286 }
287
OnStop()288 void MiscdeviceService::OnStop()
289 {
290 CALL_LOG_ENTER;
291 if (state_ == MiscdeviceServiceState::STATE_STOPPED) {
292 MISC_HILOGW("MiscdeviceService stopped already");
293 return;
294 }
295 state_ = MiscdeviceServiceState::STATE_STOPPED;
296 int32_t ret = vibratorHdiConnection_.DestroyHdiConnection();
297 if (ret != ERR_OK) {
298 MISC_HILOGE("Destroy hdi connection fail");
299 }
300 #ifdef MEMMGR_ENABLE
301 Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), PROCESS_TYPE_SA, PROCESS_STATUS_DIED,
302 MISCDEVICE_SERVICE_ABILITY_ID);
303 #endif // MEMMGR_ENABLE
304 }
305
ShouldIgnoreVibrate(const VibrateInfo & info)306 bool MiscdeviceService::ShouldIgnoreVibrate(const VibrateInfo &info)
307 {
308 std::lock_guard<std::mutex> lock(isVibrationPriorityReadyMutex_);
309 if (!isVibrationPriorityReady_) {
310 MISC_HILOGE("Vibraion priority manager not ready");
311 return VIBRATION;
312 }
313 return (PriorityManager->ShouldIgnoreVibrate(info, vibratorThread_) != VIBRATION);
314 }
315
Vibrate(int32_t vibratorId,int32_t timeOut,int32_t usage,bool systemUsage)316 int32_t MiscdeviceService::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage, bool systemUsage)
317 {
318 if ((timeOut <= MIN_VIBRATOR_TIME) || (timeOut > MAX_VIBRATOR_TIME)
319 || (usage >= USAGE_MAX) || (usage < 0)) {
320 MISC_HILOGE("Invalid parameter");
321 return PARAMETER_ERROR;
322 }
323 VibrateInfo info = {
324 .mode = VIBRATE_TIME,
325 .packageName = GetPackageName(GetCallingTokenID()),
326 .pid = GetCallingPid(),
327 .uid = GetCallingUid(),
328 .usage = usage,
329 .systemUsage = systemUsage,
330 .duration = timeOut
331 };
332 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
333 std::string curVibrateTime = GetCurrentTime();
334 if (ShouldIgnoreVibrate(info)) {
335 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
336 return ERROR;
337 }
338 StartVibrateThread(info);
339 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
340 "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid,
341 info.usage, vibratorId, info.duration);
342 return NO_ERROR;
343 }
344
StopVibrator(int32_t vibratorId)345 int32_t MiscdeviceService::StopVibrator(int32_t vibratorId)
346 {
347 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
348 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
349 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() &&
350 !vibratorHdiConnection_.IsVibratorRunning())) {
351 MISC_HILOGD("No vibration, no need to stop");
352 return ERROR;
353 }
354 if (vibratorHdiConnection_.IsVibratorRunning()) {
355 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
356 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC);
357 }
358 #else
359 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
360 MISC_HILOGD("No vibration, no need to stop");
361 return ERROR;
362 }
363 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
364 StopVibrateThread();
365 std::string packageName = GetPackageName(GetCallingTokenID());
366 std::string curVibrateTime = GetCurrentTime();
367 MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d",
368 curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId);
369 return NO_ERROR;
370 }
371
PlayVibratorEffect(int32_t vibratorId,const std::string & effect,int32_t count,int32_t usage,bool systemUsage)372 int32_t MiscdeviceService::PlayVibratorEffect(int32_t vibratorId, const std::string &effect,
373 int32_t count, int32_t usage, bool systemUsage)
374 {
375 if ((count < MIN_VIBRATOR_COUNT) || (count > MAX_VIBRATOR_COUNT) || (usage >= USAGE_MAX) || (usage < 0)) {
376 MISC_HILOGE("Invalid parameter");
377 return PARAMETER_ERROR;
378 }
379 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
380 if (!effectInfo) {
381 MISC_HILOGE("GetEffectInfo fail");
382 return ERROR;
383 }
384 if (!(effectInfo->isSupportEffect)) {
385 MISC_HILOGE("Effect not supported");
386 return PARAMETER_ERROR;
387 }
388 VibrateInfo info = {
389 .mode = VIBRATE_PRESET,
390 .packageName = GetPackageName(GetCallingTokenID()),
391 .pid = GetCallingPid(),
392 .uid = GetCallingUid(),
393 .usage = usage,
394 .systemUsage = systemUsage,
395 .duration = effectInfo->duration,
396 .effect = effect,
397 .count = count,
398 .intensity = INTENSITY_ADJUST_MAX
399 };
400 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
401 std::string curVibrateTime = GetCurrentTime();
402 if (ShouldIgnoreVibrate(info)) {
403 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
404 return ERROR;
405 }
406 StartVibrateThread(info);
407 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
408 "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s, count:%{public}d", curVibrateTime.c_str(),
409 info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str(), info.count);
410 return NO_ERROR;
411 }
412
StartVibrateThread(VibrateInfo info)413 void MiscdeviceService::StartVibrateThread(VibrateInfo info)
414 {
415 if (vibratorThread_ == nullptr) {
416 vibratorThread_ = std::make_shared<VibratorThread>();
417 }
418 StopVibrateThread();
419 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
420 if (vibratorHdiConnection_.IsVibratorRunning()) {
421 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
422 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC);
423 }
424 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
425 vibratorThread_->UpdateVibratorEffect(info);
426 vibratorThread_->Start("VibratorThread");
427 DumpHelper->SaveVibrateRecord(info);
428 }
429
StopVibrateThread()430 void MiscdeviceService::StopVibrateThread()
431 {
432 if ((vibratorThread_ != nullptr) && (vibratorThread_->IsRunning())) {
433 vibratorThread_->SetExitStatus(true);
434 vibratorThread_->WakeUp();
435 vibratorThread_->NotifyExitSync();
436 vibratorThread_->SetExitStatus(false);
437 }
438 }
439
StopVibrator(int32_t vibratorId,const std::string & mode)440 int32_t MiscdeviceService::StopVibrator(int32_t vibratorId, const std::string &mode)
441 {
442 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
443 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
444 MISC_HILOGD("No vibration, no need to stop");
445 return ERROR;
446 }
447 const VibrateInfo info = vibratorThread_->GetCurrentVibrateInfo();
448 if (info.mode != mode) {
449 MISC_HILOGD("Stop vibration information mismatch");
450 return ERROR;
451 }
452 StopVibrateThread();
453 std::string packageName = GetPackageName(GetCallingTokenID());
454 std::string curVibrateTime = GetCurrentTime();
455 MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d,"
456 "mode:%{public}s", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId, mode.c_str());
457 return NO_ERROR;
458 }
459
IsSupportEffect(const std::string & effect,bool & state)460 int32_t MiscdeviceService::IsSupportEffect(const std::string &effect, bool &state)
461 {
462 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
463 if (!effectInfo) {
464 MISC_HILOGE("GetEffectInfo fail");
465 return ERROR;
466 }
467 state = effectInfo->isSupportEffect;
468 return NO_ERROR;
469 }
470
GetCurrentTime()471 std::string MiscdeviceService::GetCurrentTime()
472 {
473 timespec curTime;
474 clock_gettime(CLOCK_REALTIME, &curTime);
475 struct tm *timeinfo = localtime(&(curTime.tv_sec));
476 std::string currentTime;
477 if (timeinfo == nullptr) {
478 MISC_HILOGE("timeinfo is null");
479 return currentTime;
480 }
481 currentTime.append(std::to_string(timeinfo->tm_year + BASE_YEAR)).append("-")
482 .append(std::to_string(timeinfo->tm_mon + BASE_MON)).append("-").append(std::to_string(timeinfo->tm_mday))
483 .append(" ").append(std::to_string(timeinfo->tm_hour)).append(":").append(std::to_string(timeinfo->tm_min))
484 .append(":").append(std::to_string(timeinfo->tm_sec)).append(".")
485 .append(std::to_string(curTime.tv_nsec / (CONVERSION_RATE * CONVERSION_RATE)));
486 return currentTime;
487 }
488
489 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId,const RawFileDescriptor & rawFd,int32_t usage,bool systemUsage,const VibrateParameter & parameter)490 int32_t MiscdeviceService::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
491 bool systemUsage, const VibrateParameter ¶meter)
492 {
493 if (!(g_capacity.isSupportHdHaptic || g_capacity.isSupportPresetMapping || g_capacity.isSupportTimeDelay)) {
494 MISC_HILOGE("The device does not support this operation");
495 return IS_NOT_SUPPORTED;
496 }
497 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
498 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
499 return PARAMETER_ERROR;
500 }
501 JsonParser parser(rawFd);
502 VibratorDecoderCreator creator;
503 std::unique_ptr<IVibratorDecoder> decoder(creator.CreateDecoder(parser));
504 CHKPR(decoder, ERROR);
505 VibratePackage package;
506 int32_t ret = decoder->DecodeEffect(rawFd, parser, package);
507 if (ret != SUCCESS || package.patterns.empty()) {
508 MISC_HILOGE("Decode effect error");
509 return ERROR;
510 }
511 MergeVibratorParmeters(parameter, package);
512 package.Dump();
513 VibrateInfo info = {
514 .packageName = GetPackageName(GetCallingTokenID()),
515 .pid = GetCallingPid(),
516 .uid = GetCallingUid(),
517 .usage = usage,
518 .systemUsage = systemUsage,
519 .package = package,
520 };
521 if (g_capacity.isSupportHdHaptic) {
522 info.mode = VIBRATE_CUSTOM_HD;
523 } else if (g_capacity.isSupportPresetMapping) {
524 info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
525 } else if (g_capacity.isSupportTimeDelay) {
526 info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
527 }
528 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
529 std::string curVibrateTime = GetCurrentTime();
530 if (ShouldIgnoreVibrate(info)) {
531 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
532 return ERROR;
533 }
534 StartVibrateThread(info);
535 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
536 "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid,
537 info.usage, vibratorId, package.packageDuration);
538 return NO_ERROR;
539 }
540 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
541
GetPackageName(AccessTokenID tokenId)542 std::string MiscdeviceService::GetPackageName(AccessTokenID tokenId)
543 {
544 std::string packageName;
545 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
546 switch (tokenType) {
547 case ATokenTypeEnum::TOKEN_HAP: {
548 HapTokenInfo hapInfo;
549 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
550 MISC_HILOGE("Get hap token info fail");
551 return {};
552 }
553 packageName = hapInfo.bundleName;
554 break;
555 }
556 case ATokenTypeEnum::TOKEN_NATIVE:
557 case ATokenTypeEnum::TOKEN_SHELL: {
558 NativeTokenInfo tokenInfo;
559 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
560 MISC_HILOGE("Get native token info fail");
561 return {};
562 }
563 packageName = tokenInfo.processName;
564 break;
565 }
566 default: {
567 MISC_HILOGW("Token type not match");
568 break;
569 }
570 }
571 return packageName;
572 }
573
GetLightList()574 std::vector<LightInfoIPC> MiscdeviceService::GetLightList()
575 {
576 std::string packageName = GetPackageName(GetCallingTokenID());
577 MISC_HILOGI("GetLightList, package:%{public}s", packageName.c_str());
578 if (!InitLightList()) {
579 MISC_HILOGE("InitLightList init failed");
580 return lightInfos_;
581 }
582 return lightInfos_;
583 }
584
InitLightList()585 bool MiscdeviceService::InitLightList()
586 {
587 int32_t ret = lightHdiConnection_.GetLightList(lightInfos_);
588 if (ret != ERR_OK) {
589 MISC_HILOGE("InitLightList failed, ret:%{public}d", ret);
590 return false;
591 }
592 return true;
593 }
594
TurnOn(int32_t lightId,const LightColor & color,const LightAnimationIPC & animation)595 int32_t MiscdeviceService::TurnOn(int32_t lightId, const LightColor &color, const LightAnimationIPC &animation)
596 {
597 std::string packageName = GetPackageName(GetCallingTokenID());
598 MISC_HILOGI("TurnOn, package:%{public}s", packageName.c_str());
599 if (!IsValid(lightId)) {
600 MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
601 return MISCDEVICE_NATIVE_SAM_ERR;
602 }
603 if (!IsLightAnimationValid(animation)) {
604 MISC_HILOGE("animation is invalid");
605 return MISCDEVICE_NATIVE_SAM_ERR;
606 }
607 int32_t ret = lightHdiConnection_.TurnOn(lightId, color, animation);
608 if (ret != ERR_OK) {
609 MISC_HILOGE("TurnOn failed, error:%{public}d", ret);
610 return ERROR;
611 }
612 return ret;
613 }
614
TurnOff(int32_t lightId)615 int32_t MiscdeviceService::TurnOff(int32_t lightId)
616 {
617 std::string packageName = GetPackageName(GetCallingTokenID());
618 MISC_HILOGI("TurnOff, package:%{public}s", packageName.c_str());
619 if (!IsValid(lightId)) {
620 MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
621 return MISCDEVICE_NATIVE_SAM_ERR;
622 }
623 int32_t ret = lightHdiConnection_.TurnOff(lightId);
624 if (ret != ERR_OK) {
625 MISC_HILOGE("TurnOff failed, error:%{public}d", ret);
626 return ERROR;
627 }
628 return ret;
629 }
630
Dump(int32_t fd,const std::vector<std::u16string> & args)631 int32_t MiscdeviceService::Dump(int32_t fd, const std::vector<std::u16string> &args)
632 {
633 CALL_LOG_ENTER;
634 if (fd < 0) {
635 MISC_HILOGE("Invalid fd");
636 return DUMP_PARAM_ERR;
637 }
638 if (args.empty()) {
639 MISC_HILOGE("args cannot be empty");
640 dprintf(fd, "args cannot be empty\n");
641 DumpHelper->DumpHelp(fd);
642 return DUMP_PARAM_ERR;
643 }
644 std::vector<std::string> argList = { "" };
645 std::transform(args.begin(), args.end(), std::back_inserter(argList),
646 [](const std::u16string &arg) {
647 return Str16ToStr8(arg);
648 });
649 DumpHelper->ParseCommand(fd, argList);
650 return ERR_OK;
651 }
652
PlayPattern(const VibratePattern & pattern,int32_t usage,bool systemUsage,const VibrateParameter & parameter)653 int32_t MiscdeviceService::PlayPattern(const VibratePattern &pattern, int32_t usage,
654 bool systemUsage, const VibrateParameter ¶meter)
655 {
656 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
657 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
658 return PARAMETER_ERROR;
659 }
660 VibratePattern vibratePattern = {
661 .startTime = 0,
662 .events = pattern.events
663 };
664 std::vector<VibratePattern> patterns = {vibratePattern};
665 VibratePackage package = {
666 .patterns = patterns
667 };
668 MergeVibratorParmeters(parameter, package);
669 package.Dump();
670 VibrateInfo info = {
671 .mode = VIBRATE_BUTT,
672 .packageName = GetPackageName(GetCallingTokenID()),
673 .pid = GetCallingPid(),
674 .uid = GetCallingUid(),
675 .usage = usage,
676 .systemUsage = systemUsage
677 };
678 if (g_capacity.isSupportHdHaptic) {
679 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
680 std::string curVibrateTime = GetCurrentTime();
681 if (ShouldIgnoreVibrate(info)) {
682 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
683 return ERROR;
684 }
685 StartVibrateThread(info);
686 return vibratorHdiConnection_.PlayPattern(package.patterns.front());
687 } else if (g_capacity.isSupportPresetMapping) {
688 info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
689 } else if (g_capacity.isSupportTimeDelay) {
690 info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
691 }
692 info.package = package;
693 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
694 std::string curVibrateTime = GetCurrentTime();
695 if (ShouldIgnoreVibrate(info)) {
696 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
697 return ERROR;
698 }
699 StartVibrateThread(info);
700 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
701 "duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage,
702 pattern.patternDuration);
703 return ERR_OK;
704 }
705
GetDelayTime(int32_t & delayTime)706 int32_t MiscdeviceService::GetDelayTime(int32_t &delayTime)
707 {
708 std::string packageName = GetPackageName(GetCallingTokenID());
709 MISC_HILOGD("GetDelayTime, package:%{public}s", packageName.c_str());
710 return vibratorHdiConnection_.GetDelayTime(g_capacity.GetVibrateMode(), delayTime);
711 }
712
CheckVibratorParmeters(const VibrateParameter & parameter)713 bool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter ¶meter)
714 {
715 if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) ||
716 (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) {
717 MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d",
718 parameter.intensity, parameter.frequency);
719 return false;
720 }
721 return true;
722 }
723
MergeVibratorParmeters(const VibrateParameter & parameter,VibratePackage & package)724 void MiscdeviceService::MergeVibratorParmeters(const VibrateParameter ¶meter, VibratePackage &package)
725 {
726 if ((parameter.intensity == INTENSITY_ADJUST_MAX) && (parameter.frequency == 0)) {
727 MISC_HILOGD("The adjust parameter is not need to merge");
728 return;
729 }
730 parameter.Dump();
731 for (VibratePattern &pattern : package.patterns) {
732 for (VibrateEvent &event : pattern.events) {
733 float intensityScale = static_cast<float>(parameter.intensity) / INTENSITY_ADJUST_MAX;
734 if ((event.tag == EVENT_TAG_TRANSIENT) || (event.points.empty())) {
735 event.intensity = static_cast<int32_t>(event.intensity * intensityScale);
736 event.intensity = std::max(std::min(event.intensity, INTENSITY_MAX), INTENSITY_MIN);
737 event.frequency = event.frequency + parameter.frequency;
738 event.frequency = std::max(std::min(event.frequency, FREQUENCY_MAX), FREQUENCY_MIN);
739 } else {
740 for (VibrateCurvePoint &point : event.points) {
741 point.intensity = static_cast<int32_t>(point.intensity * intensityScale);
742 point.intensity = std::max(std::min(point.intensity, INTENSITY_ADJUST_MAX), INTENSITY_ADJUST_MIN);
743 point.frequency = point.frequency + parameter.frequency;
744 point.frequency = std::max(std::min(point.frequency, FREQUENCY_ADJUST_MAX), FREQUENCY_ADJUST_MIN);
745 }
746 }
747 }
748 }
749 }
750
TransferClientRemoteObject(const sptr<IRemoteObject> & vibratorServiceClient)751 int32_t MiscdeviceService::TransferClientRemoteObject(const sptr<IRemoteObject> &vibratorServiceClient)
752 {
753 auto clientPid = GetCallingPid();
754 if (clientPid < 0) {
755 MISC_HILOGE("ClientPid is invalid, clientPid:%{public}d", clientPid);
756 return ERROR;
757 }
758 RegisterClientDeathRecipient(vibratorServiceClient, clientPid);
759 return ERR_OK;
760 }
761
ProcessDeathObserver(const wptr<IRemoteObject> & object)762 void MiscdeviceService::ProcessDeathObserver(const wptr<IRemoteObject> &object)
763 {
764 CALL_LOG_ENTER;
765 sptr<IRemoteObject> client = object.promote();
766 int32_t clientPid = FindClientPid(client);
767 VibrateInfo info;
768 {
769 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
770 if (vibratorThread_ == nullptr) {
771 vibratorThread_ = std::make_shared<VibratorThread>();
772 }
773 info = vibratorThread_->GetCurrentVibrateInfo();
774 }
775 int32_t vibratePid = info.pid;
776 MISC_HILOGI("ClientPid:%{public}d, VibratePid:%{public}d", clientPid, vibratePid);
777 if ((clientPid != INVALID_PID) && (clientPid == vibratePid)) {
778 StopVibrator(VIBRATOR_ID);
779 }
780 UnregisterClientDeathRecipient(client);
781 }
782
RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient,int32_t pid)783 void MiscdeviceService::RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient, int32_t pid)
784 {
785 if (vibratorServiceClient == nullptr) {
786 MISC_HILOGE("VibratorServiceClient is nullptr");
787 return;
788 }
789 std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
790 if (clientDeathObserver_ == nullptr) {
791 clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MiscdeviceService *>(this));
792 if (clientDeathObserver_ == nullptr) {
793 MISC_HILOGE("ClientDeathObserver_ is nullptr");
794 return;
795 }
796 }
797 vibratorServiceClient->AddDeathRecipient(clientDeathObserver_);
798 SaveClientPid(vibratorServiceClient, pid);
799 }
800
UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)801 void MiscdeviceService::UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)
802 {
803 if (vibratorServiceClient == nullptr) {
804 MISC_HILOGE("vibratorServiceClient is nullptr");
805 return;
806 }
807 int32_t clientPid = FindClientPid(vibratorServiceClient);
808 if (clientPid == INVALID_PID) {
809 MISC_HILOGE("Pid is invalid");
810 return;
811 }
812 std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
813 vibratorServiceClient->RemoveDeathRecipient(clientDeathObserver_);
814 DestroyClientPid(vibratorServiceClient);
815 }
816
SaveClientPid(const sptr<IRemoteObject> & vibratorServiceClient,int32_t pid)817 void MiscdeviceService::SaveClientPid(const sptr<IRemoteObject> &vibratorServiceClient, int32_t pid)
818 {
819 if (vibratorServiceClient == nullptr) {
820 MISC_HILOGE("VibratorServiceClient is nullptr");
821 return;
822 }
823 std::lock_guard<std::mutex> lock(clientPidMapMutex_);
824 clientPidMap_.insert(std::make_pair(vibratorServiceClient, pid));
825 }
826
FindClientPid(const sptr<IRemoteObject> & vibratorServiceClient)827 int32_t MiscdeviceService::FindClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
828 {
829 if (vibratorServiceClient == nullptr) {
830 MISC_HILOGE("VibratorServiceClient is nullptr");
831 return INVALID_PID;
832 }
833 std::lock_guard<std::mutex> lock(clientPidMapMutex_);
834 auto it = clientPidMap_.find(vibratorServiceClient);
835 if (it == clientPidMap_.end()) {
836 MISC_HILOGE("Cannot find client pid");
837 return INVALID_PID;
838 }
839 return it->second;
840 }
841
DestroyClientPid(const sptr<IRemoteObject> & vibratorServiceClient)842 void MiscdeviceService::DestroyClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
843 {
844 if (vibratorServiceClient == nullptr) {
845 MISC_HILOGD("VibratorServiceClient is nullptr");
846 return;
847 }
848 std::lock_guard<std::mutex> lock(clientPidMapMutex_);
849 auto it = clientPidMap_.find(vibratorServiceClient);
850 if (it == clientPidMap_.end()) {
851 MISC_HILOGE("Cannot find client pid");
852 return;
853 }
854 clientPidMap_.erase(it);
855 }
856
PlayPrimitiveEffect(int32_t vibratorId,const std::string & effect,int32_t intensity,int32_t usage,bool systemUsage,int32_t count)857 int32_t MiscdeviceService::PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect,
858 int32_t intensity, int32_t usage, bool systemUsage, int32_t count)
859 {
860 if ((intensity <= INTENSITY_MIN) || (intensity > INTENSITY_MAX) || (usage >= USAGE_MAX) || (usage < 0)) {
861 MISC_HILOGE("Invalid parameter");
862 return PARAMETER_ERROR;
863 }
864 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
865 if (!effectInfo) {
866 MISC_HILOGE("GetEffectInfo fail");
867 return ERROR;
868 }
869 if (!(effectInfo->isSupportEffect)) {
870 MISC_HILOGE("Effect not supported");
871 return PARAMETER_ERROR;
872 }
873 VibrateInfo info = {
874 .mode = VIBRATE_PRESET,
875 .packageName = GetPackageName(GetCallingTokenID()),
876 .pid = GetCallingPid(),
877 .uid = GetCallingUid(),
878 .usage = usage,
879 .systemUsage = systemUsage,
880 .duration = effectInfo->duration,
881 .effect = effect,
882 .count = count,
883 .intensity = intensity
884 };
885 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
886 std::string curVibrateTime = GetCurrentTime();
887 if (ShouldIgnoreVibrate(info)) {
888 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
889 return ERROR;
890 }
891 StartVibrateThread(info);
892 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
893 "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s", curVibrateTime.c_str(),
894 info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str());
895 return NO_ERROR;
896 }
897
GetVibratorCapacity(VibratorCapacity & capacity)898 int32_t MiscdeviceService::GetVibratorCapacity(VibratorCapacity &capacity)
899 {
900 capacity = g_capacity;
901 return ERR_OK;
902 }
903 } // namespace Sensors
904 } // namespace OHOS
905