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