1 /*
2  * Copyright (c) 2021-2024 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 "adapter/dnetwork_adapter.h"
17 
18 #include <chrono>
19 #include <functional>
20 #include <thread>
21 #include <unistd.h>
22 
23 #include "errors.h"
24 #include "event_runner.h"
25 
26 #include "distributed_sched_utils.h"
27 #include "dtbschedmgr_device_info_storage.h"
28 #include "dtbschedmgr_log.h"
29 #include "mission/distributed_bm_storage.h"
30 #include "mission/dsched_sync_e2e.h"
31 
32 namespace OHOS {
33 namespace DistributedSchedule {
34 using namespace std::chrono_literals;
35 using namespace DistributedHardware;
36 
37 namespace {
38 constexpr int32_t RETRY_REGISTER_CALLBACK_TIMES = 5;
39 constexpr int32_t RETRY_REGISTER_CALLBACK_DELAY_TIME = 1000; // 1s
40 const std::string PKG_NAME = "DBinderBus_Dms_" + std::to_string(getprocpid());
41 
42 const std::string EMPTY_DEVICE_ID = "";
43 const std::string TAG = "DnetworkAdapter";
44 }
45 
46 std::shared_ptr<AppExecFwk::EventHandler> DnetworkAdapter::dnetworkHandler_;
47 std::mutex DnetworkAdapter::listenerSetMutex_;
48 std::set<std::shared_ptr<DeviceListener>> DnetworkAdapter::listenerSet_;
49 
GetInstance()50 std::shared_ptr<DnetworkAdapter> DnetworkAdapter::GetInstance()
51 {
52     static auto instance = std::make_shared<DnetworkAdapter>();
53     return instance;
54 }
55 
Init()56 void DnetworkAdapter::Init()
57 {
58     initCallback_ = std::make_shared<DeviceInitCallBack>();
59     stateCallback_ = std::make_shared<DmsDeviceStateCallback>();
60     devTrustChangeCallback_ = std::make_shared<DmsDevTrustChangeCallback>();
61     auto runner = AppExecFwk::EventRunner::Create("dmsDnetwork");
62     dnetworkHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
63 }
64 
OnRemoteDied()65 void DnetworkAdapter::DeviceInitCallBack::OnRemoteDied()
66 {
67     HILOGI("DeviceInitCallBack OnRemoteDied");
68     DtbschedmgrDeviceInfoStorage::GetInstance().Init();
69 }
70 
OnDeviceOnline(const DmDeviceInfo& deviceInfo)71 void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo& deviceInfo)
72 {
73     HILOGI("OnNodeOnline netwokId: %{public}s.", GetAnonymStr(deviceInfo.networkId).c_str());
74     if (DmsKvSyncE2E::GetInstance()->CheckDeviceCfg()) {
75         DmsKvSyncE2E::GetInstance()->PushAndPullData(deviceInfo.networkId);
76     }
77     DmsKvSyncE2E::GetInstance()->ClearSyncRecord(deviceInfo.networkId);
78 
79     auto onlineNotifyTask = [deviceInfo]() {
80         std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
81         for (auto& listener : listenerSet_) {
82             if (listener != nullptr) {
83                 listener->OnDeviceOnline(deviceInfo);
84             }
85         }
86     };
87     if (dnetworkHandler_ == nullptr || !dnetworkHandler_->PostTask(onlineNotifyTask)) {
88         HILOGE("OnNodeOnline post task failed");
89         return;
90     }
91 }
92 
OnDeviceOffline(const DmDeviceInfo& deviceInfo)93 void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo& deviceInfo)
94 {
95     HILOGI("OnNodeOffline networkId: %{public}s.", GetAnonymStr(deviceInfo.networkId).c_str());
96     DmsKvSyncE2E::GetInstance()->ClearSyncRecord(deviceInfo.networkId);
97     auto offlineNotifyTask = [deviceInfo]() {
98         std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
99         for (auto& listener : listenerSet_) {
100             if (listener != nullptr) {
101                 listener->OnDeviceOffline(deviceInfo);
102             }
103         }
104     };
105     if (dnetworkHandler_ == nullptr || !dnetworkHandler_->PostTask(offlineNotifyTask)) {
106         HILOGE("OnNodeOffline post task failed");
107         return;
108     }
109 }
110 
OnDeviceChanged(const DmDeviceInfo& deviceInfo)111 void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo& deviceInfo)
112 {
113     std::string networkId = deviceInfo.networkId;
114     HILOGI("OnDeviceChanged networkId: %{public}s.", GetAnonymStr(networkId).c_str());
115 }
116 
OnDeviceReady(const DmDeviceInfo& deviceInfo)117 void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceReady(const DmDeviceInfo& deviceInfo)
118 {
119     HILOGI("called");
120 }
121 
OnDeviceTrustChange(const std::string &udid, const std::string &uuid, const DmAuthForm authform)122 void DnetworkAdapter::DmsDevTrustChangeCallback::OnDeviceTrustChange(const std::string &udid,
123     const std::string &uuid, const DmAuthForm authform)
124 {
125     HILOGI("called");
126     if (udid.empty() || uuid.empty()) {
127         HILOGE("udid or uuid is empty!");
128         return;
129     }
130     if (authform != DmAuthForm::IDENTICAL_ACCOUNT) {
131         HILOGE("peer is not same account");
132         return;
133     }
134     if (!DmsBmStorage::GetInstance()->DelDataOfLogoutDev(udid, uuid)) {
135         HILOGE("DelDataOfLogoutDev failed");
136     }
137     HILOGI("end");
138 }
139 
AddDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)140 bool DnetworkAdapter::AddDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)
141 {
142     HILOGD("AddDeviceChangeListener called");
143     if (dnetworkHandler_ == nullptr) {
144         HILOGE("handler is null");
145         return false;
146     }
147     {
148         std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
149         if (listenerSet_.find(listener) == listenerSet_.end()) {
150             listenerSet_.insert(listener);
151         }
152         if (listenerSet_.size() > 1) {
153             return true;
154         }
155     }
156     auto registerTask = [this]() {
157         HILOGD("AddDeviceChangeListener register mission...");
158         int32_t retryTimes = 0;
159         int32_t errCode = ERR_OK;
160         while (retryTimes++ < RETRY_REGISTER_CALLBACK_TIMES) {
161             int32_t ret = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, initCallback_);
162             if (ret != ERR_OK) {
163                 HILOGE("init device manager failed, ret:%{public}d", ret);
164                 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_REGISTER_CALLBACK_DELAY_TIME));
165                 continue;
166             }
167             errCode = DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "", stateCallback_);
168             if (errCode != ERR_OK) {
169                 HILOGD("AddDeviceChangeListener Reg errCode = %{public}d, retrying...", errCode);
170                 errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
171                 HILOGD("AddDeviceChangeListener Unreg errCode = %{public}d", errCode);
172                 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_REGISTER_CALLBACK_DELAY_TIME));
173                 continue;
174             }
175             errCode = DeviceManager::GetInstance().RegDevTrustChangeCallback(PKG_NAME, devTrustChangeCallback_);
176             HILOGI("RegDevTrustChangeCallback errCode = %{public}d", errCode);
177             if (UpdateDeviceInfoStorage()) {
178                 break;
179             }
180         }
181         HILOGI("AddDeviceChangeListener %{public}s", (errCode == ERR_OK) ? "success" : "timeout");
182     };
183     if (!dnetworkHandler_->PostTask(registerTask)) {
184         HILOGE("AddDeviceChangeListener post task failed");
185         return false;
186     }
187     return true;
188 }
189 
UpdateDeviceInfoStorage()190 bool DnetworkAdapter::UpdateDeviceInfoStorage()
191 {
192     HILOGI("UpdateDeviceInfoStorage start.");
193     return DtbschedmgrDeviceInfoStorage::GetInstance().UpdateDeviceInfoStorage();
194 }
195 
RemoveDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)196 void DnetworkAdapter::RemoveDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)
197 {
198     HILOGD("RemoveDeviceChangeListener called");
199     {
200         std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
201         listenerSet_.erase(listener);
202         if (listenerSet_.size() > 0) {
203             return;
204         }
205     }
206 
207     int32_t errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
208     if (errCode != ERR_OK) {
209         HILOGE("RemoveDeviceChangeListener remove failed, errCode = %{public}d", errCode);
210     }
211     HILOGD("RemoveDeviceChangeListener remove ok");
212 }
213 
GetLocalBasicInfo(DmDeviceInfo& dmDeviceInfo)214 bool DnetworkAdapter::GetLocalBasicInfo(DmDeviceInfo& dmDeviceInfo)
215 {
216     int32_t errCode = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, dmDeviceInfo);
217     if (errCode != ERR_OK) {
218         HILOGE("GetLocalBasicInfo errCode = %{public}d", errCode);
219         return false;
220     }
221     return true;
222 }
223 
GetUdidByNetworkId(const std::string& networkId)224 std::string DnetworkAdapter::GetUdidByNetworkId(const std::string& networkId)
225 {
226     if (networkId.empty()) {
227         HILOGE("networkId is empty");
228         return "";
229     }
230     std::string udid = "";
231     int32_t errCode = DeviceManager::GetInstance().GetUdidByNetworkId(PKG_NAME, networkId, udid);
232     if (errCode != ERR_OK) {
233         HILOGE("GetUdidByNetworkId errCode = %{public}d", errCode);
234         return "";
235     }
236     return udid;
237 }
238 
GetUuidByNetworkId(const std::string& networkId)239 std::string DnetworkAdapter::GetUuidByNetworkId(const std::string& networkId)
240 {
241     if (networkId.empty()) {
242         HILOGE("networkId is empty");
243         return "";
244     }
245     std::string uuid = "";
246     int32_t errCode = DeviceManager::GetInstance().GetUuidByNetworkId(PKG_NAME, networkId, uuid);
247     if (errCode != ERR_OK) {
248         HILOGE("GetUuidByNetworkId errCode = %{public}d", errCode);
249         return "";
250     }
251     return uuid;
252 }
253 } // namespace DistributedSchedule
254 } // namespace OHOS
255