• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "vibrator_service_client.h"
17 
18 #include <algorithm>
19 #include <climits>
20 #include <set>
21 #include <thread>
22 #include <vector>
23 
24 
25 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
26 #include "hisysevent.h"
27 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
28 #ifdef HIVIEWDFX_HITRACE_ENABLE
29 #include "hitrace_meter.h"
30 #endif // HIVIEWDFX_HITRACE_ENABLE
31 #include "iservice_registry.h"
32 #include "securec.h"
33 #include "system_ability_definition.h"
34 
35 #include "death_recipient_template.h"
36 #include "sensors_errors.h"
37 #include "vibrator_decoder_creator.h"
38 
39 #undef LOG_TAG
40 #define LOG_TAG "VibratorServiceClient"
41 
42 namespace OHOS {
43 namespace Sensors {
44 static constexpr int32_t MIN_VIBRATOR_EVENT_TIME = 100;
45 static constexpr int32_t FREQUENCY_UPPER_BOUND = 100;
46 static constexpr int32_t FREQUENCY_LOWER_BOUND = -100;
47 static constexpr int32_t INTENSITY_UPPER_BOUND = 100;
48 static constexpr int32_t INTENSITY_LOWER_BOUND = 0;
49 static constexpr int32_t TAKE_AVERAGE = 2;
50 static constexpr int32_t MAX_PATTERN_EVENT_NUM = 1000;
51 static constexpr int32_t MAX_PATTERN_NUM = 1000;
52 static constexpr int32_t CURVE_POINT_NUM_MIN = 4;
53 static constexpr int32_t CURVE_POINT_NUM_MAX = 16;
54 static constexpr int32_t EVENT_NUM_MAX = 16;
55 static_assert(INTENSITY_UPPER_BOUND != INTENSITY_LOWER_BOUND, "upper bound and lower bound cannot be the same");
56 
57 using namespace OHOS::HiviewDFX;
58 
59 namespace {
60 #if (defined(__aarch64__) || defined(__x86_64__))
61     static const std::string DECODER_LIBRARY_PATH = "/system/lib64/platformsdk/libvibrator_decoder.z.so";
62 #else
63     static const std::string DECODER_LIBRARY_PATH = "/system/lib/platformsdk/libvibrator_decoder.z.so";
64 #endif
65 } // namespace
66 
~VibratorServiceClient()67 VibratorServiceClient::~VibratorServiceClient()
68 {
69     {
70         std::lock_guard<std::mutex> clientLock(clientMutex_);
71         if (miscdeviceProxy_ != nullptr && serviceDeathObserver_ != nullptr) {
72             auto remoteObject = miscdeviceProxy_->AsObject();
73             if (remoteObject != nullptr) {
74                 remoteObject->RemoveDeathRecipient(serviceDeathObserver_);
75             }
76         }
77     }
78     std::lock_guard<std::mutex> decodeLock(decodeMutex_);
79     if (decodeHandle_.destroy != nullptr && decodeHandle_.handle != nullptr) {
80         decodeHandle_.destroy(decodeHandle_.decoder);
81         decodeHandle_.decoder = nullptr;
82         decodeHandle_.Free();
83     }
84 }
85 
InitServiceClient()86 int32_t VibratorServiceClient::InitServiceClient()
87 {
88     CALL_LOG_ENTER;
89     std::lock_guard<std::mutex> clientLock(clientMutex_);
90     if (miscdeviceProxy_ != nullptr) {
91         MISC_HILOGD("miscdeviceProxy_ already init");
92         return ERR_OK;
93     }
94     if (vibratorClient_ == nullptr) {
95         vibratorClient_ = new (std::nothrow) VibratorClientStub();
96     }
97     auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
98     if (sm == nullptr) {
99         MISC_HILOGE("sm cannot be null");
100         return MISC_NATIVE_SAM_ERR;
101     }
102     miscdeviceProxy_ = iface_cast<IMiscdeviceService>(sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID));
103     if (miscdeviceProxy_ != nullptr) {
104         serviceDeathObserver_ =
105             new (std::nothrow) DeathRecipientTemplate(*const_cast<VibratorServiceClient *>(this));
106         CHKPR(serviceDeathObserver_, MISC_NATIVE_GET_SERVICE_ERR);
107         auto remoteObject = miscdeviceProxy_->AsObject();
108         CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
109         remoteObject->AddDeathRecipient(serviceDeathObserver_);
110         int32_t ret = TransferClientRemoteObject();
111         if (ret != ERR_OK) {
112             MISC_HILOGE("TransferClientRemoteObject failed, ret:%{public}d", ret);
113             return ERROR;
114         }
115         return ERR_OK;
116     }
117 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
118     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_EXCEPTION",
119         HiSysEvent::EventType::FAULT, "PKG_NAME", "InitServiceClient", "ERROR_CODE", MISC_NATIVE_GET_SERVICE_ERR);
120 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
121     MISC_HILOGE("Get service failed");
122     return MISC_NATIVE_GET_SERVICE_ERR;
123 }
124 
TransferClientRemoteObject()125 int32_t VibratorServiceClient::TransferClientRemoteObject()
126 {
127     auto remoteObject = vibratorClient_->AsObject();
128     CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
129     CHKPR(miscdeviceProxy_, ERROR);
130 #ifdef HIVIEWDFX_HITRACE_ENABLE
131     StartTrace(HITRACE_TAG_SENSORS, "TransferClientRemoteObject");
132 #endif // HIVIEWDFX_HITRACE_ENABLE
133     int32_t ret = miscdeviceProxy_->TransferClientRemoteObject(remoteObject);
134     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_TRANSFER_CLIENT_REMOTE_OBJECT, ret);
135 #ifdef HIVIEWDFX_HITRACE_ENABLE
136     FinishTrace(HITRACE_TAG_SENSORS);
137 #endif // HIVIEWDFX_HITRACE_ENABLE
138     return ret;
139 }
140 
Vibrate(const VibratorIdentifier & identifier,int32_t timeOut,int32_t usage,bool systemUsage)141 int32_t VibratorServiceClient::Vibrate(const VibratorIdentifier &identifier, int32_t timeOut, int32_t usage,
142     bool systemUsage)
143 {
144     MISC_HILOGD("Vibrate begin, time:%{public}d, usage:%{public}d, deviceId:%{public}d, vibratorId:%{public}d",
145         timeOut, usage, identifier.deviceId, identifier.vibratorId);
146     int32_t ret = InitServiceClient();
147     if (ret != ERR_OK) {
148         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
149         return MISC_NATIVE_GET_SERVICE_ERR;
150     }
151     std::lock_guard<std::mutex> clientLock(clientMutex_);
152     CHKPR(miscdeviceProxy_, ERROR);
153 #ifdef HIVIEWDFX_HITRACE_ENABLE
154     StartTrace(HITRACE_TAG_SENSORS, "VibrateTime");
155 #endif // HIVIEWDFX_HITRACE_ENABLE
156     VibratorIdentifierIPC vibrateIdentifier;
157     vibrateIdentifier.deviceId = identifier.deviceId;
158     vibrateIdentifier.vibratorId = identifier.vibratorId;
159     ret = miscdeviceProxy_->Vibrate(vibrateIdentifier, timeOut, usage, systemUsage);
160     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_VIBRATE, ret);
161 #ifdef HIVIEWDFX_HITRACE_ENABLE
162     FinishTrace(HITRACE_TAG_SENSORS);
163 #endif // HIVIEWDFX_HITRACE_ENABLE
164     if (ret != ERR_OK) {
165         MISC_HILOGE("Vibrate time failed, ret:%{public}d, time:%{public}d, usage:%{public}d", ret, timeOut, usage);
166     }
167     return ret;
168 }
169 
Vibrate(const VibratorIdentifier & identifier,const std::string & effect,int32_t loopCount,int32_t usage,bool systemUsage)170 int32_t VibratorServiceClient::Vibrate(const VibratorIdentifier &identifier, const std::string &effect,
171     int32_t loopCount, int32_t usage, bool systemUsage)
172 {
173     MISC_HILOGD("Vibrate begin, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
174         effect.c_str(), loopCount, usage);
175     int32_t ret = InitServiceClient();
176     if (ret != ERR_OK) {
177         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
178         return MISC_NATIVE_GET_SERVICE_ERR;
179     }
180     std::lock_guard<std::mutex> clientLock(clientMutex_);
181     CHKPR(miscdeviceProxy_, ERROR);
182 #ifdef HIVIEWDFX_HITRACE_ENABLE
183     StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
184 #endif // HIVIEWDFX_HITRACE_ENABLE
185     VibratorIdentifierIPC vibrateIdentifier;
186     vibrateIdentifier.deviceId = identifier.deviceId;
187     vibrateIdentifier.vibratorId = identifier.vibratorId;
188     ret = miscdeviceProxy_->PlayVibratorEffect(vibrateIdentifier, effect, loopCount, usage, systemUsage);
189     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_EFFECT, ret);
190 #ifdef HIVIEWDFX_HITRACE_ENABLE
191     FinishTrace(HITRACE_TAG_SENSORS);
192 #endif // HIVIEWDFX_HITRACE_ENABLE
193     if (ret != ERR_OK) {
194         MISC_HILOGE("Vibrate effect failed, ret:%{public}d, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
195             ret, effect.c_str(), loopCount, usage);
196     }
197     return ret;
198 }
199 
200 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(const VibratorIdentifier & identifier,const RawFileDescriptor & rawFd,int32_t usage,bool systemUsage,const VibratorParameter & parameter)201 int32_t VibratorServiceClient::PlayVibratorCustom(const VibratorIdentifier &identifier, const RawFileDescriptor &rawFd,
202     int32_t usage, bool systemUsage, const VibratorParameter &parameter)
203 {
204     MISC_HILOGD("Vibrate begin, fd:%{public}d, offset:%{public}lld, length:%{public}lld, usage:%{public}d",
205         rawFd.fd, static_cast<long long>(rawFd.offset), static_cast<long long>(rawFd.length), usage);
206     int32_t ret = InitServiceClient();
207     if (ret != ERR_OK) {
208         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
209         return MISC_NATIVE_GET_SERVICE_ERR;
210     }
211     std::lock_guard<std::mutex> clientLock(clientMutex_);
212     CHKPR(miscdeviceProxy_, ERROR);
213 #ifdef HIVIEWDFX_HITRACE_ENABLE
214     StartTrace(HITRACE_TAG_SENSORS, "PlayVibratorCustom");
215 #endif // HIVIEWDFX_HITRACE_ENABLE
216     CustomHapticInfoIPC customHapticInfoIPC;
217     customHapticInfoIPC.usage = usage;
218     customHapticInfoIPC.systemUsage = systemUsage;
219     customHapticInfoIPC.parameter.intensity = parameter.intensity;
220     customHapticInfoIPC.parameter.frequency = parameter.frequency;
221     VibratorIdentifierIPC vibrateIdentifier;
222     vibrateIdentifier.deviceId = identifier.deviceId;
223     vibrateIdentifier.vibratorId = identifier.vibratorId;
224     ret = miscdeviceProxy_->PlayVibratorCustom(vibrateIdentifier, rawFd.fd, rawFd.offset,
225         rawFd.length, customHapticInfoIPC);
226     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_CUSTOM, ret);
227 #ifdef HIVIEWDFX_HITRACE_ENABLE
228     FinishTrace(HITRACE_TAG_SENSORS);
229 #endif // HIVIEWDFX_HITRACE_ENABLE
230     if (ret != ERR_OK) {
231         MISC_HILOGE("PlayVibratorCustom failed, ret:%{public}d, usage:%{public}d", ret, usage);
232     }
233     return ret;
234 }
235 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
236 
StopVibrator(const VibratorIdentifier & identifier,const std::string & mode)237 int32_t VibratorServiceClient::StopVibrator(const VibratorIdentifier &identifier, const std::string &mode)
238 {
239     MISC_HILOGD("StopVibrator begin, deviceId:%{public}d, vibratorId:%{public}d, mode:%{public}s", identifier.deviceId,
240         identifier.vibratorId, mode.c_str());
241     int32_t ret = InitServiceClient();
242     if (ret != ERR_OK) {
243         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
244         return MISC_NATIVE_GET_SERVICE_ERR;
245     }
246     std::lock_guard<std::mutex> clientLock(clientMutex_);
247     CHKPR(miscdeviceProxy_, ERROR);
248 #ifdef HIVIEWDFX_HITRACE_ENABLE
249     StartTrace(HITRACE_TAG_SENSORS, "StopVibratorByMode");
250 #endif // HIVIEWDFX_HITRACE_ENABLE
251     VibratorIdentifierIPC vibrateIdentifier;
252     vibrateIdentifier.deviceId = identifier.deviceId;
253     vibrateIdentifier.vibratorId = identifier.vibratorId;
254     ret = miscdeviceProxy_->StopVibratorByMode(vibrateIdentifier, mode);
255     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR_BY_MODE, ret);
256 #ifdef HIVIEWDFX_HITRACE_ENABLE
257     FinishTrace(HITRACE_TAG_SENSORS);
258 #endif // HIVIEWDFX_HITRACE_ENABLE
259     if (ret != ERR_OK) {
260         MISC_HILOGD("StopVibrator by mode failed, ret:%{public}d, mode:%{public}s", ret, mode.c_str());
261     }
262     return ret;
263 }
264 
StopVibrator(const VibratorIdentifier & identifier)265 int32_t VibratorServiceClient::StopVibrator(const VibratorIdentifier &identifier)
266 {
267     MISC_HILOGD("StopVibrator begin, deviceId:%{public}d, vibratorId:%{public}d", identifier.deviceId,
268         identifier.vibratorId);
269     int32_t ret = InitServiceClient();
270     if (ret != ERR_OK) {
271         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
272         return MISC_NATIVE_GET_SERVICE_ERR;
273     }
274     std::lock_guard<std::mutex> clientLock(clientMutex_);
275     CHKPR(miscdeviceProxy_, ERROR);
276 #ifdef HIVIEWDFX_HITRACE_ENABLE
277     StartTrace(HITRACE_TAG_SENSORS, "StopVibratorAll");
278 #endif // HIVIEWDFX_HITRACE_ENABLE
279     VibratorIdentifierIPC vibrateIdentifier;
280     vibrateIdentifier.deviceId = identifier.deviceId;
281     vibrateIdentifier.vibratorId = identifier.vibratorId;
282     ret = miscdeviceProxy_->StopVibrator(vibrateIdentifier);
283     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR, ret);
284 #ifdef HIVIEWDFX_HITRACE_ENABLE
285     FinishTrace(HITRACE_TAG_SENSORS);
286 #endif // HIVIEWDFX_HITRACE_ENABLE
287     if (ret != ERR_OK) {
288         MISC_HILOGD("StopVibrator failed, ret:%{public}d", ret);
289     }
290     return ret;
291 }
292 
IsHdHapticSupported(const VibratorIdentifier & identifier)293 bool VibratorServiceClient::IsHdHapticSupported(const VibratorIdentifier &identifier)
294 {
295     CALL_LOG_ENTER;
296     int32_t ret = InitServiceClient();
297     if (ret != ERR_OK) {
298         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
299         return MISC_NATIVE_GET_SERVICE_ERR;
300     }
301     VibratorCapacity capacity_;
302     std::lock_guard<std::mutex> clientLock(clientMutex_);
303     CHKPR(miscdeviceProxy_, ERROR);
304 #ifdef HIVIEWDFX_HITRACE_ENABLE
305     StartTrace(HITRACE_TAG_SENSORS, "IsHdHapticSupported");
306 #endif // HIVIEWDFX_HITRACE_ENABLE
307     ret = GetVibratorCapacity(identifier, capacity_);
308 #ifdef HIVIEWDFX_HITRACE_ENABLE
309     FinishTrace(HITRACE_TAG_SENSORS);
310 #endif // HIVIEWDFX_HITRACE_ENABLE
311     if (ret != ERR_OK) {
312         MISC_HILOGE("IsHdHapticSupported failed, ret:%{public}d", ret);
313     }
314     return capacity_.isSupportHdHaptic;
315 }
316 
IsSupportEffect(const VibratorIdentifier & identifier,const std::string & effect,bool & state)317 int32_t VibratorServiceClient::IsSupportEffect(const VibratorIdentifier &identifier, const std::string &effect,
318     bool &state)
319 {
320     MISC_HILOGD("IsSupportEffect begin, effect:%{public}s", effect.c_str());
321     int32_t ret = InitServiceClient();
322     if (ret != ERR_OK) {
323         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
324         return MISC_NATIVE_GET_SERVICE_ERR;
325     }
326     std::lock_guard<std::mutex> clientLock(clientMutex_);
327     CHKPR(miscdeviceProxy_, ERROR);
328 #ifdef HIVIEWDFX_HITRACE_ENABLE
329     StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
330 #endif // HIVIEWDFX_HITRACE_ENABLE
331     VibratorIdentifierIPC vibrateIdentifier;
332     vibrateIdentifier.deviceId = identifier.deviceId;
333     vibrateIdentifier.vibratorId = identifier.vibratorId;
334     ret = miscdeviceProxy_->IsSupportEffect(vibrateIdentifier, effect, state);
335     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_IS_SUPPORT_EFFECT, ret);
336 #ifdef HIVIEWDFX_HITRACE_ENABLE
337     FinishTrace(HITRACE_TAG_SENSORS);
338 #endif // HIVIEWDFX_HITRACE_ENABLE
339     if (ret != ERR_OK) {
340         MISC_HILOGE("Query effect support failed, ret:%{public}d, effect:%{public}s", ret, effect.c_str());
341     }
342     return ret;
343 }
344 
ProcessDeathObserver(const wptr<IRemoteObject> & object)345 void VibratorServiceClient::ProcessDeathObserver(const wptr<IRemoteObject> &object)
346 {
347     CALL_LOG_ENTER;
348     (void)object;
349     {
350         std::lock_guard<std::mutex> clientLock(clientMutex_);
351         miscdeviceProxy_ = nullptr;
352     }
353     int32_t ret = InitServiceClient();
354     if (ret != ERR_OK) {
355         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
356         return;
357     }
358 }
359 
LoadDecoderLibrary(const std::string & path)360 int32_t VibratorServiceClient::LoadDecoderLibrary(const std::string& path)
361 {
362     std::lock_guard<std::mutex> decodeLock(decodeMutex_);
363     if (decodeHandle_.handle != nullptr) {
364         MISC_HILOGD("The library has already been loaded");
365         return ERR_OK;
366     }
367     char libRealPath[PATH_MAX] = {};
368     if (realpath(path.c_str(), libRealPath) == nullptr) {
369         MISC_HILOGE("Get file real path fail");
370         return ERROR;
371     }
372     decodeHandle_.handle = dlopen(libRealPath, RTLD_LAZY);
373     if (decodeHandle_.handle == nullptr) {
374         MISC_HILOGE("dlopen failed, reason:%{public}s", dlerror());
375         return ERROR;
376     }
377     decodeHandle_.create = reinterpret_cast<IVibratorDecoder *(*)(const JsonParser &)>(
378         dlsym(decodeHandle_.handle, "Create"));
379     if (decodeHandle_.create == nullptr) {
380         MISC_HILOGE("dlsym create failed: error: %{public}s", dlerror());
381         decodeHandle_.Free();
382         return ERROR;
383     }
384     decodeHandle_.destroy = reinterpret_cast<void (*)(IVibratorDecoder *)>
385         (dlsym(decodeHandle_.handle, "Destroy"));
386     if (decodeHandle_.destroy == nullptr) {
387         MISC_HILOGE("dlsym destroy failed: error: %{public}s", dlerror());
388         decodeHandle_.Free();
389         return ERROR;
390     }
391     return ERR_OK;
392 }
393 
PreProcess(const VibratorFileDescription & fd,VibratorPackage & package)394 int32_t VibratorServiceClient::PreProcess(const VibratorFileDescription &fd, VibratorPackage &package)
395 {
396     if (LoadDecoderLibrary(DECODER_LIBRARY_PATH) != 0) {
397         MISC_HILOGE("LoadDecoderLibrary fail");
398         return ERROR;
399     }
400     RawFileDescriptor rawFd = {
401         .fd = fd.fd,
402         .offset = fd.offset,
403         .length = fd.length
404     };
405     JsonParser parser(rawFd);
406     std::lock_guard<std::mutex> decodeLock(decodeMutex_);
407     decodeHandle_.decoder = decodeHandle_.create(parser);
408     CHKPR(decodeHandle_.decoder, ERROR);
409     VibratePackage pkg = {};
410     if (decodeHandle_.decoder->DecodeEffect(rawFd, parser, pkg) != 0) {
411         MISC_HILOGE("DecodeEffect fail");
412         decodeHandle_.destroy(decodeHandle_.decoder);
413         decodeHandle_.decoder = nullptr;
414         return ERROR;
415     }
416     decodeHandle_.destroy(decodeHandle_.decoder);
417     decodeHandle_.decoder = nullptr;
418     return ConvertVibratorPackage(pkg, package);
419 }
420 
GetDelayTime(const VibratorIdentifier & identifier,int32_t & delayTime)421 int32_t VibratorServiceClient::GetDelayTime(const VibratorIdentifier &identifier, int32_t &delayTime)
422 {
423     int32_t ret = InitServiceClient();
424     if (ret != ERR_OK) {
425         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
426         return MISC_NATIVE_GET_SERVICE_ERR;
427     }
428     std::lock_guard<std::mutex> clientLock(clientMutex_);
429     CHKPR(miscdeviceProxy_, ERROR);
430 #ifdef HIVIEWDFX_HITRACE_ENABLE
431     StartTrace(HITRACE_TAG_SENSORS, "GetDelayTime");
432 #endif // HIVIEWDFX_HITRACE_ENABLE
433     VibratorIdentifierIPC vibrateIdentifier;
434     vibrateIdentifier.deviceId = identifier.deviceId;
435     vibrateIdentifier.vibratorId = identifier.vibratorId;
436     ret = miscdeviceProxy_->GetDelayTime(vibrateIdentifier, delayTime);
437     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_GET_DELAY_TIME, ret);
438 #ifdef HIVIEWDFX_HITRACE_ENABLE
439     FinishTrace(HITRACE_TAG_SENSORS);
440 #endif // HIVIEWDFX_HITRACE_ENABLE
441     if (ret != ERR_OK) {
442         MISC_HILOGE("GetDelayTime failed, ret:%{public}d", ret);
443     }
444     return ret;
445 }
446 
InitPlayPattern(const VibratorIdentifier & identifier,const VibratorPattern & pattern,int32_t usage,bool systemUsage,const VibratorParameter & parameter)447 int32_t VibratorServiceClient::InitPlayPattern(const VibratorIdentifier &identifier, const VibratorPattern &pattern,
448     int32_t usage, bool systemUsage, const VibratorParameter &parameter)
449 {
450     MISC_HILOGD("Vibrate begin, usage:%{public}d", usage);
451     int32_t ret = InitServiceClient();
452     if (ret != ERR_OK) {
453         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
454         return MISC_NATIVE_GET_SERVICE_ERR;
455     }
456 #ifdef HIVIEWDFX_HITRACE_ENABLE
457     StartTrace(HITRACE_TAG_SENSORS, "PlayPattern");
458 #endif // HIVIEWDFX_HITRACE_ENABLE
459     VibratePattern vibratePattern = {};
460     vibratePattern.startTime = pattern.time;
461     if (pattern.eventNum < 0 || pattern.eventNum > MAX_PATTERN_EVENT_NUM) {
462         MISC_HILOGE("VibratorPattern's eventNum is invalid, eventNum:%{public}d", pattern.eventNum);
463         return ERROR;
464     }
465     for (int32_t i = 0; i < pattern.eventNum; ++i) {
466         if (pattern.events == nullptr) {
467             MISC_HILOGE("VibratorPattern's events is null");
468             return ERROR;
469         }
470         VibrateEvent event;
471         event.tag = static_cast<VibrateTag>(pattern.events[i].type);
472         event.time = pattern.events[i].time;
473         event.duration = pattern.events[i].duration;
474         event.intensity = pattern.events[i].intensity;
475         event.frequency = pattern.events[i].frequency;
476         event.index = pattern.events[i].index;
477         if ((pattern.events[i].pointNum < CURVE_POINT_NUM_MIN) || (pattern.events[i].pointNum > CURVE_POINT_NUM_MAX)) {
478             MISC_HILOGE("The size of curve point is out of bounds, size:%{public}d", pattern.events[i].pointNum);
479             vibratePattern.events.emplace_back(event);
480             vibratePattern.patternDuration = pattern.patternDuration;
481             continue;
482         }
483         for (int32_t j = 0; j < pattern.events[i].pointNum; ++j) {
484             if (pattern.events[i].points == nullptr) {
485                 MISC_HILOGE("VibratorEvent's points is null");
486                 continue;
487             }
488             VibrateCurvePoint point;
489             point.time = pattern.events[i].points[j].time;
490             point.intensity = pattern.events[i].points[j].intensity;
491             point.frequency = pattern.events[i].points[j].frequency;
492             event.points.emplace_back(point);
493         }
494         vibratePattern.events.emplace_back(event);
495         vibratePattern.patternDuration = pattern.patternDuration;
496     }
497     CustomHapticInfoIPC customHapticInfoIPC;
498     customHapticInfoIPC.usage = usage;
499     customHapticInfoIPC.systemUsage = systemUsage;
500     customHapticInfoIPC.parameter.intensity = parameter.intensity;
501     customHapticInfoIPC.parameter.frequency = parameter.frequency;
502     customHapticInfoIPC.parameter.sessionId = parameter.sessionId;
503     VibratorIdentifierIPC vibrateIdentifier;
504     vibrateIdentifier.deviceId = identifier.deviceId;
505     vibrateIdentifier.vibratorId = identifier.vibratorId;
506     std::lock_guard<std::mutex> clientLock(clientMutex_);
507     CHKPR(miscdeviceProxy_, ERROR);
508     ret = miscdeviceProxy_->PlayPattern(vibrateIdentifier, vibratePattern, customHapticInfoIPC);
509     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_PATTERN, ret);
510     return ret;
511 }
512 
PlayPattern(const VibratorIdentifier & identifier,const VibratorPattern & pattern,int32_t usage,bool systemUsage,const VibratorParameter & parameter)513 int32_t VibratorServiceClient::PlayPattern(const VibratorIdentifier &identifier, const VibratorPattern &pattern,
514     int32_t usage, bool systemUsage, const VibratorParameter &parameter)
515 {
516     MISC_HILOGD("Vibrate begin, usage:%{public}d", usage);
517     int32_t ret = InitServiceClient();
518     if (ret != ERR_OK) {
519         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
520         return MISC_NATIVE_GET_SERVICE_ERR;
521     }
522 #ifdef HIVIEWDFX_HITRACE_ENABLE
523     StartTrace(HITRACE_TAG_SENSORS, "PlayPattern");
524 #endif // HIVIEWDFX_HITRACE_ENABLE
525     ret = InitPlayPattern(identifier, pattern, usage, systemUsage, parameter);
526 #ifdef HIVIEWDFX_HITRACE_ENABLE
527     FinishTrace(HITRACE_TAG_SENSORS);
528 #endif // HIVIEWDFX_HITRACE_ENABLE
529     if (ret != ERR_OK) {
530         MISC_HILOGE("PlayPattern failed, ret:%{public}d, usage:%{public}d", ret, usage);
531     }
532     return ret;
533 }
534 
ConvertVibratorPackage(const VibratorPackage & inPkg,VibratePackageIPC & outPkg)535 int32_t VibratorServiceClient::ConvertVibratorPackage(const VibratorPackage& inPkg, VibratePackageIPC &outPkg)
536 {
537     outPkg.packageDuration = inPkg.packageDuration;
538     for (int32_t i = 0; i < inPkg.patternNum; ++i) {
539         if (inPkg.patterns == nullptr) {
540             MISC_HILOGE("VibratorPackage's patterns is null");
541             return ERROR;
542         }
543         VibratePattern vibratePattern = {};
544         vibratePattern.startTime = inPkg.patterns[i].time;
545         vibratePattern.patternDuration = inPkg.patterns[i].patternDuration;
546         for (int32_t j = 0; j < inPkg.patterns[i].eventNum; ++j) {
547             if (inPkg.patterns[i].events == nullptr) {
548                 MISC_HILOGE("vibratePattern's events is null");
549                 return ERROR;
550             }
551             VibrateEvent event;
552             event.tag = static_cast<VibrateTag>(inPkg.patterns[i].events[j].type);
553             event.time = inPkg.patterns[i].events[j].time;
554             event.duration = inPkg.patterns[i].events[j].duration;
555             event.intensity = inPkg.patterns[i].events[j].intensity;
556             event.frequency = inPkg.patterns[i].events[j].frequency;
557             event.index = inPkg.patterns[i].events[j].index;
558             for (int32_t k = 0; k < inPkg.patterns[i].events[j].pointNum; ++k) {
559                 if (inPkg.patterns[i].events[j].points == nullptr) {
560                     MISC_HILOGE("VibratorEvent's points is null");
561                     continue;
562                 }
563                 VibrateCurvePoint point;
564                 point.time = inPkg.patterns[i].events[j].points[k].time;
565                 point.intensity = inPkg.patterns[i].events[j].points[k].intensity;
566                 point.frequency = inPkg.patterns[i].events[j].points[k].frequency;
567                 event.points.emplace_back(point);
568             }
569             vibratePattern.events.emplace_back(event);
570             vibratePattern.patternDuration = inPkg.patterns[i].patternDuration;
571         }
572         outPkg.patterns.emplace_back(vibratePattern);
573     }
574     return ERR_OK;
575 }
576 
PlayPackageBySessionId(const VibratorIdentifier & identifier,const VibratorEffectParameter & parameter,const VibratorPackage & package)577 int32_t VibratorServiceClient::PlayPackageBySessionId(const VibratorIdentifier &identifier,
578     const VibratorEffectParameter &parameter, const VibratorPackage &package)
579 {
580     MISC_HILOGD("PlayPackageBySessionId begin, sessionId:%{public}d", parameter.sessionId);
581     int32_t ret = InitServiceClient();
582     if (ret != ERR_OK) {
583         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
584         return MISC_NATIVE_GET_SERVICE_ERR;
585     }
586     VibratePackageIPC packageIPC;
587     if (ConvertVibratorPackage(package, packageIPC) != ERR_OK) {
588         MISC_HILOGE("VibratorPackage parameter invalid");
589         return PARAMETER_ERROR;
590     }
591     CustomHapticInfoIPC customHapticInfoIPC;
592     customHapticInfoIPC.usage = parameter.usage;
593     customHapticInfoIPC.systemUsage = parameter.systemUsage;
594     customHapticInfoIPC.parameter.intensity = parameter.vibratorParameter.intensity;
595     customHapticInfoIPC.parameter.frequency = parameter.vibratorParameter.frequency;
596     customHapticInfoIPC.parameter.sessionId = parameter.sessionId;
597     VibratorIdentifierIPC vibrateIdentifier;
598     vibrateIdentifier.deviceId = identifier.deviceId;
599     vibrateIdentifier.vibratorId = identifier.vibratorId;
600     std::lock_guard<std::mutex> clientLock(clientMutex_);
601 #ifdef HIVIEWDFX_HITRACE_ENABLE
602     StartTrace(HITRACE_TAG_SENSORS, "PlayPackageBySessionId");
603 #endif // HIVIEWDFX_HITRACE_ENABLE
604     CHKPR(miscdeviceProxy_, ERROR);
605     ret = miscdeviceProxy_->PlayPackageBySessionId(vibrateIdentifier, packageIPC, customHapticInfoIPC);
606     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_PACKAGE_BY_SESSION_ID, ret);
607 #ifdef HIVIEWDFX_HITRACE_ENABLE
608     FinishTrace(HITRACE_TAG_SENSORS);
609 #endif // HIVIEWDFX_HITRACE_ENABLE
610     if (ret != ERR_OK) {
611         MISC_HILOGD("PlayPackageBySessionId failed, ret:%{public}d, sessionId:%{public}d", ret, parameter.sessionId);
612     }
613     return ret;
614 }
615 
StopVibrateBySessionId(const VibratorIdentifier & identifier,uint32_t sessionId)616 int32_t VibratorServiceClient::StopVibrateBySessionId(const VibratorIdentifier &identifier, uint32_t sessionId)
617 {
618     MISC_HILOGD("StopVibrateBySessionId begin, sessionId:%{public}d", sessionId);
619     int32_t ret = InitServiceClient();
620     if (ret != ERR_OK) {
621         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
622         return MISC_NATIVE_GET_SERVICE_ERR;
623     }
624     std::lock_guard<std::mutex> clientLock(clientMutex_);
625 #ifdef HIVIEWDFX_HITRACE_ENABLE
626     StartTrace(HITRACE_TAG_SENSORS, "StopVibrateBySessionId");
627 #endif // HIVIEWDFX_HITRACE_ENABLE
628     VibratorIdentifierIPC vibrateIdentifier;
629     vibrateIdentifier.deviceId = identifier.deviceId;
630     vibrateIdentifier.vibratorId = identifier.vibratorId;
631     CHKPR(miscdeviceProxy_, ERROR);
632     ret = miscdeviceProxy_->StopVibrateBySessionId(vibrateIdentifier, sessionId);
633     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATE_BY_SESSION_ID, ret);
634 #ifdef HIVIEWDFX_HITRACE_ENABLE
635     FinishTrace(HITRACE_TAG_SENSORS);
636 #endif // HIVIEWDFX_HITRACE_ENABLE
637     if (ret != ERR_OK) {
638         MISC_HILOGE("StopVibrateBySessionId failed, ret:%{public}d, sessionId:%{public}d", ret, sessionId);
639     }
640     return ret;
641 }
642 
ConvertVibratorPackage(const VibratePackage & inPkg,VibratorPackage & outPkg)643 int32_t VibratorServiceClient::ConvertVibratorPackage(const VibratePackage& inPkg,
644     VibratorPackage &outPkg)
645 {
646     inPkg.Dump();
647     int32_t patternSize = static_cast<int32_t>(inPkg.patterns.size());
648     VibratorPattern *patterns = (VibratorPattern *)malloc(sizeof(VibratorPattern) * patternSize);
649     CHKPR(patterns, ERROR);
650     outPkg.patternNum = patternSize;
651     int32_t clientPatternDuration = 0;
652     for (int32_t i = 0; i < patternSize; ++i) {
653         patterns[i].time = inPkg.patterns[i].startTime;
654         auto vibrateEvents = inPkg.patterns[i].events;
655         int32_t eventSize = static_cast<int32_t>(vibrateEvents.size());
656         patterns[i].eventNum = eventSize;
657         VibratorEvent *events = (VibratorEvent *)malloc(sizeof(VibratorEvent) * eventSize);
658         if (events == nullptr) {
659             free(patterns);
660             patterns = nullptr;
661             return ERROR;
662         }
663         for (int32_t j = 0; j < eventSize; ++j) {
664             events[j].type = static_cast<VibratorEventType >(vibrateEvents[j].tag);
665             events[j].time = vibrateEvents[j].time;
666             events[j].duration = vibrateEvents[j].duration;
667             events[j].intensity = vibrateEvents[j].intensity;
668             events[j].frequency = vibrateEvents[j].frequency;
669             events[j].index = vibrateEvents[j].index;
670             auto vibratePoints = vibrateEvents[j].points;
671             events[j].pointNum = static_cast<int32_t>(vibratePoints.size());
672             VibratorCurvePoint *points = (VibratorCurvePoint *)malloc(sizeof(VibratorCurvePoint) * events[j].pointNum);
673             if (points == nullptr) {
674                 free(patterns);
675                 patterns = nullptr;
676                 free(events);
677                 events = nullptr;
678                 return ERROR;
679             }
680             for (int32_t k = 0; k < events[j].pointNum; ++k) {
681                 points[k].time = vibratePoints[k].time;
682                 points[k].intensity  = vibratePoints[k].intensity;
683                 points[k].frequency  = vibratePoints[k].frequency;
684             }
685             events[j].points = points;
686             clientPatternDuration = events[j].time + events[j].duration;
687         }
688         patterns[i].events = events;
689         patterns[i].patternDuration = clientPatternDuration;
690     }
691     outPkg.patterns = patterns;
692     outPkg.packageDuration = inPkg.packageDuration;
693     return ERR_OK;
694 }
695 
FreeVibratorPackage(VibratorPackage & package)696 int32_t VibratorServiceClient::FreeVibratorPackage(VibratorPackage &package)
697 {
698     int32_t patternSize = package.patternNum;
699     if ((patternSize <= 0) || (package.patterns == nullptr)) {
700         MISC_HILOGW("Patterns is not need to free, pattern size:%{public}d", patternSize);
701         return ERROR;
702     }
703     auto patterns = package.patterns;
704     for (int32_t i = 0; i < patternSize; ++i) {
705         int32_t eventNum = patterns[i].eventNum;
706         if ((eventNum <= 0) || (patterns[i].events == nullptr)) {
707             MISC_HILOGW("Events is not need to free, event size:%{public}d", eventNum);
708             continue;
709         }
710         auto events = patterns[i].events;
711         for (int32_t j = 0; j < eventNum; ++j) {
712             if (events[j].points != nullptr) {
713                 free(events[j].points);
714                 events[j].points = nullptr;
715             }
716         }
717         free(events);
718         events = nullptr;
719     }
720     free(patterns);
721     patterns = nullptr;
722     return ERR_OK;
723 }
724 
PlayPrimitiveEffect(const VibratorIdentifier & identifier,const std::string & effect,const PrimitiveEffect & primitiveEffect)725 int32_t VibratorServiceClient::PlayPrimitiveEffect(const VibratorIdentifier &identifier, const std::string &effect,
726     const PrimitiveEffect &primitiveEffect)
727 {
728     MISC_HILOGD("Vibrate begin, effect:%{public}s, intensity:%{public}d, usage:%{public}d, count:%{public}d",
729         effect.c_str(), primitiveEffect.intensity, primitiveEffect.usage, primitiveEffect.count);
730     int32_t ret = InitServiceClient();
731     if (ret != ERR_OK) {
732         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
733         return MISC_NATIVE_GET_SERVICE_ERR;
734     }
735     std::lock_guard<std::mutex> clientLock(clientMutex_);
736     CHKPR(miscdeviceProxy_, ERROR);
737 #ifdef HIVIEWDFX_HITRACE_ENABLE
738     StartTrace(HITRACE_TAG_SENSORS, "PlayPrimitiveEffect");
739 #endif // HIVIEWDFX_HITRACE_ENABLE
740     PrimitiveEffectIPC primitiveEffectIPC;
741     primitiveEffectIPC.intensity = primitiveEffect.intensity;
742     primitiveEffectIPC.usage = primitiveEffect.usage;
743     primitiveEffectIPC.systemUsage = primitiveEffect.systemUsage;
744     primitiveEffectIPC.count = primitiveEffect.count;
745     VibratorIdentifierIPC vibrateIdentifier;
746     vibrateIdentifier.deviceId = identifier.deviceId;
747     vibrateIdentifier.vibratorId = identifier.vibratorId;
748     ret = miscdeviceProxy_->PlayPrimitiveEffect(vibrateIdentifier, effect, primitiveEffectIPC);
749     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_PRIMITIVE_EFFECT, ret);
750 #ifdef HIVIEWDFX_HITRACE_ENABLE
751     FinishTrace(HITRACE_TAG_SENSORS);
752 #endif // HIVIEWDFX_HITRACE_ENABLE
753     if (ret != ERR_OK) {
754         MISC_HILOGE("Play primitive effect failed, ret:%{public}d, effect:%{public}s, intensity:%{public}d,"
755             "usage:%{public}d, count:%{public}d", ret, effect.c_str(), primitiveEffect.intensity,
756             primitiveEffect.usage, primitiveEffect.count);
757     }
758     return ret;
759 }
760 
GetVibratorCapacity(const VibratorIdentifier & identifier,VibratorCapacity & capacity)761 int32_t VibratorServiceClient::GetVibratorCapacity(const VibratorIdentifier &identifier, VibratorCapacity &capacity)
762 {
763     CHKPR(miscdeviceProxy_, ERROR);
764 #ifdef HIVIEWDFX_HITRACE_ENABLE
765     StartTrace(HITRACE_TAG_SENSORS, "GetVibratorCapacity");
766 #endif // HIVIEWDFX_HITRACE_ENABLE
767     VibratorIdentifierIPC vibrateIdentifier;
768     vibrateIdentifier.deviceId = identifier.deviceId;
769     vibrateIdentifier.vibratorId = identifier.vibratorId;
770     int32_t ret = miscdeviceProxy_->GetVibratorCapacity(vibrateIdentifier, capacity);
771     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_GET_VIBRATOR_CAPACITY, ret);
772 #ifdef HIVIEWDFX_HITRACE_ENABLE
773     FinishTrace(HITRACE_TAG_SENSORS);
774 #endif // HIVIEWDFX_HITRACE_ENABLE
775     capacity.Dump();
776     return ret;
777 }
778 
IsSupportVibratorCustom(const VibratorIdentifier & identifier)779 bool VibratorServiceClient::IsSupportVibratorCustom(const VibratorIdentifier &identifier)
780 {
781     MISC_HILOGD("Vibrate begin");
782     int32_t ret = InitServiceClient();
783     if (ret != ERR_OK) {
784         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
785     }
786     VibratorCapacity capacity_;
787     std::lock_guard<std::mutex> clientLock(clientMutex_);
788     CHKPR(miscdeviceProxy_, ERROR);
789 #ifdef HIVIEWDFX_HITRACE_ENABLE
790     StartTrace(HITRACE_TAG_SENSORS, "IsSupportVibratorCustom");
791 #endif // HIVIEWDFX_HITRACE_ENABLE
792     ret = GetVibratorCapacity(identifier, capacity_);
793 #ifdef HIVIEWDFX_HITRACE_ENABLE
794     FinishTrace(HITRACE_TAG_SENSORS);
795 #endif // HIVIEWDFX_HITRACE_ENABLE
796     if (ret != ERR_OK) {
797         MISC_HILOGE("Is support vibrator custom, ret:%{public}d", ret);
798     }
799     return (capacity_.isSupportHdHaptic || capacity_.isSupportPresetMapping || capacity_.isSupportTimeDelay);
800 }
801 
SeekTimeOnPackage(int32_t seekTime,const VibratorPackage & completePackage,VibratorPackage & seekPackage)802 int32_t VibratorServiceClient::SeekTimeOnPackage(int32_t seekTime, const VibratorPackage &completePackage,
803     VibratorPackage &seekPackage)
804 {
805     VibratePackage convertPackage = {};
806     ConvertSeekVibratorPackage(completePackage, convertPackage, seekTime);
807     return ConvertVibratorPackage(convertPackage, seekPackage);
808 }
809 
SubscribeVibratorPlugInfo(const VibratorUser * user)810 int32_t VibratorServiceClient::SubscribeVibratorPlugInfo(const VibratorUser *user)
811 {
812     MISC_HILOGD("In, SubscribeVibratorPlugInfo");
813     CHKPR(user, OHOS::Sensors::ERROR);
814     CHKPR(user->callback, OHOS::Sensors::ERROR);
815 
816     int32_t ret = InitServiceClient();
817     if (ret != ERR_OK) {
818         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
819         return MISC_NATIVE_GET_SERVICE_ERR;
820     }
821 
822     std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
823     auto status = subscribeSet_.insert(user);
824     if (!status.second) {
825         MISC_HILOGD("User has been subscribed");
826     } else {
827         std::lock_guard<std::mutex> clientLock(clientMutex_);
828         auto remoteObject = vibratorClient_->AsObject();
829         CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
830         CHKPR(miscdeviceProxy_, ERROR);
831 #ifdef HIVIEWDFX_HITRACE_ENABLE
832         StartTrace(HITRACE_TAG_SENSORS, "SubscribeVibratorPlugInfo");
833 #endif // HIVIEWDFX_HITRACE_ENABLE
834         ret = miscdeviceProxy_->SubscribeVibratorPlugInfo(remoteObject);
835         WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_SUBSCRIBE_VIBRATOR_PLUG_INFO, ret);
836 #ifdef HIVIEWDFX_HITRACE_ENABLE
837         FinishTrace(HITRACE_TAG_SENSORS);
838 #endif // HIVIEWDFX_HITRACE_ENABLE
839         if (ret != ERR_OK) {
840             MISC_HILOGE("Subscribe vibrator plug info failed");
841             return ret;
842         }
843     }
844     return OHOS::Sensors::SUCCESS;
845 }
846 
UnsubscribeVibratorPlugInfo(const VibratorUser * user)847 int32_t VibratorServiceClient::UnsubscribeVibratorPlugInfo(const VibratorUser *user)
848 {
849     MISC_HILOGD("In, UnsubscribeVibratorPlugInfo");
850     CHKPR(user, OHOS::Sensors::ERROR);
851     CHKPR(user->callback, OHOS::Sensors::ERROR);
852 
853     std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
854     if (subscribeSet_.find(user) == subscribeSet_.end()) {
855         MISC_HILOGD("Deactivate user first");
856         return OHOS::Sensors::ERROR;
857     }
858     subscribeSet_.erase(user);
859     return OHOS::Sensors::SUCCESS;
860 }
861 
GetSubscribeUserCallback(int32_t deviceId)862 std::set<RecordVibratorPlugCallback> VibratorServiceClient::GetSubscribeUserCallback(int32_t deviceId)
863 {
864     CALL_LOG_ENTER;
865     std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
866     std::set<RecordVibratorPlugCallback> callback;
867     for (const auto &it : subscribeSet_) {
868         auto ret = callback.insert(it->callback);
869         if (!ret.second) {
870             MISC_HILOGD("callback insert fail");
871         }
872     }
873     return callback;
874 }
875 
HandleVibratorData(VibratorStatusEvent statusEvent)876 bool VibratorServiceClient::HandleVibratorData(VibratorStatusEvent statusEvent) __attribute__((no_sanitize("cfi")))
877 {
878     CALL_LOG_ENTER;
879     if (statusEvent.type == PLUG_STATE_EVENT_PLUG_OUT) {
880         std::lock_guard<std::mutex> VibratorEffectLock(vibratorEffectMutex_);
881         for (auto it = vibratorEffectMap_.begin(); it != vibratorEffectMap_.end();) {
882             if (it->first.deviceId == statusEvent.deviceId) {
883                 it = vibratorEffectMap_.erase(it);
884             } else {
885                 ++it;
886             }
887         }
888     }
889     std::lock_guard<std::recursive_mutex> subscribeLock(subscribeMutex_);
890     auto callbacks = GetSubscribeUserCallback(statusEvent.deviceId);
891     MISC_HILOGD("callbacks.size() = %{public}zu", callbacks.size());
892     MISC_HILOGD("VibratorStatusEvent = [type = %{public}d, deviceId = %{public}d]",
893                 statusEvent.type, statusEvent.deviceId);
894     for (const auto &callback : callbacks) {
895         MISC_HILOGD("callback is run");
896         if (callback != nullptr)
897             callback(&statusEvent);
898     }
899     return true;
900 }
901 
SetUsage(const VibratorIdentifier & identifier,int32_t usage,bool systemUsage)902 void VibratorServiceClient::SetUsage(const VibratorIdentifier &identifier, int32_t usage, bool systemUsage)
903 {
904     std::lock_guard<std::mutex> VibratorEffectLock(vibratorEffectMutex_);
905     auto it = vibratorEffectMap_.find(identifier);
906     if (it != vibratorEffectMap_.end()) {
907         it->second.usage = usage;
908         it->second.systemUsage = systemUsage;
909     } else {
910         VibratorEffectParameter param = {
911             .usage = usage,
912             .systemUsage = systemUsage,
913         };
914         vibratorEffectMap_[identifier] = param;
915     }
916 }
917 
SetLoopCount(const VibratorIdentifier & identifier,int32_t count)918 void VibratorServiceClient::SetLoopCount(const VibratorIdentifier &identifier, int32_t count)
919 {
920     std::lock_guard<std::mutex> VibratorEffectLock(vibratorEffectMutex_);
921     auto it = vibratorEffectMap_.find(identifier);
922     if (it != vibratorEffectMap_.end()) {
923         it->second.loopCount = count;
924     } else {
925         VibratorEffectParameter param = {
926             .loopCount = count,
927         };
928         vibratorEffectMap_[identifier] = param;
929     }
930 }
931 
SetParameters(const VibratorIdentifier & identifier,const VibratorParameter & parameter)932 void VibratorServiceClient::SetParameters(const VibratorIdentifier &identifier, const VibratorParameter &parameter)
933 {
934     std::lock_guard<std::mutex> VibratorEffectLock(vibratorEffectMutex_);
935     auto it = vibratorEffectMap_.find(identifier);
936     if (it != vibratorEffectMap_.end()) {
937         it->second.vibratorParameter = parameter;
938     } else {
939         VibratorEffectParameter param = {
940             .vibratorParameter = parameter,
941         };
942         vibratorEffectMap_[identifier] = param;
943     }
944 }
945 
GetVibratorEffectParameter(const VibratorIdentifier & identifier)946 VibratorEffectParameter VibratorServiceClient::GetVibratorEffectParameter(const VibratorIdentifier &identifier)
947 {
948     std::lock_guard<std::mutex> VibratorEffectLock(vibratorEffectMutex_);
949     auto it = vibratorEffectMap_.find(identifier);
950     if (it != vibratorEffectMap_.end()) {
951         return it->second;
952     }
953     return VibratorEffectParameter();
954 }
955 
ConvertSeekVibratorPackage(const VibratorPackage & completePackage,VibratePackage & convertPackage,int32_t seekTime)956 void VibratorServiceClient::ConvertSeekVibratorPackage(const VibratorPackage &completePackage,
957     VibratePackage &convertPackage, int32_t seekTime)
958 {
959     convertPackage.packageDuration = completePackage.packageDuration;
960     if (completePackage.patternNum < 0 || completePackage.patternNum > MAX_PATTERN_NUM) {
961         MISC_HILOGE("completePackage.patternNum is invalid, patternNum:%{public}d", completePackage.patternNum);
962         return;
963     }
964     for (int32_t i = 0; i < completePackage.patternNum; ++i) {
965         VibratePattern vibratePattern = {};
966         int32_t patternStartTime = completePackage.patterns[i].time;
967         if (patternStartTime >= seekTime) {
968             ConvertVibratorPattern(completePackage.patterns[i], vibratePattern);
969             convertPackage.patterns.emplace_back(vibratePattern);
970             continue;
971         }
972         vibratePattern.startTime = seekTime;
973         if (completePackage.patterns[i].eventNum <= 0 || completePackage.patterns[i].eventNum > EVENT_NUM_MAX) {
974             MISC_HILOGE("The size of pattern is out of bounds, size:%{public}d", completePackage.patterns[i].eventNum);
975             if (vibratePattern.events.empty()) {
976                 continue;
977             }
978             convertPackage.patterns.emplace_back(vibratePattern);
979             continue;
980         }
981         for (int32_t j = 0; j < completePackage.patterns[i].eventNum; ++j) {
982             VibrateEvent vibrateEvent = {};
983             if (SkipEventAndConvertVibratorEvent(completePackage.patterns[i].events[j], vibratePattern,
984                                                  patternStartTime, vibrateEvent)) {
985                 convertPackage.packageDuration -= completePackage.patterns[i].events[j].duration;
986                 convertPackage.packageDuration += vibrateEvent.duration;
987                 convertPackage.packageDuration = convertPackage.packageDuration < 0 ? 0
988                                                                                     : convertPackage.packageDuration;
989                 continue;
990             }
991             vibrateEvent.tag = static_cast<VibrateTag>(completePackage.patterns[i].events[j].type);
992             vibrateEvent.time = completePackage.patterns[i].events[j].time + patternStartTime - seekTime;
993             vibrateEvent.duration = completePackage.patterns[i].events[j].duration;
994             vibrateEvent.intensity = completePackage.patterns[i].events[j].intensity;
995             vibrateEvent.frequency = completePackage.patterns[i].events[j].frequency;
996             vibrateEvent.index = completePackage.patterns[i].events[j].index;
997             int32_t pointNum = completePackage.patterns[i].events[j].pointNum;
998             if ((pointNum < CURVE_POINT_NUM_MIN) || (pointNum > CURVE_POINT_NUM_MAX)) {
999                 MISC_HILOGE("The size of curve point is out of bounds, size:%{public}d", pointNum);
1000                 vibratePattern.patternDuration += vibrateEvent.duration;
1001                 vibratePattern.events.emplace_back(vibrateEvent);
1002                 continue;
1003             }
1004             for (size_t k = 0; k < static_cast<uint32_t>(pointNum); ++k) {
1005                 VibrateCurvePoint vibrateCurvePoint = {};
1006                 vibrateCurvePoint.time = completePackage.patterns[i].events[j].points[k].time;
1007                 vibrateCurvePoint.intensity = completePackage.patterns[i].events[j].points[k].intensity;
1008                 vibrateCurvePoint.frequency = completePackage.patterns[i].events[j].points[k].frequency;
1009                 vibrateEvent.points.emplace_back(vibrateCurvePoint);
1010             }
1011             vibratePattern.patternDuration += vibrateEvent.duration;
1012             vibratePattern.events.emplace_back(vibrateEvent);
1013         }
1014         if (vibratePattern.events.empty()) {
1015             continue;
1016         }
1017         convertPackage.patterns.emplace_back(vibratePattern);
1018     }
1019 }
1020 
ConvertVibratorPattern(const VibratorPattern & vibratorPattern,VibratePattern & vibratePattern)1021 void VibratorServiceClient::ConvertVibratorPattern(const VibratorPattern &vibratorPattern,
1022     VibratePattern &vibratePattern)
1023 {
1024     vibratePattern.startTime = vibratorPattern.time;
1025     vibratePattern.patternDuration = vibratorPattern.patternDuration;
1026     if (vibratorPattern.eventNum < 0 || vibratorPattern.eventNum > MAX_PATTERN_EVENT_NUM) {
1027         MISC_HILOGE("VibratorPattern's eventNum is invalid, eventNum:%{public}d", vibratorPattern.eventNum);
1028         return;
1029     }
1030     for (int32_t j = 0; j < vibratorPattern.eventNum; ++j) {
1031         VibrateEvent vibrateEvent = {};
1032         vibrateEvent.tag = static_cast<VibrateTag>(vibratorPattern.events[j].type);
1033         vibrateEvent.time = vibratorPattern.events[j].time;
1034         vibrateEvent.duration = vibratorPattern.events[j].duration;
1035         vibrateEvent.intensity = vibratorPattern.events[j].intensity;
1036         vibrateEvent.frequency = vibratorPattern.events[j].frequency;
1037         vibrateEvent.index = vibratorPattern.events[j].index;
1038         for (size_t k = 0; k < static_cast<uint32_t>(vibratorPattern.events[j].pointNum); ++k) {
1039             VibrateCurvePoint vibrateCurvePoint = {};
1040             vibrateCurvePoint.time = vibratorPattern.events[j].points[k].time;
1041             vibrateCurvePoint.intensity = vibratorPattern.events[j].points[k].intensity;
1042             vibrateCurvePoint.frequency = vibratorPattern.events[j].points[k].frequency;
1043             vibrateEvent.points.emplace_back(vibrateCurvePoint);
1044         }
1045         vibratePattern.events.emplace_back(vibrateEvent);
1046     }
1047 }
1048 
ModulatePackage(const VibratorEvent & modulationCurve,const VibratorPackage & beforeModulationPackage,VibratorPackage & afterModulationPackage)1049 int32_t VibratorServiceClient::ModulatePackage(const VibratorEvent &modulationCurve,
1050     const VibratorPackage &beforeModulationPackage, VibratorPackage &afterModulationPackage)
1051 {
1052     if (beforeModulationPackage.patternNum <= 0 || beforeModulationPackage.patterns == nullptr) {
1053         MISC_HILOGE("ModulatePackage failed: patternNum is less than 0 or patterns is null");
1054         return ERROR;
1055     }
1056     if (modulationCurve.time < 0 || modulationCurve.duration < 0 || modulationCurve.pointNum <= 0
1057         || modulationCurve.points == nullptr) {
1058         MISC_HILOGE("ModulatePackage failed: invalid modulationCurve, time: %{public}d, duration: %{public}d, "
1059             "pointNum: %{public}d", modulationCurve.time, modulationCurve.duration, modulationCurve.pointNum);
1060         return ERROR;
1061     }
1062     afterModulationPackage = beforeModulationPackage;
1063     afterModulationPackage.patterns = nullptr;
1064     VibratorPattern *vibratePattern = nullptr;
1065     vibratePattern = static_cast<VibratorPattern *>(
1066         calloc(beforeModulationPackage.patternNum, sizeof(VibratorPattern)));
1067     if (vibratePattern == nullptr) {
1068         MISC_HILOGE("ModulatePackage failed: failure of memory allocation for VibratePattern");
1069         return ERROR;
1070     }
1071     for (int32_t i = 0; i < beforeModulationPackage.patternNum; i++) {
1072         const VibratorPattern &beforeModPattern = beforeModulationPackage.patterns[i];
1073         VibratorPattern &afterModPattern = vibratePattern[i];
1074         afterModPattern.events = nullptr;
1075         if (ModulateVibratorPattern(modulationCurve, beforeModPattern, afterModPattern) != ERR_OK) {
1076             MISC_HILOGE("ModulatePackage failed: failure of ModulateVibratorPattern");
1077             FreePartiallyAllocatedVibratorPatterns(&vibratePattern, i);
1078             return ERROR;
1079         }
1080     }
1081     afterModulationPackage.patterns = vibratePattern;
1082     return ERR_OK;
1083 }
1084 
1085 /**
1086  * fields 'time' in VibratorPattern,VibratorEvent and VibratorCurvePoint is shown in following figure
1087  *        |--------------------------------|-------------------------|-------------------------|----------------
1088  *   VibratorPattern.time          when event happens     when curve point 1 happens    when curve point 2 happens
1089  *        |<-------VibratorEvent.time----->|
1090  *                                                                   |<--curvePoint 1's time-->|
1091  *                                                                    (VibratorCurvePoint.time)
1092  */
ModulateVibratorPattern(const VibratorEvent & modulationCurve,const VibratorPattern & beforeModulationPattern,VibratorPattern & afterModulationPattern)1093 int32_t VibratorServiceClient::ModulateVibratorPattern(const VibratorEvent &modulationCurve,
1094     const VibratorPattern &beforeModulationPattern, VibratorPattern &afterModulationPattern)
1095 {
1096     if (beforeModulationPattern.eventNum <= 0 || beforeModulationPattern.events == nullptr) {
1097         MISC_HILOGE("ModulatePackage failed due to invalid parameter");
1098         return ERROR;
1099     }
1100     VibratorEvent* eventsAfterMod = static_cast<VibratorEvent *>(
1101         calloc(beforeModulationPattern.eventNum, sizeof(VibratorEvent)));
1102     if (eventsAfterMod == nullptr) {
1103         MISC_HILOGE("ModulatePackage failed due to failure of memory allocation for VibratorEvent");
1104         return ERROR;
1105     }
1106     for (int i = 0; i < beforeModulationPattern.eventNum; i++) {
1107         eventsAfterMod[i].points = nullptr;
1108         if (ModulateVibratorEvent(modulationCurve, beforeModulationPattern.time,
1109             beforeModulationPattern.events[i], eventsAfterMod[i]) != ERR_OK) {
1110             MISC_HILOGE("ModulatePackage failed due to failure of handling VibrateEvent");
1111             FreePartiallyAllocatedVibratorEvents(&eventsAfterMod, i);
1112             afterModulationPattern.events = nullptr;
1113             return ERROR;
1114         }
1115     }
1116     afterModulationPattern = beforeModulationPattern;
1117     afterModulationPattern.events = eventsAfterMod;
1118     return ERR_OK;
1119 }
1120 
FreePartiallyAllocatedVibratorPatterns(VibratorPattern ** patterns,int32_t partialIdx)1121 void VibratorServiceClient::FreePartiallyAllocatedVibratorPatterns(VibratorPattern** patterns, int32_t partialIdx)
1122 {
1123     if (patterns == nullptr || *patterns == nullptr) {
1124         MISC_HILOGW("FreePartiallyAllocatedVibratorPatterns failed because patterns is null");
1125         return;
1126     }
1127     for (int32_t i = partialIdx; i >= 0; i--) {
1128         FreePartiallyAllocatedVibratorEvents(&((*patterns)[i].events), (*patterns)[i].eventNum - 1);
1129         (*patterns)[i].events = nullptr;
1130     }
1131     free(*patterns);
1132     *patterns = nullptr;
1133 }
1134 
FreePartiallyAllocatedVibratorEvents(VibratorEvent ** events,int32_t partialIdx)1135 void VibratorServiceClient::FreePartiallyAllocatedVibratorEvents(VibratorEvent** events, int32_t partialIdx)
1136 {
1137     if (events == nullptr || *events == nullptr) {
1138         MISC_HILOGW("FreePartiallyAllocatedVibratorEvents failed because events is null");
1139         return;
1140     }
1141     for (int32_t i = partialIdx; i >= 0; i--) {
1142         free((*events)[i].points);
1143         (*events)[i].points = nullptr;
1144     }
1145     free(*events);
1146     *events = nullptr;
1147 }
1148 
ModulateVibratorEvent(const VibratorEvent & modulationCurve,int32_t patternStartTime,const VibratorEvent & beforeModulationEvent,VibratorEvent & afterModulationEvent)1149 int32_t VibratorServiceClient::ModulateVibratorEvent(const VibratorEvent &modulationCurve,
1150     int32_t patternStartTime, const VibratorEvent &beforeModulationEvent, VibratorEvent &afterModulationEvent)
1151 {
1152     std::vector<VibratorCurveInterval> modInterval;
1153     ConvertVibratorEventsToCurveIntervals(modulationCurve, 0, modInterval);
1154     if (beforeModulationEvent.type != EVENT_TYPE_CONTINUOUS || beforeModulationEvent.pointNum == 0 ||
1155         beforeModulationEvent.points == nullptr) {
1156         return ModulateEventWithoutCurvePoints(modInterval, patternStartTime,
1157             beforeModulationEvent, afterModulationEvent);
1158     }
1159     return ModulateEventWithCurvePoints(modInterval, patternStartTime, beforeModulationEvent, afterModulationEvent);
1160 }
1161 
ModulateEventWithoutCurvePoints(const std::vector<VibratorCurveInterval> & modInterval,int32_t patternStartTime,const VibratorEvent & beforeModEvent,VibratorEvent & afterModEvent)1162 int32_t VibratorServiceClient::ModulateEventWithoutCurvePoints(const std::vector<VibratorCurveInterval>& modInterval,
1163     int32_t patternStartTime, const VibratorEvent &beforeModEvent, VibratorEvent &afterModEvent)
1164 {
1165     afterModEvent = beforeModEvent;
1166     afterModEvent.pointNum = 0;
1167     afterModEvent.points = nullptr;
1168     int32_t startTime = beforeModEvent.time + patternStartTime;
1169     int32_t idx = 0;
1170     BinarySearchInterval(modInterval, startTime, idx);
1171     if (idx >= 0) {
1172         afterModEvent.intensity = RestrictIntensityRange(
1173             beforeModEvent.intensity * modInterval[idx].intensity / (INTENSITY_UPPER_BOUND - INTENSITY_LOWER_BOUND));
1174         afterModEvent.frequency = RestrictFrequencyRange(beforeModEvent.frequency + modInterval[idx].frequency);
1175     }
1176     return ERR_OK;
1177 }
1178 
1179 // absoluteTime = VibratorPattern::time + VibratorEvent::time + VibratorCurvePoint::time
ModulateEventWithCurvePoints(std::vector<VibratorCurveInterval> & modInterval,int32_t patternStartTime,const VibratorEvent & beforeModulationEvent,VibratorEvent & afterModulationEvent)1180 int32_t VibratorServiceClient::ModulateEventWithCurvePoints(std::vector<VibratorCurveInterval>& modInterval,
1181     int32_t patternStartTime, const VibratorEvent &beforeModulationEvent, VibratorEvent &afterModulationEvent)
1182 {
1183     if (beforeModulationEvent.pointNum == 0 || beforeModulationEvent.points == nullptr) {
1184         MISC_HILOGE("ModulateContinuousVibratorEvent: invalid event, event should hava curve points");
1185         return ERROR;
1186     }
1187     if (beforeModulationEvent.pointNum < CURVE_POINT_NUM_MIN || beforeModulationEvent.pointNum > CURVE_POINT_NUM_MAX) {
1188         MISC_HILOGE("ModulateContinuousVibratorEvent: invalid event, count of curve points should range from "
1189             "%{public}d to %{public}d", CURVE_POINT_NUM_MIN, CURVE_POINT_NUM_MAX);
1190         return ERROR;
1191     }
1192     VibratorCurvePoint* curvePoints = GetCurveListAfterModulation(modInterval, beforeModulationEvent, patternStartTime);
1193     if (curvePoints == nullptr) {
1194         MISC_HILOGE("ModulateContinuousVibratorEvent failed due to failure of GetCurveListAfterModulation");
1195         return ERROR;
1196     }
1197     afterModulationEvent = beforeModulationEvent;
1198     afterModulationEvent.points = curvePoints;
1199     return ERR_OK;
1200 }
1201 
GetCurveListAfterModulation(const std::vector<VibratorCurveInterval> & modInterval,const VibratorEvent & beforeModEvent,int32_t patternOffset)1202 VibratorCurvePoint* VibratorServiceClient::GetCurveListAfterModulation(
1203     const std::vector<VibratorCurveInterval>& modInterval, const VibratorEvent &beforeModEvent,
1204     int32_t patternOffset)
1205 {
1206     VibratorCurvePoint* curvePoints = static_cast<VibratorCurvePoint *>(
1207         calloc(beforeModEvent.pointNum, sizeof(VibratorCurvePoint)));
1208     if (curvePoints == nullptr) {
1209         MISC_HILOGE("ModulateVibratorEvent failed due to failure of memory allocation for VibratorCurvePoint");
1210         return nullptr;
1211     }
1212     int32_t modIdx = 0;
1213     int32_t startTimeOffset = patternOffset + beforeModEvent.time;
1214     for (int32_t curveIdx = 0; curveIdx < beforeModEvent.pointNum; curveIdx++) {
1215         const VibratorCurvePoint& beforeModCurvePoint = beforeModEvent.points[curveIdx];
1216         curvePoints[curveIdx] = beforeModCurvePoint;
1217         BinarySearchInterval(modInterval, startTimeOffset + beforeModCurvePoint.time, modIdx);
1218         if (modIdx >= 0) {
1219             curvePoints[curveIdx].intensity = RestrictIntensityRange(
1220                 beforeModCurvePoint.intensity * modInterval[modIdx].intensity /
1221                 (INTENSITY_UPPER_BOUND - INTENSITY_LOWER_BOUND));
1222             curvePoints[curveIdx].frequency = RestrictFrequencyRange(
1223                 beforeModCurvePoint.frequency + modInterval[modIdx].frequency);
1224         }
1225     }
1226     return curvePoints;
1227 }
1228 
BinarySearchInterval(const std::vector<VibratorCurveInterval> & interval,int32_t val,int32_t & idx)1229 void VibratorServiceClient::BinarySearchInterval(
1230     const std::vector<VibratorCurveInterval>& interval, int32_t val, int32_t& idx)
1231 {
1232     if (val < interval.begin()->beginTime || val > interval.rbegin()->endTime) {
1233         idx = -1;
1234         return;
1235     }
1236     if (val >= interval.begin()->beginTime && val <= interval.begin()->endTime) {
1237         idx = 0;
1238         return;
1239     }
1240     int32_t headIdx = 0;
1241     int32_t tailIdx = static_cast<int32_t>(interval.size() - 1);
1242     while (tailIdx - headIdx > 1) {
1243         int32_t middleIdx = ((tailIdx - headIdx) / TAKE_AVERAGE) + headIdx;
1244         if (interval[middleIdx].endTime < val) {
1245             headIdx = middleIdx;
1246         } else {
1247             tailIdx = middleIdx;
1248         }
1249     }
1250     idx = tailIdx;
1251     return;
1252 }
1253 
ConvertVibratorEventsToCurveIntervals(const VibratorEvent & vibratorEvent,int32_t patternTimeOffset,std::vector<VibratorCurveInterval> & curveInterval)1254 void VibratorServiceClient::ConvertVibratorEventsToCurveIntervals(
1255     const VibratorEvent &vibratorEvent, int32_t patternTimeOffset, std::vector<VibratorCurveInterval>& curveInterval)
1256 {
1257     int32_t fullOffset = patternTimeOffset + vibratorEvent.time;
1258     const VibratorCurvePoint* curvePoints = vibratorEvent.points;
1259     for (int32_t i = 0; i < vibratorEvent.pointNum; i++) {
1260         if (curvePoints[i].time < vibratorEvent.duration) {
1261             int32_t beginTime = fullOffset + curvePoints[i].time;
1262             int32_t endTime = fullOffset + ((i + 1) < vibratorEvent.pointNum ?
1263                 std::min(curvePoints[i + 1].time, vibratorEvent.duration) : vibratorEvent.duration);
1264             int32_t frequency = curvePoints[i].frequency;
1265             int32_t intensity = curvePoints[i].intensity;
1266             curveInterval.emplace_back(VibratorCurveInterval{
1267                 .beginTime = beginTime, .endTime = endTime, .intensity = intensity, .frequency = frequency});
1268         } else {
1269             break;
1270         }
1271     }
1272 }
1273 
RestrictFrequencyRange(int32_t frequency)1274 int32_t VibratorServiceClient::RestrictFrequencyRange(int32_t frequency)
1275 {
1276     if (frequency > FREQUENCY_UPPER_BOUND) {
1277         return FREQUENCY_UPPER_BOUND;
1278     } else if (frequency < FREQUENCY_LOWER_BOUND) {
1279         return FREQUENCY_LOWER_BOUND;
1280     } else {
1281         return frequency;
1282     }
1283 }
1284 
RestrictIntensityRange(int32_t intensity)1285 int32_t VibratorServiceClient::RestrictIntensityRange(int32_t intensity)
1286 {
1287     if (intensity > INTENSITY_UPPER_BOUND) {
1288         return INTENSITY_UPPER_BOUND;
1289     } else if (intensity < INTENSITY_LOWER_BOUND) {
1290         return INTENSITY_LOWER_BOUND;
1291     } else {
1292         return intensity;
1293     }
1294 }
1295 
SkipEventAndConvertVibratorEvent(const VibratorEvent & vibratorEvent,VibratePattern & vibratePattern,int32_t patternStartTime,VibrateEvent & vibrateEvent)1296 bool VibratorServiceClient::SkipEventAndConvertVibratorEvent(const VibratorEvent &vibratorEvent,
1297     VibratePattern &vibratePattern, int32_t patternStartTime, VibrateEvent &vibrateEvent)
1298 {
1299     int32_t eventStartTime = vibratorEvent.time + patternStartTime;
1300     if (vibratePattern.startTime > eventStartTime) {
1301         if (vibratorEvent.type == EVENT_TYPE_CONTINUOUS &&
1302             (eventStartTime + vibratorEvent.duration - vibratePattern.startTime) >= MIN_VIBRATOR_EVENT_TIME) {
1303             vibrateEvent.tag = static_cast<VibrateTag>(vibratorEvent.type);
1304             vibrateEvent.duration = eventStartTime + vibratorEvent.duration - vibratePattern.startTime;
1305             vibrateEvent.intensity = vibratorEvent.intensity;
1306             vibrateEvent.frequency = vibratorEvent.frequency;
1307             vibrateEvent.index = vibratorEvent.index;
1308             vibratePattern.patternDuration += vibrateEvent.duration;
1309             vibratePattern.events.emplace_back(vibrateEvent);
1310         }
1311         return true;
1312     }
1313     return false;
1314 }
1315 
GetVibratorList(const VibratorIdentifier & identifier,std::vector<VibratorInfos> & vibratorInfo)1316 int32_t VibratorServiceClient::GetVibratorList(const VibratorIdentifier& identifier,
1317     std::vector<VibratorInfos>& vibratorInfo)
1318 {
1319     CALL_LOG_ENTER;
1320     MISC_HILOGD("VibratorIdentifier = [deviceId = %{public}d, vibratorId = %{public}d]", identifier.deviceId,
1321         identifier.vibratorId);
1322     int32_t ret = InitServiceClient();
1323     if (ret != ERR_OK) {
1324         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
1325         return MISC_NATIVE_GET_SERVICE_ERR;
1326     }
1327     CHKPR(miscdeviceProxy_, OHOS::Sensors::ERROR);
1328 
1329     VibratorIdentifierIPC param;
1330     param.deviceId = identifier.deviceId;
1331     param.vibratorId = identifier.vibratorId;
1332     std::vector<VibratorInfoIPC> vibratorInfoList;
1333 #ifdef HIVIEWDFX_HITRACE_ENABLE
1334     StartTrace(HITRACE_TAG_SENSORS, "GetVibratorList");
1335 #endif // HIVIEWDFX_HITRACE_ENABLE
1336     ret = miscdeviceProxy_->GetVibratorList(param, vibratorInfoList);
1337     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_GET_VIBRATOR_LIST, ret);
1338 #ifdef HIVIEWDFX_HITRACE_ENABLE
1339     FinishTrace(HITRACE_TAG_SENSORS);
1340 #endif // HIVIEWDFX_HITRACE_ENABLE
1341     if (ret != ERR_OK) {
1342         MISC_HILOGE("Get vibrator info list failed, [ret = %{public}d, deviceId = %{public}d,\
1343             vibratorId = %{public}d]", ret, identifier.deviceId, identifier.vibratorId);
1344         return ret;
1345     }
1346     for (auto &info : vibratorInfoList) {
1347         VibratorInfos resInfo;
1348         resInfo.deviceId = info.deviceId;
1349         resInfo.vibratorId = info.vibratorId;
1350         resInfo.deviceName = info.deviceName;
1351         resInfo.isSupportHdHaptic = info.isSupportHdHaptic;
1352         resInfo.isLocalVibrator = info.isLocalVibrator;
1353         vibratorInfo.push_back(resInfo);
1354     }
1355     return OHOS::Sensors::SUCCESS;
1356 }
1357 
GetEffectInfo(const VibratorIdentifier & identifier,const std::string & effectType,EffectInfo & effectInfo)1358 int32_t VibratorServiceClient::GetEffectInfo(const VibratorIdentifier& identifier,
1359     const std::string& effectType, EffectInfo& effectInfo)
1360 {
1361     CALL_LOG_ENTER;
1362     MISC_HILOGD("VibratorIdentifier = [deviceId = %{public}d, vibratorId = %{public}d, effectType = %{public}s]",
1363         identifier.deviceId, identifier.vibratorId, effectType.c_str());
1364     int32_t ret = InitServiceClient();
1365     if (ret != OHOS::Sensors::SUCCESS) {
1366         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
1367         return MISC_NATIVE_GET_SERVICE_ERR;
1368     }
1369     CHKPR(miscdeviceProxy_, OHOS::Sensors::ERROR);
1370     VibratorIdentifierIPC param;
1371     param.deviceId = identifier.deviceId;
1372     param.vibratorId = identifier.vibratorId;
1373     EffectInfoIPC resInfo;
1374 #ifdef HIVIEWDFX_HITRACE_ENABLE
1375     StartTrace(HITRACE_TAG_SENSORS, "GetEffectInfo");
1376 #endif // HIVIEWDFX_HITRACE_ENABLE
1377     ret = miscdeviceProxy_->GetEffectInfo(param, effectType, resInfo);
1378     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_GET_EFFECT_INFO, ret);
1379 #ifdef HIVIEWDFX_HITRACE_ENABLE
1380     FinishTrace(HITRACE_TAG_SENSORS);
1381 #endif // HIVIEWDFX_HITRACE_ENABLE
1382     if (ret != ERR_OK) {
1383         MISC_HILOGE("Get effect info failed, [ret = %{public}d, deviceId = %{public}d, vibratorId = %{public}d,\
1384             effectType = %{public}s]", ret, identifier.deviceId, identifier.vibratorId, effectType.c_str());
1385         return ret;
1386     }
1387     effectInfo.isSupportEffect = resInfo.isSupportEffect;
1388     return OHOS::Sensors::SUCCESS;
1389 }
1390 
WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode code,int32_t ret)1391 void VibratorServiceClient::WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode code, int32_t ret)
1392 {
1393 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
1394     if (ret != NO_ERROR) {
1395         switch (code) {
1396             case IMiscdeviceServiceIpcCode::COMMAND_VIBRATE:
1397                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1398                     HiSysEvent::EventType::FAULT, "PKG_NAME", "Vibrate", "ERROR_CODE", ret);
1399                 break;
1400             case IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR:
1401                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1402                     HiSysEvent::EventType::FAULT, "PKG_NAME", "StopVibrator", "ERROR_CODE", ret);
1403                 break;
1404             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_EFFECT:
1405                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1406                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayVibratorEffect", "ERROR_CODE", ret);
1407                 break;
1408             case IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR_BY_MODE:
1409                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1410                     HiSysEvent::EventType::FAULT, "PKG_NAME", "StopVibratorByMode", "ERROR_CODE", ret);
1411                 break;
1412             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_CUSTOM:
1413                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1414                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayVibratorCustom", "ERROR_CODE", ret);
1415                 break;
1416             case IMiscdeviceServiceIpcCode::COMMAND_GET_VIBRATOR_CAPACITY:
1417                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1418                     HiSysEvent::EventType::FAULT, "PKG_NAME", "GetVibratorCapacity", "ERROR_CODE", ret);
1419                 break;
1420             case IMiscdeviceServiceIpcCode::COMMAND_GET_VIBRATOR_LIST:
1421                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1422                     HiSysEvent::EventType::FAULT, "PKG_NAME", "GetVibratorList", "ERROR_CODE", ret);
1423                 break;
1424             case IMiscdeviceServiceIpcCode::COMMAND_GET_EFFECT_INFO:
1425                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1426                     HiSysEvent::EventType::FAULT, "PKG_NAME", "GetEffectInfo", "ERROR_CODE", ret);
1427                 break;
1428             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_PACKAGE_BY_SESSION_ID:
1429                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1430                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayPackageBySessionId", "ERROR_CODE", ret);
1431                 break;
1432             case IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATE_BY_SESSION_ID:
1433                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1434                     HiSysEvent::EventType::FAULT, "PKG_NAME", "StopVibrateBySessionId", "ERROR_CODE", ret);
1435                 break;
1436             default:
1437                 MISC_HILOGW("Code does not exist, code:%{public}d", static_cast<int32_t>(code));
1438                 break;
1439         }
1440     }
1441 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
1442 }
1443 
WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode code,int32_t ret)1444 void VibratorServiceClient::WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode code, int32_t ret)
1445 {
1446 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
1447     if (ret != NO_ERROR) {
1448         switch (code) {
1449             case IMiscdeviceServiceIpcCode::COMMAND_IS_SUPPORT_EFFECT:
1450                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1451                     HiSysEvent::EventType::FAULT, "PKG_NAME", "IsSupportEffect", "ERROR_CODE", ret);
1452                 break;
1453             case IMiscdeviceServiceIpcCode::COMMAND_GET_DELAY_TIME:
1454                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1455                     HiSysEvent::EventType::FAULT, "PKG_NAME", "GetDelayTime", "ERROR_CODE", ret);
1456                 break;
1457             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_PATTERN:
1458                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1459                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayPattern", "ERROR_CODE", ret);
1460                 break;
1461             case IMiscdeviceServiceIpcCode::COMMAND_TRANSFER_CLIENT_REMOTE_OBJECT:
1462                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1463                     HiSysEvent::EventType::FAULT, "PKG_NAME", "TransferClientRemoteObject", "ERROR_CODE", ret);
1464                 break;
1465             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_PRIMITIVE_EFFECT:
1466                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
1467                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayPrimitiveEffect", "ERROR_CODE", ret);
1468                 break;
1469             default:
1470                 MISC_HILOGW("Code does not exist, code:%{public}d", static_cast<int32_t>(code));
1471                 break;
1472         }
1473     }
1474 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
1475 }
1476 } // namespace Sensors
1477 } // namespace OHOS
1478