/* * 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 "device/device_manager_agent.h" #include #include #include #include #include "device_auth.h" #include "dfs_daemon_event_dfx.h" #include "dfs_error.h" #include "dfsu_exception.h" #include "ipc/i_daemon.h" #include "iremote_object.h" #include "iservice_registry.h" #include "mountpoint/mount_manager.h" #include "network/devsl_dispatcher.h" #include "network/softbus/softbus_agent.h" #include "os_account_manager.h" #include "parameters.h" #include "softbus_bus_center.h" #include "system_ability_definition.h" #include "utils_log.h" namespace OHOS { namespace Storage { namespace DistributedFile { namespace { constexpr int32_t DEVICE_OS_TYPE_OH = 10; constexpr int MAX_RETRY_COUNT = 7; constexpr int PEER_TO_PEER_GROUP = 256; constexpr int ACROSS_ACCOUNT_AUTHORIZE_GROUP = 1282; const int32_t MOUNT_DFS_COUNT_ONE = 1; const uint32_t MAX_ONLINE_DEVICE_SIZE = 10000; const int32_t INVALID_USER_ID = -1; constexpr const char* PARAM_KEY_OS_TYPE = "OS_TYPE"; const std::string SAME_ACCOUNT_MARK = "const.distributed_file_only_for_same_account_test"; } // namespace using namespace std; DeviceManagerAgent::DeviceManagerAgent() : DfsuActor(this, std::numeric_limits::max()) {} DeviceManagerAgent::~DeviceManagerAgent() { try { StopInstance(); } catch (const DfsuException &e) { // do not throw exception } catch (const std::exception &e) { // do not throw exception } } void DeviceManagerAgent::StartInstance() { StartActor(); } void DeviceManagerAgent::StopInstance() { StopActor(); } void DeviceManagerAgent::Start() { DevslDispatcher::Start(); RegisterToExternalDm(); InitLocalNodeInfo(); InitDeviceAuthService(); } void DeviceManagerAgent::Stop() { DestroyDeviceAuthService(); UnregisterFromExternalDm(); DevslDispatcher::Stop(); } void DeviceManagerAgent::JoinGroup(weak_ptr mp) { LOGI("join group begin"); auto smp = mp.lock(); if (!smp) { stringstream ss("Failed to join group: Received empty mountpoint"); LOGE("%{public}s", ss.str().c_str()); throw runtime_error(ss.str()); } shared_ptr agent = nullptr; { unique_lock lock(mpToNetworksMutex_); agent = make_shared(mp); auto [ignored, inserted] = mpToNetworks_.insert({ smp->GetID(), agent }); if (!inserted) { stringstream ss; ss << "Failed to join group: Mountpoint existed" << smp->ToString(); throw runtime_error(ss.str()); } } agent->StartActor(); LOGI("join group end, id : %{public}d, account : %{public}s", smp->GetID(), smp->isAccountLess() ? "no" : "yes"); } void DeviceManagerAgent::QuitGroup(weak_ptr mp) { LOGI("quit group begin"); OfflineAllDevice(); auto smp = mp.lock(); if (!smp) { stringstream ss("Failed to quit group: Received empty mountpoint"); LOGE("%{public}s", ss.str().c_str()); throw runtime_error(ss.str()); } unique_lock lock(mpToNetworksMutex_); auto it = mpToNetworks_.find(smp->GetID()); if (it == mpToNetworks_.end()) { stringstream ss; ss << "Failed to quit group: Mountpoint didn't exist " << smp->ToString(); throw runtime_error(ss.str()); } it->second->StopActor(); mpToNetworks_.erase(smp->GetID()); LOGI("quit group end, id : %{public}d, account : %{public}s", smp->GetID(), smp->isAccountLess() ? "no" : "yes"); } void DeviceManagerAgent::OfflineAllDevice() { unique_lock lock(mpToNetworksMutex_); for (auto [ignore, net] : cidNetTypeRecord_) { if (net == nullptr) { continue; } auto cmd = make_unique>(&NetworkAgentTemplate::DisconnectAllDevices); net->Recv(move(cmd)); } } void DeviceManagerAgent::ReconnectOnlineDevices() { unique_lock lock(mpToNetworksMutex_); for (auto [ignore, net] : cidNetTypeRecord_) { if (net == nullptr) { continue; } } } std::shared_ptr DeviceManagerAgent::FindNetworkBaseTrustRelation(bool isAccountless) { LOGI("enter: isAccountless %{public}d", isAccountless); for (auto [ignore, net] : mpToNetworks_) { if (net != nullptr) { auto smp = net->GetMountPoint(); if (smp != nullptr && smp->isAccountLess() == isAccountless) { return net; } } } LOGE("not find this net in mpToNetworks, isAccountless %{public}d", isAccountless); return nullptr; } int32_t DeviceManagerAgent::GetNetworkType(const string &cid) { int32_t networkType = 0; string pkgName = IDaemon::SERVICE_NAME; auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); int errCode = deviceManager.GetNetworkTypeByNetworkId(pkgName, cid, networkType); if (errCode) { LOGE("get network type error:%{public}d", errCode); } return networkType; } bool DeviceManagerAgent::IsWifiNetworkType(int32_t networkType) { if ((networkType == -1) || !(static_cast(networkType) & (1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI))) { return false; } return true; } void DeviceManagerAgent::OnDeviceReady(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("networkId %{public}s, OnDeviceReady begin", Utils::GetAnonyString(deviceInfo.networkId).c_str()); int32_t ret = IsSupportedDevice(deviceInfo); if (ret != FileManagement::ERR_OK) { LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); return; } // online first query this dev's trust info DeviceInfo info(deviceInfo); QueryRelatedGroups(info.udid_, info.cid_); // based on dev's trust info, choose corresponding network agent to obtain socket unique_lock lock(mpToNetworksMutex_); auto it = cidNetTypeRecord_.find(info.cid_); if (it == cidNetTypeRecord_.end()) { LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str()); LOGI("OnDeviceReady end"); return; } auto type_ = cidNetworkType_.find(info.cid_); if (type_ == cidNetworkType_.end()) { LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str()); LOGI("OnDeviceReady end"); return; } int32_t newNetworkType = type_->second = GetNetworkType(info.cid_); LOGI("newNetworkType:%{public}d", newNetworkType); if (!IsWifiNetworkType(newNetworkType)) { LOGE("cid %{public}s networkType:%{public}d", Utils::GetAnonyString(info.cid_).c_str(), type_->second); LOGI("OnDeviceReady end"); return; } LOGI("OnDeviceReady end"); } void DeviceManagerAgent::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("OnDeviceOffline begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); DeviceInfo info(deviceInfo); unique_lock lock(mpToNetworksMutex_); auto it = cidNetTypeRecord_.find(info.cid_); if (it == cidNetTypeRecord_.end()) { LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str()); LOGI("OnDeviceOffline end"); return; } auto type_ = cidNetworkType_.find(info.cid_); if (type_ == cidNetworkType_.end()) { LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str()); LOGI("OnDeviceOffline end"); return; } auto networkId = std::string(deviceInfo.networkId); auto deviceId = std::string(deviceInfo.deviceId); if (deviceId.empty()) { deviceId = GetDeviceIdByNetworkId(networkId); } if (!networkId.empty()) { UMountDfsDocs(networkId, deviceId, true); } auto cmd2 = make_unique>( &NetworkAgentTemplate::DisconnectDeviceByP2PHmdfs, info); it->second->Recv(move(cmd2)); cidNetTypeRecord_.erase(info.cid_); cidNetworkType_.erase(info.cid_); LOGI("OnDeviceOffline end"); } void DeviceManagerAgent::ClearCount(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("ClearCount networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); DeviceInfo info(deviceInfo); unique_lock lock(mpToNetworksMutex_); auto it = cidNetTypeRecord_.find(info.cid_); if (it == cidNetTypeRecord_.end()) { LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str()); return; } it->second->DisconnectDeviceByP2P(info); } int32_t DeviceManagerAgent::OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("[OnDeviceP2POnline] networkId %{public}s, OnDeviceOnline begin", Utils::GetAnonyString(deviceInfo.networkId).c_str()); int32_t ret = IsSupportedDevice(deviceInfo); if (ret != FileManagement::ERR_OK) { LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); return P2P_FAILED; } DeviceInfo info(deviceInfo); QueryRelatedGroups(info.udid_, info.cid_); unique_lock lock(mpToNetworksMutex_); auto it = cidNetTypeRecord_.find(info.cid_); if (it == cidNetTypeRecord_.end()) { LOGE("[OnDeviceP2POnline] cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str()); return P2P_FAILED; } auto type_ = cidNetworkType_.find(info.cid_); if (type_ == cidNetworkType_.end()) { LOGE("[OnDeviceP2POnline] cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str()); return P2P_FAILED; } auto cmd = make_unique>( &NetworkAgentTemplate::ConnectDeviceByP2PAsync, info); cmd->UpdateOption({.tryTimes_ = MAX_RETRY_COUNT}); it->second->Recv(move(cmd)); LOGI("OnDeviceP2POnline end networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); return P2P_SUCCESS; } int32_t DeviceManagerAgent::OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("OnDeviceP2POffline begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); DeviceInfo info(deviceInfo); unique_lock lock(mpToNetworksMutex_); auto it = cidNetTypeRecord_.find(info.cid_); if (it == cidNetTypeRecord_.end()) { LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str()); return P2P_FAILED; } auto type_ = cidNetworkType_.find(info.cid_); if (type_ == cidNetworkType_.end()) { LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str()); return P2P_FAILED; } auto cmd = make_unique>( &NetworkAgentTemplate::DisconnectDeviceByP2P, info); it->second->Recv(move(cmd)); cidNetTypeRecord_.erase(info.cid_); cidNetworkType_.erase(info.cid_); LOGI("OnDeviceP2POffline end"); return P2P_SUCCESS; } bool DeviceManagerAgent::MountDfsCountOnly(const std::string &deviceId) { if (deviceId.empty()) { LOGI("deviceId empty"); return false; } std::lock_guard lock(mountDfsCountMutex_); auto itCount = mountDfsCount_.find(deviceId); if (itCount == mountDfsCount_.end()) { LOGI("mountDfsCount_ can not find key"); return false; } if (itCount->second > 0) { LOGI("[MountDfsCountOnly] deviceId %{public}s has already established a link, count %{public}d, \ increase count by one now", Utils::GetAnonyString(deviceId).c_str(), itCount->second); return true; } return false; } bool DeviceManagerAgent::UMountDfsCountOnly(const std::string &deviceId, bool needClear) { if (deviceId.empty()) { LOGI("deviceId empty"); return false; } std::lock_guard lock(mountDfsCountMutex_); auto itCount = mountDfsCount_.find(deviceId); if (itCount == mountDfsCount_.end()) { LOGI("mountDfsCount_ can not find key"); return true; } if (needClear) { LOGI("mountDfsCount_ erase"); mountDfsCount_.erase(itCount); return false; } if (itCount->second > MOUNT_DFS_COUNT_ONE) { LOGI("[UMountDfsCountOnly] deviceId %{public}s has already established more than one link, \ count %{public}d, decrease count by one now", Utils::GetAnonyString(deviceId).c_str(), itCount->second); mountDfsCount_[deviceId]--; return true; } LOGI("[UMountDfsCountOnly] deviceId %{public}s erase count", Utils::GetAnonyString(deviceId).c_str()); return false; } int32_t DeviceManagerAgent::GetCurrentUserId() { std::vector userIds{}; auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds); if (ret != NO_ERROR || userIds.empty()) { LOGE("query active os account id failed, ret = %{public}d", ret); return INVALID_USER_ID; } LOGI("DeviceManagerAgent::GetCurrentUserId end."); return userIds[0]; } void DeviceManagerAgent::GetStorageManager() { auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (saMgr == nullptr) { LOGE("GetSystemAbilityManager filed"); return; } auto storageObj = saMgr->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID); if (storageObj == nullptr) { LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy"); return; } storageMgrProxy_ = iface_cast(storageObj); if (storageMgrProxy_ == nullptr) { LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy!"); return; } LOGI("GetStorageManager end."); return; } void DeviceManagerAgent::AddNetworkId(uint32_t tokenId, const std::string &networkId) { LOGI("DeviceManagerAgent::AddNetworkId, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str()); std::lock_guard lock(networkIdMapMutex_); networkIdMap_[tokenId].insert(networkId); } void DeviceManagerAgent::RemoveNetworkId(uint32_t tokenId) { LOGI("DeviceManagerAgent::RemoveNetworkId start"); std::lock_guard lock(networkIdMapMutex_); networkIdMap_.erase(tokenId); } void DeviceManagerAgent::RemoveNetworkIdByOne(uint32_t tokenId, const std::string &networkId) { std::lock_guard lock(networkIdMapMutex_); auto it = networkIdMap_.find(tokenId); if (it != networkIdMap_.end()) { (it->second).erase(networkId); if (it->second.empty()) { networkIdMap_.erase(it); } LOGI("DeviceManagerAgent::RemoveNetworkIdByOne success, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str()); } } void DeviceManagerAgent::RemoveNetworkIdForAllToken(const std::string &networkId) { std::lock_guard lock(networkIdMapMutex_); if (networkId.empty()) { LOGE("networkId is empty"); return; } for (auto it = networkIdMap_.begin(); it != networkIdMap_.end();) { it->second.erase(networkId); if (it->second.empty()) { it = networkIdMap_.erase(it); } else { ++it; } LOGI("RemoveNetworkIdForAllToken, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str()); } } void DeviceManagerAgent::ClearNetworkId() { std::lock_guard lock(networkIdMapMutex_); networkIdMap_.clear(); } std::unordered_set DeviceManagerAgent::GetNetworkIds(uint32_t tokenId) { std::lock_guard lock(networkIdMapMutex_); return networkIdMap_[tokenId]; } int32_t DeviceManagerAgent::MountDfsDocs(const std::string &networkId, const std::string &deviceId) { LOGI("MountDfsDocs start"); if (networkId.empty() || deviceId.empty()) { LOGE("NetworkId or DeviceId is empty"); return INVALID_USER_ID; } int32_t ret = NO_ERROR; if (MountDfsCountOnly(deviceId)) { LOGI("only count plus one, do not need mount"); IncreaseMountDfsCount(deviceId); return ret; } int32_t userId = GetCurrentUserId(); if (userId == INVALID_USER_ID) { LOGE("GetCurrentUserId Fail"); return INVALID_USER_ID; } GetStorageManager(); if (storageMgrProxy_ == nullptr) { LOGE("storageMgrProxy_ is null"); return INVALID_USER_ID; } ret = storageMgrProxy_->MountDfsDocs(userId, "account", networkId, deviceId); if (ret != NO_ERROR) { LOGE("MountDfsDocs fail, ret = %{public}d", ret); } else { LOGE("MountDfsDocs success, deviceId %{public}s increase count by one now", Utils::GetAnonyString(deviceId).c_str()); IncreaseMountDfsCount(deviceId); } LOGI("storageMgr.MountDfsDocs end."); return ret; } int32_t DeviceManagerAgent::UMountDfsDocs(const std::string &networkId, const std::string &deviceId, bool needClear) { LOGI("UMountDfsDocs start in OpenP2PConnection, networkId: %{public}s, deviceId: %{public}s", Utils::GetAnonyString(networkId).c_str(), Utils::GetAnonyString(deviceId).c_str()); if (networkId.empty() || deviceId.empty()) { LOGE("NetworkId or DeviceId is empty"); return INVALID_USER_ID; } int32_t ret = NO_ERROR; if (UMountDfsCountOnly(deviceId, needClear)) { LOGE("do not need umount"); return ret; } int32_t userId = GetCurrentUserId(); if (userId == INVALID_USER_ID) { LOGE("GetCurrentUserId Fail"); return INVALID_USER_ID; } GetStorageManager(); if (storageMgrProxy_ == nullptr) { LOGE("storageMgrProxy_ is null"); return INVALID_USER_ID; } ret = storageMgrProxy_->UMountDfsDocs(userId, "account", networkId, deviceId); if (ret != NO_ERROR) { LOGE("UMountDfsDocs fail, ret = %{public}d", ret); } else { LOGE("UMountDfsDocs success, deviceId %{public}s erase count", Utils::GetAnonyString(deviceId).c_str()); RemoveMountDfsCount(deviceId); } LOGI("storageMgr.UMountDfsDocs end."); return ret; } void DeviceManagerAgent::IncreaseMountDfsCount(const std::string &deviceId) { std::lock_guard lock(mountDfsCountMutex_); mountDfsCount_[deviceId]++; } void DeviceManagerAgent::RemoveMountDfsCount(const std::string &deviceId) { std::lock_guard lock(mountDfsCountMutex_); mountDfsCount_.erase(deviceId); } void DeviceManagerAgent::NotifyRemoteReverseObj(const std::string &networkId, int32_t status) { for (auto it = appCallConnect_.begin(); it != appCallConnect_.end(); ++it) { auto onstatusReverseProxy = it->second; if (onstatusReverseProxy == nullptr) { LOGI("get onstatusReverseProxy fail"); return; } onstatusReverseProxy->OnStatus(networkId, status); LOGI("NotifyRemoteReverseObj, deviceId: %{public}s", Utils::GetAnonyString(networkId).c_str()); } } int32_t DeviceManagerAgent::AddRemoteReverseObj(uint32_t callingTokenId, sptr remoteReverseObj) { std::lock_guard lock(appCallConnectMutex_); auto it = appCallConnect_.find(callingTokenId); if (it != appCallConnect_.end()) { LOGE("AddRemoteReverseObj fail"); return FileManagement::E_INVAL_ARG; } appCallConnect_[callingTokenId] = remoteReverseObj; LOGI("DeviceManagerAgent::AddRemoteReverseObj::add new value suceess"); return FileManagement::E_OK; } int32_t DeviceManagerAgent::RemoveRemoteReverseObj(bool clear, uint32_t callingTokenId) { LOGI("DeviceManagerAgent::RemoveRemoteReverseObj called"); if (clear) { appCallConnect_.clear(); return FileManagement::E_OK; } auto it = appCallConnect_.find(callingTokenId); if (it == appCallConnect_.end()) { LOGE("RemoveRemoteReverseObj fail"); return FileManagement::E_INVAL_ARG; } appCallConnect_.erase(it); LOGI("DeviceManagerAgent::RemoveRemoteReverseObj end"); return FileManagement::E_OK; } int32_t DeviceManagerAgent::FindListenerByObject(const wptr &remote, uint32_t &tokenId, sptr& listener) { std::lock_guard lock(appCallConnectMutex_); for (auto it = appCallConnect_.begin(); it != appCallConnect_.end(); ++it) { if (remote != (it->second)->AsObject()) { continue; } tokenId = it->first; listener = it->second; return FileManagement::E_OK; } return FileManagement::E_INVAL_ARG; } std::string DeviceManagerAgent::GetDeviceIdByNetworkId(const std::string &networkId) { LOGI("DeviceManagerAgent::GetDeviceIdByNetworkId called"); if (networkId.empty()) { return ""; } std::vector deviceList; DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(IDaemon::SERVICE_NAME, "", deviceList); if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) { LOGE("the size of trust device list is invalid, size=%zu", deviceList.size()); return ""; } std::string deviceId = ""; for (const auto &device : deviceList) { if (std::string(device.networkId) == networkId) { deviceId = std::string(device.deviceId); } } LOGI("DeviceManagerAgent::GetDeviceIdByNetworkId end"); return deviceId; } void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo) { if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end() && jsonObject[FIELD_GROUP_NAME].is_string()) { groupInfo.groupName = jsonObject.at(FIELD_GROUP_NAME).get(); } if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end() && jsonObject[FIELD_GROUP_ID].is_string()) { groupInfo.groupId = jsonObject.at(FIELD_GROUP_ID).get(); } if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end() && jsonObject[FIELD_GROUP_OWNER].is_string()) { groupInfo.groupOwner = jsonObject.at(FIELD_GROUP_OWNER).get(); } if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end() && jsonObject[FIELD_GROUP_TYPE].is_number()) { groupInfo.groupType = jsonObject.at(FIELD_GROUP_TYPE).get(); } } void DeviceManagerAgent::QueryRelatedGroups(const std::string &udid, const std::string &networkId) { auto network = FindNetworkBaseTrustRelation(false); if (network != nullptr) { cidNetTypeRecord_.insert({ networkId, network }); cidNetworkType_.insert({ networkId, GetNetworkType(networkId) }); } } bool DeviceManagerAgent::CheckIsAccountless(const GroupInfo &group) { // because of there no same_account, only for test, del later LOGI("SAME_ACCOUNT_MARK val is %{public}d", system::GetBoolParameter(SAME_ACCOUNT_MARK, false)); if (system::GetBoolParameter(SAME_ACCOUNT_MARK, false) == true) { // isaccountless == false LOGI("SAME_ACCOUNT_MARK val is true(same account)"); return false; } else { // isaccountless == true return true; } if (group.groupType == PEER_TO_PEER_GROUP || group.groupType == ACROSS_ACCOUNT_AUTHORIZE_GROUP) { return true; } return false; } void DeviceManagerAgent::OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo) { LOGI("OnDeviceInfoChanged begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); if (deviceInfo.networkType == -1) { LOGI("OnDeviceInfoChanged end"); return; } int32_t ret = IsSupportedDevice(deviceInfo); if (ret != FileManagement::ERR_OK) { LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); return; } DeviceInfo info(deviceInfo); unique_lock lock(mpToNetworksMutex_); auto it = cidNetTypeRecord_.find(info.cid_); if (it == cidNetTypeRecord_.end()) { LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str()); LOGI("OnDeviceInfoChanged end"); return; } auto type_ = cidNetworkType_.find(info.cid_); if (type_ == cidNetworkType_.end()) { LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str()); LOGI("OnDeviceInfoChanged end"); return; } int32_t oldNetworkType = type_->second; int32_t newNetworkType = type_->second = deviceInfo.networkType; LOGI("oldNetworkType %{public}d, newNetworkType %{public}d", oldNetworkType, newNetworkType); LOGI("OnDeviceInfoChanged end"); } void DeviceManagerAgent::InitDeviceInfos() { string extra = ""; string pkgName = IDaemon::SERVICE_NAME; vector deviceInfoList; auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceInfoList); if (errCode) { ThrowException(errCode, "Failed to get info of remote devices"); } for (const auto &deviceInfo : deviceInfoList) { int32_t ret = IsSupportedDevice(deviceInfo); if (ret != FileManagement::ERR_OK) { LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str()); continue; } DeviceInfo info(deviceInfo); QueryRelatedGroups(info.udid_, info.cid_); } } int32_t DeviceManagerAgent::IsSupportedDevice(const DistributedHardware::DmDeviceInfo &deviceInfo) { std::vector deviceList; DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(IDaemon::SERVICE_NAME, "", deviceList); if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) { LOGE("trust device list size is invalid, size=%zu", deviceList.size()); return FileManagement::ERR_BAD_VALUE; } DistributedHardware::DmDeviceInfo infoTemp; for (const auto &info : deviceList) { if (std::string_view(info.networkId) == std::string_view(deviceInfo.networkId)) { infoTemp = info; break; } } if (infoTemp.extraData.empty()) { LOGE("extraData is empty"); RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_FAILED, RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, RadarReporter::GET_SAME_ACCOUNT_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::deviceManager); return FileManagement::ERR_BAD_VALUE; } nlohmann::json entraDataJson = nlohmann::json::parse(infoTemp.extraData, nullptr, false); if (entraDataJson.is_discarded()) { LOGE("entraDataJson parse failed."); return FileManagement::ERR_BAD_VALUE; } if (!Utils::IsInt32(entraDataJson, PARAM_KEY_OS_TYPE)) { LOGE("error json int32_t param."); return FileManagement::ERR_BAD_VALUE; } int32_t osType = entraDataJson[PARAM_KEY_OS_TYPE].get(); if (osType != DEVICE_OS_TYPE_OH) { LOGE("%{private}s the device os type = %{private}d is not openharmony.", Utils::GetAnonyString(infoTemp.deviceId).c_str(), osType); return FileManagement::ERR_BAD_VALUE; } return FileManagement::ERR_OK; } void DeviceManagerAgent::InitLocalNodeInfo() { auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); DistributedHardware::DmDeviceInfo localDeviceInfo{}; int errCode = deviceManager.GetLocalDeviceInfo(IDaemon::SERVICE_NAME, localDeviceInfo); if (errCode != 0) { ThrowException(errCode, "Failed to get info of local devices"); } localDeviceInfo_.SetCid(string(localDeviceInfo.networkId)); } void DeviceManagerAgent::OnRemoteDied() { LOGI("device manager service died"); } DeviceInfo &DeviceManagerAgent::GetLocalDeviceInfo() { return localDeviceInfo_; } vector DeviceManagerAgent::GetRemoteDevicesInfo() { string extra = ""; string pkgName = IDaemon::SERVICE_NAME; vector deviceList; auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceList); if (errCode) { ThrowException(errCode, "Failed to get info of remote devices"); } vector res; for (const auto &item : deviceList) { res.push_back(DeviceInfo(item)); } return res; } void DeviceManagerAgent::RegisterToExternalDm() { auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); string pkgName = IDaemon::SERVICE_NAME; int errCode = deviceManager.InitDeviceManager(pkgName, shared_from_this()); if (errCode != 0) { ThrowException(errCode, "Failed to InitDeviceManager"); } string extra = ""; errCode = deviceManager.RegisterDevStateCallback(pkgName, extra, shared_from_this()); if (errCode != 0) { ThrowException(errCode, "Failed to RegisterDevStateCallback"); } LOGI("RegisterToExternalDm Succeed"); } void DeviceManagerAgent::UnregisterFromExternalDm() { auto &deviceManager = DistributedHardware::DeviceManager::GetInstance(); string pkgName = IDaemon::SERVICE_NAME; int errCode = deviceManager.UnRegisterDevStateCallback(pkgName); if (errCode != 0) { ThrowException(errCode, "Failed to UnRegisterDevStateCallback"); } errCode = deviceManager.UnInitDeviceManager(pkgName); if (errCode != 0) { ThrowException(errCode, "Failed to UnInitDeviceManager"); } LOGI("UnregisterFromExternalDm Succeed"); } } // namespace DistributedFile } // namespace Storage } // namespace OHOS