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