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 &parameter)500 int32_t MiscdeviceService::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
501     bool systemUsage, const VibrateParameter &parameter)
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 &parameter)663 int32_t MiscdeviceService::PlayPattern(const VibratePattern &pattern, int32_t usage,
664     bool systemUsage, const VibrateParameter &parameter)
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 &parameter)723 bool MiscdeviceService::CheckVibratorParmeters(const VibrateParameter &parameter)
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 &parameter, VibratePackage &package)734 void MiscdeviceService::MergeVibratorParmeters(const VibrateParameter &parameter, 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