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