1 /*
2  * Copyright (c) 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 "ddm_adapter_impl.h"
17 
18 #include <algorithm>
19 
20 #include "devicestatus_define.h"
21 #include "utility.h"
22 
23 #undef LOG_TAG
24 #define LOG_TAG "DDMAdapterImpl"
25 
26 namespace OHOS {
27 namespace Msdp {
28 namespace DeviceStatus {
29 
30 #define D_DEV_MGR   DistributedHardware::DeviceManager::GetInstance()
31 constexpr size_t MAX_ONLINE_DEVICE_SIZE = 10000;
32 
~DDMAdapterImpl()33 DDMAdapterImpl::~DDMAdapterImpl()
34 {
35     Disable();
36 }
37 
Enable()38 int32_t DDMAdapterImpl::Enable()
39 {
40     CALL_DEBUG_ENTER;
41     std::lock_guard guard(lock_);
42     std::string pkgName(FI_PKG_NAME);
43     std::string extra;
44     initCb_ = std::make_shared<DmInitCb>();
45 
46     int32_t ret = D_DEV_MGR.InitDeviceManager(pkgName, initCb_);
47     if (ret != 0) {
48         FI_HILOGE("DM::InitDeviceManager fail");
49         goto INIT_FAIL;
50     }
51     boardStateCb_ = std::make_shared<DmBoardStateCb>(shared_from_this());
52 
53     ret = D_DEV_MGR.RegisterDevStateCallback(pkgName, extra, boardStateCb_);
54     if (ret != 0) {
55         FI_HILOGE("DM::RegisterDevStateCallback fail");
56         goto REG_FAIL;
57     }
58     return RET_OK;
59 
60 REG_FAIL:
61     ret = D_DEV_MGR.UnInitDeviceManager(pkgName);
62     if (ret != 0) {
63         FI_HILOGE("DM::UnInitDeviceManager fail");
64     }
65     boardStateCb_.reset();
66 
67 INIT_FAIL:
68     initCb_.reset();
69     return RET_ERR;
70 }
71 
Disable()72 void DDMAdapterImpl::Disable()
73 {
74     CALL_DEBUG_ENTER;
75     std::lock_guard guard(lock_);
76     std::string pkgName(FI_PKG_NAME);
77 
78     if (boardStateCb_ != nullptr) {
79         boardStateCb_.reset();
80         int32_t ret = D_DEV_MGR.UnRegisterDevStateCallback(pkgName);
81         if (ret != 0) {
82             FI_HILOGE("DM::UnRegisterDevStateCallback fail");
83         }
84     }
85     if (initCb_ != nullptr) {
86         initCb_.reset();
87         int32_t ret = D_DEV_MGR.UnInitDeviceManager(pkgName);
88         if (ret != 0) {
89             FI_HILOGE("DM::UnInitDeviceManager fail");
90         }
91     }
92 }
93 
AddBoardObserver(std::shared_ptr<IBoardObserver> observer)94 void DDMAdapterImpl::AddBoardObserver(std::shared_ptr<IBoardObserver> observer)
95 {
96     CALL_DEBUG_ENTER;
97     std::lock_guard guard(lock_);
98     CHKPV(observer);
99     observers_.erase(Observer());
100     observers_.emplace(observer);
101 }
102 
RemoveBoardObserver(std::shared_ptr<IBoardObserver> observer)103 void DDMAdapterImpl::RemoveBoardObserver(std::shared_ptr<IBoardObserver> observer)
104 {
105     CALL_DEBUG_ENTER;
106     std::lock_guard guard(lock_);
107     CHKPV(observer);
108     observers_.erase(Observer());
109     if (auto iter = observers_.find(Observer(observer)); iter != observers_.end()) {
110         observers_.erase(iter);
111     }
112 }
113 
GetTrustedDeviceList(std::vector<DistributedHardware::DmDeviceInfo> & deviceList)114 int32_t DDMAdapterImpl::GetTrustedDeviceList(std::vector<DistributedHardware::DmDeviceInfo> &deviceList)
115 {
116     CALL_INFO_TRACE;
117     deviceList.clear();
118     if (int32_t ret = D_DEV_MGR.GetTrustedDeviceList(FI_PKG_NAME, "", deviceList); ret != RET_OK) {
119         FI_HILOGE("GetTrustedDeviceList failed, ret %{public}d.", ret);
120         return RET_ERR;
121     }
122     return RET_OK;
123 }
124 
CheckSameAccountToLocal(const std::string & networkId)125 bool DDMAdapterImpl::CheckSameAccountToLocal(const std::string &networkId)
126 {
127     CALL_INFO_TRACE;
128     std::vector<DistributedHardware::DmDeviceInfo> deviceList;
129     if (GetTrustedDeviceList(deviceList) != RET_OK) {
130         FI_HILOGE("GetTrustedDeviceList failed");
131         return false;
132     }
133     if (size_t size = deviceList.size(); size == 0 || size > MAX_ONLINE_DEVICE_SIZE) {
134         FI_HILOGE("Trust device list size is invalid");
135         return false;
136     }
137     for (const auto &deviceInfo : deviceList) {
138         if (std::string(deviceInfo.networkId) == networkId) {
139             return (deviceInfo.authForm == DistributedHardware::DmAuthForm::IDENTICAL_ACCOUNT);
140         }
141     }
142     return false;
143 }
144 
OnBoardOnline(const std::string & networkId)145 void DDMAdapterImpl::OnBoardOnline(const std::string &networkId)
146 {
147     CALL_DEBUG_ENTER;
148     std::lock_guard guard(lock_);
149     FI_HILOGI("Board \'%{public}s\' is online", Utility::Anonymize(networkId).c_str());
150     std::for_each(observers_.cbegin(), observers_.cend(),
151         [&networkId](const auto &item) {
152             if (auto observer = item.Lock(); observer != nullptr) {
153                 observer->OnBoardOnline(networkId);
154             }
155         });
156 }
157 
OnBoardOffline(const std::string & networkId)158 void DDMAdapterImpl::OnBoardOffline(const std::string &networkId)
159 {
160     CALL_DEBUG_ENTER;
161     std::lock_guard guard(lock_);
162     FI_HILOGI("Board \'%{public}s\' is offline", Utility::Anonymize(networkId).c_str());
163     std::for_each(observers_.cbegin(), observers_.cend(),
164         [&networkId](const auto &item) {
165             if (auto observer = item.Lock(); observer != nullptr) {
166                 observer->OnBoardOffline(networkId);
167             }
168         });
169 }
170 } // namespace DeviceStatus
171 } // namespace Msdp
172 } // namespace OHOS
173