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