• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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