• 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 <climits>
19 #include <thread>
20 
21 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
22 #include "hisysevent.h"
23 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
24 #ifdef HIVIEWDFX_HITRACE_ENABLE
25 #include "hitrace_meter.h"
26 #endif // HIVIEWDFX_HITRACE_ENABLE
27 #include "iservice_registry.h"
28 #include "system_ability_definition.h"
29 
30 #include "death_recipient_template.h"
31 #include "sensors_errors.h"
32 #include "vibrator_decoder_creator.h"
33 
34 #undef LOG_TAG
35 #define LOG_TAG "VibratorServiceClient"
36 
37 namespace OHOS {
38 namespace Sensors {
39 static constexpr int32_t MIN_VIBRATOR_EVENT_TIME = 100;
40 using namespace OHOS::HiviewDFX;
41 
42 namespace {
43 #if (defined(__aarch64__) || defined(__x86_64__))
44     static const std::string DECODER_LIBRARY_PATH = "/system/lib64/platformsdk/libvibrator_decoder.z.so";
45 #else
46     static const std::string DECODER_LIBRARY_PATH = "/system/lib/platformsdk/libvibrator_decoder.z.so";
47 #endif
48 } // namespace
49 
~VibratorServiceClient()50 VibratorServiceClient::~VibratorServiceClient()
51 {
52     if (miscdeviceProxy_ != nullptr && serviceDeathObserver_ != nullptr) {
53         auto remoteObject = miscdeviceProxy_->AsObject();
54         if (remoteObject != nullptr) {
55             remoteObject->RemoveDeathRecipient(serviceDeathObserver_);
56         }
57     }
58     std::lock_guard<std::mutex> decodeLock(decodeMutex_);
59     if (decodeHandle_.destroy != nullptr && decodeHandle_.handle != nullptr) {
60         decodeHandle_.destroy(decodeHandle_.decoder);
61         decodeHandle_.decoder = nullptr;
62         decodeHandle_.Free();
63     }
64 }
65 
InitServiceClient()66 int32_t VibratorServiceClient::InitServiceClient()
67 {
68     CALL_LOG_ENTER;
69     std::lock_guard<std::mutex> clientLock(clientMutex_);
70     if (miscdeviceProxy_ != nullptr) {
71         MISC_HILOGD("miscdeviceProxy_ already init");
72         return ERR_OK;
73     }
74     if (vibratorClient_ == nullptr) {
75         vibratorClient_ = new (std::nothrow) VibratorClientStub();
76     }
77     auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
78     if (sm == nullptr) {
79         MISC_HILOGE("sm cannot be null");
80         return MISC_NATIVE_SAM_ERR;
81     }
82     miscdeviceProxy_ = iface_cast<IMiscdeviceService>(sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID));
83     if (miscdeviceProxy_ != nullptr) {
84         serviceDeathObserver_ =
85             new (std::nothrow) DeathRecipientTemplate(*const_cast<VibratorServiceClient *>(this));
86         CHKPR(serviceDeathObserver_, MISC_NATIVE_GET_SERVICE_ERR);
87         auto remoteObject = miscdeviceProxy_->AsObject();
88         CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
89         remoteObject->AddDeathRecipient(serviceDeathObserver_);
90         int32_t ret = TransferClientRemoteObject();
91         if (ret != ERR_OK) {
92             MISC_HILOGE("TransferClientRemoteObject failed, ret:%{public}d", ret);
93             return ERROR;
94         }
95         ret = GetVibratorCapacity();
96         if (ret != ERR_OK) {
97             MISC_HILOGE("GetVibratorCapacity failed, ret:%{public}d", ret);
98             return ERROR;
99         }
100         return ERR_OK;
101     }
102 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
103     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_EXCEPTION",
104         HiSysEvent::EventType::FAULT, "PKG_NAME", "InitServiceClient", "ERROR_CODE", MISC_NATIVE_GET_SERVICE_ERR);
105 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
106     MISC_HILOGE("Get service failed");
107     return MISC_NATIVE_GET_SERVICE_ERR;
108 }
109 
TransferClientRemoteObject()110 int32_t VibratorServiceClient::TransferClientRemoteObject()
111 {
112     auto remoteObject = vibratorClient_->AsObject();
113     CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
114     CHKPR(miscdeviceProxy_, ERROR);
115 #ifdef HIVIEWDFX_HITRACE_ENABLE
116     StartTrace(HITRACE_TAG_SENSORS, "TransferClientRemoteObject");
117 #endif // HIVIEWDFX_HITRACE_ENABLE
118     int32_t ret = miscdeviceProxy_->TransferClientRemoteObject(remoteObject);
119     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_TRANSFER_CLIENT_REMOTE_OBJECT, ret);
120 #ifdef HIVIEWDFX_HITRACE_ENABLE
121     FinishTrace(HITRACE_TAG_SENSORS);
122 #endif // HIVIEWDFX_HITRACE_ENABLE
123     return ret;
124 }
125 
Vibrate(int32_t vibratorId,int32_t timeOut,int32_t usage,bool systemUsage)126 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage, bool systemUsage)
127 {
128     MISC_HILOGD("Vibrate begin, time:%{public}d, usage:%{public}d", timeOut, usage);
129     int32_t ret = InitServiceClient();
130     if (ret != ERR_OK) {
131         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
132         return MISC_NATIVE_GET_SERVICE_ERR;
133     }
134     std::lock_guard<std::mutex> clientLock(clientMutex_);
135     CHKPR(miscdeviceProxy_, ERROR);
136 #ifdef HIVIEWDFX_HITRACE_ENABLE
137     StartTrace(HITRACE_TAG_SENSORS, "VibrateTime");
138 #endif // HIVIEWDFX_HITRACE_ENABLE
139     ret = miscdeviceProxy_->Vibrate(vibratorId, timeOut, usage, systemUsage);
140     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_VIBRATE, ret);
141 #ifdef HIVIEWDFX_HITRACE_ENABLE
142     FinishTrace(HITRACE_TAG_SENSORS);
143 #endif // HIVIEWDFX_HITRACE_ENABLE
144     if (ret != ERR_OK) {
145         MISC_HILOGE("Vibrate time failed, ret:%{public}d, time:%{public}d, usage:%{public}d", ret, timeOut, usage);
146     }
147     return ret;
148 }
149 
Vibrate(int32_t vibratorId,const std::string & effect,int32_t loopCount,int32_t usage,bool systemUsage)150 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, const std::string &effect,
151     int32_t loopCount, int32_t usage, bool systemUsage)
152 {
153     MISC_HILOGD("Vibrate begin, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
154         effect.c_str(), loopCount, usage);
155     int32_t ret = InitServiceClient();
156     if (ret != ERR_OK) {
157         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
158         return MISC_NATIVE_GET_SERVICE_ERR;
159     }
160     std::lock_guard<std::mutex> clientLock(clientMutex_);
161     CHKPR(miscdeviceProxy_, ERROR);
162 #ifdef HIVIEWDFX_HITRACE_ENABLE
163     StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
164 #endif // HIVIEWDFX_HITRACE_ENABLE
165     ret = miscdeviceProxy_->PlayVibratorEffect(vibratorId, effect, loopCount, usage, systemUsage);
166     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_EFFECT, ret);
167 #ifdef HIVIEWDFX_HITRACE_ENABLE
168     FinishTrace(HITRACE_TAG_SENSORS);
169 #endif // HIVIEWDFX_HITRACE_ENABLE
170     if (ret != ERR_OK) {
171         MISC_HILOGE("Vibrate effect failed, ret:%{public}d, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
172             ret, effect.c_str(), loopCount, usage);
173     }
174     return ret;
175 }
176 
177 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId,const RawFileDescriptor & rawFd,int32_t usage,bool systemUsage,const VibratorParameter & parameter)178 int32_t VibratorServiceClient::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
179     bool systemUsage, const VibratorParameter &parameter)
180 {
181     MISC_HILOGD("Vibrate begin, fd:%{public}d, offset:%{public}lld, length:%{public}lld, usage:%{public}d",
182         rawFd.fd, static_cast<long long>(rawFd.offset), static_cast<long long>(rawFd.length), usage);
183     int32_t ret = InitServiceClient();
184     if (ret != ERR_OK) {
185         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
186         return MISC_NATIVE_GET_SERVICE_ERR;
187     }
188     std::lock_guard<std::mutex> clientLock(clientMutex_);
189     CHKPR(miscdeviceProxy_, ERROR);
190 #ifdef HIVIEWDFX_HITRACE_ENABLE
191     StartTrace(HITRACE_TAG_SENSORS, "PlayVibratorCustom");
192 #endif // HIVIEWDFX_HITRACE_ENABLE
193     VibrateParameter vibateParameter;
194     vibateParameter.intensity = parameter.intensity;
195     vibateParameter.frequency = parameter.frequency;
196     ret = miscdeviceProxy_->PlayVibratorCustom(vibratorId, rawFd.fd, rawFd.offset, rawFd.length, usage, systemUsage,
197         vibateParameter);
198     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_CUSTOM, ret);
199 #ifdef HIVIEWDFX_HITRACE_ENABLE
200     FinishTrace(HITRACE_TAG_SENSORS);
201 #endif // HIVIEWDFX_HITRACE_ENABLE
202     if (ret != ERR_OK) {
203         MISC_HILOGE("PlayVibratorCustom failed, ret:%{public}d, usage:%{public}d", ret, usage);
204     }
205     return ret;
206 }
207 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
208 
StopVibrator(int32_t vibratorId,const std::string & mode)209 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId, const std::string &mode)
210 {
211     MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d, mode:%{public}s", vibratorId, mode.c_str());
212     int32_t ret = InitServiceClient();
213     if (ret != ERR_OK) {
214         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
215         return MISC_NATIVE_GET_SERVICE_ERR;
216     }
217     std::lock_guard<std::mutex> clientLock(clientMutex_);
218     CHKPR(miscdeviceProxy_, ERROR);
219 #ifdef HIVIEWDFX_HITRACE_ENABLE
220     StartTrace(HITRACE_TAG_SENSORS, "StopVibratorByMode");
221 #endif // HIVIEWDFX_HITRACE_ENABLE
222     ret = miscdeviceProxy_->StopVibratorByMode(vibratorId, mode);
223     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR_BY_MODE, ret);
224 #ifdef HIVIEWDFX_HITRACE_ENABLE
225     FinishTrace(HITRACE_TAG_SENSORS);
226 #endif // HIVIEWDFX_HITRACE_ENABLE
227     if (ret != ERR_OK) {
228         MISC_HILOGD("StopVibrator by mode failed, ret:%{public}d, mode:%{public}s", ret, mode.c_str());
229     }
230     return ret;
231 }
232 
StopVibrator(int32_t vibratorId)233 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId)
234 {
235     MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d", vibratorId);
236     int32_t ret = InitServiceClient();
237     if (ret != ERR_OK) {
238         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
239         return MISC_NATIVE_GET_SERVICE_ERR;
240     }
241     std::lock_guard<std::mutex> clientLock(clientMutex_);
242     CHKPR(miscdeviceProxy_, ERROR);
243 #ifdef HIVIEWDFX_HITRACE_ENABLE
244     StartTrace(HITRACE_TAG_SENSORS, "StopVibratorAll");
245 #endif // HIVIEWDFX_HITRACE_ENABLE
246     ret = miscdeviceProxy_->StopVibrator(vibratorId);
247     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR, ret);
248 #ifdef HIVIEWDFX_HITRACE_ENABLE
249     FinishTrace(HITRACE_TAG_SENSORS);
250 #endif // HIVIEWDFX_HITRACE_ENABLE
251     if (ret != ERR_OK) {
252         MISC_HILOGD("StopVibrator failed, ret:%{public}d", ret);
253     }
254     return ret;
255 }
256 
IsHdHapticSupported()257 bool VibratorServiceClient::IsHdHapticSupported()
258 {
259     CALL_LOG_ENTER;
260     int32_t ret = InitServiceClient();
261     if (ret != ERR_OK) {
262         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
263         return MISC_NATIVE_GET_SERVICE_ERR;
264     }
265     return capacity_.isSupportHdHaptic;
266 }
267 
IsSupportEffect(const std::string & effect,bool & state)268 int32_t VibratorServiceClient::IsSupportEffect(const std::string &effect, bool &state)
269 {
270     MISC_HILOGD("IsSupportEffect begin, effect:%{public}s", effect.c_str());
271     int32_t ret = InitServiceClient();
272     if (ret != ERR_OK) {
273         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
274         return MISC_NATIVE_GET_SERVICE_ERR;
275     }
276     std::lock_guard<std::mutex> clientLock(clientMutex_);
277     CHKPR(miscdeviceProxy_, ERROR);
278 #ifdef HIVIEWDFX_HITRACE_ENABLE
279     StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
280 #endif // HIVIEWDFX_HITRACE_ENABLE
281     ret = miscdeviceProxy_->IsSupportEffect(effect, state);
282     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_IS_SUPPORT_EFFECT, ret);
283 #ifdef HIVIEWDFX_HITRACE_ENABLE
284     FinishTrace(HITRACE_TAG_SENSORS);
285 #endif // HIVIEWDFX_HITRACE_ENABLE
286     if (ret != ERR_OK) {
287         MISC_HILOGE("Query effect support failed, ret:%{public}d, effect:%{public}s", ret, effect.c_str());
288     }
289     return ret;
290 }
291 
ProcessDeathObserver(const wptr<IRemoteObject> & object)292 void VibratorServiceClient::ProcessDeathObserver(const wptr<IRemoteObject> &object)
293 {
294     CALL_LOG_ENTER;
295     (void)object;
296     {
297         std::lock_guard<std::mutex> clientLock(clientMutex_);
298         miscdeviceProxy_ = nullptr;
299     }
300     int32_t ret = InitServiceClient();
301     if (ret != ERR_OK) {
302         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
303         return;
304     }
305 }
306 
LoadDecoderLibrary(const std::string & path)307 int32_t VibratorServiceClient::LoadDecoderLibrary(const std::string& path)
308 {
309     std::lock_guard<std::mutex> decodeLock(decodeMutex_);
310     if (decodeHandle_.handle != nullptr) {
311         MISC_HILOGD("The library has already been loaded");
312         return ERR_OK;
313     }
314     char libRealPath[PATH_MAX] = {};
315     if (realpath(path.c_str(), libRealPath) == nullptr) {
316         MISC_HILOGE("Get file real path fail");
317         return ERROR;
318     }
319     decodeHandle_.handle = dlopen(libRealPath, RTLD_LAZY);
320     if (decodeHandle_.handle == nullptr) {
321         MISC_HILOGE("dlopen failed, reason:%{public}s", dlerror());
322         return ERROR;
323     }
324     decodeHandle_.create = reinterpret_cast<IVibratorDecoder *(*)(const JsonParser &)>(
325         dlsym(decodeHandle_.handle, "Create"));
326     if (decodeHandle_.create == nullptr) {
327         MISC_HILOGE("dlsym create failed: error: %{public}s", dlerror());
328         decodeHandle_.Free();
329         return ERROR;
330     }
331     decodeHandle_.destroy = reinterpret_cast<void (*)(IVibratorDecoder *)>
332         (dlsym(decodeHandle_.handle, "Destroy"));
333     if (decodeHandle_.destroy == nullptr) {
334         MISC_HILOGE("dlsym destroy failed: error: %{public}s", dlerror());
335         decodeHandle_.Free();
336         return ERROR;
337     }
338     return ERR_OK;
339 }
340 
PreProcess(const VibratorFileDescription & fd,VibratorPackage & package)341 int32_t VibratorServiceClient::PreProcess(const VibratorFileDescription &fd, VibratorPackage &package)
342 {
343     if (LoadDecoderLibrary(DECODER_LIBRARY_PATH) != 0) {
344         MISC_HILOGE("LoadDecoderLibrary fail");
345         return ERROR;
346     }
347     RawFileDescriptor rawFd = {
348         .fd = fd.fd,
349         .offset = fd.offset,
350         .length = fd.length
351     };
352     JsonParser parser(rawFd);
353     decodeHandle_.decoder = decodeHandle_.create(parser);
354     CHKPR(decodeHandle_.decoder, ERROR);
355     VibratePackage pkg = {};
356     if (decodeHandle_.decoder->DecodeEffect(rawFd, parser, pkg) != 0) {
357         MISC_HILOGE("DecodeEffect fail");
358         decodeHandle_.destroy(decodeHandle_.decoder);
359         decodeHandle_.decoder = nullptr;
360         return ERROR;
361     }
362     decodeHandle_.destroy(decodeHandle_.decoder);
363     decodeHandle_.decoder = nullptr;
364     return ConvertVibratorPackage(pkg, package);
365 }
366 
GetDelayTime(int32_t & delayTime)367 int32_t VibratorServiceClient::GetDelayTime(int32_t &delayTime)
368 {
369     int32_t ret = InitServiceClient();
370     if (ret != ERR_OK) {
371         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
372         return MISC_NATIVE_GET_SERVICE_ERR;
373     }
374     std::lock_guard<std::mutex> clientLock(clientMutex_);
375     CHKPR(miscdeviceProxy_, ERROR);
376 #ifdef HIVIEWDFX_HITRACE_ENABLE
377     StartTrace(HITRACE_TAG_SENSORS, "GetDelayTime");
378 #endif // HIVIEWDFX_HITRACE_ENABLE
379     ret = miscdeviceProxy_->GetDelayTime(delayTime);
380     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_GET_DELAY_TIME, ret);
381 #ifdef HIVIEWDFX_HITRACE_ENABLE
382     FinishTrace(HITRACE_TAG_SENSORS);
383 #endif // HIVIEWDFX_HITRACE_ENABLE
384     if (ret != ERR_OK) {
385         MISC_HILOGE("GetDelayTime failed, ret:%{public}d", ret);
386     }
387     return ret;
388 }
389 
InitPlayPattern(const VibratorPattern & pattern,int32_t usage,bool systemUsage,const VibratorParameter & parameter)390 int32_t VibratorServiceClient::InitPlayPattern(const VibratorPattern &pattern, int32_t usage,
391     bool systemUsage, const VibratorParameter &parameter)
392 {
393     VibratePattern vibratePattern = {};
394     vibratePattern.startTime = pattern.time;
395     for (int32_t i = 0; i < pattern.eventNum; ++i) {
396         if (pattern.events == nullptr) {
397             MISC_HILOGE("VibratorPattern's events is null");
398             return ERROR;
399         }
400         VibrateEvent event;
401         event.tag = static_cast<VibrateTag>(pattern.events[i].type);
402         event.time = pattern.events[i].time;
403         event.duration = pattern.events[i].duration;
404         event.intensity = pattern.events[i].intensity;
405         event.frequency = pattern.events[i].frequency;
406         event.index = pattern.events[i].index;
407         for (int32_t j = 0; j < pattern.events[i].pointNum; ++j) {
408             if (pattern.events[i].points == nullptr) {
409                 MISC_HILOGE("VibratorEvent's points is null");
410                 continue;
411             }
412             VibrateCurvePoint point;
413             point.time = pattern.events[i].points[j].time;
414             point.intensity = pattern.events[i].points[j].intensity;
415             point.frequency = pattern.events[i].points[j].frequency;
416             event.points.emplace_back(point);
417         }
418         vibratePattern.events.emplace_back(event);
419         vibratePattern.patternDuration = pattern.patternDuration;
420     }
421     VibrateParameter vibateParameter;
422     vibateParameter.intensity = parameter.intensity;
423     vibateParameter.frequency = parameter.frequency;
424     std::lock_guard<std::mutex> clientLock(clientMutex_);
425     CHKPR(miscdeviceProxy_, ERROR);
426     int32_t ret = miscdeviceProxy_->PlayPattern(vibratePattern, usage, systemUsage, vibateParameter);
427     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_PATTERN, ret);
428     return ret;
429 }
430 
PlayPattern(const VibratorPattern & pattern,int32_t usage,bool systemUsage,const VibratorParameter & parameter)431 int32_t VibratorServiceClient::PlayPattern(const VibratorPattern &pattern, int32_t usage,
432     bool systemUsage, const VibratorParameter &parameter)
433 {
434     MISC_HILOGD("Vibrate begin, usage:%{public}d", usage);
435     int32_t ret = InitServiceClient();
436     if (ret != ERR_OK) {
437         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
438         return MISC_NATIVE_GET_SERVICE_ERR;
439     }
440 #ifdef HIVIEWDFX_HITRACE_ENABLE
441     StartTrace(HITRACE_TAG_SENSORS, "PlayPattern");
442 #endif // HIVIEWDFX_HITRACE_ENABLE
443     ret = InitPlayPattern(pattern, usage, systemUsage, parameter);
444 #ifdef HIVIEWDFX_HITRACE_ENABLE
445     FinishTrace(HITRACE_TAG_SENSORS);
446 #endif // HIVIEWDFX_HITRACE_ENABLE
447     if (ret != ERR_OK) {
448         MISC_HILOGE("PlayPattern failed, ret:%{public}d, usage:%{public}d", ret, usage);
449     }
450     return ret;
451 }
452 
ConvertVibratorPackage(const VibratePackage & inPkg,VibratorPackage & outPkg)453 int32_t VibratorServiceClient::ConvertVibratorPackage(const VibratePackage& inPkg,
454     VibratorPackage &outPkg)
455 {
456     inPkg.Dump();
457     int32_t patternSize = static_cast<int32_t>(inPkg.patterns.size());
458     VibratorPattern *patterns = (VibratorPattern *)malloc(sizeof(VibratorPattern) * patternSize);
459     CHKPR(patterns, ERROR);
460     outPkg.patternNum = patternSize;
461     int32_t clientPatternDuration = 0;
462     for (int32_t i = 0; i < patternSize; ++i) {
463         patterns[i].time = inPkg.patterns[i].startTime;
464         auto vibrateEvents = inPkg.patterns[i].events;
465         int32_t eventSize = static_cast<int32_t>(vibrateEvents.size());
466         patterns[i].eventNum = eventSize;
467         VibratorEvent *events = (VibratorEvent *)malloc(sizeof(VibratorEvent) * eventSize);
468         if (events == nullptr) {
469             free(patterns);
470             patterns = nullptr;
471             return ERROR;
472         }
473         for (int32_t j = 0; j < eventSize; ++j) {
474             events[j].type = static_cast<VibratorEventType >(vibrateEvents[j].tag);
475             events[j].time = vibrateEvents[j].time;
476             events[j].duration = vibrateEvents[j].duration;
477             events[j].intensity = vibrateEvents[j].intensity;
478             events[j].frequency = vibrateEvents[j].frequency;
479             events[j].index = vibrateEvents[j].index;
480             auto vibratePoints = vibrateEvents[j].points;
481             events[j].pointNum = static_cast<int32_t>(vibratePoints.size());
482             VibratorCurvePoint *points = (VibratorCurvePoint *)malloc(sizeof(VibratorCurvePoint) * events[j].pointNum);
483             if (points == nullptr) {
484                 free(patterns);
485                 patterns = nullptr;
486                 free(events);
487                 events = nullptr;
488                 return ERROR;
489             }
490             for (int32_t k = 0; k < events[j].pointNum; ++k) {
491                 points[k].time = vibratePoints[k].time;
492                 points[k].intensity  = vibratePoints[k].intensity;
493                 points[k].frequency  = vibratePoints[k].frequency;
494             }
495             events[j].points = points;
496             clientPatternDuration = events[j].time + events[j].duration;
497         }
498         patterns[i].events = events;
499         patterns[i].patternDuration = clientPatternDuration;
500     }
501     outPkg.patterns = patterns;
502     outPkg.packageDuration = inPkg.packageDuration;
503     return ERR_OK;
504 }
505 
FreeVibratorPackage(VibratorPackage & package)506 int32_t VibratorServiceClient::FreeVibratorPackage(VibratorPackage &package)
507 {
508     int32_t patternSize = package.patternNum;
509     if ((patternSize <= 0) || (package.patterns == nullptr)) {
510         MISC_HILOGW("Patterns is not need to free, pattern size:%{public}d", patternSize);
511         return ERROR;
512     }
513     auto patterns = package.patterns;
514     for (int32_t i = 0; i < patternSize; ++i) {
515         int32_t eventNum = patterns[i].eventNum;
516         if ((eventNum <= 0) || (patterns[i].events == nullptr)) {
517             MISC_HILOGW("Events is not need to free, event size:%{public}d", eventNum);
518             continue;
519         }
520         auto events = patterns[i].events;
521         for (int32_t j = 0; j < eventNum; ++j) {
522             if (events[j].points != nullptr) {
523                 free(events[j].points);
524                 events[j].points = nullptr;
525             }
526         }
527         free(events);
528         events = nullptr;
529     }
530     free(patterns);
531     patterns = nullptr;
532     return ERR_OK;
533 }
534 
PlayPrimitiveEffect(int32_t vibratorId,const std::string & effect,int32_t intensity,int32_t usage,bool systemUsage,int32_t count)535 int32_t VibratorServiceClient::PlayPrimitiveEffect(int32_t vibratorId, const std::string &effect, int32_t intensity,
536     int32_t usage, bool systemUsage, int32_t count)
537 {
538     MISC_HILOGD("Vibrate begin, effect:%{public}s, intensity:%{public}d, usage:%{public}d, count:%{public}d",
539         effect.c_str(), intensity, usage, count);
540     int32_t ret = InitServiceClient();
541     if (ret != ERR_OK) {
542         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
543         return MISC_NATIVE_GET_SERVICE_ERR;
544     }
545     std::lock_guard<std::mutex> clientLock(clientMutex_);
546     CHKPR(miscdeviceProxy_, ERROR);
547 #ifdef HIVIEWDFX_HITRACE_ENABLE
548     StartTrace(HITRACE_TAG_SENSORS, "PlayPrimitiveEffect");
549 #endif // HIVIEWDFX_HITRACE_ENABLE
550     ret = miscdeviceProxy_->PlayPrimitiveEffect(vibratorId, effect, intensity, usage, systemUsage, count);
551     WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_PLAY_PRIMITIVE_EFFECT, ret);
552 #ifdef HIVIEWDFX_HITRACE_ENABLE
553     FinishTrace(HITRACE_TAG_SENSORS);
554 #endif // HIVIEWDFX_HITRACE_ENABLE
555     if (ret != ERR_OK) {
556         MISC_HILOGE("Play primitive effect failed, ret:%{public}d, effect:%{public}s, intensity:%{public}d,"
557             "usage:%{public}d, count:%{public}d", ret, effect.c_str(), intensity, usage, count);
558     }
559     return ret;
560 }
561 
GetVibratorCapacity()562 int32_t VibratorServiceClient::GetVibratorCapacity()
563 {
564     CHKPR(miscdeviceProxy_, ERROR);
565 #ifdef HIVIEWDFX_HITRACE_ENABLE
566     StartTrace(HITRACE_TAG_SENSORS, "GetVibratorCapacity");
567 #endif // HIVIEWDFX_HITRACE_ENABLE
568     int32_t ret = miscdeviceProxy_->GetVibratorCapacity(capacity_);
569     WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode::COMMAND_GET_VIBRATOR_CAPACITY, ret);
570 #ifdef HIVIEWDFX_HITRACE_ENABLE
571     FinishTrace(HITRACE_TAG_SENSORS);
572 #endif // HIVIEWDFX_HITRACE_ENABLE
573     capacity_.Dump();
574     return ret;
575 }
576 
IsSupportVibratorCustom()577 bool VibratorServiceClient::IsSupportVibratorCustom()
578 {
579     int32_t ret = InitServiceClient();
580     if (ret != ERR_OK) {
581         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
582     }
583     return (capacity_.isSupportHdHaptic || capacity_.isSupportPresetMapping || capacity_.isSupportTimeDelay);
584 }
585 
SeekTimeOnPackage(int32_t seekTime,const VibratorPackage & completePackage,VibratorPackage & seekPackage)586 int32_t VibratorServiceClient::SeekTimeOnPackage(int32_t seekTime, const VibratorPackage &completePackage,
587     VibratorPackage &seekPackage)
588 {
589     VibratePackage convertPackage = {};
590     ConvertSeekVibratorPackage(completePackage, convertPackage, seekTime);
591     return ConvertVibratorPackage(convertPackage, seekPackage);
592 }
593 
ConvertSeekVibratorPackage(const VibratorPackage & completePackage,VibratePackage & convertPackage,int32_t seekTime)594 void VibratorServiceClient::ConvertSeekVibratorPackage(const VibratorPackage &completePackage,
595     VibratePackage &convertPackage, int32_t seekTime)
596 {
597     convertPackage.packageDuration = completePackage.packageDuration;
598     for (int32_t i = 0; i < completePackage.patternNum; ++i) {
599         VibratePattern vibratePattern = {};
600         int32_t patternStartTime = completePackage.patterns[i].time;
601         if (patternStartTime >= seekTime) {
602             ConvertVibratorPattern(completePackage.patterns[i], vibratePattern);
603             convertPackage.patterns.emplace_back(vibratePattern);
604             continue;
605         }
606         vibratePattern.startTime = seekTime;
607         for (int32_t j = 0; j < completePackage.patterns[i].eventNum; ++j) {
608             VibrateEvent vibrateEvent = {};
609             if (SkipEventAndConvertVibratorEvent(completePackage.patterns[i].events[j], vibratePattern,
610                                                  patternStartTime, vibrateEvent)) {
611                 convertPackage.packageDuration -= completePackage.patterns[i].events[j].duration;
612                 convertPackage.packageDuration += vibrateEvent.duration;
613                 convertPackage.packageDuration = convertPackage.packageDuration < 0 ? 0
614                                                                                     : convertPackage.packageDuration;
615                 continue;
616             }
617             vibrateEvent.tag = static_cast<VibrateTag>(completePackage.patterns[i].events[j].type);
618             vibrateEvent.time = completePackage.patterns[i].events[j].time + patternStartTime - seekTime;
619             vibrateEvent.duration = completePackage.patterns[i].events[j].duration;
620             vibrateEvent.intensity = completePackage.patterns[i].events[j].intensity;
621             vibrateEvent.frequency = completePackage.patterns[i].events[j].frequency;
622             vibrateEvent.index = completePackage.patterns[i].events[j].index;
623             for (size_t k = 0; k < static_cast<uint32_t>(completePackage.patterns[i].events[j].pointNum); ++k) {
624                 VibrateCurvePoint vibrateCurvePoint = {};
625                 vibrateCurvePoint.time = completePackage.patterns[i].events[j].points[k].time;
626                 vibrateCurvePoint.intensity = completePackage.patterns[i].events[j].points[k].intensity;
627                 vibrateCurvePoint.frequency = completePackage.patterns[i].events[j].points[k].frequency;
628                 vibrateEvent.points.emplace_back(vibrateCurvePoint);
629             }
630             vibratePattern.patternDuration += vibrateEvent.duration;
631             vibratePattern.events.emplace_back(vibrateEvent);
632         }
633         if (vibratePattern.events.empty()) {
634             continue;
635         }
636         convertPackage.patterns.emplace_back(vibratePattern);
637     }
638 }
639 
ConvertVibratorPattern(const VibratorPattern & vibratorPattern,VibratePattern & vibratePattern)640 void VibratorServiceClient::ConvertVibratorPattern(const VibratorPattern &vibratorPattern,
641     VibratePattern &vibratePattern)
642 {
643     vibratePattern.startTime = vibratorPattern.time;
644     vibratePattern.patternDuration = vibratorPattern.patternDuration;
645     for (int32_t j = 0; j < vibratorPattern.eventNum; ++j) {
646         VibrateEvent vibrateEvent = {};
647         vibrateEvent.tag = static_cast<VibrateTag>(vibratorPattern.events[j].type);
648         vibrateEvent.time = vibratorPattern.events[j].time;
649         vibrateEvent.duration = vibratorPattern.events[j].duration;
650         vibrateEvent.intensity = vibratorPattern.events[j].intensity;
651         vibrateEvent.frequency = vibratorPattern.events[j].frequency;
652         vibrateEvent.index = vibratorPattern.events[j].index;
653         for (size_t k = 0; k < static_cast<uint32_t>(vibratorPattern.events[j].pointNum); ++k) {
654             VibrateCurvePoint vibrateCurvePoint = {};
655             vibrateCurvePoint.time = vibratorPattern.events[j].points[k].time;
656             vibrateCurvePoint.intensity = vibratorPattern.events[j].points[k].intensity;
657             vibrateCurvePoint.frequency = vibratorPattern.events[j].points[k].frequency;
658             vibrateEvent.points.emplace_back(vibrateCurvePoint);
659         }
660         vibratePattern.events.emplace_back(vibrateEvent);
661     }
662 }
663 
SkipEventAndConvertVibratorEvent(const VibratorEvent & vibratorEvent,VibratePattern & vibratePattern,int32_t patternStartTime,VibrateEvent & vibrateEvent)664 bool VibratorServiceClient::SkipEventAndConvertVibratorEvent(const VibratorEvent &vibratorEvent,
665     VibratePattern &vibratePattern, int32_t patternStartTime, VibrateEvent &vibrateEvent)
666 {
667     int32_t eventStartTime = vibratorEvent.time + patternStartTime;
668     if (vibratePattern.startTime > eventStartTime) {
669         if (vibratorEvent.type == EVENT_TYPE_CONTINUOUS &&
670             (eventStartTime + vibratorEvent.duration - vibratePattern.startTime) >= MIN_VIBRATOR_EVENT_TIME) {
671             vibrateEvent.tag = static_cast<VibrateTag>(vibratorEvent.type);
672             vibrateEvent.duration = eventStartTime + vibratorEvent.duration - vibratePattern.startTime;
673             vibrateEvent.intensity = vibratorEvent.intensity;
674             vibrateEvent.frequency = vibratorEvent.frequency;
675             vibrateEvent.index = vibratorEvent.index;
676             vibratePattern.patternDuration += vibrateEvent.duration;
677             vibratePattern.events.emplace_back(vibrateEvent);
678         }
679         return true;
680     }
681     return false;
682 }
683 
WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode code,int32_t ret)684 void VibratorServiceClient::WriteVibratorHiSysIPCEvent(IMiscdeviceServiceIpcCode code, int32_t ret)
685 {
686 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
687     if (ret != NO_ERROR) {
688         switch (code) {
689             case IMiscdeviceServiceIpcCode::COMMAND_VIBRATE:
690                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
691                     HiSysEvent::EventType::FAULT, "PKG_NAME", "Vibrate", "ERROR_CODE", ret);
692                 break;
693             case IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR:
694                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
695                     HiSysEvent::EventType::FAULT, "PKG_NAME", "StopVibrator", "ERROR_CODE", ret);
696                 break;
697             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_EFFECT:
698                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
699                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayVibratorEffect", "ERROR_CODE", ret);
700                 break;
701             case IMiscdeviceServiceIpcCode::COMMAND_STOP_VIBRATOR_BY_MODE:
702                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
703                     HiSysEvent::EventType::FAULT, "PKG_NAME", "StopVibratorByMode", "ERROR_CODE", ret);
704                 break;
705             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_VIBRATOR_CUSTOM:
706                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
707                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayVibratorCustom", "ERROR_CODE", ret);
708                 break;
709             case IMiscdeviceServiceIpcCode::COMMAND_GET_VIBRATOR_CAPACITY:
710                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
711                     HiSysEvent::EventType::FAULT, "PKG_NAME", "GetVibratorCapacity", "ERROR_CODE", ret);
712                 break;
713             default:
714                 MISC_HILOGW("Code does not exist, code:%{public}d", static_cast<int32_t>(code));
715                 break;
716         }
717     }
718 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
719 }
720 
WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode code,int32_t ret)721 void VibratorServiceClient::WriteOtherHiSysIPCEvent(IMiscdeviceServiceIpcCode code, int32_t ret)
722 {
723 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
724     if (ret != NO_ERROR) {
725         switch (code) {
726             case IMiscdeviceServiceIpcCode::COMMAND_IS_SUPPORT_EFFECT:
727                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
728                     HiSysEvent::EventType::FAULT, "PKG_NAME", "IsSupportEffect", "ERROR_CODE", ret);
729                 break;
730             case IMiscdeviceServiceIpcCode::COMMAND_GET_DELAY_TIME:
731                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
732                     HiSysEvent::EventType::FAULT, "PKG_NAME", "GetDelayTime", "ERROR_CODE", ret);
733                 break;
734             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_PATTERN:
735                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
736                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayPattern", "ERROR_CODE", ret);
737                 break;
738             case IMiscdeviceServiceIpcCode::COMMAND_TRANSFER_CLIENT_REMOTE_OBJECT:
739                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
740                     HiSysEvent::EventType::FAULT, "PKG_NAME", "TransferClientRemoteObject", "ERROR_CODE", ret);
741                 break;
742             case IMiscdeviceServiceIpcCode::COMMAND_PLAY_PRIMITIVE_EFFECT:
743                 HiSysEventWrite(HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_IPC_EXCEPTION",
744                     HiSysEvent::EventType::FAULT, "PKG_NAME", "PlayPrimitiveEffect", "ERROR_CODE", ret);
745                 break;
746             default:
747                 MISC_HILOGW("Code does not exist, code:%{public}d", static_cast<int32_t>(code));
748                 break;
749         }
750     }
751 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
752 }
753 } // namespace Sensors
754 } // namespace OHOS
755