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 #if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR)
349 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() &&
350 !vibratorHdiConnection_.IsVibratorRunning())) {
351 MISC_HILOGD("No vibration, no need to stop");
352 return ERROR;
353 }
354 if (vibratorHdiConnection_.IsVibratorRunning()) {
355 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
356 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC);
357 }
358 #else
359 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
360 MISC_HILOGD("No vibration, no need to stop");
361 return ERROR;
362 }
363 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR
364 StopVibrateThread();
365 std::string packageName = GetPackageName(GetCallingTokenID());
366 std::string curVibrateTime = GetCurrentTime();
367 MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d",
368 curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId);
369 return NO_ERROR;
370 }
371
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 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
380 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
381 if (!effectInfo) {
382 MISC_HILOGE("GetEffectInfo fail");
383 return ERROR;
384 }
385 if (!(effectInfo->isSupportEffect)) {
386 MISC_HILOGE("Effect not supported");
387 return PARAMETER_ERROR;
388 }
389 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
390 VibrateInfo info = {
391 .mode = VIBRATE_PRESET,
392 .packageName = GetPackageName(GetCallingTokenID()),
393 .pid = GetCallingPid(),
394 .uid = GetCallingUid(),
395 .usage = usage,
396 .systemUsage = systemUsage,
397 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
398 .duration = effectInfo->duration,
399 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
400 .effect = effect,
401 .count = count,
402 .intensity = INTENSITY_ADJUST_MAX
403 };
404 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
405 std::string curVibrateTime = GetCurrentTime();
406 if (ShouldIgnoreVibrate(info)) {
407 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
408 return ERROR;
409 }
410 StartVibrateThread(info);
411 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
412 "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s, count:%{public}d", curVibrateTime.c_str(),
413 info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str(), info.count);
414 return NO_ERROR;
415 }
416
StartVibrateThread(VibrateInfo info)417 void MiscdeviceService::StartVibrateThread(VibrateInfo info)
418 {
419 if (vibratorThread_ == nullptr) {
420 vibratorThread_ = std::make_shared<VibratorThread>();
421 }
422 StopVibrateThread();
423 #if defined (OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM) && defined (HDF_DRIVERS_INTERFACE_VIBRATOR)
424 if (vibratorHdiConnection_.IsVibratorRunning()) {
425 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
426 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_HDHAPTIC);
427 }
428 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM && HDF_DRIVERS_INTERFACE_VIBRATOR
429 vibratorThread_->UpdateVibratorEffect(info);
430 vibratorThread_->Start("VibratorThread");
431 DumpHelper->SaveVibrateRecord(info);
432 }
433
StopVibrateThread()434 void MiscdeviceService::StopVibrateThread()
435 {
436 if ((vibratorThread_ != nullptr) && (vibratorThread_->IsRunning())) {
437 vibratorThread_->SetExitStatus(true);
438 vibratorThread_->WakeUp();
439 vibratorThread_->NotifyExitSync();
440 vibratorThread_->SetExitStatus(false);
441 }
442 }
443
StopVibrator(int32_t vibratorId, const std::string &mode)444 int32_t MiscdeviceService::StopVibrator(int32_t vibratorId, const std::string &mode)
445 {
446 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
447 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
448 MISC_HILOGD("No vibration, no need to stop");
449 return ERROR;
450 }
451 const VibrateInfo info = vibratorThread_->GetCurrentVibrateInfo();
452 if (info.mode != mode) {
453 MISC_HILOGD("Stop vibration information mismatch");
454 return ERROR;
455 }
456 StopVibrateThread();
457 std::string packageName = GetPackageName(GetCallingTokenID());
458 std::string curVibrateTime = GetCurrentTime();
459 MISC_HILOGI("Stop vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, vibratorId:%{public}d,"
460 "mode:%{public}s", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), vibratorId, mode.c_str());
461 return NO_ERROR;
462 }
463
IsSupportEffect(const std::string &effect, bool &state)464 int32_t MiscdeviceService::IsSupportEffect(const std::string &effect, bool &state)
465 {
466 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
467 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
468 if (!effectInfo) {
469 MISC_HILOGE("GetEffectInfo fail");
470 return ERROR;
471 }
472 state = effectInfo->isSupportEffect;
473 std::string packageName = GetPackageName(GetCallingTokenID());
474 std::string curVibrateTime = GetCurrentTime();
475 MISC_HILOGI("IsSupportEffect, currentTime:%{public}s, package:%{public}s, pid:%{public}d, effect:%{public}s,"
476 "state:%{public}d", curVibrateTime.c_str(), packageName.c_str(), GetCallingPid(), effect.c_str(), state);
477 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
478 return NO_ERROR;
479 }
480
GetCurrentTime()481 std::string MiscdeviceService::GetCurrentTime()
482 {
483 timespec curTime;
484 clock_gettime(CLOCK_REALTIME, &curTime);
485 struct tm *timeinfo = localtime(&(curTime.tv_sec));
486 std::string currentTime;
487 if (timeinfo == nullptr) {
488 MISC_HILOGE("timeinfo is null");
489 return currentTime;
490 }
491 currentTime.append(std::to_string(timeinfo->tm_year + BASE_YEAR)).append("-")
492 .append(std::to_string(timeinfo->tm_mon + BASE_MON)).append("-").append(std::to_string(timeinfo->tm_mday))
493 .append(" ").append(std::to_string(timeinfo->tm_hour)).append(":").append(std::to_string(timeinfo->tm_min))
494 .append(":").append(std::to_string(timeinfo->tm_sec)).append(".")
495 .append(std::to_string(curTime.tv_nsec / (CONVERSION_RATE * CONVERSION_RATE)));
496 return currentTime;
497 }
498
499 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage, bool systemUsage, const VibrateParameter ¶meter)500 int32_t MiscdeviceService::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
501 bool systemUsage, const VibrateParameter ¶meter)
502 {
503 if (!(g_capacity.isSupportHdHaptic || g_capacity.isSupportPresetMapping || g_capacity.isSupportTimeDelay)) {
504 MISC_HILOGE("The device does not support this operation");
505 return IS_NOT_SUPPORTED;
506 }
507 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
508 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
509 return PARAMETER_ERROR;
510 }
511 JsonParser parser(rawFd);
512 VibratorDecoderCreator creator;
513 std::unique_ptr<IVibratorDecoder> decoder(creator.CreateDecoder(parser));
514 CHKPR(decoder, ERROR);
515 VibratePackage package;
516 int32_t ret = decoder->DecodeEffect(rawFd, parser, package);
517 if (ret != SUCCESS || package.patterns.empty()) {
518 MISC_HILOGE("Decode effect error");
519 return ERROR;
520 }
521 MergeVibratorParmeters(parameter, package);
522 package.Dump();
523 VibrateInfo info = {
524 .packageName = GetPackageName(GetCallingTokenID()),
525 .pid = GetCallingPid(),
526 .uid = GetCallingUid(),
527 .usage = usage,
528 .systemUsage = systemUsage,
529 .package = package,
530 };
531 if (g_capacity.isSupportHdHaptic) {
532 info.mode = VIBRATE_CUSTOM_HD;
533 } else if (g_capacity.isSupportPresetMapping) {
534 info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
535 } else if (g_capacity.isSupportTimeDelay) {
536 info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
537 }
538 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
539 std::string curVibrateTime = GetCurrentTime();
540 if (ShouldIgnoreVibrate(info)) {
541 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
542 return ERROR;
543 }
544 StartVibrateThread(info);
545 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
546 "vibratorId:%{public}d, duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid,
547 info.usage, vibratorId, package.packageDuration);
548 return NO_ERROR;
549 }
550 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
551
GetPackageName(AccessTokenID tokenId)552 std::string MiscdeviceService::GetPackageName(AccessTokenID tokenId)
553 {
554 std::string packageName;
555 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
556 switch (tokenType) {
557 case ATokenTypeEnum::TOKEN_HAP: {
558 HapTokenInfo hapInfo;
559 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
560 MISC_HILOGE("Get hap token info fail");
561 return {};
562 }
563 packageName = hapInfo.bundleName;
564 break;
565 }
566 case ATokenTypeEnum::TOKEN_NATIVE:
567 case ATokenTypeEnum::TOKEN_SHELL: {
568 NativeTokenInfo tokenInfo;
569 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
570 MISC_HILOGE("Get native token info fail");
571 return {};
572 }
573 packageName = tokenInfo.processName;
574 break;
575 }
576 default: {
577 MISC_HILOGW("Token type not match");
578 break;
579 }
580 }
581 return packageName;
582 }
583
GetLightList()584 std::vector<LightInfoIPC> MiscdeviceService::GetLightList()
585 {
586 std::string packageName = GetPackageName(GetCallingTokenID());
587 MISC_HILOGI("GetLightList, package:%{public}s", packageName.c_str());
588 if (!InitLightList()) {
589 MISC_HILOGE("InitLightList init failed");
590 return lightInfos_;
591 }
592 return lightInfos_;
593 }
594
InitLightList()595 bool MiscdeviceService::InitLightList()
596 {
597 int32_t ret = lightHdiConnection_.GetLightList(lightInfos_);
598 if (ret != ERR_OK) {
599 MISC_HILOGE("InitLightList failed, ret:%{public}d", ret);
600 return false;
601 }
602 return true;
603 }
604
TurnOn(int32_t lightId, const LightColor &color, const LightAnimationIPC &animation)605 int32_t MiscdeviceService::TurnOn(int32_t lightId, const LightColor &color, const LightAnimationIPC &animation)
606 {
607 std::string packageName = GetPackageName(GetCallingTokenID());
608 MISC_HILOGI("TurnOn, package:%{public}s", packageName.c_str());
609 if (!IsValid(lightId)) {
610 MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
611 return MISCDEVICE_NATIVE_SAM_ERR;
612 }
613 if (!IsLightAnimationValid(animation)) {
614 MISC_HILOGE("animation is invalid");
615 return MISCDEVICE_NATIVE_SAM_ERR;
616 }
617 int32_t ret = lightHdiConnection_.TurnOn(lightId, color, animation);
618 if (ret != ERR_OK) {
619 MISC_HILOGE("TurnOn failed, error:%{public}d", ret);
620 return ERROR;
621 }
622 return ret;
623 }
624
TurnOff(int32_t lightId)625 int32_t MiscdeviceService::TurnOff(int32_t lightId)
626 {
627 std::string packageName = GetPackageName(GetCallingTokenID());
628 MISC_HILOGI("TurnOff, package:%{public}s", packageName.c_str());
629 if (!IsValid(lightId)) {
630 MISC_HILOGE("lightId is invalid, lightId:%{public}d", lightId);
631 return MISCDEVICE_NATIVE_SAM_ERR;
632 }
633 int32_t ret = lightHdiConnection_.TurnOff(lightId);
634 if (ret != ERR_OK) {
635 MISC_HILOGE("TurnOff failed, error:%{public}d", ret);
636 return ERROR;
637 }
638 return ret;
639 }
640
Dump(int32_t fd, const std::vector<std::u16string> &args)641 int32_t MiscdeviceService::Dump(int32_t fd, const std::vector<std::u16string> &args)
642 {
643 CALL_LOG_ENTER;
644 if (fd < 0) {
645 MISC_HILOGE("Invalid fd");
646 return DUMP_PARAM_ERR;
647 }
648 if (args.empty()) {
649 MISC_HILOGE("args cannot be empty");
650 dprintf(fd, "args cannot be empty\n");
651 DumpHelper->DumpHelp(fd);
652 return DUMP_PARAM_ERR;
653 }
654 std::vector<std::string> argList = { "" };
655 std::transform(args.begin(), args.end(), std::back_inserter(argList),
656 [](const std::u16string &arg) {
657 return Str16ToStr8(arg);
658 });
659 DumpHelper->ParseCommand(fd, argList);
660 return ERR_OK;
661 }
662
PlayPattern(const VibratePattern &pattern, int32_t usage, bool systemUsage, const VibrateParameter ¶meter)663 int32_t MiscdeviceService::PlayPattern(const VibratePattern &pattern, int32_t usage,
664 bool systemUsage, const VibrateParameter ¶meter)
665 {
666 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
667 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
668 return PARAMETER_ERROR;
669 }
670 VibratePattern vibratePattern = {
671 .startTime = 0,
672 .events = pattern.events
673 };
674 std::vector<VibratePattern> patterns = {vibratePattern};
675 VibratePackage package = {
676 .patterns = patterns
677 };
678 MergeVibratorParmeters(parameter, package);
679 package.Dump();
680 VibrateInfo info = {
681 .mode = VIBRATE_BUTT,
682 .packageName = GetPackageName(GetCallingTokenID()),
683 .pid = GetCallingPid(),
684 .uid = GetCallingUid(),
685 .usage = usage,
686 .systemUsage = systemUsage
687 };
688 if (g_capacity.isSupportHdHaptic) {
689 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
690 std::string curVibrateTime = GetCurrentTime();
691 if (ShouldIgnoreVibrate(info)) {
692 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
693 return ERROR;
694 }
695 StartVibrateThread(info);
696 return vibratorHdiConnection_.PlayPattern(package.patterns.front());
697 } else if (g_capacity.isSupportPresetMapping) {
698 info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
699 } else if (g_capacity.isSupportTimeDelay) {
700 info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
701 }
702 info.package = package;
703 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
704 std::string curVibrateTime = GetCurrentTime();
705 if (ShouldIgnoreVibrate(info)) {
706 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
707 return ERROR;
708 }
709 StartVibrateThread(info);
710 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
711 "duration:%{public}d", curVibrateTime.c_str(), info.packageName.c_str(), info.pid, info.usage,
712 pattern.patternDuration);
713 return ERR_OK;
714 }
715
GetDelayTime(int32_t &delayTime)716 int32_t MiscdeviceService::GetDelayTime(int32_t &delayTime)
717 {
718 std::string packageName = GetPackageName(GetCallingTokenID());
719 MISC_HILOGD("GetDelayTime, package:%{public}s", packageName.c_str());
720 return vibratorHdiConnection_.GetDelayTime(g_capacity.GetVibrateMode(), delayTime);
721 }
722
CheckVibratorParmeters(const VibrateParameter ¶meter)723 bool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter ¶meter)
724 {
725 if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) ||
726 (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) {
727 MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d",
728 parameter.intensity, parameter.frequency);
729 return false;
730 }
731 return true;
732 }
733
MergeVibratorParmeters(const VibrateParameter ¶meter, VibratePackage &package)734 void MiscdeviceService::MergeVibratorParmeters(const VibrateParameter ¶meter, VibratePackage &package)
735 {
736 if ((parameter.intensity == INTENSITY_ADJUST_MAX) && (parameter.frequency == 0)) {
737 MISC_HILOGD("The adjust parameter is not need to merge");
738 return;
739 }
740 parameter.Dump();
741 for (VibratePattern &pattern : package.patterns) {
742 for (VibrateEvent &event : pattern.events) {
743 float intensityScale = static_cast<float>(parameter.intensity) / INTENSITY_ADJUST_MAX;
744 if ((event.tag == EVENT_TAG_TRANSIENT) || (event.points.empty())) {
745 event.intensity = static_cast<int32_t>(event.intensity * intensityScale);
746 event.intensity = std::max(std::min(event.intensity, INTENSITY_MAX), INTENSITY_MIN);
747 event.frequency = event.frequency + parameter.frequency;
748 event.frequency = std::max(std::min(event.frequency, FREQUENCY_MAX), FREQUENCY_MIN);
749 } else {
750 for (VibrateCurvePoint &point : event.points) {
751 point.intensity = static_cast<int32_t>(point.intensity * intensityScale);
752 point.intensity = std::max(std::min(point.intensity, INTENSITY_ADJUST_MAX), INTENSITY_ADJUST_MIN);
753 point.frequency = point.frequency + parameter.frequency;
754 point.frequency = std::max(std::min(point.frequency, FREQUENCY_ADJUST_MAX), FREQUENCY_ADJUST_MIN);
755 }
756 }
757 }
758 }
759 }
760
TransferClientRemoteObject(const sptr<IRemoteObject> &vibratorServiceClient)761 int32_t MiscdeviceService::TransferClientRemoteObject(const sptr<IRemoteObject> &vibratorServiceClient)
762 {
763 auto clientPid = GetCallingPid();
764 if (clientPid < 0) {
765 MISC_HILOGE("ClientPid is invalid, clientPid:%{public}d", clientPid);
766 return ERROR;
767 }
768 RegisterClientDeathRecipient(vibratorServiceClient, clientPid);
769 return ERR_OK;
770 }
771
ProcessDeathObserver(const wptr<IRemoteObject> &object)772 void MiscdeviceService::ProcessDeathObserver(const wptr<IRemoteObject> &object)
773 {
774 CALL_LOG_ENTER;
775 sptr<IRemoteObject> client = object.promote();
776 int32_t clientPid = FindClientPid(client);
777 VibrateInfo info;
778 {
779 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
780 if (vibratorThread_ == nullptr) {
781 vibratorThread_ = std::make_shared<VibratorThread>();
782 }
783 info = vibratorThread_->GetCurrentVibrateInfo();
784 }
785 int32_t vibratePid = info.pid;
786 MISC_HILOGI("ClientPid:%{public}d, VibratePid:%{public}d", clientPid, vibratePid);
787 if ((clientPid != INVALID_PID) && (clientPid == vibratePid)) {
788 StopVibrator(VIBRATOR_ID);
789 }
790 UnregisterClientDeathRecipient(client);
791 }
792
RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient, int32_t pid)793 void MiscdeviceService::RegisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient, int32_t pid)
794 {
795 if (vibratorServiceClient == nullptr) {
796 MISC_HILOGE("VibratorServiceClient is nullptr");
797 return;
798 }
799 std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
800 if (clientDeathObserver_ == nullptr) {
801 clientDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<MiscdeviceService *>(this));
802 if (clientDeathObserver_ == nullptr) {
803 MISC_HILOGE("ClientDeathObserver_ is nullptr");
804 return;
805 }
806 }
807 vibratorServiceClient->AddDeathRecipient(clientDeathObserver_);
808 SaveClientPid(vibratorServiceClient, pid);
809 }
810
UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)811 void MiscdeviceService::UnregisterClientDeathRecipient(sptr<IRemoteObject> vibratorServiceClient)
812 {
813 if (vibratorServiceClient == nullptr) {
814 MISC_HILOGE("vibratorServiceClient is nullptr");
815 return;
816 }
817 int32_t clientPid = FindClientPid(vibratorServiceClient);
818 if (clientPid == INVALID_PID) {
819 MISC_HILOGE("Pid is invalid");
820 return;
821 }
822 std::lock_guard<std::mutex> lock(clientDeathObserverMutex_);
823 vibratorServiceClient->RemoveDeathRecipient(clientDeathObserver_);
824 DestroyClientPid(vibratorServiceClient);
825 }
826
SaveClientPid(const sptr<IRemoteObject> &vibratorServiceClient, int32_t pid)827 void MiscdeviceService::SaveClientPid(const sptr<IRemoteObject> &vibratorServiceClient, int32_t pid)
828 {
829 if (vibratorServiceClient == nullptr) {
830 MISC_HILOGE("VibratorServiceClient is nullptr");
831 return;
832 }
833 std::lock_guard<std::mutex> lock(clientPidMapMutex_);
834 clientPidMap_.insert(std::make_pair(vibratorServiceClient, pid));
835 }
836
FindClientPid(const sptr<IRemoteObject> &vibratorServiceClient)837 int32_t MiscdeviceService::FindClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
838 {
839 if (vibratorServiceClient == nullptr) {
840 MISC_HILOGE("VibratorServiceClient is nullptr");
841 return INVALID_PID;
842 }
843 std::lock_guard<std::mutex> lock(clientPidMapMutex_);
844 auto it = clientPidMap_.find(vibratorServiceClient);
845 if (it == clientPidMap_.end()) {
846 MISC_HILOGE("Cannot find client pid");
847 return INVALID_PID;
848 }
849 return it->second;
850 }
851
DestroyClientPid(const sptr<IRemoteObject> &vibratorServiceClient)852 void MiscdeviceService::DestroyClientPid(const sptr<IRemoteObject> &vibratorServiceClient)
853 {
854 if (vibratorServiceClient == nullptr) {
855 MISC_HILOGD("VibratorServiceClient is nullptr");
856 return;
857 }
858 std::lock_guard<std::mutex> lock(clientPidMapMutex_);
859 auto it = clientPidMap_.find(vibratorServiceClient);
860 if (it == clientPidMap_.end()) {
861 MISC_HILOGE("Cannot find client pid");
862 return;
863 }
864 clientPidMap_.erase(it);
865 }
866
PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect, int32_t intensity, int32_t usage, bool systemUsage, int32_t count)867 int32_t MiscdeviceService::PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect,
868 int32_t intensity, int32_t usage, bool systemUsage, int32_t count)
869 {
870 if ((intensity <= INTENSITY_MIN) || (intensity > INTENSITY_MAX) || (usage >= USAGE_MAX) || (usage < 0)) {
871 MISC_HILOGE("Invalid parameter");
872 return PARAMETER_ERROR;
873 }
874 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
875 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
876 if (!effectInfo) {
877 MISC_HILOGE("GetEffectInfo fail");
878 return ERROR;
879 }
880 if (!(effectInfo->isSupportEffect)) {
881 MISC_HILOGE("Effect not supported");
882 return PARAMETER_ERROR;
883 }
884 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
885 VibrateInfo info = {
886 .mode = VIBRATE_PRESET,
887 .packageName = GetPackageName(GetCallingTokenID()),
888 .pid = GetCallingPid(),
889 .uid = GetCallingUid(),
890 .usage = usage,
891 .systemUsage = systemUsage,
892 #ifdef HDF_DRIVERS_INTERFACE_VIBRATOR
893 .duration = effectInfo->duration,
894 #endif // HDF_DRIVERS_INTERFACE_VIBRATOR
895 .effect = effect,
896 .count = count,
897 .intensity = intensity
898 };
899 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
900 std::string curVibrateTime = GetCurrentTime();
901 if (ShouldIgnoreVibrate(info)) {
902 MISC_HILOGE("%{public}s:vibration is ignored and high priority is vibrating", curVibrateTime.c_str());
903 return ERROR;
904 }
905 StartVibrateThread(info);
906 MISC_HILOGI("Start vibrator, currentTime:%{public}s, package:%{public}s, pid:%{public}d, usage:%{public}d,"
907 "vibratorId:%{public}d, duration:%{public}d, effect:%{public}s", curVibrateTime.c_str(),
908 info.packageName.c_str(), info.pid, info.usage, vibratorId, info.duration, info.effect.c_str());
909 return NO_ERROR;
910 }
911
GetVibratorCapacity(VibratorCapacity &capacity)912 int32_t MiscdeviceService::GetVibratorCapacity(VibratorCapacity &capacity)
913 {
914 capacity = g_capacity;
915 return ERR_OK;
916 }
917 } // namespace Sensors
918 } // namespace OHOS
919