1 /*
2 * Copyright (c) 2021-2023 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
21 #include <string_ex.h>
22
23 #include "sensors_errors.h"
24 #include "system_ability_definition.h"
25 #include "vibration_priority_manager.h"
26 #ifdef HDF_DRIVERS_INTERFACE_LIGHT
27 #include "v1_0/light_interface_proxy.h"
28 #endif // HDF_DRIVERS_INTERFACE_LIGHT
29 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
30 #include "default_vibrator_decoder.h"
31 #include "default_vibrator_decoder_factory.h"
32 #include "parameters.h"
33 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
34
35 #undef LOG_TAG
36 #define LOG_TAG "MiscdeviceService"
37
38 namespace OHOS {
39 namespace Sensors {
40 namespace {
41 auto g_miscdeviceService = MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance();
42 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(g_miscdeviceService.GetRefPtr());
43 constexpr int32_t MIN_VIBRATOR_TIME = 0;
44 constexpr int32_t MAX_VIBRATOR_TIME = 1800000;
45 constexpr int32_t MIN_VIBRATOR_COUNT = 1;
46 constexpr int32_t MAX_VIBRATOR_COUNT = 1000;
47 constexpr int32_t INTENSITY_MIN = 0;
48 constexpr int32_t INTENSITY_MAX = 100;
49 constexpr int32_t FREQUENCY_MIN = 0;
50 constexpr int32_t FREQUENCY_MAX = 100;
51 constexpr int32_t INTENSITY_ADJUST_MIN = 0;
52 constexpr int32_t INTENSITY_ADJUST_MAX = 100;
53 constexpr int32_t FREQUENCY_ADJUST_MIN = -100;
54 constexpr int32_t FREQUENCY_ADJUST_MAX = 100;
55 VibratorCapacity g_capacity;
56 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
57 const std::string PHONE_TYPE = "phone";
58 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
59 } // namespace
60
MiscdeviceService()61 MiscdeviceService::MiscdeviceService()
62 : SystemAbility(MISCDEVICE_SERVICE_ABILITY_ID, true),
63 lightExist_(false),
64 vibratorExist_(false),
65 state_(MiscdeviceServiceState::STATE_STOPPED),
66 vibratorThread_(nullptr)
67 {
68 MISC_HILOGD("Add SystemAbility");
69 }
70
~MiscdeviceService()71 MiscdeviceService::~MiscdeviceService()
72 {
73 StopVibrateThread();
74 }
75
OnDump()76 void MiscdeviceService::OnDump()
77 {
78 MISC_HILOGI("Ondump is invoked");
79 }
80
OnStart()81 void MiscdeviceService::OnStart()
82 {
83 CALL_LOG_ENTER;
84 if (state_ == MiscdeviceServiceState::STATE_RUNNING) {
85 MISC_HILOGW("state_ already started");
86 return;
87 }
88 if (!InitInterface()) {
89 MISC_HILOGE("Init interface error");
90 }
91 if (!InitLightInterface()) {
92 MISC_HILOGE("InitLightInterface failed");
93 }
94 if (!SystemAbility::Publish(MiscdeviceDelayedSpSingleton<MiscdeviceService>::GetInstance())) {
95 MISC_HILOGE("Publish MiscdeviceService failed");
96 return;
97 }
98 auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_));
99 if (!ret.second) {
100 MISC_HILOGI("Light exist in miscDeviceIdMap_");
101 ret.first->second = lightExist_;
102 }
103 ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_));
104 if (!ret.second) {
105 MISC_HILOGI("Vibrator exist in miscDeviceIdMap_");
106 ret.first->second = vibratorExist_;
107 }
108 state_ = MiscdeviceServiceState::STATE_RUNNING;
109 }
110
OnStartFuzz()111 void MiscdeviceService::OnStartFuzz()
112 {
113 CALL_LOG_ENTER;
114 if (state_ == MiscdeviceServiceState::STATE_RUNNING) {
115 MISC_HILOGW("state_ already started");
116 return;
117 }
118 if (!InitInterface()) {
119 MISC_HILOGE("Init interface error");
120 }
121 if (!InitLightInterface()) {
122 MISC_HILOGE("InitLightInterface failed");
123 }
124 auto ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::LED, lightExist_));
125 if (!ret.second) {
126 MISC_HILOGI("Light exist in miscDeviceIdMap_");
127 ret.first->second = lightExist_;
128 }
129 ret = miscDeviceIdMap_.insert(std::make_pair(MiscdeviceDeviceId::VIBRATOR, vibratorExist_));
130 if (!ret.second) {
131 MISC_HILOGI("Vibrator exist in miscDeviceIdMap_");
132 ret.first->second = vibratorExist_;
133 }
134 state_ = MiscdeviceServiceState::STATE_RUNNING;
135 }
136
InitInterface()137 bool MiscdeviceService::InitInterface()
138 {
139 auto ret = vibratorHdiConnection_.ConnectHdi();
140 if (ret != ERR_OK) {
141 MISC_HILOGE("InitVibratorServiceImpl failed");
142 return false;
143 }
144 if (vibratorHdiConnection_.GetVibratorCapacity(g_capacity) != ERR_OK) {
145 MISC_HILOGE("GetVibratorCapacity failed");
146 }
147 return true;
148 }
149
InitLightInterface()150 bool MiscdeviceService::InitLightInterface()
151 {
152 auto ret = lightHdiConnection_.ConnectHdi();
153 if (ret != ERR_OK) {
154 MISC_HILOGE("ConnectHdi failed");
155 return false;
156 }
157 return true;
158 }
159
IsValid(int32_t lightId)160 bool MiscdeviceService::IsValid(int32_t lightId)
161 {
162 CALL_LOG_ENTER;
163 for (const auto &item : lightInfos_) {
164 if (lightId == item.GetLightId()) {
165 return true;
166 }
167 }
168 return false;
169 }
170
IsLightAnimationValid(const LightAnimationIPC & animation)171 bool MiscdeviceService::IsLightAnimationValid(const LightAnimationIPC &animation)
172 {
173 CALL_LOG_ENTER;
174 int32_t mode = animation.GetMode();
175 int32_t onTime = animation.GetOnTime();
176 int32_t offTime = animation.GetOffTime();
177 if ((mode < 0) || (mode >= LIGHT_MODE_BUTT)) {
178 MISC_HILOGE("animation mode is invalid, mode:%{pubilc}d", mode);
179 return false;
180 }
181 if ((onTime < 0) || (offTime < 0)) {
182 MISC_HILOGE("animation onTime or offTime is invalid, onTime:%{pubilc}d, offTime:%{pubilc}d",
183 onTime, offTime);
184 return false;
185 }
186 return true;
187 }
188
OnStop()189 void MiscdeviceService::OnStop()
190 {
191 CALL_LOG_ENTER;
192 if (state_ == MiscdeviceServiceState::STATE_STOPPED) {
193 MISC_HILOGW("MiscdeviceService stopped already");
194 return;
195 }
196 state_ = MiscdeviceServiceState::STATE_STOPPED;
197 int32_t ret = vibratorHdiConnection_.DestroyHdiConnection();
198 if (ret != ERR_OK) {
199 MISC_HILOGE("Destroy hdi connection fail");
200 }
201 }
202
ShouldIgnoreVibrate(const VibrateInfo & info)203 bool MiscdeviceService::ShouldIgnoreVibrate(const VibrateInfo &info)
204 {
205 return (PriorityManager->ShouldIgnoreVibrate(info, vibratorThread_) != VIBRATION);
206 }
207
Vibrate(int32_t vibratorId,int32_t timeOut,int32_t usage)208 int32_t MiscdeviceService::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage)
209 {
210 std::string packageName = GetPackageName(GetCallingTokenID());
211 MISC_HILOGD("Start vibrator time, time:%{public}d, usage:%{public}d, package:%{public}s",
212 timeOut, usage, packageName.c_str());
213 if ((timeOut <= MIN_VIBRATOR_TIME) || (timeOut > MAX_VIBRATOR_TIME)
214 || (usage >= USAGE_MAX) || (usage < 0)) {
215 MISC_HILOGE("Invalid parameter");
216 return PARAMETER_ERROR;
217 }
218 VibrateInfo info = {
219 .mode = VIBRATE_TIME,
220 .packageName = packageName,
221 .pid = GetCallingPid(),
222 .uid = GetCallingUid(),
223 .usage = usage,
224 .duration = timeOut
225 };
226 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
227 if (ShouldIgnoreVibrate(info)) {
228 MISC_HILOGE("Vibration is ignored and high priority is vibrating");
229 return ERROR;
230 }
231 StartVibrateThread(info);
232 return NO_ERROR;
233 }
234
StopVibrator(int32_t vibratorId)235 int32_t MiscdeviceService::StopVibrator(int32_t vibratorId)
236 {
237 std::string packageName = GetPackageName(GetCallingTokenID());
238 MISC_HILOGD("Stop vibrator, package:%{public}s", packageName.c_str());
239 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
240 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
241 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning() &&
242 !vibratorHdiConnection_.IsVibratorRunning())) {
243 MISC_HILOGD("No vibration, no need to stop");
244 return ERROR;
245 }
246 while (vibratorHdiConnection_.IsVibratorRunning()) {
247 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
248 }
249 #else
250 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
251 MISC_HILOGD("No vibration, no need to stop");
252 return ERROR;
253 }
254 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
255 StopVibrateThread();
256 return NO_ERROR;
257 }
258
PlayVibratorEffect(int32_t vibratorId,const std::string & effect,int32_t count,int32_t usage)259 int32_t MiscdeviceService::PlayVibratorEffect(int32_t vibratorId, const std::string &effect,
260 int32_t count, int32_t usage)
261 {
262 std::string packageName = GetPackageName(GetCallingTokenID());
263 MISC_HILOGD("Start vibrator effect, effect:%{public}s, count:%{public}d, usage:%{public}d, package:%{public}s",
264 effect.c_str(), count, usage, packageName.c_str());
265 if ((count < MIN_VIBRATOR_COUNT) || (count > MAX_VIBRATOR_COUNT) || (usage >= USAGE_MAX) || (usage < 0)) {
266 MISC_HILOGE("Invalid parameter");
267 return PARAMETER_ERROR;
268 }
269 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
270 if (!effectInfo) {
271 MISC_HILOGE("GetEffectInfo fail");
272 return ERROR;
273 }
274 if (!(effectInfo->isSupportEffect)) {
275 MISC_HILOGE("Effect not supported");
276 return PARAMETER_ERROR;
277 }
278 VibrateInfo info = {
279 .mode = VIBRATE_PRESET,
280 .packageName = packageName,
281 .pid = GetCallingPid(),
282 .uid = GetCallingUid(),
283 .usage = usage,
284 .duration = effectInfo->duration,
285 .effect = effect,
286 .count = count
287 };
288 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
289 if (ShouldIgnoreVibrate(info)) {
290 MISC_HILOGE("Vibration is ignored and high priority is vibrating");
291 return ERROR;
292 }
293 StartVibrateThread(info);
294 return NO_ERROR;
295 }
296
StartVibrateThread(VibrateInfo info)297 void MiscdeviceService::StartVibrateThread(VibrateInfo info)
298 {
299 if (vibratorThread_ == nullptr) {
300 vibratorThread_ = std::make_shared<VibratorThread>();
301 }
302 StopVibrateThread();
303 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
304 if (vibratorHdiConnection_.IsVibratorRunning()) {
305 vibratorHdiConnection_.Stop(HDF_VIBRATOR_MODE_PRESET);
306 }
307 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
308 vibratorThread_->UpdateVibratorEffect(info);
309 vibratorThread_->Start("VibratorThread");
310 DumpHelper->SaveVibrateRecord(info);
311 }
312
StopVibrateThread()313 void MiscdeviceService::StopVibrateThread()
314 {
315 if ((vibratorThread_ != nullptr) && (vibratorThread_->IsRunning())) {
316 vibratorThread_->SetExitStatus(true);
317 vibratorThread_->WakeUp();
318 vibratorThread_->NotifyExitSync();
319 vibratorThread_->SetExitStatus(false);
320 }
321 }
322
StopVibrator(int32_t vibratorId,const std::string & mode)323 int32_t MiscdeviceService::StopVibrator(int32_t vibratorId, const std::string &mode)
324 {
325 std::string packageName = GetPackageName(GetCallingTokenID());
326 MISC_HILOGD("Stop vibrator, mode:%{public}s, package:%{public}s", mode.c_str(), packageName.c_str());
327 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
328 if ((vibratorThread_ == nullptr) || (!vibratorThread_->IsRunning())) {
329 MISC_HILOGD("No vibration, no need to stop");
330 return ERROR;
331 }
332 const VibrateInfo info = vibratorThread_->GetCurrentVibrateInfo();
333 if (info.mode != mode) {
334 MISC_HILOGD("Stop vibration information mismatch");
335 return ERROR;
336 }
337 StopVibrateThread();
338 return NO_ERROR;
339 }
340
IsSupportEffect(const std::string & effect,bool & state)341 int32_t MiscdeviceService::IsSupportEffect(const std::string &effect, bool &state)
342 {
343 std::optional<HdfEffectInfo> effectInfo = vibratorHdiConnection_.GetEffectInfo(effect);
344 if (!effectInfo) {
345 MISC_HILOGE("GetEffectInfo fail");
346 return ERROR;
347 }
348 state = effectInfo->isSupportEffect;
349 return NO_ERROR;
350 }
351
352 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId,const RawFileDescriptor & rawFd,int32_t usage,const VibrateParameter & parameter)353 int32_t MiscdeviceService::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
354 const VibrateParameter ¶meter)
355 {
356 std::string packageName = GetPackageName(GetCallingTokenID());
357 MISC_HILOGD("Start vibrator custom, usage:%{public}d, package:%{public}s", usage, packageName.c_str());
358 if (OHOS::system::GetDeviceType() != PHONE_TYPE) {
359 MISC_HILOGE("The device does not support this operation");
360 return IS_NOT_SUPPORTED;
361 }
362 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
363 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
364 return PARAMETER_ERROR;
365 }
366 std::unique_ptr<IVibratorDecoderFactory> decoderFactory = std::make_unique<DefaultVibratorDecoderFactory>();
367 std::unique_ptr<IVibratorDecoder> decoder(decoderFactory->CreateDecoder());
368 VibratePackage package;
369 int32_t ret = decoder->DecodeEffect(rawFd, package);
370 if (ret != SUCCESS || package.patterns.empty()) {
371 MISC_HILOGE("Decode effect error");
372 return ERROR;
373 }
374 MergeVibratorParmeters(parameter, package);
375 package.Dump();
376 VibrateInfo info = {
377 .mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT,
378 .packageName = packageName,
379 .pid = GetCallingPid(),
380 .uid = GetCallingUid(),
381 .usage = usage,
382 .package = package,
383 };
384 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
385 if (ShouldIgnoreVibrate(info)) {
386 MISC_HILOGE("Vibration is ignored and high priority is vibrating");
387 return ERROR;
388 }
389 StartVibrateThread(info);
390 return NO_ERROR;
391 }
392 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
393
GetPackageName(AccessTokenID tokenId)394 std::string MiscdeviceService::GetPackageName(AccessTokenID tokenId)
395 {
396 std::string packageName;
397 int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
398 switch (tokenType) {
399 case ATokenTypeEnum::TOKEN_HAP: {
400 HapTokenInfo hapInfo;
401 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
402 MISC_HILOGE("Get hap token info fail");
403 return {};
404 }
405 packageName = hapInfo.bundleName;
406 break;
407 }
408 case ATokenTypeEnum::TOKEN_NATIVE:
409 case ATokenTypeEnum::TOKEN_SHELL: {
410 NativeTokenInfo tokenInfo;
411 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
412 MISC_HILOGE("Get native token info fail");
413 return {};
414 }
415 packageName = tokenInfo.processName;
416 break;
417 }
418 default: {
419 MISC_HILOGW("Token type not match");
420 break;
421 }
422 }
423 return packageName;
424 }
425
GetLightList()426 std::vector<LightInfoIPC> MiscdeviceService::GetLightList()
427 {
428 std::string packageName = GetPackageName(GetCallingTokenID());
429 MISC_HILOGI("GetLightList, package:%{public}s", packageName.c_str());
430 if (!InitLightList()) {
431 MISC_HILOGE("InitLightList init failed");
432 return lightInfos_;
433 }
434 return lightInfos_;
435 }
436
InitLightList()437 bool MiscdeviceService::InitLightList()
438 {
439 int32_t ret = lightHdiConnection_.GetLightList(lightInfos_);
440 if (ret != ERR_OK) {
441 MISC_HILOGE("InitLightList failed, ret:%{public}d", ret);
442 return false;
443 }
444 return true;
445 }
446
TurnOn(int32_t lightId,const LightColor & color,const LightAnimationIPC & animation)447 int32_t MiscdeviceService::TurnOn(int32_t lightId, const LightColor &color, const LightAnimationIPC &animation)
448 {
449 std::string packageName = GetPackageName(GetCallingTokenID());
450 MISC_HILOGI("TurnOn, package:%{public}s", packageName.c_str());
451 if (!IsValid(lightId)) {
452 MISC_HILOGE("lightId is invalid, lightId:%{pubilc}d", lightId);
453 return MISCDEVICE_NATIVE_SAM_ERR;
454 }
455 if (!IsLightAnimationValid(animation)) {
456 MISC_HILOGE("animation is invalid");
457 return MISCDEVICE_NATIVE_SAM_ERR;
458 }
459 int32_t ret = lightHdiConnection_.TurnOn(lightId, color, animation);
460 if (ret != ERR_OK) {
461 MISC_HILOGE("TurnOn failed, error:%{public}d", ret);
462 return ERROR;
463 }
464 return ret;
465 }
466
TurnOff(int32_t lightId)467 int32_t MiscdeviceService::TurnOff(int32_t lightId)
468 {
469 std::string packageName = GetPackageName(GetCallingTokenID());
470 MISC_HILOGI("TurnOff, package:%{public}s", packageName.c_str());
471 if (!IsValid(lightId)) {
472 MISC_HILOGE("lightId is invalid, lightId:%{pubilc}d", lightId);
473 return MISCDEVICE_NATIVE_SAM_ERR;
474 }
475 int32_t ret = lightHdiConnection_.TurnOff(lightId);
476 if (ret != ERR_OK) {
477 MISC_HILOGE("TurnOff failed, error:%{public}d", ret);
478 return ERROR;
479 }
480 return ret;
481 }
482
Dump(int32_t fd,const std::vector<std::u16string> & args)483 int32_t MiscdeviceService::Dump(int32_t fd, const std::vector<std::u16string> &args)
484 {
485 CALL_LOG_ENTER;
486 if (fd < 0) {
487 MISC_HILOGE("Invalid fd");
488 return DUMP_PARAM_ERR;
489 }
490 if (args.empty()) {
491 MISC_HILOGE("args cannot be empty");
492 dprintf(fd, "args cannot be empty\n");
493 DumpHelper->DumpHelp(fd);
494 return DUMP_PARAM_ERR;
495 }
496 std::vector<std::string> argList = { "" };
497 std::transform(args.begin(), args.end(), std::back_inserter(argList),
498 [](const std::u16string &arg) {
499 return Str16ToStr8(arg);
500 });
501 DumpHelper->ParseCommand(fd, argList);
502 return ERR_OK;
503 }
504
PlayPattern(const VibratePattern & pattern,int32_t usage,const VibrateParameter & parameter)505 int32_t MiscdeviceService::PlayPattern(const VibratePattern &pattern, int32_t usage,
506 const VibrateParameter ¶meter)
507 {
508 std::string packageName = GetPackageName(GetCallingTokenID());
509 MISC_HILOGD("Start vibrator pattern, usage:%{public}d, package:%{public}s", usage, packageName.c_str());
510 if ((usage >= USAGE_MAX) || (usage < 0) || (!CheckVibratorParmeters(parameter))) {
511 MISC_HILOGE("Invalid parameter, usage:%{public}d", usage);
512 return PARAMETER_ERROR;
513 }
514 VibratePattern vibratePattern = {
515 .startTime = 0,
516 .events = pattern.events
517 };
518 std::vector<VibratePattern> patterns = {vibratePattern};
519 VibratePackage package = {
520 .patterns = patterns
521 };
522 MergeVibratorParmeters(parameter, package);
523 package.Dump();
524 VibrateInfo info = {
525 .mode = VIBRATE_BUTT,
526 .packageName = packageName,
527 .pid = GetCallingPid(),
528 .uid = GetCallingUid(),
529 .usage = usage,
530 };
531 g_capacity.Dump();
532 if (g_capacity.isSupportHdHaptic) {
533 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
534 if (ShouldIgnoreVibrate(info)) {
535 MISC_HILOGE("Vibration is ignored and high priority is vibrating");
536 return ERROR;
537 }
538 StartVibrateThread(info);
539 return vibratorHdiConnection_.PlayPattern(package.patterns.front());
540 } else if (g_capacity.isSupportPresetMapping) {
541 info.mode = VIBRATE_CUSTOM_COMPOSITE_EFFECT;
542 } else if (g_capacity.isSupportTimeDelay) {
543 info.mode = VIBRATE_CUSTOM_COMPOSITE_TIME;
544 }
545 info.package = package;
546 std::lock_guard<std::mutex> lock(vibratorThreadMutex_);
547 if (ShouldIgnoreVibrate(info)) {
548 MISC_HILOGE("Vibration is ignored and high priority is vibrating");
549 return ERROR;
550 }
551 StartVibrateThread(info);
552 return ERR_OK;
553 }
554
GetDelayTime(int32_t & delayTime)555 int32_t MiscdeviceService::GetDelayTime(int32_t &delayTime)
556 {
557 std::string packageName = GetPackageName(GetCallingTokenID());
558 MISC_HILOGD("GetDelayTime, package:%{public}s", packageName.c_str());
559 return vibratorHdiConnection_.GetDelayTime(g_capacity.GetVibrateMode(), delayTime);
560 }
561
CheckVibratorParmeters(const VibrateParameter & parameter)562 bool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter ¶meter)
563 {
564 if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) ||
565 (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) {
566 MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d",
567 parameter.intensity, parameter.frequency);
568 return false;
569 }
570 return true;
571 }
572
MergeVibratorParmeters(const VibrateParameter & parameter,VibratePackage & package)573 void MiscdeviceService::MergeVibratorParmeters(const VibrateParameter ¶meter, VibratePackage &package)
574 {
575 if ((parameter.intensity == INTENSITY_ADJUST_MAX) && (parameter.frequency == 0)) {
576 MISC_HILOGD("The adjust parameter is not need to merge");
577 return;
578 }
579 parameter.Dump();
580 for (VibratePattern &pattern : package.patterns) {
581 for (VibrateEvent &event : pattern.events) {
582 float intensityScale = static_cast<float>(parameter.intensity) / INTENSITY_ADJUST_MAX;
583 if ((event.tag == EVENT_TAG_TRANSIENT) || (event.points.empty())) {
584 event.intensity = static_cast<int32_t>(event.intensity * intensityScale);
585 event.intensity = std::max(std::min(event.intensity, INTENSITY_MAX), INTENSITY_MIN);
586 event.frequency = event.frequency + parameter.frequency;
587 event.frequency = std::max(std::min(event.frequency, FREQUENCY_MAX), FREQUENCY_MIN);
588 } else {
589 for (VibrateCurvePoint &point : event.points) {
590 point.intensity = static_cast<int32_t>(point.intensity * intensityScale);
591 point.intensity = std::max(std::min(point.intensity, INTENSITY_ADJUST_MAX), INTENSITY_ADJUST_MIN);
592 point.frequency = point.frequency + parameter.frequency;
593 point.frequency = std::max(std::min(point.frequency, FREQUENCY_ADJUST_MAX), FREQUENCY_ADJUST_MIN);
594 }
595 }
596 }
597 }
598 }
599 } // namespace Sensors
600 } // namespace OHOS
601