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