1 /*
2 * Copyright (c) 2021 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 "dm_device_state_manager.h"
17
18 #include "dm_adapter_manager.h"
19 #include "dm_anonymous.h"
20 #include "dm_constants.h"
21 #include "dm_log.h"
22
23 namespace OHOS {
24 namespace DistributedHardware {
DmDeviceStateManager(std::shared_ptr<SoftbusConnector> softbusConnector,std::shared_ptr<DeviceManagerServiceListener> listener,std::shared_ptr<HiChainConnector> hiChainConnector)25 DmDeviceStateManager::DmDeviceStateManager(std::shared_ptr<SoftbusConnector> softbusConnector,
26 std::shared_ptr<DeviceManagerServiceListener> listener, std::shared_ptr<HiChainConnector> hiChainConnector)
27 : softbusConnector_(softbusConnector), listener_(listener), hiChainConnector_(hiChainConnector)
28 {
29 profileSoName_ = "libdevicemanagerext_profile.z.so";
30 decisionSoName_ = "libdevicemanagerext_decision.z.so";
31 LOGI("DmDeviceStateManager constructor");
32 }
33
~DmDeviceStateManager()34 DmDeviceStateManager::~DmDeviceStateManager()
35 {
36 LOGI("DmDeviceStateManager destructor");
37 if (softbusConnector_ != nullptr) {
38 softbusConnector_->UnRegisterSoftbusStateCallback("DM_PKG_NAME");
39 }
40 }
41
RegisterProfileListener(const std::string & pkgName,const DmDeviceInfo & info)42 int32_t DmDeviceStateManager::RegisterProfileListener(const std::string &pkgName, const DmDeviceInfo &info)
43 {
44 DmAdapterManager &adapterMgrPtr = DmAdapterManager::GetInstance();
45 std::shared_ptr<IProfileAdapter> profileAdapter = adapterMgrPtr.GetProfileAdapter(profileSoName_);
46 if (profileAdapter != nullptr) {
47 std::string deviceUdid;
48 int32_t ret = SoftbusConnector::GetUdidByNetworkId(info.deviceId, deviceUdid);
49 if (ret == DM_OK) {
50 std::string uuid;
51 DmDeviceInfo saveInfo = info;
52 SoftbusConnector::GetUuidByNetworkId(info.deviceId, uuid);
53 {
54 #if defined(__LITEOS_M__)
55 DmMutex mutexLock;
56 #else
57 std::lock_guard<std::mutex> mutexLock(remoteDeviceInfosMutex_);
58 #endif
59 remoteDeviceInfos_[uuid] = saveInfo;
60 }
61 LOGI("RegisterProfileListener in, deviceId = %s, deviceUdid = %s, uuid = %s", GetAnonyString(
62 std::string(info.deviceId)).c_str(), GetAnonyString(deviceUdid).c_str(), GetAnonyString(uuid).c_str());
63 profileAdapter->RegisterProfileListener(pkgName, deviceUdid, shared_from_this());
64 }
65 }
66 return DM_OK;
67 }
68
UnRegisterProfileListener(const std::string & pkgName,const DmDeviceInfo & info)69 int32_t DmDeviceStateManager::UnRegisterProfileListener(const std::string &pkgName, const DmDeviceInfo &info)
70 {
71 DmAdapterManager &adapterMgrPtr = DmAdapterManager::GetInstance();
72 std::shared_ptr<IProfileAdapter> profileAdapter = adapterMgrPtr.GetProfileAdapter(profileSoName_);
73 if (profileAdapter != nullptr) {
74 LOGI("UnRegister Profile Listener");
75 profileAdapter->UnRegisterProfileListener(pkgName);
76 }
77 {
78 #if defined(__LITEOS_M__)
79 DmMutex mutexLock;
80 #else
81 std::lock_guard<std::mutex> mutexLock(remoteDeviceInfosMutex_);
82 #endif
83 if (remoteDeviceInfos_.find(std::string(info.deviceId)) != remoteDeviceInfos_.end()) {
84 remoteDeviceInfos_.erase(std::string(info.deviceId));
85 }
86 }
87 return DM_OK;
88 }
89
PostDeviceOnline(const std::string & pkgName,const DmDeviceInfo & info)90 void DmDeviceStateManager::PostDeviceOnline(const std::string &pkgName, const DmDeviceInfo &info)
91 {
92 LOGI("DmDeviceStateManager::PostDeviceOnline in");
93 if (listener_ != nullptr) {
94 DmDeviceState state = DEVICE_STATE_ONLINE;
95 listener_->OnDeviceStateChange(pkgName, state, info);
96 }
97 LOGI("DmDeviceStateManager::PostDeviceOnline out");
98 }
99
PostDeviceOffline(const std::string & pkgName,const DmDeviceInfo & info)100 void DmDeviceStateManager::PostDeviceOffline(const std::string &pkgName, const DmDeviceInfo &info)
101 {
102 LOGI("DmDeviceStateManager::PostDeviceOffline in");
103 if (listener_ != nullptr) {
104 DmDeviceState state = DEVICE_STATE_OFFLINE;
105 listener_->OnDeviceStateChange(pkgName, state, info);
106 }
107 LOGI("DmDeviceStateManager::PostDeviceOffline out");
108 }
109
OnDeviceOnline(const std::string & pkgName,const DmDeviceInfo & info)110 void DmDeviceStateManager::OnDeviceOnline(const std::string &pkgName, const DmDeviceInfo &info)
111 {
112 LOGI("OnDeviceOnline function is called back with pkgName: %s", pkgName.c_str());
113 RegisterOffLineTimer(info);
114 RegisterProfileListener(pkgName, info);
115
116 DmAdapterManager &adapterMgrPtr = DmAdapterManager::GetInstance();
117 std::shared_ptr<IDecisionAdapter> decisionAdapter = adapterMgrPtr.GetDecisionAdapter(decisionSoName_);
118 if (decisionAdapter == nullptr) {
119 LOGE("OnDeviceOnline decision adapter is null");
120 PostDeviceOnline(pkgName, info);
121 } else if (decisionInfos_.size() == 0) {
122 PostDeviceOnline(pkgName, info);
123 } else {
124 std::string extra;
125 std::vector<DmDeviceInfo> infoList;
126 LOGI("OnDeviceOnline decision decisionInfos_ size: %d", decisionInfos_.size());
127 for (auto iter : decisionInfos_) {
128 std::string listenerPkgName = iter.first;
129 std::string extra = iter.second;
130 infoList.clear();
131 infoList.push_back(info);
132 decisionAdapter->FilterDeviceList(infoList, extra);
133 if (infoList.size() == 1) {
134 PostDeviceOnline(listenerPkgName, info);
135 }
136 }
137 }
138 LOGI("DmDeviceStateManager::OnDeviceOnline out");
139 }
140
OnDeviceOffline(const std::string & pkgName,const DmDeviceInfo & info)141 void DmDeviceStateManager::OnDeviceOffline(const std::string &pkgName, const DmDeviceInfo &info)
142 {
143 LOGI("OnDeviceOnline function is called with pkgName: %s", pkgName.c_str());
144 StartOffLineTimer(info);
145 UnRegisterProfileListener(pkgName, info);
146
147 DmAdapterManager &adapterMgrPtr = DmAdapterManager::GetInstance();
148 std::shared_ptr<IDecisionAdapter> decisionAdapter = adapterMgrPtr.GetDecisionAdapter(decisionSoName_);
149 if (decisionAdapter == nullptr) {
150 LOGE("OnDeviceOnline decision adapter is null");
151 PostDeviceOffline(pkgName, info);
152 } else if (decisionInfos_.size() == 0) {
153 PostDeviceOffline(pkgName, info);
154 } else {
155 std::string extra;
156 std::vector<DmDeviceInfo> infoList;
157 LOGI("OnDeviceOnline decision decisionInfos_ size: %d", decisionInfos_.size());
158 for (auto iter : decisionInfos_) {
159 std::string listenerPkgName = iter.first;
160 std::string extra = iter.second;
161 infoList.clear();
162 infoList.push_back(info);
163 decisionAdapter->FilterDeviceList(infoList, extra);
164 if (infoList.size() == 1) {
165 PostDeviceOffline(listenerPkgName, info);
166 }
167 }
168 }
169 LOGI("DmDeviceStateManager::OnDeviceOffline out");
170 }
171
OnDeviceChanged(const std::string & pkgName,const DmDeviceInfo & info)172 void DmDeviceStateManager::OnDeviceChanged(const std::string &pkgName, const DmDeviceInfo &info)
173 {
174 LOGI("OnDeviceChanged function is called back with pkgName: %s", pkgName.c_str());
175 }
176
OnDeviceReady(const std::string & pkgName,const DmDeviceInfo & info)177 void DmDeviceStateManager::OnDeviceReady(const std::string &pkgName, const DmDeviceInfo &info)
178 {
179 LOGI("OnDeviceReady function is called back with pkgName: %s", pkgName.c_str());
180 }
181
OnProfileReady(const std::string & pkgName,const std::string & deviceId)182 void DmDeviceStateManager::OnProfileReady(const std::string &pkgName, const std::string &deviceId)
183 {
184 LOGI("OnProfileReady function is called back");
185 if (pkgName.empty() || deviceId.empty()) {
186 LOGE("On profile ready pkgName is empty or deviceId is deviceId");
187 return;
188 }
189 DmDeviceInfo saveInfo;
190 {
191 #if defined(__LITEOS_M__)
192 DmMutex mutexLock;
193 #else
194 std::lock_guard<std::mutex> mutexLock(remoteDeviceInfosMutex_);
195 #endif
196 auto iter = remoteDeviceInfos_.find(deviceId);
197 if (iter == remoteDeviceInfos_.end()) {
198 LOGE("OnProfileReady complete not find deviceId: %s", GetAnonyString(deviceId).c_str());
199 return;
200 }
201 saveInfo = iter->second;
202 }
203 if (listener_ != nullptr) {
204 DmDeviceState state = DEVICE_INFO_READY;
205 listener_->OnDeviceStateChange(pkgName, state, saveInfo);
206 }
207 }
208
RegisterSoftbusStateCallback()209 int32_t DmDeviceStateManager::RegisterSoftbusStateCallback()
210 {
211 if (softbusConnector_ != nullptr) {
212 return softbusConnector_->RegisterSoftbusStateCallback(DM_PKG_NAME, shared_from_this());
213 }
214 return DM_OK;
215 }
216
RegisterDevStateCallback(const std::string & pkgName,const std::string & extra)217 void DmDeviceStateManager::RegisterDevStateCallback(const std::string &pkgName, const std::string &extra)
218 {
219 LOGI("DmDeviceStateManager::RegisterDevStateCallback pkgName=%s, extra=%s", pkgName.c_str(), extra.c_str());
220 if (pkgName != "") {
221 decisionInfos_[pkgName] = extra;
222 }
223 }
224
UnRegisterDevStateCallback(const std::string & pkgName,const std::string & extra)225 void DmDeviceStateManager::UnRegisterDevStateCallback(const std::string &pkgName, const std::string &extra)
226 {
227 LOGI("DmDeviceStateManager::UnRegisterDevStateCallback pkgName=%s, extra=%s", pkgName.c_str(), extra.c_str());
228 auto iter = decisionInfos_.find(pkgName);
229 if (iter == decisionInfos_.end()) {
230 } else {
231 decisionInfos_.erase(pkgName);
232 }
233 }
234
RegisterOffLineTimer(const DmDeviceInfo & deviceInfo)235 void DmDeviceStateManager::RegisterOffLineTimer(const DmDeviceInfo &deviceInfo)
236 {
237 std::string deviceId;
238 int32_t ret = softbusConnector_->GetUdidByNetworkId(deviceInfo.deviceId, deviceId);
239 if (ret != DM_OK) {
240 LOGE("fail to get udid by networkId");
241 return;
242 }
243 LOGI("Register OffLine Timer with device: %s", GetAnonyString(deviceId).c_str());
244
245 #if defined(__LITEOS_M__)
246 DmMutex mutexLock;
247 #else
248 std::lock_guard<std::mutex> mutexLock(timerMapMutex_);
249 #endif
250 for (auto &iter : stateTimerInfoMap_) {
251 if (iter.second.netWorkId == deviceInfo.deviceId) {
252 timer_->DeleteTimer(iter.second.timerName);
253 return;
254 }
255 }
256
257 if (timer_ == nullptr) {
258 timer_ = std::make_shared<DmTimer>();
259 }
260 std::string timerName = TIMER_PREFIX + STATE_TIMER_PREFIX + std::to_string(mCumulativeQuantity_++);
261 StateTimerInfo stateTimer = {
262 .timerName = timerName,
263 .netWorkId = deviceInfo.deviceId,
264 .deviceId = deviceId
265 };
266 stateTimerInfoMap_[timerName] = stateTimer;
267 }
268
StartOffLineTimer(const DmDeviceInfo & deviceInfo)269 void DmDeviceStateManager::StartOffLineTimer(const DmDeviceInfo &deviceInfo)
270 {
271 #if defined(__LITEOS_M__)
272 DmMutex mutexLock;
273 #else
274 std::lock_guard<std::mutex> mutexLock(timerMapMutex_);
275 #endif
276 LOGI("start offline timer");
277 for (auto &iter : stateTimerInfoMap_) {
278 if (iter.second.netWorkId == deviceInfo.deviceId) {
279 timer_->StartTimer(iter.second.timerName, OFFLINE_TIMEOUT,
280 [this] (std::string name) {
281 DmDeviceStateManager::DeleteTimeOutGroup(name);
282 });
283 }
284 }
285 }
286
DeleteTimeOutGroup(std::string name)287 void DmDeviceStateManager::DeleteTimeOutGroup(std::string name)
288 {
289 #if defined(__LITEOS_M__)
290 DmMutex mutexLock;
291 #else
292 std::lock_guard<std::mutex> mutexLock(timerMapMutex_);
293 #endif
294 if (hiChainConnector_ != nullptr) {
295 auto iter = stateTimerInfoMap_.find(name);
296 if (iter != stateTimerInfoMap_.end()) {
297 LOGI("remove hichain group with device: %s",
298 GetAnonyString(stateTimerInfoMap_[name].deviceId).c_str());
299 hiChainConnector_->DeleteTimeOutGroup(stateTimerInfoMap_[name].deviceId.c_str());
300 }
301 }
302 stateTimerInfoMap_.erase(name);
303 }
304 } // namespace DistributedHardware
305 } // namespace OHOS
306