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