• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2025 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 "device/device_manager_agent.h"
17 
18 #include <limits>
19 #include <sstream>
20 #include <string>
21 #include <unordered_set>
22 
23 #include "device_auth.h"
24 #include "dfs_daemon_event_dfx.h"
25 #include "dfs_error.h"
26 #include "dfsu_exception.h"
27 #include "ipc/i_daemon.h"
28 #include "iremote_object.h"
29 #include "iservice_registry.h"
30 #include "istorage_manager.h"
31 #include "mountpoint/mount_manager.h"
32 #include "network/devsl_dispatcher.h"
33 #include "network/softbus/softbus_agent.h"
34 #include "os_account_manager.h"
35 #include "parameters.h"
36 #include "softbus_bus_center.h"
37 #include "system_ability_definition.h"
38 #include "utils_log.h"
39 
40 namespace OHOS {
41 namespace Storage {
42 namespace DistributedFile {
43 namespace {
44 constexpr int32_t DEVICE_OS_TYPE_OH = 10;
45 constexpr int MAX_RETRY_COUNT = 7;
46 constexpr int PEER_TO_PEER_GROUP = 256;
47 constexpr int ACROSS_ACCOUNT_AUTHORIZE_GROUP = 1282;
48 const int32_t MOUNT_DFS_COUNT_ONE = 1;
49 const uint32_t MAX_ONLINE_DEVICE_SIZE = 10000;
50 constexpr const char* PARAM_KEY_OS_TYPE = "OS_TYPE";
51 const std::string SAME_ACCOUNT_MARK = "const.distributed_file_only_for_same_account_test";
52 } // namespace
53 using namespace std;
54 
DeviceManagerAgent()55 DeviceManagerAgent::DeviceManagerAgent() : DfsuActor<DeviceManagerAgent>(this, std::numeric_limits<uint32_t>::max()) {}
56 
~DeviceManagerAgent()57 DeviceManagerAgent::~DeviceManagerAgent()
58 {
59     try {
60         StopInstance();
61     } catch (const DfsuException &e) {
62         // do not throw exception
63     } catch (const std::exception &e) {
64         // do not throw exception
65     }
66 }
67 
StartInstance()68 void DeviceManagerAgent::StartInstance()
69 {
70     StartActor();
71 }
72 
StopInstance()73 void DeviceManagerAgent::StopInstance()
74 {
75     StopActor();
76 }
77 
Start()78 void DeviceManagerAgent::Start()
79 {
80     DevslDispatcher::Start();
81     RegisterToExternalDm();
82     InitLocalNodeInfo();
83     InitDeviceAuthService();
84 }
85 
Stop()86 void DeviceManagerAgent::Stop()
87 {
88     DestroyDeviceAuthService();
89     UnregisterFromExternalDm();
90     DevslDispatcher::Stop();
91 }
92 
JoinGroup(weak_ptr<MountPoint> mp)93 void DeviceManagerAgent::JoinGroup(weak_ptr<MountPoint> mp)
94 {
95     LOGI("join group begin");
96     auto smp = mp.lock();
97     if (!smp) {
98         stringstream ss("Failed to join group: Received empty mountpoint");
99         LOGE("%{public}s", ss.str().c_str());
100         throw runtime_error(ss.str());
101     }
102 
103     shared_ptr<SoftbusAgent> agent = nullptr;
104     {
105         unique_lock<mutex> lock(mpToNetworksMutex_);
106         agent = make_shared<SoftbusAgent>(mp);
107         auto [ignored, inserted] = mpToNetworks_.insert({ smp->GetID(), agent });
108         if (!inserted) {
109             stringstream ss;
110             ss << "Failed to join group: Mountpoint existed" << smp->ToString();
111             throw runtime_error(ss.str());
112         }
113     }
114     agent->StartActor();
115     LOGI("join group end, id : %{public}d, account : %{public}s", smp->GetID(), smp->isAccountLess() ? "no" : "yes");
116 }
117 
QuitGroup(shared_ptr<MountPoint> smp)118 void DeviceManagerAgent::QuitGroup(shared_ptr<MountPoint> smp)
119 {
120     LOGI("quit group begin");
121     OfflineAllDevice();
122 
123     if (!smp) {
124         stringstream ss("Failed to quit group: Received empty mountpoint");
125         LOGE("%{public}s", ss.str().c_str());
126         throw runtime_error(ss.str());
127     }
128 
129     unique_lock<mutex> lock(mpToNetworksMutex_);
130     auto it = mpToNetworks_.find(smp->GetID());
131     if (it == mpToNetworks_.end()) {
132         stringstream ss;
133         ss << "Failed to quit group: Mountpoint didn't exist " << smp->ToString();
134         throw runtime_error(ss.str());
135     }
136 
137     it->second->StopActor();
138     mpToNetworks_.erase(smp->GetID());
139     LOGI("quit group end, id : %{public}d, account : %{public}s", smp->GetID(), smp->isAccountLess() ? "no" : "yes");
140 }
141 
OfflineAllDevice()142 void DeviceManagerAgent::OfflineAllDevice()
143 {
144     unique_lock<mutex> lock(mpToNetworksMutex_);
145     for (auto [ignore, net] : cidNetTypeRecord_) {
146         if (net == nullptr) {
147             continue;
148         }
149         auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate>>(&NetworkAgentTemplate::DisconnectAllDevices);
150         net->Recv(move(cmd));
151     }
152 }
153 
ReconnectOnlineDevices()154 void DeviceManagerAgent::ReconnectOnlineDevices()
155 {
156     unique_lock<mutex> lock(mpToNetworksMutex_);
157     for (auto [ignore, net] : cidNetTypeRecord_) {
158         if (net == nullptr) {
159             continue;
160         }
161     }
162 }
163 
FindNetworkBaseTrustRelation(bool isAccountless)164 std::shared_ptr<NetworkAgentTemplate> DeviceManagerAgent::FindNetworkBaseTrustRelation(bool isAccountless)
165 {
166     LOGI("enter: isAccountless %{public}d", isAccountless);
167     for (auto [ignore, net] : mpToNetworks_) {
168         if (net != nullptr) {
169             auto smp = net->GetMountPoint();
170             if (smp != nullptr && smp->isAccountLess() == isAccountless) {
171                 return net;
172             }
173         }
174     }
175     LOGE("not find this net in mpToNetworks, isAccountless %{public}d", isAccountless);
176     return nullptr;
177 }
178 
GetNetworkType(const string & cid)179 int32_t DeviceManagerAgent::GetNetworkType(const string &cid)
180 {
181     int32_t networkType = 0;
182     string pkgName = IDaemon::SERVICE_NAME;
183     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
184     int errCode = deviceManager.GetNetworkTypeByNetworkId(pkgName, cid, networkType);
185     if (errCode) {
186         LOGE("get network type error:%{public}d", errCode);
187     }
188 
189     return networkType;
190 }
191 
IsWifiNetworkType(int32_t networkType)192 bool DeviceManagerAgent::IsWifiNetworkType(int32_t networkType)
193 {
194     if ((networkType == -1) ||
195         !(static_cast<uint32_t>(networkType) & (1 << DistributedHardware::BIT_NETWORK_TYPE_WIFI))) {
196         return false;
197     }
198 
199     return true;
200 }
201 
OnDeviceReady(const DistributedHardware::DmDeviceInfo & deviceInfo)202 void DeviceManagerAgent::OnDeviceReady(const DistributedHardware::DmDeviceInfo &deviceInfo)
203 {
204 }
205 
OnDeviceOffline(const DistributedHardware::DmDeviceInfo & deviceInfo)206 void DeviceManagerAgent::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo)
207 {
208     LOGI("OnDeviceOffline  begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
209     DeviceInfo info(deviceInfo);
210 
211     unique_lock<mutex> lock(mpToNetworksMutex_);
212     auto it = cidNetTypeRecord_.find(info.cid_);
213     if (it == cidNetTypeRecord_.end()) {
214         LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
215         LOGI("OnDeviceOffline end");
216         return;
217     }
218 
219     auto type_ = cidNetworkType_.find(info.cid_);
220     if (type_ == cidNetworkType_.end()) {
221         LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
222         LOGI("OnDeviceOffline end");
223         return;
224     }
225 
226     auto networkId = std::string(deviceInfo.networkId);
227     auto deviceId = std::string(deviceInfo.deviceId);
228     if (deviceId.empty()) {
229         deviceId = GetDeviceIdByNetworkId(networkId);
230     }
231     if (!networkId.empty()) {
232         UMountDfsDocs(networkId, deviceId, true);
233     }
234 
235     auto cmd2 = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
236         &NetworkAgentTemplate::DisconnectDeviceByP2PHmdfs, info);
237     it->second->Recv(move(cmd2));
238 
239     cidNetTypeRecord_.erase(info.cid_);
240     cidNetworkType_.erase(info.cid_);
241 
242     int32_t ret = NO_ERROR;
243     int32_t userId = GetCurrentUserId();
244     auto localNetworkId = GetLocalDeviceInfo().GetCid();
245     if (userId == INVALID_USER_ID) {
246         LOGE("DeviceManagerAgent::GetCurrentUserId Fail");
247     }
248     GetStorageManager();
249     if (storageMgrProxy_ == nullptr) {
250         LOGE("storageMgrProxy_ is null");
251     }
252     ret = storageMgrProxy_->UMountDisShareFile(userId, localNetworkId);
253     if (ret != NO_ERROR) {
254         LOGE("UMountDisShareFile failed, ret =%{public}d", ret);
255     } else {
256         LOGI("UMountDisShareFile success");
257     }
258 
259     LOGI("OnDeviceOffline end");
260 }
261 
ClearCount(const DistributedHardware::DmDeviceInfo & deviceInfo)262 void DeviceManagerAgent::ClearCount(const DistributedHardware::DmDeviceInfo &deviceInfo)
263 {
264     LOGI("ClearCount networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
265     DeviceInfo info(deviceInfo);
266     unique_lock<mutex> lock(mpToNetworksMutex_);
267     auto it = cidNetTypeRecord_.find(info.cid_);
268     if (it == cidNetTypeRecord_.end()) {
269         LOGE("cid %{public}s network is null!",  Utils::GetAnonyString(info.cid_).c_str());
270         return;
271     }
272     it->second->DisconnectDeviceByP2P(info);
273 }
274 
OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo & deviceInfo)275 int32_t DeviceManagerAgent::OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo &deviceInfo)
276 {
277     LOGI("[OnDeviceP2POnline] networkId %{public}s, OnDeviceOnline begin",
278         Utils::GetAnonyString(deviceInfo.networkId).c_str());
279     int32_t ret = IsSupportedDevice(deviceInfo);
280     if (ret != FileManagement::ERR_OK) {
281         LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
282         return P2P_FAILED;
283     }
284     DeviceInfo info(deviceInfo);
285     QueryRelatedGroups(info.udid_, info.cid_);
286 
287     unique_lock<mutex> lock(mpToNetworksMutex_);
288     auto it = cidNetTypeRecord_.find(info.cid_);
289     if (it == cidNetTypeRecord_.end()) {
290         LOGE("[OnDeviceP2POnline] cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
291         return P2P_FAILED;
292     }
293     auto type_ = cidNetworkType_.find(info.cid_);
294     if (type_ == cidNetworkType_.end()) {
295         LOGE("[OnDeviceP2POnline] cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
296         return P2P_FAILED;
297     }
298     auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
299         &NetworkAgentTemplate::ConnectDeviceByP2PAsync, info);
300     cmd->UpdateOption({.tryTimes_ = MAX_RETRY_COUNT});
301     it->second->Recv(move(cmd));
302     LOGI("OnDeviceP2POnline end networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
303     return P2P_SUCCESS;
304 }
305 
OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo & deviceInfo)306 int32_t DeviceManagerAgent::OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo &deviceInfo)
307 {
308     LOGI("OnDeviceP2POffline  begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
309     DeviceInfo info(deviceInfo);
310 
311     unique_lock<mutex> lock(mpToNetworksMutex_);
312     auto it = cidNetTypeRecord_.find(info.cid_);
313     if (it == cidNetTypeRecord_.end()) {
314         LOGE("cid %{public}s network is null!",  Utils::GetAnonyString(info.cid_).c_str());
315         return P2P_FAILED;
316     }
317     auto type_ = cidNetworkType_.find(info.cid_);
318     if (type_ == cidNetworkType_.end()) {
319         LOGE("cid %{public}s network type is null!",  Utils::GetAnonyString(info.cid_).c_str());
320         return P2P_FAILED;
321     }
322     auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
323         &NetworkAgentTemplate::DisconnectDeviceByP2P, info);
324     it->second->Recv(move(cmd));
325     cidNetTypeRecord_.erase(info.cid_);
326     cidNetworkType_.erase(info.cid_);
327     LOGI("OnDeviceP2POffline end");
328     return P2P_SUCCESS;
329 }
330 
MountDfsCountOnly(const std::string & deviceId)331 bool DeviceManagerAgent::MountDfsCountOnly(const std::string &deviceId)
332 {
333     if (deviceId.empty()) {
334         LOGI("deviceId empty");
335         return false;
336     }
337     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
338     auto itCount = mountDfsCount_.find(deviceId);
339     if (itCount == mountDfsCount_.end()) {
340         LOGI("mountDfsCount_ can not find key");
341         return false;
342     }
343     if (itCount->second > 0) {
344         LOGI("[MountDfsCountOnly] deviceId %{public}s has already established a link, count %{public}d, \
345             increase count by one now", Utils::GetAnonyString(deviceId).c_str(), itCount->second);
346         return true;
347     }
348     return false;
349 }
350 
UMountDfsCountOnly(const std::string & deviceId,bool needClear)351 bool DeviceManagerAgent::UMountDfsCountOnly(const std::string &deviceId, bool needClear)
352 {
353     if (deviceId.empty()) {
354         LOGI("deviceId empty");
355         return false;
356     }
357     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
358     auto itCount = mountDfsCount_.find(deviceId);
359     if (itCount == mountDfsCount_.end()) {
360         LOGI("mountDfsCount_ can not find key");
361         return true;
362     }
363     if (needClear) {
364         LOGI("mountDfsCount_ erase");
365         mountDfsCount_.erase(itCount);
366         return false;
367     }
368     if (itCount->second > MOUNT_DFS_COUNT_ONE) {
369         LOGI("[UMountDfsCountOnly] deviceId %{public}s has already established more than one link, \
370             count %{public}d, decrease count by one now",
371             Utils::GetAnonyString(deviceId).c_str(), itCount->second);
372         mountDfsCount_[deviceId]--;
373         return true;
374     }
375     LOGI("[UMountDfsCountOnly] deviceId %{public}s erase count", Utils::GetAnonyString(deviceId).c_str());
376     return false;
377 }
378 
GetCurrentUserId()379 int32_t DeviceManagerAgent::GetCurrentUserId()
380 {
381     std::vector<int32_t> userIds{};
382     auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds);
383     if (ret != NO_ERROR || userIds.empty()) {
384         LOGE("query active os account id failed, ret = %{public}d", ret);
385         return INVALID_USER_ID;
386     }
387     LOGI("DeviceManagerAgent::GetCurrentUserId end.");
388     return userIds[0];
389 }
390 
GetStorageManager()391 void DeviceManagerAgent::GetStorageManager()
392 {
393     auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
394     if (saMgr == nullptr) {
395         LOGE("GetSystemAbilityManager filed");
396         return;
397     }
398 
399     auto storageObj = saMgr->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
400     if (storageObj == nullptr) {
401         LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy");
402         return;
403     }
404 
405     storageMgrProxy_ = iface_cast<StorageManager::IStorageManager>(storageObj);
406     if (storageMgrProxy_ == nullptr) {
407         LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy!");
408         return;
409     }
410 
411     LOGI("GetStorageManager end.");
412     return;
413 }
414 
AddNetworkId(uint32_t tokenId,const std::string & networkId)415 void DeviceManagerAgent::AddNetworkId(uint32_t tokenId, const std::string &networkId)
416 {
417     LOGI("DeviceManagerAgent::AddNetworkId, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str());
418     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
419     networkIdMap_[tokenId].insert(networkId);
420 }
421 
RemoveNetworkId(uint32_t tokenId)422 void DeviceManagerAgent::RemoveNetworkId(uint32_t tokenId)
423 {
424     LOGI("DeviceManagerAgent::RemoveNetworkId start");
425     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
426     networkIdMap_.erase(tokenId);
427 }
428 
RemoveNetworkIdByOne(uint32_t tokenId,const std::string & networkId)429 void DeviceManagerAgent::RemoveNetworkIdByOne(uint32_t tokenId, const std::string &networkId)
430 {
431     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
432     auto it = networkIdMap_.find(tokenId);
433     if (it != networkIdMap_.end()) {
434         (it->second).erase(networkId);
435         if (it->second.empty()) {
436             networkIdMap_.erase(it);
437         }
438         LOGI("DeviceManagerAgent::RemoveNetworkIdByOne success, networkId: %{public}s",
439             Utils::GetAnonyString(networkId).c_str());
440     }
441 }
442 
RemoveNetworkIdForAllToken(const std::string & networkId)443 void DeviceManagerAgent::RemoveNetworkIdForAllToken(const std::string &networkId)
444 {
445     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
446     if (networkId.empty()) {
447         LOGE("networkId is empty");
448         return;
449     }
450     for (auto it = networkIdMap_.begin(); it != networkIdMap_.end();) {
451         it->second.erase(networkId);
452         if (it->second.empty()) {
453             it = networkIdMap_.erase(it);
454         } else {
455             ++it;
456         }
457         LOGI("RemoveNetworkIdForAllToken, networkId: %{public}s",
458             Utils::GetAnonyString(networkId).c_str());
459     }
460 }
461 
ClearNetworkId()462 void DeviceManagerAgent::ClearNetworkId()
463 {
464     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
465     networkIdMap_.clear();
466 }
467 
GetNetworkIds(uint32_t tokenId)468 std::unordered_set<std::string> DeviceManagerAgent::GetNetworkIds(uint32_t tokenId)
469 {
470     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
471     return networkIdMap_[tokenId];
472 }
473 
MountDfsDocs(const std::string & networkId,const std::string & deviceId)474 int32_t DeviceManagerAgent::MountDfsDocs(const std::string &networkId, const std::string &deviceId)
475 {
476     LOGI("MountDfsDocs start");
477     if (networkId.empty() || deviceId.empty()) {
478         LOGE("NetworkId or DeviceId is empty");
479         return INVALID_USER_ID;
480     }
481     int32_t ret = NO_ERROR;
482     if (MountDfsCountOnly(deviceId)) {
483         LOGI("only count plus one, do not need mount");
484         IncreaseMountDfsCount(deviceId);
485         return ret;
486     }
487     int32_t userId = GetCurrentUserId();
488     if (userId == INVALID_USER_ID) {
489         LOGE("GetCurrentUserId Fail");
490         return INVALID_USER_ID;
491     }
492     GetStorageManager();
493     if (storageMgrProxy_ == nullptr) {
494         LOGE("storageMgrProxy_ is null");
495         return INVALID_USER_ID;
496     }
497     ret = storageMgrProxy_->MountDfsDocs(userId, "account", networkId, deviceId);
498     if (ret != NO_ERROR) {
499         LOGE("MountDfsDocs fail, ret = %{public}d", ret);
500     } else {
501         LOGE("MountDfsDocs success, deviceId %{public}s increase count by one now",
502             Utils::GetAnonyString(deviceId).c_str());
503         IncreaseMountDfsCount(deviceId);
504     }
505     LOGI("storageMgr.MountDfsDocs end.");
506     return ret;
507 }
508 
UMountDfsDocs(const std::string & networkId,const std::string & deviceId,bool needClear)509 int32_t DeviceManagerAgent::UMountDfsDocs(const std::string &networkId, const std::string &deviceId, bool needClear)
510 {
511     LOGI("UMountDfsDocs start in OpenP2PConnection, networkId: %{public}s, deviceId: %{public}s",
512         Utils::GetAnonyString(networkId).c_str(), Utils::GetAnonyString(deviceId).c_str());
513     if (networkId.empty() || deviceId.empty()) {
514         LOGE("NetworkId or DeviceId is empty");
515         return INVALID_USER_ID;
516     }
517     int32_t ret = NO_ERROR;
518     if (UMountDfsCountOnly(deviceId, needClear)) {
519         LOGE("do not need umount");
520         return ret;
521     }
522     int32_t userId = GetCurrentUserId();
523     if (userId == INVALID_USER_ID) {
524         LOGE("GetCurrentUserId Fail");
525         return INVALID_USER_ID;
526     }
527     GetStorageManager();
528     if (storageMgrProxy_ == nullptr) {
529         LOGE("storageMgrProxy_ is null");
530         return INVALID_USER_ID;
531     }
532     ret = storageMgrProxy_->UMountDfsDocs(userId, "account", networkId, deviceId);
533     if (ret != NO_ERROR) {
534         LOGE("UMountDfsDocs fail, ret = %{public}d", ret);
535     } else {
536         LOGE("UMountDfsDocs success, deviceId %{public}s erase count",
537             Utils::GetAnonyString(deviceId).c_str());
538         RemoveMountDfsCount(deviceId);
539     }
540     LOGI("storageMgr.UMountDfsDocs end.");
541     return ret;
542 }
543 
IncreaseMountDfsCount(const std::string & deviceId)544 void DeviceManagerAgent::IncreaseMountDfsCount(const std::string &deviceId)
545 {
546     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
547     mountDfsCount_[deviceId]++;
548 }
549 
RemoveMountDfsCount(const std::string & deviceId)550 void DeviceManagerAgent::RemoveMountDfsCount(const std::string &deviceId)
551 {
552     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
553     mountDfsCount_.erase(deviceId);
554 }
555 
NotifyRemoteReverseObj(const std::string & networkId,int32_t status)556 void DeviceManagerAgent::NotifyRemoteReverseObj(const std::string &networkId, int32_t status)
557 {
558     std::lock_guard<std::mutex> lock(appCallConnectMutex_);
559     for (auto it = appCallConnect_.begin(); it != appCallConnect_.end(); ++it) {
560         auto onstatusReverseProxy = it->second;
561         if (onstatusReverseProxy == nullptr) {
562             LOGI("get onstatusReverseProxy fail");
563             return;
564         }
565         onstatusReverseProxy->OnStatus(networkId, status);
566         LOGI("NotifyRemoteReverseObj, deviceId: %{public}s", Utils::GetAnonyString(networkId).c_str());
567     }
568 }
569 
AddRemoteReverseObj(uint32_t callingTokenId,sptr<IFileDfsListener> remoteReverseObj)570 int32_t DeviceManagerAgent::AddRemoteReverseObj(uint32_t callingTokenId, sptr<IFileDfsListener> remoteReverseObj)
571 {
572     std::lock_guard<std::mutex> lock(appCallConnectMutex_);
573     auto it = appCallConnect_.find(callingTokenId);
574     if (it != appCallConnect_.end()) {
575         LOGE("AddRemoteReverseObj fail");
576         return FileManagement::E_INVAL_ARG;
577     }
578     appCallConnect_[callingTokenId] = remoteReverseObj;
579     LOGI("DeviceManagerAgent::AddRemoteReverseObj::add new value suceess");
580     return FileManagement::E_OK;
581 }
582 
RemoveRemoteReverseObj(bool clear,uint32_t callingTokenId)583 int32_t DeviceManagerAgent::RemoveRemoteReverseObj(bool clear, uint32_t callingTokenId)
584 {
585     LOGI("DeviceManagerAgent::RemoveRemoteReverseObj called");
586     if (clear) {
587         appCallConnect_.clear();
588         return FileManagement::E_OK;
589     }
590 
591     auto it = appCallConnect_.find(callingTokenId);
592     if (it == appCallConnect_.end()) {
593         LOGE("RemoveRemoteReverseObj fail");
594         return FileManagement::E_INVAL_ARG;
595     }
596     appCallConnect_.erase(it);
597     LOGI("DeviceManagerAgent::RemoveRemoteReverseObj end");
598     return FileManagement::E_OK;
599 }
600 
FindListenerByObject(const wptr<IRemoteObject> & remote,uint32_t & tokenId,sptr<IFileDfsListener> & listener)601 int32_t DeviceManagerAgent::FindListenerByObject(const wptr<IRemoteObject> &remote,
602                                                  uint32_t &tokenId, sptr<IFileDfsListener>& listener)
603 {
604     std::lock_guard<std::mutex> lock(appCallConnectMutex_);
605     for (auto it = appCallConnect_.begin(); it != appCallConnect_.end(); ++it) {
606         if (remote != (it->second)->AsObject()) {
607             continue;
608         }
609         tokenId = it->first;
610         listener = it->second;
611         return FileManagement::E_OK;
612     }
613     return FileManagement::E_INVAL_ARG;
614 }
615 
GetDeviceIdByNetworkId(const std::string & networkId)616 std::string DeviceManagerAgent::GetDeviceIdByNetworkId(const std::string &networkId)
617 {
618     LOGI("DeviceManagerAgent::GetDeviceIdByNetworkId called");
619     if (networkId.empty()) {
620         return "";
621     }
622     std::vector<DistributedHardware::DmDeviceInfo> deviceList;
623     DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(IDaemon::SERVICE_NAME, "", deviceList);
624     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
625         LOGE("the size of trust device list is invalid, size=%zu", deviceList.size());
626         return "";
627     }
628     std::string deviceId = "";
629     for (const auto &device : deviceList) {
630         if (std::string(device.networkId) == networkId) {
631             deviceId = std::string(device.deviceId);
632         }
633     }
634     LOGI("DeviceManagerAgent::GetDeviceIdByNetworkId end");
635     return deviceId;
636 }
637 
from_json(const nlohmann::json & jsonObject,GroupInfo & groupInfo)638 void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo)
639 {
640     if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end() && jsonObject[FIELD_GROUP_NAME].is_string()) {
641         groupInfo.groupName = jsonObject.at(FIELD_GROUP_NAME).get<std::string>();
642     }
643 
644     if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end() && jsonObject[FIELD_GROUP_ID].is_string()) {
645         groupInfo.groupId = jsonObject.at(FIELD_GROUP_ID).get<std::string>();
646     }
647 
648     if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end() && jsonObject[FIELD_GROUP_OWNER].is_string()) {
649         groupInfo.groupOwner = jsonObject.at(FIELD_GROUP_OWNER).get<std::string>();
650     }
651 
652     if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end() && jsonObject[FIELD_GROUP_TYPE].is_number()) {
653         groupInfo.groupType = jsonObject.at(FIELD_GROUP_TYPE).get<int32_t>();
654     }
655 }
656 
QueryRelatedGroups(const std::string & udid,const std::string & networkId)657 void DeviceManagerAgent::QueryRelatedGroups(const std::string &udid, const std::string &networkId)
658 {
659     unique_lock<mutex> lock(mpToNetworksMutex_);
660     auto network = FindNetworkBaseTrustRelation(false);
661     if (network != nullptr) {
662         cidNetTypeRecord_.insert({ networkId, network });
663         cidNetworkType_.insert({ networkId, GetNetworkType(networkId) });
664     }
665 }
666 
CheckIsAccountless(const GroupInfo & group)667 bool DeviceManagerAgent::CheckIsAccountless(const GroupInfo &group)
668 {
669     // because of there no same_account, only for test, del later
670     LOGI("SAME_ACCOUNT_MARK val is %{public}d", system::GetBoolParameter(SAME_ACCOUNT_MARK, false));
671     if (system::GetBoolParameter(SAME_ACCOUNT_MARK, false) == true) { // isaccountless == false
672         LOGI("SAME_ACCOUNT_MARK val is true(same account)");
673         return false;
674     } else { // isaccountless == true
675         return true;
676     }
677 
678     if (group.groupType == PEER_TO_PEER_GROUP || group.groupType == ACROSS_ACCOUNT_AUTHORIZE_GROUP) {
679         return true;
680     }
681     return false;
682 }
683 
OnDeviceChanged(const DistributedHardware::DmDeviceInfo & deviceInfo)684 void DeviceManagerAgent::OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo)
685 {
686     LOGI("OnDeviceInfoChanged  begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
687     if (deviceInfo.networkType == -1) {
688         LOGI("OnDeviceInfoChanged end");
689         return;
690     }
691     int32_t ret = IsSupportedDevice(deviceInfo);
692     if (ret != FileManagement::ERR_OK) {
693         LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
694         return;
695     }
696 
697     DeviceInfo info(deviceInfo);
698     unique_lock<mutex> lock(mpToNetworksMutex_);
699 
700     auto it = cidNetTypeRecord_.find(info.cid_);
701     if (it == cidNetTypeRecord_.end()) {
702         LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
703         LOGI("OnDeviceInfoChanged end");
704         return;
705     }
706 
707     auto type_ = cidNetworkType_.find(info.cid_);
708     if (type_ == cidNetworkType_.end()) {
709         LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
710         LOGI("OnDeviceInfoChanged end");
711         return;
712     }
713 
714     int32_t oldNetworkType = type_->second;
715     int32_t newNetworkType = type_->second = deviceInfo.networkType;
716     LOGI("oldNetworkType %{public}d, newNetworkType %{public}d", oldNetworkType, newNetworkType);
717     LOGI("OnDeviceInfoChanged end");
718 }
719 
InitDeviceInfos()720 void DeviceManagerAgent::InitDeviceInfos()
721 {
722     string extra = "";
723     string pkgName = IDaemon::SERVICE_NAME;
724     vector<DistributedHardware::DmDeviceInfo> deviceInfoList;
725 
726     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
727     int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceInfoList);
728     if (errCode) {
729         ThrowException(errCode, "Failed to get info of remote devices");
730     }
731 
732     for (const auto &deviceInfo : deviceInfoList) {
733         int32_t ret = IsSupportedDevice(deviceInfo);
734         if (ret != FileManagement::ERR_OK) {
735             LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
736             continue;
737         }
738         DeviceInfo info(deviceInfo);
739         QueryRelatedGroups(info.udid_, info.cid_);
740     }
741 }
742 
IsSupportedDevice(const DistributedHardware::DmDeviceInfo & deviceInfo)743 int32_t DeviceManagerAgent::IsSupportedDevice(const DistributedHardware::DmDeviceInfo &deviceInfo)
744 {
745     std::vector<DistributedHardware::DmDeviceInfo> deviceList;
746     DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(IDaemon::SERVICE_NAME, "", deviceList);
747     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
748         LOGE("trust device list size is invalid, size=%zu", deviceList.size());
749         return FileManagement::ERR_BAD_VALUE;
750     }
751     DistributedHardware::DmDeviceInfo infoTemp;
752     for (const auto &info : deviceList) {
753         if (std::string_view(info.networkId) == std::string_view(deviceInfo.networkId)) {
754             infoTemp = info;
755             break;
756         }
757     }
758 
759     if (infoTemp.extraData.empty()) {
760         LOGE("extraData is empty");
761         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_FAILED,
762             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
763             RadarReporter::GET_SAME_ACCOUNT_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::deviceManager);
764         return FileManagement::ERR_BAD_VALUE;
765     }
766     nlohmann::json entraDataJson = nlohmann::json::parse(infoTemp.extraData, nullptr, false);
767     if (entraDataJson.is_discarded()) {
768         LOGE("entraDataJson parse failed.");
769         return FileManagement::ERR_BAD_VALUE;
770     }
771     if (!Utils::IsInt32(entraDataJson, PARAM_KEY_OS_TYPE)) {
772         LOGE("error json int32_t param.");
773         return FileManagement::ERR_BAD_VALUE;
774     }
775     int32_t osType = entraDataJson[PARAM_KEY_OS_TYPE].get<int32_t>();
776     if (osType != DEVICE_OS_TYPE_OH) {
777         LOGE("%{private}s  the device os type = %{private}d is not openharmony.",
778             Utils::GetAnonyString(infoTemp.deviceId).c_str(), osType);
779         return FileManagement::ERR_BAD_VALUE;
780     }
781     return FileManagement::ERR_OK;
782 }
783 
InitLocalNodeInfo()784 void DeviceManagerAgent::InitLocalNodeInfo()
785 {
786     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
787     DistributedHardware::DmDeviceInfo localDeviceInfo{};
788     int errCode = deviceManager.GetLocalDeviceInfo(IDaemon::SERVICE_NAME, localDeviceInfo);
789     if (errCode != 0) {
790         ThrowException(errCode, "Failed to get info of local devices");
791     }
792     localDeviceInfo_.SetCid(string(localDeviceInfo.networkId));
793 }
794 
OnRemoteDied()795 void DeviceManagerAgent::OnRemoteDied()
796 {
797     LOGI("device manager service died");
798 }
799 
GetLocalDeviceInfo()800 DeviceInfo &DeviceManagerAgent::GetLocalDeviceInfo()
801 {
802     return localDeviceInfo_;
803 }
804 
GetRemoteDevicesInfo()805 vector<DeviceInfo> DeviceManagerAgent::GetRemoteDevicesInfo()
806 {
807     string extra = "";
808     string pkgName = IDaemon::SERVICE_NAME;
809     vector<DistributedHardware::DmDeviceInfo> deviceList;
810 
811     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
812     int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceList);
813     if (errCode) {
814         ThrowException(errCode, "Failed to get info of remote devices");
815     }
816 
817     vector<DeviceInfo> res;
818     for (const auto &item : deviceList) {
819         res.push_back(DeviceInfo(item));
820     }
821     return res;
822 }
823 
RegisterToExternalDm()824 void DeviceManagerAgent::RegisterToExternalDm()
825 {
826     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
827     string pkgName = IDaemon::SERVICE_NAME;
828     int errCode = deviceManager.InitDeviceManager(pkgName, shared_from_this());
829     if (errCode != 0) {
830         ThrowException(errCode, "Failed to InitDeviceManager");
831     }
832     string extra = "";
833     errCode = deviceManager.RegisterDevStateCallback(pkgName, extra, shared_from_this());
834     if (errCode != 0) {
835         ThrowException(errCode, "Failed to RegisterDevStateCallback");
836     }
837     LOGI("RegisterToExternalDm Succeed");
838 }
839 
UnregisterFromExternalDm()840 void DeviceManagerAgent::UnregisterFromExternalDm()
841 {
842     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
843     string pkgName = IDaemon::SERVICE_NAME;
844     int errCode = deviceManager.UnRegisterDevStateCallback(pkgName);
845     if (errCode != 0) {
846         ThrowException(errCode, "Failed to UnRegisterDevStateCallback");
847     }
848     errCode = deviceManager.UnInitDeviceManager(pkgName);
849     if (errCode != 0) {
850         ThrowException(errCode, "Failed to UnInitDeviceManager");
851     }
852     LOGI("UnregisterFromExternalDm Succeed");
853 }
854 } // namespace DistributedFile
855 } // namespace Storage
856 } // namespace OHOS
857