• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &parameter)
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 &parameter)
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 &parameter)
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 &parameter, 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