1 /*
2 * Copyright (c) 2022-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 "devicestatus_msdp_client_impl.h"
17
18 #include <string>
19
20 #include <dlfcn.h>
21
22 #include "devicestatus_define.h"
23 #include "devicestatus_dumper.h"
24 #include "fi_log.h"
25
26 #undef LOG_TAG
27 #define LOG_TAG "DeviceStatusMsdpClientImpl"
28
29 namespace OHOS {
30 namespace Msdp {
31 namespace DeviceStatus {
32 namespace {
33 #ifdef __aarch64__
34 const std::string DEVICESTATUS_MOCK_LIB_PATH { "/system/lib64/libdevicestatus_mock.z.so" };
35 const std::string DEVICESTATUS_ALGO_LIB_PATH { "/system/lib64/libdevicestatus_algo.z.so" };
36 #else
37 const std::string DEVICESTATUS_MOCK_LIB_PATH { "/system/lib/libdevicestatus_mock.z.so" };
38 const std::string DEVICESTATUS_ALGO_LIB_PATH { "/system/lib/libdevicestatus_algo.z.so" };
39 #endif
40 using ClientType = Type;
41 using ClientValue = OnChangedValue;
42 } // namespace
43
DeviceStatusMsdpClientImpl()44 DeviceStatusMsdpClientImpl::DeviceStatusMsdpClientImpl()
45 {
46 for (int32_t type = 0; type < static_cast<int32_t>(Type::TYPE_MAX); ++type) {
47 algoCallCounts_[static_cast<Type>(type)] = 0;
48 mockCallCounts_[static_cast<Type>(type)] = 0;
49 }
50 }
51
InitMsdpImpl(Type type)52 ErrCode DeviceStatusMsdpClientImpl::InitMsdpImpl(Type type)
53 {
54 CALL_DEBUG_ENTER;
55 if (GetSensorHdi(type) == RET_OK) {
56 FI_HILOGI("GetSensorHdi is support");
57 return RET_OK;
58 }
59 #ifdef DEVICE_STATUS_SENSOR_ENABLE
60 if (AlgoHandle(type) == RET_OK) {
61 FI_HILOGI("AlgoHandle is support");
62 return RET_OK;
63 }
64 #else
65 FI_HILOGE("Enable:sensor is not exist");
66 #endif // DEVICE_STATUS_SENSOR_ENABLE
67 if (MockHandle(type) == RET_OK) {
68 FI_HILOGI("MockHandle is support");
69 return RET_OK;
70 }
71 return RET_ERR;
72 }
73
MockHandle(Type type)74 ErrCode DeviceStatusMsdpClientImpl::MockHandle(Type type)
75 {
76 if (StartMock(type) == RET_ERR) {
77 FI_HILOGE("Start mock Library failed");
78 return RET_ERR;
79 }
80 std::unique_lock lock(mutex_);
81 CHKPR(iMock_, RET_ERR);
82 iMock_->Enable(type);
83 auto iter = mockCallCounts_.find(type);
84 if (iter == mockCallCounts_.end()) {
85 auto ret = mockCallCounts_.emplace(type, 0);
86 if (!ret.second) {
87 FI_HILOGW("type is duplicated");
88 return RET_ERR;
89 }
90 } else {
91 iter->second++;
92 }
93 RegisterMock();
94 if (type > TYPE_MAX || type < TYPE_INVALID) {
95 FI_HILOGE("Type invalid");
96 return RET_ERR;
97 }
98 FI_HILOGI("mockCallCounts_:%{public}d", mockCallCounts_[type]);
99 return RET_OK;
100 }
101
AlgoHandle(Type type)102 ErrCode DeviceStatusMsdpClientImpl::AlgoHandle(Type type)
103 {
104 if (GetAlgoAbility(type) == RET_ERR) {
105 FI_HILOGE("Algo Library is not support");
106 return RET_ERR;
107 }
108 if (StartAlgo(type) == RET_ERR) {
109 FI_HILOGE("Start algo Library failed");
110 return RET_ERR;
111 }
112 CHKPR(iAlgo_, RET_ERR);
113 if ((iAlgo_->Enable(type)) == RET_ERR) {
114 FI_HILOGE("Enable algo Library failed");
115 return RET_ERR;
116 }
117 std::unique_lock lock(mutex_);
118 auto iter = algoCallCounts_.find(type);
119 if (iter == algoCallCounts_.end()) {
120 auto ret = algoCallCounts_.emplace(type, 0);
121 if (!ret.second) {
122 FI_HILOGW("Type is duplicated");
123 return RET_ERR;
124 }
125 } else {
126 iter->second++;
127 }
128 RegisterAlgo();
129 FI_HILOGI("algoCallCounts_:%{public}d", algoCallCounts_[type]);
130 return RET_OK;
131 }
132
StartAlgo(Type type)133 ErrCode DeviceStatusMsdpClientImpl::StartAlgo(Type type)
134 {
135 if (LoadAlgoLibrary() == RET_ERR) {
136 FI_HILOGE("Load algo Library failed");
137 return RET_ERR;
138 }
139 std::unique_lock lock(mutex_);
140 iAlgo_ = GetAlgoInst(type);
141 CHKPR(iAlgo_, RET_ERR);
142 return RET_OK;
143 }
144
StartMock(Type type)145 ErrCode DeviceStatusMsdpClientImpl::StartMock(Type type)
146 {
147 if (LoadMockLibrary() == RET_ERR) {
148 FI_HILOGE("Load mock Library failed");
149 return RET_ERR;
150 }
151 std::unique_lock lock(mutex_);
152 iMock_ = GetMockInst(type);
153 if (iMock_ == nullptr) {
154 FI_HILOGE("Get mock module failed");
155 return RET_ERR;
156 }
157 return RET_OK;
158 }
159
GetSensorHdi(Type type)160 ErrCode DeviceStatusMsdpClientImpl::GetSensorHdi(Type type)
161 {
162 return RET_ERR;
163 }
164
GetAlgoAbility(Type type)165 ErrCode DeviceStatusMsdpClientImpl::GetAlgoAbility(Type type)
166 {
167 if ((type == Type::TYPE_ABSOLUTE_STILL) || (type == Type::TYPE_HORIZONTAL_POSITION) ||
168 (type == Type::TYPE_VERTICAL_POSITION)) {
169 FI_HILOGI("Support ability type:%{public}d", type);
170 return RET_OK;
171 }
172 FI_HILOGI("Not support ability");
173 return RET_ERR;
174 }
175
Disable(Type type)176 ErrCode DeviceStatusMsdpClientImpl::Disable(Type type)
177 {
178 CALL_DEBUG_ENTER;
179 return (((SensorHdiDisable(type) == RET_OK) || (AlgoDisable(type) == RET_OK) || (MockDisable(type) == RET_OK)) ?
180 RET_OK : RET_ERR);
181 }
182
SensorHdiDisable(Type type)183 ErrCode DeviceStatusMsdpClientImpl::SensorHdiDisable(Type type)
184 {
185 return RET_ERR;
186 }
187
AlgoDisable(Type type)188 ErrCode DeviceStatusMsdpClientImpl::AlgoDisable(Type type)
189 {
190 #ifdef DEVICE_STATUS_SENSOR_ENABLE
191 CALL_DEBUG_ENTER;
192 CHKPR(iAlgo_, RET_ERR);
193 auto iter = algoCallCounts_.find(type);
194 if (iter == algoCallCounts_.end()) {
195 FI_HILOGE("Failed to find record type");
196 return RET_ERR;
197 }
198 if (iter->second == 0) {
199 algoCallCounts_.erase(type);
200 } else {
201 iAlgo_->Disable(type);
202 UnregisterAlgo();
203 }
204 algoCallCounts_.erase(type);
205 if (algoCallCounts_.empty()) {
206 if (UnloadAlgoLibrary() == RET_ERR) {
207 FI_HILOGE("Failed to close algorithm library");
208 return RET_ERR;
209 }
210 FI_HILOGI("Close algorithm library");
211 iAlgo_ = nullptr;
212 callBacksMgr_ = nullptr;
213 }
214 FI_HILOGI("algoCallCounts_:%{public}d", algoCallCounts_[type]);
215 return RET_OK;
216 #else
217 FI_HILOGE("Disable:sensor is not exist");
218 return RET_ERR;
219 #endif // DEVICE_STATUS_SENSOR_ENABLE
220 }
221
MockDisable(Type type)222 ErrCode DeviceStatusMsdpClientImpl::MockDisable(Type type)
223 {
224 CALL_DEBUG_ENTER;
225 std::unique_lock lock(mutex_);
226 CHKPR(iMock_, RET_ERR);
227 auto iter = mockCallCounts_.find(type);
228 if (iter == mockCallCounts_.end()) {
229 FI_HILOGE("Failed to find record type");
230 return RET_ERR;
231 }
232 if (iter->second == 0) {
233 mockCallCounts_.erase(type);
234 } else {
235 iMock_->DisableCount(type);
236 iMock_->Disable(type);
237 UnregisterMock();
238 }
239 iter->second--;
240 if (mockCallCounts_.empty()) {
241 if (UnloadMockLibrary() == RET_ERR) {
242 FI_HILOGE("Failed to close library");
243 return RET_ERR;
244 }
245 iMock_ = nullptr;
246 callBacksMgr_ = nullptr;
247 }
248 return RET_OK;
249 }
250
ImplCallback(const Data & data)251 ErrCode DeviceStatusMsdpClientImpl::ImplCallback(const Data &data)
252 {
253 std::unique_lock lock(mutex_);
254 CHKPR(callBacksMgr_, RET_ERR);
255 callBacksMgr_(data);
256 return RET_OK;
257 }
258
RegisterImpl(const CallbackManager & callback)259 ErrCode DeviceStatusMsdpClientImpl::RegisterImpl(const CallbackManager &callback)
260 {
261 callBacksMgr_ = callback;
262 return RET_OK;
263 }
264
OnResult(const Data & data)265 void DeviceStatusMsdpClientImpl::OnResult(const Data &data)
266 {
267 FI_HILOGD("type:%{public}d, value:%{public}d", data.type, data.value);
268 MsdpCallback(data);
269 }
270
RegisterMock()271 ErrCode DeviceStatusMsdpClientImpl::RegisterMock()
272 {
273 CALL_DEBUG_ENTER;
274 if (iMock_ != nullptr) {
275 std::shared_ptr<IMsdp::MsdpAlgoCallback> callback = shared_from_this();
276 iMock_->RegisterCallback(callback);
277 }
278 return RET_OK;
279 }
280
UnregisterMock()281 ErrCode DeviceStatusMsdpClientImpl::UnregisterMock()
282 {
283 CALL_DEBUG_ENTER;
284 CHKPR(iMock_, RET_ERR);
285 iMock_->UnregisterCallback();
286 return RET_OK;
287 }
288
RegisterAlgo()289 ErrCode DeviceStatusMsdpClientImpl::RegisterAlgo()
290 {
291 CALL_DEBUG_ENTER;
292 if (iAlgo_ != nullptr) {
293 std::shared_ptr<IMsdp::MsdpAlgoCallback> callback_ = shared_from_this();
294 iAlgo_->RegisterCallback(callback_);
295 }
296 return RET_OK;
297 }
298
UnregisterAlgo()299 ErrCode DeviceStatusMsdpClientImpl::UnregisterAlgo()
300 {
301 CALL_DEBUG_ENTER;
302 CHKPR(iAlgo_, RET_ERR);
303 iAlgo_->UnregisterCallback();
304 return RET_OK;
305 }
306
MsdpCallback(const Data & data)307 int32_t DeviceStatusMsdpClientImpl::MsdpCallback(const Data &data)
308 {
309 CALL_DEBUG_ENTER;
310 std::unique_lock callLock(callMutex_);
311 DS_DUMPER->PushDeviceStatus(data);
312 SaveObserverData(data);
313 if (notifyManagerFlag_) {
314 ImplCallback(data);
315 notifyManagerFlag_ = false;
316 }
317 return RET_OK;
318 }
319
SaveObserverData(const Data & data)320 Data DeviceStatusMsdpClientImpl::SaveObserverData(const Data &data)
321 {
322 CALL_DEBUG_ENTER;
323 for (auto iter = deviceStatusDatas_.begin(); iter != deviceStatusDatas_.end(); ++iter) {
324 if (iter->first == data.type) {
325 iter->second = data.value;
326 notifyManagerFlag_ = true;
327 return data;
328 }
329 }
330 auto ret = deviceStatusDatas_.insert(std::make_pair(data.type, data.value));
331 if (!ret.second) {
332 FI_HILOGW("type is duplicated");
333 return data;
334 }
335 notifyManagerFlag_ = true;
336 return data;
337 }
338
GetObserverData() const339 std::map<ClientType, ClientValue> DeviceStatusMsdpClientImpl::GetObserverData() const
340 {
341 return deviceStatusDatas_;
342 }
343
GetDeviceStatusTimestamp()344 void DeviceStatusMsdpClientImpl::GetDeviceStatusTimestamp()
345 {}
346
GetLongtitude()347 void DeviceStatusMsdpClientImpl::GetLongtitude()
348 {}
349
GetLatitude()350 void DeviceStatusMsdpClientImpl::GetLatitude()
351 {}
352
LoadMockLibrary()353 ErrCode DeviceStatusMsdpClientImpl::LoadMockLibrary()
354 {
355 CALL_DEBUG_ENTER;
356 std::unique_lock lock(mutex_);
357 if (mock_.handle != nullptr) {
358 FI_HILOGW("mock handle is not nullptr");
359 return RET_OK;
360 }
361 std::string dlName = DEVICESTATUS_MOCK_LIB_PATH;
362 char libRealPath[PATH_MAX] = { 0 };
363 if (realpath(dlName .c_str(), libRealPath) == nullptr) {
364 FI_HILOGE("Get absolute algoPath is error, errno:%{public}d", errno);
365 return RET_ERR;
366 }
367 mock_.handle = dlopen(libRealPath, RTLD_LAZY);
368 if (mock_.handle == nullptr) {
369 FI_HILOGE("Cannot load library error:%{public}s", dlerror());
370 return RET_ERR;
371 }
372 FI_HILOGI("Start create pointer");
373 mock_.create = reinterpret_cast<LoadMockLibraryFunc>(dlsym(mock_.handle, "Create"));
374 FI_HILOGI("Start destroy pointer");
375 mock_.destroy = reinterpret_cast<LoadMockLibraryPtr>(dlsym(mock_.handle, "Destroy"));
376 if ((mock_.create == nullptr) || (mock_.destroy == nullptr)) {
377 FI_HILOGE("%{public}s dlsym Create or Destroy failed",
378 dlName.c_str());
379 dlclose(mock_.handle);
380 mock_.Clear();
381 if (mock_.handle == nullptr) {
382 return RET_OK;
383 }
384 FI_HILOGE("Load mock failed");
385 return RET_ERR;
386 }
387 return RET_OK;
388 }
389
UnloadMockLibrary()390 ErrCode DeviceStatusMsdpClientImpl::UnloadMockLibrary()
391 {
392 CALL_DEBUG_ENTER;
393 std::unique_lock lock(mutex_);
394 CHKPR(mock_.handle, RET_ERR);
395 if (mock_.pAlgorithm != nullptr) {
396 mock_.destroy(mock_.pAlgorithm);
397 mock_.pAlgorithm = nullptr;
398 }
399 dlclose(mock_.handle);
400 mock_.Clear();
401 return RET_OK;
402 }
403
GetMockInst(Type type)404 IMsdp* DeviceStatusMsdpClientImpl::GetMockInst(Type type)
405 {
406 CALL_DEBUG_ENTER;
407 CHKPP(mock_.handle);
408 if (type > TYPE_MAX || type < TYPE_INVALID) {
409 FI_HILOGE("Type invalid");
410 return nullptr;
411 }
412 if (mock_.pAlgorithm == nullptr) {
413 mock_.pAlgorithm = mock_.create();
414 mockCallCounts_[type] = 0;
415 }
416 return mock_.pAlgorithm;
417 }
418
LoadAlgoLibrary()419 ErrCode DeviceStatusMsdpClientImpl::LoadAlgoLibrary()
420 {
421 CALL_DEBUG_ENTER;
422 std::unique_lock lock(mutex_);
423 if (algo_.handle != nullptr) {
424 FI_HILOGE("Algo handle has exists");
425 return RET_OK;
426 }
427 std::string dlName = DEVICESTATUS_ALGO_LIB_PATH;
428 char libRealPath[PATH_MAX] = { 0 };
429 if (realpath(dlName .c_str(), libRealPath) == nullptr) {
430 FI_HILOGE("Get absolute algoPath is error, errno:%{public}d", errno);
431 return RET_ERR;
432 }
433 algo_.handle = dlopen(libRealPath, RTLD_LAZY);
434 if (algo_.handle == nullptr) {
435 FI_HILOGE("Cannot load library error:%{public}s", dlerror());
436 return RET_ERR;
437 }
438 FI_HILOGI("Start create pointer");
439 algo_.create = reinterpret_cast<LoadMockLibraryFunc>(dlsym(algo_.handle, "Create"));
440 FI_HILOGI("Start destroy pointer");
441 algo_.destroy = reinterpret_cast<LoadMockLibraryPtr>(dlsym(algo_.handle, "Destroy"));
442 if ((algo_.create == nullptr) || (algo_.destroy == nullptr)) {
443 FI_HILOGE("%{public}s dlsym Create or Destroy failed",
444 dlName.c_str());
445 dlclose(algo_.handle);
446 algo_.Clear();
447 if (algo_.handle == nullptr) {
448 return RET_OK;
449 }
450 FI_HILOGE("Load algo failed");
451 return RET_ERR;
452 }
453 return RET_OK;
454 }
455
UnloadAlgoLibrary()456 ErrCode DeviceStatusMsdpClientImpl::UnloadAlgoLibrary()
457 {
458 CALL_DEBUG_ENTER;
459 std::unique_lock lock(mutex_);
460 CHKPR(algo_.handle, RET_ERR);
461 if (algo_.pAlgorithm != nullptr) {
462 algo_.destroy(algo_.pAlgorithm);
463 algo_.pAlgorithm = nullptr;
464 }
465 dlclose(algo_.handle);
466 algo_.Clear();
467 return RET_OK;
468 }
469
GetAlgoInst(Type type)470 IMsdp* DeviceStatusMsdpClientImpl::GetAlgoInst(Type type)
471 {
472 CALL_DEBUG_ENTER;
473 std::unique_lock lock(mutex_);
474 CHKPP(algo_.handle);
475 if (algo_.pAlgorithm == nullptr) {
476 algo_.pAlgorithm = algo_.create();
477 }
478 return algo_.pAlgorithm;
479 }
480 } // namespace DeviceStatus
481 } // namespace Msdp
482 } // namespace OHOS
483