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