/* * Copyright (c) 2021-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "adapter/dnetwork_adapter.h" #include <chrono> #include <functional> #include <thread> #include <unistd.h> #include "errors.h" #include "event_runner.h" #include "distributed_sched_utils.h" #include "dtbschedmgr_device_info_storage.h" #include "dtbschedmgr_log.h" #include "mission/dsched_sync_e2e.h" namespace OHOS { namespace DistributedSchedule { using namespace std::chrono_literals; using namespace DistributedHardware; namespace { constexpr int32_t RETRY_REGISTER_CALLBACK_TIMES = 5; constexpr int32_t RETRY_REGISTER_CALLBACK_DELAY_TIME = 1000; // 1s const std::string PKG_NAME = "DBinderBus_Dms_" + std::to_string(getprocpid()); const std::string EMPTY_DEVICE_ID = ""; const std::string TAG = "DnetworkAdapter"; } std::shared_ptr<AppExecFwk::EventHandler> DnetworkAdapter::dnetworkHandler_; std::mutex DnetworkAdapter::listenerSetMutex_; std::set<std::shared_ptr<DeviceListener>> DnetworkAdapter::listenerSet_; std::shared_ptr<DnetworkAdapter> DnetworkAdapter::GetInstance() { static auto instance = std::make_shared<DnetworkAdapter>(); return instance; } void DnetworkAdapter::Init() { initCallback_ = std::make_shared<DeviceInitCallBack>(); stateCallback_ = std::make_shared<DmsDeviceStateCallback>(); auto runner = AppExecFwk::EventRunner::Create("dmsDnetwork"); dnetworkHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner); } void DnetworkAdapter::DeviceInitCallBack::OnRemoteDied() { HILOGI("DeviceInitCallBack OnRemoteDied"); DtbschedmgrDeviceInfoStorage::GetInstance().Init(); } void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceOnline(const DmDeviceInfo& deviceInfo) { HILOGI("OnNodeOnline netwokId: %{public}s.", GetAnonymStr(deviceInfo.networkId).c_str()); if (DmsKvSyncE2E::GetInstance()->CheckDeviceCfg()) { DmsKvSyncE2E::GetInstance()->PushAndPullData(deviceInfo.networkId); } DmsKvSyncE2E::GetInstance()->ClearSyncRecord(deviceInfo.networkId); auto onlineNotifyTask = [deviceInfo]() { std::lock_guard<std::mutex> autoLock(listenerSetMutex_); for (auto& listener : listenerSet_) { if (listener != nullptr) { listener->OnDeviceOnline(deviceInfo); } } }; if (dnetworkHandler_ == nullptr || !dnetworkHandler_->PostTask(onlineNotifyTask)) { HILOGE("OnNodeOnline post task failed"); return; } } void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceOffline(const DmDeviceInfo& deviceInfo) { HILOGI("OnNodeOffline networkId: %{public}s.", GetAnonymStr(deviceInfo.networkId).c_str()); DmsKvSyncE2E::GetInstance()->ClearSyncRecord(deviceInfo.networkId); auto offlineNotifyTask = [deviceInfo]() { std::lock_guard<std::mutex> autoLock(listenerSetMutex_); for (auto& listener : listenerSet_) { if (listener != nullptr) { listener->OnDeviceOffline(deviceInfo); } } }; if (dnetworkHandler_ == nullptr || !dnetworkHandler_->PostTask(offlineNotifyTask)) { HILOGE("OnNodeOffline post task failed"); return; } } void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceChanged(const DmDeviceInfo& deviceInfo) { std::string networkId = deviceInfo.networkId; HILOGI("OnDeviceChanged networkId: %{public}s.", GetAnonymStr(networkId).c_str()); } void DnetworkAdapter::DmsDeviceStateCallback::OnDeviceReady(const DmDeviceInfo& deviceInfo) { HILOGI("called"); } bool DnetworkAdapter::AddDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener) { HILOGD("AddDeviceChangeListener called"); if (dnetworkHandler_ == nullptr) { HILOGE("handler is null"); return false; } { std::lock_guard<std::mutex> autoLock(listenerSetMutex_); if (listenerSet_.find(listener) == listenerSet_.end()) { listenerSet_.insert(listener); } if (listenerSet_.size() > 1) { return true; } } auto registerTask = [this]() { HILOGD("AddDeviceChangeListener register mission..."); int32_t retryTimes = 0; int32_t errCode = ERR_OK; while (retryTimes++ < RETRY_REGISTER_CALLBACK_TIMES) { int32_t ret = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, initCallback_); if (ret != ERR_OK) { HILOGE("init device manager failed, ret:%{public}d", ret); std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_REGISTER_CALLBACK_DELAY_TIME)); continue; } errCode = DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "", stateCallback_); if (errCode != ERR_OK) { HILOGD("AddDeviceChangeListener Reg errCode = %{public}d, retrying...", errCode); errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME); HILOGD("AddDeviceChangeListener Unreg errCode = %{public}d", errCode); std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_REGISTER_CALLBACK_DELAY_TIME)); continue; } if (UpdateDeviceInfoStorage()) { break; } } HILOGI("AddDeviceChangeListener %{public}s", (errCode == ERR_OK) ? "success" : "timeout"); }; if (!dnetworkHandler_->PostTask(registerTask)) { HILOGE("AddDeviceChangeListener post task failed"); return false; } return true; } bool DnetworkAdapter::UpdateDeviceInfoStorage() { HILOGI("UpdateDeviceInfoStorage start."); return DtbschedmgrDeviceInfoStorage::GetInstance().UpdateDeviceInfoStorage(); } void DnetworkAdapter::RemoveDeviceChangeListener(const std::shared_ptr<DeviceListener>& listener) { HILOGD("RemoveDeviceChangeListener called"); { std::lock_guard<std::mutex> autoLock(listenerSetMutex_); listenerSet_.erase(listener); if (listenerSet_.size() > 0) { return; } } int32_t errCode = DeviceManager::GetInstance().UnRegisterDevStateCallback(PKG_NAME); if (errCode != ERR_OK) { HILOGE("RemoveDeviceChangeListener remove failed, errCode = %{public}d", errCode); } HILOGD("RemoveDeviceChangeListener remove ok"); } bool DnetworkAdapter::GetLocalBasicInfo(DmDeviceInfo& dmDeviceInfo) { int32_t errCode = DeviceManager::GetInstance().GetLocalDeviceInfo(PKG_NAME, dmDeviceInfo); if (errCode != ERR_OK) { HILOGE("GetLocalBasicInfo errCode = %{public}d", errCode); return false; } return true; } std::string DnetworkAdapter::GetUdidByNetworkId(const std::string& networkId) { if (networkId.empty()) { HILOGE("networkId is empty"); return ""; } std::string udid = ""; int32_t errCode = DeviceManager::GetInstance().GetUdidByNetworkId(PKG_NAME, networkId, udid); if (errCode != ERR_OK) { HILOGE("GetUdidByNetworkId errCode = %{public}d", errCode); return ""; } return udid; } std::string DnetworkAdapter::GetUuidByNetworkId(const std::string& networkId) { if (networkId.empty()) { HILOGE("networkId is empty"); return ""; } std::string uuid = ""; int32_t errCode = DeviceManager::GetInstance().GetUuidByNetworkId(PKG_NAME, networkId, uuid); if (errCode != ERR_OK) { HILOGE("GetUuidByNetworkId errCode = %{public}d", errCode); return ""; } return uuid; } } // namespace DistributedSchedule } // namespace OHOS