1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3686862fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4686862fbSopenharmony_ci * you may not use this file except in compliance with the License.
5686862fbSopenharmony_ci * You may obtain a copy of the License at
6686862fbSopenharmony_ci *
7686862fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8686862fbSopenharmony_ci *
9686862fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10686862fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11686862fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12686862fbSopenharmony_ci * See the License for the specific language governing permissions and
13686862fbSopenharmony_ci * limitations under the License.
14686862fbSopenharmony_ci */
15686862fbSopenharmony_ci
16686862fbSopenharmony_ci#include "adapter/dnetwork_adapter.h"
17686862fbSopenharmony_ci
18686862fbSopenharmony_ci#include <chrono>
19686862fbSopenharmony_ci#include <functional>
20686862fbSopenharmony_ci#include <thread>
21686862fbSopenharmony_ci#include <unistd.h>
22686862fbSopenharmony_ci
23686862fbSopenharmony_ci#include "errors.h"
24686862fbSopenharmony_ci#include "event_runner.h"
25686862fbSopenharmony_ci
26686862fbSopenharmony_ci#include "distributed_sched_utils.h"
27686862fbSopenharmony_ci#include "dtbschedmgr_device_info_storage.h"
28686862fbSopenharmony_ci#include "dtbschedmgr_log.h"
29686862fbSopenharmony_ci#include "mission/distributed_bm_storage.h"
30686862fbSopenharmony_ci#include "mission/dsched_sync_e2e.h"
31686862fbSopenharmony_ci
32686862fbSopenharmony_cinamespace OHOS {
33686862fbSopenharmony_cinamespace DistributedSchedule {
34686862fbSopenharmony_ciusing namespace std::chrono_literals;
35686862fbSopenharmony_ciusing namespace DistributedHardware;
36686862fbSopenharmony_ci
37686862fbSopenharmony_cinamespace {
38686862fbSopenharmony_ciconstexpr int32_t RETRY_REGISTER_CALLBACK_TIMES = 5;
39686862fbSopenharmony_ciconstexpr int32_t RETRY_REGISTER_CALLBACK_DELAY_TIME = 1000; // 1s
40686862fbSopenharmony_ciconst std::string PKG_NAME = "DBinderBus_Dms_" + std::to_string(getprocpid());
41686862fbSopenharmony_ci
42686862fbSopenharmony_ciconst std::string EMPTY_DEVICE_ID = "";
43686862fbSopenharmony_ciconst std::string TAG = "DnetworkAdapter";
44686862fbSopenharmony_ci}
45686862fbSopenharmony_ci
46686862fbSopenharmony_cistd::shared_ptr<AppExecFwk::EventHandler> DnetworkAdapter::dnetworkHandler_;
47686862fbSopenharmony_cistd::mutex DnetworkAdapter::listenerSetMutex_;
48686862fbSopenharmony_cistd::set<std::shared_ptr<DeviceListener>> DnetworkAdapter::listenerSet_;
49686862fbSopenharmony_ci
50686862fbSopenharmony_cistd::shared_ptr<DnetworkAdapter> DnetworkAdapter::GetInstance()
51686862fbSopenharmony_ci{
52686862fbSopenharmony_ci    static auto instance = std::make_shared<DnetworkAdapter>();
53686862fbSopenharmony_ci    return instance;
54686862fbSopenharmony_ci}
55686862fbSopenharmony_ci
56686862fbSopenharmony_civoid DnetworkAdapter::Init()
57686862fbSopenharmony_ci{
58686862fbSopenharmony_ci    initCallback_ = std::make_shared<DeviceInitCallBack>();
59686862fbSopenharmony_ci    stateCallback_ = std::make_shared<DmsDeviceStateCallback>();
60686862fbSopenharmony_ci    devTrustChangeCallback_ = std::make_shared<DmsDevTrustChangeCallback>();
61686862fbSopenharmony_ci    auto runner = AppExecFwk::EventRunner::Create("dmsDnetwork");
62686862fbSopenharmony_ci    dnetworkHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
63686862fbSopenharmony_ci}
64686862fbSopenharmony_ci
65686862fbSopenharmony_civoid DnetworkAdapter::DeviceInitCallBack::OnRemoteDied()
66686862fbSopenharmony_ci{
67686862fbSopenharmony_ci    HILOGI("DeviceInitCallBack OnRemoteDied");
68686862fbSopenharmony_ci    DtbschedmgrDeviceInfoStorage::GetInstance().Init();
69686862fbSopenharmony_ci}
70686862fbSopenharmony_ci
71686862fbSopenharmony_civoid DnetworkAdapter::DmsDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo& deviceInfo)
72686862fbSopenharmony_ci{
73686862fbSopenharmony_ci    HILOGI("OnNodeOnline netwokId: %{public}s.", GetAnonymStr(deviceInfo.networkId).c_str());
74686862fbSopenharmony_ci    if (DmsKvSyncE2E::GetInstance()->CheckDeviceCfg()) {
75686862fbSopenharmony_ci        DmsKvSyncE2E::GetInstance()->PushAndPullData(deviceInfo.networkId);
76686862fbSopenharmony_ci    }
77686862fbSopenharmony_ci    DmsKvSyncE2E::GetInstance()->ClearSyncRecord(deviceInfo.networkId);
78686862fbSopenharmony_ci
79686862fbSopenharmony_ci    auto onlineNotifyTask = [deviceInfo]() {
80686862fbSopenharmony_ci        std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
81686862fbSopenharmony_ci        for (auto& listener : listenerSet_) {
82686862fbSopenharmony_ci            if (listener != nullptr) {
83686862fbSopenharmony_ci                listener->OnDeviceOnline(deviceInfo);
84686862fbSopenharmony_ci            }
85686862fbSopenharmony_ci        }
86686862fbSopenharmony_ci    };
87686862fbSopenharmony_ci    if (dnetworkHandler_ == nullptr || !dnetworkHandler_->PostTask(onlineNotifyTask)) {
88686862fbSopenharmony_ci        HILOGE("OnNodeOnline post task failed");
89686862fbSopenharmony_ci        return;
90686862fbSopenharmony_ci    }
91686862fbSopenharmony_ci}
92686862fbSopenharmony_ci
93686862fbSopenharmony_civoid DnetworkAdapter::DmsDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo& deviceInfo)
94686862fbSopenharmony_ci{
95686862fbSopenharmony_ci    HILOGI("OnNodeOffline networkId: %{public}s.", GetAnonymStr(deviceInfo.networkId).c_str());
96686862fbSopenharmony_ci    DmsKvSyncE2E::GetInstance()->ClearSyncRecord(deviceInfo.networkId);
97686862fbSopenharmony_ci    auto offlineNotifyTask = [deviceInfo]() {
98686862fbSopenharmony_ci        std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
99686862fbSopenharmony_ci        for (auto& listener : listenerSet_) {
100686862fbSopenharmony_ci            if (listener != nullptr) {
101686862fbSopenharmony_ci                listener->OnDeviceOffline(deviceInfo);
102686862fbSopenharmony_ci            }
103686862fbSopenharmony_ci        }
104686862fbSopenharmony_ci    };
105686862fbSopenharmony_ci    if (dnetworkHandler_ == nullptr || !dnetworkHandler_->PostTask(offlineNotifyTask)) {
106686862fbSopenharmony_ci        HILOGE("OnNodeOffline post task failed");
107686862fbSopenharmony_ci        return;
108686862fbSopenharmony_ci    }
109686862fbSopenharmony_ci}
110686862fbSopenharmony_ci
111686862fbSopenharmony_civoid DnetworkAdapter::DmsDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo& deviceInfo)
112686862fbSopenharmony_ci{
113686862fbSopenharmony_ci    std::string networkId = deviceInfo.networkId;
114686862fbSopenharmony_ci    HILOGI("OnDeviceChanged networkId: %{public}s.", GetAnonymStr(networkId).c_str());
115686862fbSopenharmony_ci}
116686862fbSopenharmony_ci
117686862fbSopenharmony_civoid DnetworkAdapter::DmsDeviceStateCallback::OnDeviceReady(const DmDeviceInfo& deviceInfo)
118686862fbSopenharmony_ci{
119686862fbSopenharmony_ci    HILOGI("called");
120686862fbSopenharmony_ci}
121686862fbSopenharmony_ci
122686862fbSopenharmony_civoid DnetworkAdapter::DmsDevTrustChangeCallback::OnDeviceTrustChange(const std::string &udid,
123686862fbSopenharmony_ci    const std::string &uuid, const DmAuthForm authform)
124686862fbSopenharmony_ci{
125686862fbSopenharmony_ci    HILOGI("called");
126686862fbSopenharmony_ci    if (udid.empty() || uuid.empty()) {
127686862fbSopenharmony_ci        HILOGE("udid or uuid is empty!");
128686862fbSopenharmony_ci        return;
129686862fbSopenharmony_ci    }
130686862fbSopenharmony_ci    if (authform != DmAuthForm::IDENTICAL_ACCOUNT) {
131686862fbSopenharmony_ci        HILOGE("peer is not same account");
132686862fbSopenharmony_ci        return;
133686862fbSopenharmony_ci    }
134686862fbSopenharmony_ci    if (!DmsBmStorage::GetInstance()->DelDataOfLogoutDev(udid, uuid)) {
135686862fbSopenharmony_ci        HILOGE("DelDataOfLogoutDev failed");
136686862fbSopenharmony_ci    }
137686862fbSopenharmony_ci    HILOGI("end");
138686862fbSopenharmony_ci}
139686862fbSopenharmony_ci
140686862fbSopenharmony_cibool DnetworkAdapter::AddDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)
141686862fbSopenharmony_ci{
142686862fbSopenharmony_ci    HILOGD("AddDeviceChangeListener called");
143686862fbSopenharmony_ci    if (dnetworkHandler_ == nullptr) {
144686862fbSopenharmony_ci        HILOGE("handler is null");
145686862fbSopenharmony_ci        return false;
146686862fbSopenharmony_ci    }
147686862fbSopenharmony_ci    {
148686862fbSopenharmony_ci        std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
149686862fbSopenharmony_ci        if (listenerSet_.find(listener) == listenerSet_.end()) {
150686862fbSopenharmony_ci            listenerSet_.insert(listener);
151686862fbSopenharmony_ci        }
152686862fbSopenharmony_ci        if (listenerSet_.size() > 1) {
153686862fbSopenharmony_ci            return true;
154686862fbSopenharmony_ci        }
155686862fbSopenharmony_ci    }
156686862fbSopenharmony_ci    auto registerTask = [this]() {
157686862fbSopenharmony_ci        HILOGD("AddDeviceChangeListener register mission...");
158686862fbSopenharmony_ci        int32_t retryTimes = 0;
159686862fbSopenharmony_ci        int32_t errCode = ERR_OK;
160686862fbSopenharmony_ci        while (retryTimes++ < RETRY_REGISTER_CALLBACK_TIMES) {
161686862fbSopenharmony_ci            int32_t ret = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, initCallback_);
162686862fbSopenharmony_ci            if (ret != ERR_OK) {
163686862fbSopenharmony_ci                HILOGE("init device manager failed, ret:%{public}d", ret);
164686862fbSopenharmony_ci                std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_REGISTER_CALLBACK_DELAY_TIME));
165686862fbSopenharmony_ci                continue;
166686862fbSopenharmony_ci            }
167686862fbSopenharmony_ci            errCode = DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "", stateCallback_);
168686862fbSopenharmony_ci            if (errCode != ERR_OK) {
169686862fbSopenharmony_ci                HILOGD("AddDeviceChangeListener Reg errCode = %{public}d, retrying...", errCode);
170686862fbSopenharmony_ci                errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
171686862fbSopenharmony_ci                HILOGD("AddDeviceChangeListener Unreg errCode = %{public}d", errCode);
172686862fbSopenharmony_ci                std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_REGISTER_CALLBACK_DELAY_TIME));
173686862fbSopenharmony_ci                continue;
174686862fbSopenharmony_ci            }
175686862fbSopenharmony_ci            errCode = DeviceManager::GetInstance().RegDevTrustChangeCallback(PKG_NAME, devTrustChangeCallback_);
176686862fbSopenharmony_ci            HILOGI("RegDevTrustChangeCallback errCode = %{public}d", errCode);
177686862fbSopenharmony_ci            if (UpdateDeviceInfoStorage()) {
178686862fbSopenharmony_ci                break;
179686862fbSopenharmony_ci            }
180686862fbSopenharmony_ci        }
181686862fbSopenharmony_ci        HILOGI("AddDeviceChangeListener %{public}s", (errCode == ERR_OK) ? "success" : "timeout");
182686862fbSopenharmony_ci    };
183686862fbSopenharmony_ci    if (!dnetworkHandler_->PostTask(registerTask)) {
184686862fbSopenharmony_ci        HILOGE("AddDeviceChangeListener post task failed");
185686862fbSopenharmony_ci        return false;
186686862fbSopenharmony_ci    }
187686862fbSopenharmony_ci    return true;
188686862fbSopenharmony_ci}
189686862fbSopenharmony_ci
190686862fbSopenharmony_cibool DnetworkAdapter::UpdateDeviceInfoStorage()
191686862fbSopenharmony_ci{
192686862fbSopenharmony_ci    HILOGI("UpdateDeviceInfoStorage start.");
193686862fbSopenharmony_ci    return DtbschedmgrDeviceInfoStorage::GetInstance().UpdateDeviceInfoStorage();
194686862fbSopenharmony_ci}
195686862fbSopenharmony_ci
196686862fbSopenharmony_civoid DnetworkAdapter::RemoveDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener)
197686862fbSopenharmony_ci{
198686862fbSopenharmony_ci    HILOGD("RemoveDeviceChangeListener called");
199686862fbSopenharmony_ci    {
200686862fbSopenharmony_ci        std::lock_guard<std::mutex> autoLock(listenerSetMutex_);
201686862fbSopenharmony_ci        listenerSet_.erase(listener);
202686862fbSopenharmony_ci        if (listenerSet_.size() > 0) {
203686862fbSopenharmony_ci            return;
204686862fbSopenharmony_ci        }
205686862fbSopenharmony_ci    }
206686862fbSopenharmony_ci
207686862fbSopenharmony_ci    int32_t errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME);
208686862fbSopenharmony_ci    if (errCode != ERR_OK) {
209686862fbSopenharmony_ci        HILOGE("RemoveDeviceChangeListener remove failed, errCode = %{public}d", errCode);
210686862fbSopenharmony_ci    }
211686862fbSopenharmony_ci    HILOGD("RemoveDeviceChangeListener remove ok");
212686862fbSopenharmony_ci}
213686862fbSopenharmony_ci
214686862fbSopenharmony_cibool DnetworkAdapter::GetLocalBasicInfo(DmDeviceInfo& dmDeviceInfo)
215686862fbSopenharmony_ci{
216686862fbSopenharmony_ci    int32_t errCode = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, dmDeviceInfo);
217686862fbSopenharmony_ci    if (errCode != ERR_OK) {
218686862fbSopenharmony_ci        HILOGE("GetLocalBasicInfo errCode = %{public}d", errCode);
219686862fbSopenharmony_ci        return false;
220686862fbSopenharmony_ci    }
221686862fbSopenharmony_ci    return true;
222686862fbSopenharmony_ci}
223686862fbSopenharmony_ci
224686862fbSopenharmony_cistd::string DnetworkAdapter::GetUdidByNetworkId(const std::string& networkId)
225686862fbSopenharmony_ci{
226686862fbSopenharmony_ci    if (networkId.empty()) {
227686862fbSopenharmony_ci        HILOGE("networkId is empty");
228686862fbSopenharmony_ci        return "";
229686862fbSopenharmony_ci    }
230686862fbSopenharmony_ci    std::string udid = "";
231686862fbSopenharmony_ci    int32_t errCode = DeviceManager::GetInstance().GetUdidByNetworkId(PKG_NAME, networkId, udid);
232686862fbSopenharmony_ci    if (errCode != ERR_OK) {
233686862fbSopenharmony_ci        HILOGE("GetUdidByNetworkId errCode = %{public}d", errCode);
234686862fbSopenharmony_ci        return "";
235686862fbSopenharmony_ci    }
236686862fbSopenharmony_ci    return udid;
237686862fbSopenharmony_ci}
238686862fbSopenharmony_ci
239686862fbSopenharmony_cistd::string DnetworkAdapter::GetUuidByNetworkId(const std::string& networkId)
240686862fbSopenharmony_ci{
241686862fbSopenharmony_ci    if (networkId.empty()) {
242686862fbSopenharmony_ci        HILOGE("networkId is empty");
243686862fbSopenharmony_ci        return "";
244686862fbSopenharmony_ci    }
245686862fbSopenharmony_ci    std::string uuid = "";
246686862fbSopenharmony_ci    int32_t errCode = DeviceManager::GetInstance().GetUuidByNetworkId(PKG_NAME, networkId, uuid);
247686862fbSopenharmony_ci    if (errCode != ERR_OK) {
248686862fbSopenharmony_ci        HILOGE("GetUuidByNetworkId errCode = %{public}d", errCode);
249686862fbSopenharmony_ci        return "";
250686862fbSopenharmony_ci    }
251686862fbSopenharmony_ci    return uuid;
252686862fbSopenharmony_ci}
253686862fbSopenharmony_ci} // namespace DistributedSchedule
254686862fbSopenharmony_ci} // namespace OHOS
255