1 /*
2 * Copyright (c) 2021-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 "dtbschedmgr_device_info_storage.h"
17
18 #include <chrono>
19 #include <thread>
20
21 #include "distributed_device_node_listener.h"
22 #include "distributed_sched_service.h"
23 #include "dtbschedmgr_log.h"
24 #include "ipc_object_proxy.h"
25 #include "ipc_skeleton.h"
26 #include "iservice_registry.h"
27 #include "system_ability_definition.h"
28
29 using namespace std;
30 namespace OHOS {
31 namespace DistributedSchedule {
32 using namespace std::chrono_literals;
33 using namespace DistributedHardware;
34
35 namespace {
36 constexpr int32_t RETRY_TIMES = 30;
37 constexpr int32_t CONNECT_SOFTBUS_RETRY_TIMES = 60;
38 const std::string TAG = "DtbschedmgrDeviceInfoStorage";
39 }
40
41 IMPLEMENT_SINGLE_INSTANCE(DtbschedmgrDeviceInfoStorage);
42
Init()43 bool DtbschedmgrDeviceInfoStorage::Init()
44 {
45 if (initHandler_ == nullptr) {
46 auto deviceInfoStorageRunner = AppExecFwk::EventRunner::Create("DmsDeviceInfoStorageManager");
47 initHandler_ = std::make_shared<AppExecFwk::EventHandler>(deviceInfoStorageRunner);
48 }
49
50 auto func = [this]() {
51 HILOGI("begin connect softbus");
52 for (int32_t retryTimes = 0; retryTimes <= CONNECT_SOFTBUS_RETRY_TIMES; retryTimes++) {
53 if (ConnectSoftbus()) {
54 return;
55 }
56 HILOGE("retry connect softbus %{public}d times", retryTimes);
57 std::this_thread::sleep_for(1s);
58 }
59 HILOGE("connect softbus 60times * 30s, error!!");
60 };
61 if (!initHandler_->PostTask(func)) {
62 HILOGE("Init handler postTask failed");
63 return false;
64 }
65 return true;
66 }
67
ConnectSoftbus()68 bool DtbschedmgrDeviceInfoStorage::ConnectSoftbus()
69 {
70 ClearAllDevices();
71 bool isReady = WaitForDnetworkReady();
72 if (!isReady) {
73 HILOGE("ConnectSoftbus wait Dnetwork failed!");
74 return false;
75 }
76 std::shared_ptr<DnetworkAdapter> dnetworkAdapter = DnetworkAdapter::GetInstance();
77 if (dnetworkAdapter == nullptr) {
78 HILOGE("DnetworkAdapter::GetInstance() null");
79 return false;
80 }
81 if (!InitNetworkIdManager(dnetworkAdapter)) {
82 HILOGE("InitNetworkIdManager failed");
83 return false;
84 }
85 HILOGI("ConnectSoftbus success");
86 return true;
87 }
88
InitNetworkIdManager(std::shared_ptr<DnetworkAdapter> dnetworkAdapter)89 bool DtbschedmgrDeviceInfoStorage::InitNetworkIdManager(std::shared_ptr<DnetworkAdapter> dnetworkAdapter)
90 {
91 if (networkIdMgrHandler_ == nullptr) {
92 auto runner = AppExecFwk::EventRunner::Create("DmsNetworkIdManager");
93 networkIdMgrHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
94 }
95
96 deviceNodeListener_ = std::make_shared<DistributedDeviceNodeListener>();
97 if (!dnetworkAdapter->AddDeviceChangeListener(deviceNodeListener_)) {
98 deviceNodeListener_ = nullptr;
99 HILOGE("AddDeviceChangeListener failed!");
100 return false;
101 }
102 return true;
103 }
104
Stop()105 void DtbschedmgrDeviceInfoStorage::Stop()
106 {
107 ClearAllDevices();
108 if (deviceNodeListener_ != nullptr) {
109 DnetworkAdapter::GetInstance()->RemoveDeviceChangeListener(deviceNodeListener_);
110 deviceNodeListener_ = nullptr;
111 }
112 }
113
WaitForDnetworkReady()114 bool DtbschedmgrDeviceInfoStorage::WaitForDnetworkReady()
115 {
116 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
117 if (samgr == nullptr) {
118 HILOGE("WaitForDnetworkReady failed to get samgr!");
119 return false;
120 }
121 int32_t retryTimeout = RETRY_TIMES;
122 do {
123 auto dnetwork = samgr->CheckSystemAbility(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID);
124 if (dnetwork != nullptr) {
125 IPCObjectProxy* proxy = reinterpret_cast<IPCObjectProxy*>(dnetwork.GetRefPtr());
126 // make sure the proxy is not dead
127 if (proxy != nullptr && !proxy->IsObjectDead()) {
128 return true;
129 }
130 }
131 HILOGI("Waiting for dnentwork service...");
132 std::this_thread::sleep_for(1s);
133 if (--retryTimeout <= 0) {
134 HILOGI("Waiting for dnentwork service timeout(30)s");
135 return false;
136 }
137 } while (true);
138 return false;
139 }
140
RegisterUuidNetworkIdMap(const std::string & networkId)141 void DtbschedmgrDeviceInfoStorage::RegisterUuidNetworkIdMap(const std::string& networkId)
142 {
143 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
144 if (uuid.empty()) {
145 HILOGE("GetUuidByNetworkId return an empty uuid!");
146 return;
147 }
148 {
149 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
150 uuidNetworkIdMap_[uuid] = networkId;
151 }
152 }
153
UnregisterUuidNetworkIdMap(const std::string & networkId)154 void DtbschedmgrDeviceInfoStorage::UnregisterUuidNetworkIdMap(const std::string& networkId)
155 {
156 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
157 if (uuid.empty()) {
158 HILOGE("GetUuidByNetworkId return an empty uuid");
159 return;
160 }
161 {
162 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
163 uuidNetworkIdMap_.erase(uuid);
164 }
165 }
166
GetDeviceIdSet(std::set<std::string> & deviceIdSet)167 void DtbschedmgrDeviceInfoStorage::GetDeviceIdSet(std::set<std::string>& deviceIdSet)
168 {
169 deviceIdSet.clear();
170 lock_guard<mutex> autoLock(deviceLock_);
171 for (const auto& device : remoteDevices_) {
172 deviceIdSet.emplace(device.first);
173 }
174 }
175
UpdateDeviceInfoStorage(const std::vector<DmDeviceInfo> & dmDeviceInfoList)176 void DtbschedmgrDeviceInfoStorage::UpdateDeviceInfoStorage(
177 const std::vector<DmDeviceInfo>& dmDeviceInfoList)
178 {
179 for (const auto& dmDeviceInfo : dmDeviceInfoList) {
180 auto deviceInfo = std::make_shared<DmsDeviceInfo>(
181 dmDeviceInfo.deviceName, dmDeviceInfo.deviceTypeId, dmDeviceInfo.networkId);
182 std::string networkId = deviceInfo->GetNetworkId();
183 RegisterUuidNetworkIdMap(networkId);
184 {
185 lock_guard<mutex> autoLock(deviceLock_);
186 remoteDevices_[networkId] = deviceInfo;
187 }
188 }
189 }
190
GetLocalDeviceId(std::string & networkId)191 bool DtbschedmgrDeviceInfoStorage::GetLocalDeviceId(std::string& networkId)
192 {
193 return GetLocalDeviceFromDnet(networkId);
194 }
195
GetLocalDeviceFromDnet(std::string & networkId)196 bool DtbschedmgrDeviceInfoStorage::GetLocalDeviceFromDnet(std::string& networkId)
197 {
198 auto dnetworkAdapter = DnetworkAdapter::GetInstance();
199 if (dnetworkAdapter == nullptr) {
200 HILOGE("GetLocalDeviceFromDnet dnetworkAdapter null");
201 return false;
202 }
203 DmDeviceInfo dmDeviceInfo;
204 if (!dnetworkAdapter->GetLocalBasicInfo(dmDeviceInfo)) {
205 HILOGE("GetLocalBasicInfo error");
206 return false;
207 }
208 networkId = dmDeviceInfo.networkId;
209 HILOGI("get local networkId from DnetworkAdapter, networkId = %{public}s",
210 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
211 return true;
212 }
213
ClearAllDevices()214 void DtbschedmgrDeviceInfoStorage::ClearAllDevices()
215 {
216 lock_guard<mutex> autoLock(deviceLock_);
217 remoteDevices_.clear();
218 }
219
GetDeviceInfoById(const string & networkId)220 std::shared_ptr<DmsDeviceInfo> DtbschedmgrDeviceInfoStorage::GetDeviceInfoById(const string& networkId)
221 {
222 lock_guard<mutex> autoLock(deviceLock_);
223 auto iter = remoteDevices_.find(networkId);
224 if (iter == remoteDevices_.end()) {
225 return nullptr;
226 }
227 return iter->second;
228 }
229
GetUuidByNetworkId(const std::string & networkId)230 std::string DtbschedmgrDeviceInfoStorage::GetUuidByNetworkId(const std::string& networkId)
231 {
232 if (networkId.empty()) {
233 HILOGW("GetUuidByNetworkId networkId empty!");
234 return "";
235 }
236 {
237 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
238 auto iter = uuidNetworkIdMap_.begin();
239 while (iter != uuidNetworkIdMap_.end()) {
240 if (iter->second == networkId) {
241 return iter->first;
242 } else {
243 ++iter;
244 }
245 }
246 }
247 std::string uuid = DnetworkAdapter::GetInstance()->GetUuidByNetworkId(networkId);
248 return uuid;
249 }
250
GetNetworkIdByUuid(const std::string & uuid)251 std::string DtbschedmgrDeviceInfoStorage::GetNetworkIdByUuid(const std::string& uuid)
252 {
253 if (uuid.empty()) {
254 HILOGW("GetNetworkIdByUuid uuid empty!");
255 return "";
256 }
257 {
258 std::lock_guard<std::mutex> autoLock(uuidNetworkIdLock_);
259 auto iter = uuidNetworkIdMap_.find(uuid);
260 if (iter != uuidNetworkIdMap_.end()) {
261 return iter->second;
262 }
263 return "";
264 }
265 }
DeviceOnlineNotify(const std::shared_ptr<DmsDeviceInfo> devInfo)266 void DtbschedmgrDeviceInfoStorage::DeviceOnlineNotify(const std::shared_ptr<DmsDeviceInfo> devInfo)
267 {
268 if (devInfo == nullptr) {
269 HILOGE("DeviceOnlineNotify devInfo null");
270 return;
271 }
272
273 if (networkIdMgrHandler_ == nullptr) {
274 HILOGE("networkIdMgrHandler null");
275 return;
276 }
277 auto nodeOnline = [this, devInfo]() {
278 std::string networkId = devInfo->GetNetworkId();
279 RegisterUuidNetworkIdMap(networkId);
280 std::string uuid = GetUuidByNetworkId(networkId);
281 HILOGI("networkId = %{public}s, uuid = %{public}s, deviceName = %{public}s",
282 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str(),
283 DnetworkAdapter::AnonymizeNetworkId(uuid).c_str(), devInfo->GetDeviceName().c_str());
284 {
285 lock_guard<mutex> autoLock(deviceLock_);
286 remoteDevices_[networkId] = devInfo;
287 }
288 DistributedSchedService::GetInstance().DeviceOnlineNotify(networkId);
289 };
290 if (!networkIdMgrHandler_->PostTask(nodeOnline)) {
291 HILOGE("DeviceOnlineNotify handler postTask failed");
292 }
293 }
294
DeviceOfflineNotify(const std::string & networkId)295 void DtbschedmgrDeviceInfoStorage::DeviceOfflineNotify(const std::string& networkId)
296 {
297 if (networkId.empty()) {
298 HILOGE("DeviceOfflineNotify networkId empty");
299 return;
300 }
301 HILOGI("DeviceOfflineNotify networkId = %{public}s",
302 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
303 if (networkIdMgrHandler_ == nullptr) {
304 HILOGE("DeviceOfflineNotify networkIdMgrHandler null");
305 return;
306 }
307 auto nodeOffline = [this, networkId]() {
308 std::string uuid = GetUuidByNetworkId(networkId);
309 HILOGI("DeviceOfflineNotify process networkId = %{public}s, uuid = %{public}s",
310 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str(), DnetworkAdapter::AnonymizeNetworkId(uuid).c_str());
311 DistributedSchedService::GetInstance().DeviceOfflineNotify(networkId);
312 UnregisterUuidNetworkIdMap(networkId);
313 lock_guard<mutex> autoLock(deviceLock_);
314 remoteDevices_.erase(networkId);
315 };
316 if (!networkIdMgrHandler_->PostTask(nodeOffline)) {
317 HILOGE("DeviceOfflineNotify handler postTask failed");
318 }
319 }
320
OnDeviceInfoChanged(const std::string & deviceId)321 void DtbschedmgrDeviceInfoStorage::OnDeviceInfoChanged(const std::string& deviceId)
322 {
323 HILOGI("OnDeviceInfoChanged called");
324 }
325
OnRemoteDied(const wptr<IRemoteObject> & remote)326 void DnetServiceDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
327 {
328 HILOGI("OnRemoteDied dnetwork service died");
329 DtbschedmgrDeviceInfoStorage::GetInstance().Init();
330 }
331 }
332 }
333