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 ¶meter)
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 ¶meter)
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 ¶meter)
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