• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "vibrator_service_client.h"
17 
18 #include <climits>
19 #include <thread>
20 
21 #include "hisysevent.h"
22 #include "hitrace_meter.h"
23 #include "iservice_registry.h"
24 #include "system_ability_definition.h"
25 
26 #include "death_recipient_template.h"
27 #include "sensors_errors.h"
28 #include "vibrator_decoder_creator.h"
29 
30 #undef LOG_TAG
31 #define LOG_TAG "VibratorServiceClient"
32 
33 namespace OHOS {
34 namespace Sensors {
35 using namespace OHOS::HiviewDFX;
36 
37 namespace {
38 constexpr int32_t GET_SERVICE_MAX_COUNT = 3;
39 constexpr uint32_t WAIT_MS = 200;
40 #ifdef __aarch64__
41     static const std::string DECODER_LIBRARY_PATH = "/system/lib64/libvibrator_decoder.z.so";
42 #else
43     static const std::string DECODER_LIBRARY_PATH = "/system/lib/libvibrator_decoder.z.so";
44 #endif
45 }  // namespace
46 
~VibratorServiceClient()47 VibratorServiceClient::~VibratorServiceClient()
48 {
49     if (miscdeviceProxy_ != nullptr && serviceDeathObserver_ != nullptr) {
50         auto remoteObject = miscdeviceProxy_->AsObject();
51         if (remoteObject != nullptr) {
52             remoteObject->RemoveDeathRecipient(serviceDeathObserver_);
53         }
54     }
55     std::lock_guard<std::mutex> decodeLock(decodeMutex_);
56     if (decodeHandle_.destroy != nullptr && decodeHandle_.handle != nullptr) {
57         decodeHandle_.destroy(decodeHandle_.decoder);
58         decodeHandle_.decoder = nullptr;
59         decodeHandle_.Free();
60     }
61 }
62 
InitServiceClient()63 int32_t VibratorServiceClient::InitServiceClient()
64 {
65     CALL_LOG_ENTER;
66     std::lock_guard<std::mutex> clientLock(clientMutex_);
67     if (miscdeviceProxy_ != nullptr) {
68         MISC_HILOGD("miscdeviceProxy_ already init");
69         return ERR_OK;
70     }
71     auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
72     if (sm == nullptr) {
73         MISC_HILOGE("sm cannot be null");
74         return MISC_NATIVE_SAM_ERR;
75     }
76     int32_t retry = 0;
77     while (retry < GET_SERVICE_MAX_COUNT) {
78         miscdeviceProxy_ = iface_cast<IMiscdeviceService>(sm->GetSystemAbility(MISCDEVICE_SERVICE_ABILITY_ID));
79         if (miscdeviceProxy_ != nullptr) {
80             MISC_HILOGD("Get service success, retry:%{public}d", retry);
81             serviceDeathObserver_ =
82                 new (std::nothrow) DeathRecipientTemplate(*const_cast<VibratorServiceClient *>(this));
83             CHKPR(serviceDeathObserver_, MISC_NATIVE_GET_SERVICE_ERR);
84             auto remoteObject = miscdeviceProxy_->AsObject();
85             CHKPR(remoteObject, MISC_NATIVE_GET_SERVICE_ERR);
86             remoteObject->AddDeathRecipient(serviceDeathObserver_);
87             return ERR_OK;
88         }
89         MISC_HILOGW("Get service failed, retry:%{public}d", retry);
90         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
91         retry++;
92     }
93     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::MISCDEVICE, "MISC_SERVICE_EXCEPTION",
94         HiSysEvent::EventType::FAULT, "PKG_NAME", "InitServiceClient", "ERROR_CODE", MISC_NATIVE_GET_SERVICE_ERR);
95     MISC_HILOGE("Get service failed");
96     return MISC_NATIVE_GET_SERVICE_ERR;
97 }
98 
Vibrate(int32_t vibratorId,int32_t timeOut,int32_t usage)99 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, int32_t timeOut, int32_t usage)
100 {
101     MISC_HILOGD("Vibrate begin, time:%{public}d, usage:%{public}d", timeOut, usage);
102     int32_t ret = InitServiceClient();
103     if (ret != ERR_OK) {
104         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
105         return MISC_NATIVE_GET_SERVICE_ERR;
106     }
107     CHKPR(miscdeviceProxy_, ERROR);
108     StartTrace(HITRACE_TAG_SENSORS, "VibrateTime");
109     ret = miscdeviceProxy_->Vibrate(vibratorId, timeOut, usage);
110     FinishTrace(HITRACE_TAG_SENSORS);
111     if (ret != ERR_OK) {
112         MISC_HILOGE("Vibrate time failed, ret:%{public}d, time:%{public}d, usage:%{public}d", ret, timeOut, usage);
113     }
114     return ret;
115 }
116 
Vibrate(int32_t vibratorId,const std::string & effect,int32_t loopCount,int32_t usage)117 int32_t VibratorServiceClient::Vibrate(int32_t vibratorId, const std::string &effect,
118     int32_t loopCount, int32_t usage)
119 {
120     MISC_HILOGD("Vibrate begin, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
121         effect.c_str(), loopCount, usage);
122     int32_t ret = InitServiceClient();
123     if (ret != ERR_OK) {
124         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
125         return MISC_NATIVE_GET_SERVICE_ERR;
126     }
127     CHKPR(miscdeviceProxy_, ERROR);
128     StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
129     ret = miscdeviceProxy_->PlayVibratorEffect(vibratorId, effect, loopCount, usage);
130     FinishTrace(HITRACE_TAG_SENSORS);
131     if (ret != ERR_OK) {
132         MISC_HILOGE("Vibrate effect failed, ret:%{public}d, effect:%{public}s, loopCount:%{public}d, usage:%{public}d",
133             ret, effect.c_str(), loopCount, usage);
134     }
135     return ret;
136 }
137 
138 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
PlayVibratorCustom(int32_t vibratorId,const RawFileDescriptor & rawFd,int32_t usage,const VibratorParameter & parameter)139 int32_t VibratorServiceClient::PlayVibratorCustom(int32_t vibratorId, const RawFileDescriptor &rawFd, int32_t usage,
140     const VibratorParameter &parameter)
141 {
142     MISC_HILOGD("Vibrate begin, fd:%{public}d, offset:%{public}lld, length:%{public}lld, usage:%{public}d",
143         rawFd.fd, static_cast<long long>(rawFd.offset), static_cast<long long>(rawFd.length), usage);
144     int32_t ret = InitServiceClient();
145     if (ret != ERR_OK) {
146         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
147         return MISC_NATIVE_GET_SERVICE_ERR;
148     }
149     CHKPR(miscdeviceProxy_, ERROR);
150     StartTrace(HITRACE_TAG_SENSORS, "PlayVibratorCustom");
151     VibrateParameter vibateParameter = {
152         .intensity = parameter.intensity,
153         .frequency = parameter.frequency
154     };
155     ret = miscdeviceProxy_->PlayVibratorCustom(vibratorId, rawFd, usage, vibateParameter);
156     FinishTrace(HITRACE_TAG_SENSORS);
157     if (ret != ERR_OK) {
158         MISC_HILOGE("PlayVibratorCustom failed, ret:%{public}d, usage:%{public}d", ret, usage);
159     }
160     return ret;
161 }
162 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
163 
StopVibrator(int32_t vibratorId,const std::string & mode)164 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId, const std::string &mode)
165 {
166     MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d, mode:%{public}s", vibratorId, mode.c_str());
167     int32_t ret = InitServiceClient();
168     if (ret != ERR_OK) {
169         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
170         return MISC_NATIVE_GET_SERVICE_ERR;
171     }
172     CHKPR(miscdeviceProxy_, ERROR);
173     StartTrace(HITRACE_TAG_SENSORS, "StopVibratorByMode");
174     ret = miscdeviceProxy_->StopVibrator(vibratorId, mode);
175     FinishTrace(HITRACE_TAG_SENSORS);
176     if (ret != ERR_OK) {
177         MISC_HILOGD("StopVibrator by mode failed, ret:%{public}d, mode:%{public}s", ret, mode.c_str());
178     }
179     return ret;
180 }
181 
StopVibrator(int32_t vibratorId)182 int32_t VibratorServiceClient::StopVibrator(int32_t vibratorId)
183 {
184     MISC_HILOGD("StopVibrator begin, vibratorId:%{public}d", vibratorId);
185     int32_t ret = InitServiceClient();
186     if (ret != ERR_OK) {
187         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
188         return MISC_NATIVE_GET_SERVICE_ERR;
189     }
190     CHKPR(miscdeviceProxy_, ERROR);
191     StartTrace(HITRACE_TAG_SENSORS, "StopVibratorAll");
192     ret = miscdeviceProxy_->StopVibrator(vibratorId);
193     FinishTrace(HITRACE_TAG_SENSORS);
194     if (ret != ERR_OK) {
195         MISC_HILOGD("StopVibrator failed, ret:%{public}d", ret);
196     }
197     return ret;
198 }
199 
IsSupportEffect(const std::string & effect,bool & state)200 int32_t VibratorServiceClient::IsSupportEffect(const std::string &effect, bool &state)
201 {
202     MISC_HILOGD("IsSupportEffect begin, effect:%{public}s", effect.c_str());
203     int32_t ret = InitServiceClient();
204     if (ret != ERR_OK) {
205         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
206         return MISC_NATIVE_GET_SERVICE_ERR;
207     }
208     CHKPR(miscdeviceProxy_, ERROR);
209     StartTrace(HITRACE_TAG_SENSORS, "VibrateEffect");
210     ret = miscdeviceProxy_->IsSupportEffect(effect, state);
211     FinishTrace(HITRACE_TAG_SENSORS);
212     if (ret != ERR_OK) {
213         MISC_HILOGE("Query effect support failed, ret:%{public}d, effect:%{public}s", ret, effect.c_str());
214     }
215     return ret;
216 }
217 
ProcessDeathObserver(const wptr<IRemoteObject> & object)218 void VibratorServiceClient::ProcessDeathObserver(const wptr<IRemoteObject> &object)
219 {
220     CALL_LOG_ENTER;
221     (void)object;
222     miscdeviceProxy_ = nullptr;
223     int32_t ret = InitServiceClient();
224     if (ret != ERR_OK) {
225         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
226         return;
227     }
228 }
229 
LoadDecoderLibrary(const std::string & path)230 int32_t VibratorServiceClient::LoadDecoderLibrary(const std::string& path)
231 {
232     std::lock_guard<std::mutex> decodeLock(decodeMutex_);
233     if (decodeHandle_.handle != nullptr) {
234         MISC_HILOGD("The library has already been loaded");
235         return ERR_OK;
236     }
237     char libRealPath[PATH_MAX] = {};
238     if (realpath(path.c_str(), libRealPath) == nullptr) {
239         MISC_HILOGE("Get file real path fail");
240         return ERROR;
241     }
242     decodeHandle_.handle = dlopen(libRealPath, RTLD_LAZY);
243     if (decodeHandle_.handle == nullptr) {
244         MISC_HILOGE("dlopen failed, reason:%{public}s", dlerror());
245         return ERROR;
246     }
247     decodeHandle_.create = reinterpret_cast<IVibratorDecoder *(*)(const RawFileDescriptor &)>(
248         dlsym(decodeHandle_.handle, "Create"));
249     if (decodeHandle_.create == nullptr) {
250         MISC_HILOGE("dlsym create failed: error: %{public}s", dlerror());
251         decodeHandle_.Free();
252         return ERROR;
253     }
254     decodeHandle_.destroy = reinterpret_cast<void (*)(IVibratorDecoder *)>
255         (dlsym(decodeHandle_.handle, "Destroy"));
256     if (decodeHandle_.destroy == nullptr) {
257         MISC_HILOGE("dlsym destroy failed: error: %{public}s", dlerror());
258         decodeHandle_.Free();
259         return ERROR;
260     }
261     return ERR_OK;
262 }
263 
PreProcess(const VibratorFileDescription & fd,VibratorPackage & package)264 int32_t VibratorServiceClient::PreProcess(const VibratorFileDescription &fd, VibratorPackage &package)
265 {
266     if (LoadDecoderLibrary(DECODER_LIBRARY_PATH) != 0) {
267         MISC_HILOGE("LoadDecoderLibrary fail");
268         return ERROR;
269     }
270     RawFileDescriptor rawFd = {
271         .fd = fd.fd,
272         .offset = fd.offset,
273         .length = fd.length
274     };
275     decodeHandle_.decoder = decodeHandle_.create(rawFd);
276     CHKPR(decodeHandle_.decoder, ERROR);
277     VibratePackage pkg = {};
278     if (decodeHandle_.decoder->DecodeEffect(rawFd, pkg) != 0) {
279         MISC_HILOGE("DecodeEffect fail");
280         decodeHandle_.destroy(decodeHandle_.decoder);
281         decodeHandle_.decoder = nullptr;
282         return ERROR;
283     }
284     decodeHandle_.destroy(decodeHandle_.decoder);
285     decodeHandle_.decoder = nullptr;
286     return ConvertVibratePackage(pkg, package);
287 }
288 
GetDelayTime(int32_t & delayTime)289 int32_t VibratorServiceClient::GetDelayTime(int32_t &delayTime)
290 {
291     int32_t ret = InitServiceClient();
292     if (ret != ERR_OK) {
293         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
294         return MISC_NATIVE_GET_SERVICE_ERR;
295     }
296     CHKPR(miscdeviceProxy_, ERROR);
297     StartTrace(HITRACE_TAG_SENSORS, "GetDelayTime");
298     ret = miscdeviceProxy_->GetDelayTime(delayTime);
299     FinishTrace(HITRACE_TAG_SENSORS);
300     if (ret != ERR_OK) {
301         MISC_HILOGE("GetDelayTime failed, ret:%{public}d", ret);
302     }
303     return ret;
304 }
305 
PlayPattern(const VibratorPattern & pattern,int32_t usage,const VibratorParameter & parameter)306 int32_t VibratorServiceClient::PlayPattern(const VibratorPattern &pattern, int32_t usage,
307     const VibratorParameter &parameter)
308 {
309     MISC_HILOGD("Vibrate begin, usage:%{public}d", usage);
310     int32_t ret = InitServiceClient();
311     if (ret != ERR_OK) {
312         MISC_HILOGE("InitServiceClient failed, ret:%{public}d", ret);
313         return MISC_NATIVE_GET_SERVICE_ERR;
314     }
315     CHKPR(miscdeviceProxy_, ERROR);
316     StartTrace(HITRACE_TAG_SENSORS, "PlayPattern");
317     VibratePattern vibratePattern = {};
318     vibratePattern.startTime = pattern.time;
319     for (int32_t i = 0; i < pattern.eventNum; ++i) {
320         if (pattern.events == nullptr) {
321             MISC_HILOGE("VibratorPattern's events is null");
322             return ERROR;
323         }
324         VibrateEvent event;
325         event.tag = static_cast<VibrateTag>(pattern.events[i].type);
326         event.time = pattern.events[i].time;
327         event.duration = pattern.events[i].duration;
328         event.intensity = pattern.events[i].intensity;
329         event.frequency = pattern.events[i].frequency;
330         event.index = pattern.events[i].index;
331         for (int32_t j = 0; j < pattern.events[i].pointNum; ++j) {
332             if (pattern.events[i].points == nullptr) {
333                 MISC_HILOGE("VibratorEvent's points is null");
334                 continue;
335             }
336             VibrateCurvePoint point;
337             point.time = pattern.events[i].points[j].time;
338             point.intensity = pattern.events[i].points[j].intensity;
339             point.frequency = pattern.events[i].points[j].frequency;
340             event.points.emplace_back(point);
341         }
342         vibratePattern.events.emplace_back(event);
343     }
344     VibrateParameter vibateParameter = {
345         .intensity = parameter.intensity,
346         .frequency = parameter.frequency
347     };
348     ret = miscdeviceProxy_->PlayPattern(vibratePattern, usage, vibateParameter);
349     FinishTrace(HITRACE_TAG_SENSORS);
350     if (ret != ERR_OK) {
351         MISC_HILOGE("PlayPattern failed, ret:%{public}d, usage:%{public}d", ret, usage);
352     }
353     return ret;
354 }
355 
ConvertVibratePackage(const VibratePackage & inPkg,VibratorPackage & outPkg)356 int32_t VibratorServiceClient::ConvertVibratePackage(const VibratePackage& inPkg,
357     VibratorPackage &outPkg)
358 {
359     inPkg.Dump();
360     int32_t patternSize = static_cast<int32_t>(inPkg.patterns.size());
361     VibratorPattern *patterns = (VibratorPattern *)malloc(sizeof(VibratorPattern) * patternSize);
362     CHKPR(patterns, ERROR);
363     outPkg.patternNum = patternSize;
364     for (int32_t i = 0; i < patternSize; ++i) {
365         patterns[i].time = inPkg.patterns[i].startTime;
366         auto vibrateEvents = inPkg.patterns[i].events;
367         int32_t eventSize = static_cast<int32_t>(vibrateEvents.size());
368         patterns[i].eventNum = eventSize;
369         VibratorEvent *events = (VibratorEvent *)malloc(sizeof(VibratorEvent) * eventSize);
370         if (events == nullptr) {
371             free(patterns);
372             patterns = nullptr;
373             return ERROR;
374         }
375         for (int32_t j = 0; j < eventSize; ++j) {
376             events[j].type = static_cast<VibratorEventType >(vibrateEvents[j].tag);
377             events[j].time = vibrateEvents[j].time;
378             events[j].duration = vibrateEvents[j].duration;
379             events[j].intensity = vibrateEvents[j].intensity;
380             events[j].frequency = vibrateEvents[j].frequency;
381             events[j].index = vibrateEvents[j].index;
382             auto vibratePoints = vibrateEvents[j].points;
383             events[j].pointNum = static_cast<int32_t>(vibratePoints.size());
384             VibratorCurvePoint *points = (VibratorCurvePoint *)malloc(sizeof(VibratorCurvePoint) * events[j].pointNum);
385             if (points == nullptr) {
386                 free(patterns);
387                 patterns = nullptr;
388                 free(events);
389                 events = nullptr;
390                 return ERROR;
391             }
392             for (int32_t k = 0; k < events[j].pointNum; ++k) {
393                 points[k].time = vibratePoints[k].time;
394                 points[k].intensity  = vibratePoints[k].intensity;
395                 points[k].frequency  = vibratePoints[k].frequency;
396             }
397             events[j].points = points;
398         }
399         patterns[i].events = events;
400     }
401     outPkg.patterns = patterns;
402     return ERR_OK;
403 }
404 
FreeVibratorPackage(VibratorPackage & package)405 int32_t VibratorServiceClient::FreeVibratorPackage(VibratorPackage &package)
406 {
407     int32_t patternSize = package.patternNum;
408     if ((patternSize <= 0) || (package.patterns == nullptr)) {
409         MISC_HILOGW("Patterns is not need to free, pattern size:%{public}d", patternSize);
410         return ERROR;
411     }
412     auto patterns = package.patterns;
413     for (int32_t i = 0; i < patternSize; ++i) {
414         int32_t eventNum = patterns[i].eventNum;
415         if ((eventNum <= 0) || (patterns[i].events == nullptr)) {
416             MISC_HILOGW("Events is not need to free, event size:%{public}d", eventNum);
417             continue;
418         }
419         auto events = patterns[i].events;
420         for (int32_t j = 0; j < eventNum; ++j) {
421             if (events[j].points != nullptr) {
422                 free(events[j].points);
423                 events[j].points = nullptr;
424             }
425         }
426         free(events);
427         events = nullptr;
428     }
429     free(patterns);
430     patterns = nullptr;
431     return ERR_OK;
432 }
433 }  // namespace Sensors
434 }  // namespace OHOS
435