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