• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "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 "mountpoint/mount_manager.h"
31 #include "network/devsl_dispatcher.h"
32 #include "network/softbus/softbus_agent.h"
33 #include "os_account_manager.h"
34 #include "parameters.h"
35 #include "softbus_bus_center.h"
36 #include "system_ability_definition.h"
37 #include "utils_log.h"
38 
39 namespace OHOS {
40 namespace Storage {
41 namespace DistributedFile {
42 namespace {
43 constexpr int32_t DEVICE_OS_TYPE_OH = 10;
44 constexpr int MAX_RETRY_COUNT = 7;
45 constexpr int PEER_TO_PEER_GROUP = 256;
46 constexpr int ACROSS_ACCOUNT_AUTHORIZE_GROUP = 1282;
47 const int32_t MOUNT_DFS_COUNT_ONE = 1;
48 const uint32_t MAX_ONLINE_DEVICE_SIZE = 10000;
49 const int32_t INVALID_USER_ID = -1;
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     LOGI("networkId %{public}s, OnDeviceReady begin", Utils::GetAnonyString(deviceInfo.networkId).c_str());
205     int32_t ret = IsSupportedDevice(deviceInfo);
206     if (ret != FileManagement::ERR_OK) {
207         LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
208         return;
209     }
210 
211     // online first query this dev's trust info
212     DeviceInfo info(deviceInfo);
213     QueryRelatedGroups(info.udid_, info.cid_);
214 
215     // based on dev's trust info, choose corresponding network agent to obtain socket
216     unique_lock<mutex> lock(mpToNetworksMutex_);
217 
218     auto it = cidNetTypeRecord_.find(info.cid_);
219     if (it == cidNetTypeRecord_.end()) {
220         LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
221         LOGI("OnDeviceReady end");
222         return;
223     }
224 
225     auto type_ = cidNetworkType_.find(info.cid_);
226     if (type_ == cidNetworkType_.end()) {
227         LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
228         LOGI("OnDeviceReady end");
229         return;
230     }
231 
232     int32_t newNetworkType = type_->second = GetNetworkType(info.cid_);
233     LOGI("newNetworkType:%{public}d", newNetworkType);
234 
235     if (!IsWifiNetworkType(newNetworkType)) {
236         LOGE("cid %{public}s networkType:%{public}d",  Utils::GetAnonyString(info.cid_).c_str(), type_->second);
237         LOGI("OnDeviceReady end");
238         return;
239     }
240     LOGI("OnDeviceReady end");
241 }
242 
OnDeviceOffline(const DistributedHardware::DmDeviceInfo & deviceInfo)243 void DeviceManagerAgent::OnDeviceOffline(const DistributedHardware::DmDeviceInfo &deviceInfo)
244 {
245     LOGI("OnDeviceOffline  begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
246     DeviceInfo info(deviceInfo);
247 
248     unique_lock<mutex> lock(mpToNetworksMutex_);
249     auto it = cidNetTypeRecord_.find(info.cid_);
250     if (it == cidNetTypeRecord_.end()) {
251         LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
252         LOGI("OnDeviceOffline end");
253         return;
254     }
255 
256     auto type_ = cidNetworkType_.find(info.cid_);
257     if (type_ == cidNetworkType_.end()) {
258         LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
259         LOGI("OnDeviceOffline end");
260         return;
261     }
262 
263     auto networkId = std::string(deviceInfo.networkId);
264     auto deviceId = std::string(deviceInfo.deviceId);
265     if (deviceId.empty()) {
266         deviceId = GetDeviceIdByNetworkId(networkId);
267     }
268     if (!networkId.empty()) {
269         UMountDfsDocs(networkId, deviceId, true);
270     }
271 
272     auto cmd2 = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
273         &NetworkAgentTemplate::DisconnectDeviceByP2PHmdfs, info);
274     it->second->Recv(move(cmd2));
275 
276     cidNetTypeRecord_.erase(info.cid_);
277     cidNetworkType_.erase(info.cid_);
278     LOGI("OnDeviceOffline end");
279 }
280 
ClearCount(const DistributedHardware::DmDeviceInfo & deviceInfo)281 void DeviceManagerAgent::ClearCount(const DistributedHardware::DmDeviceInfo &deviceInfo)
282 {
283     LOGI("ClearCount networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
284     DeviceInfo info(deviceInfo);
285     unique_lock<mutex> lock(mpToNetworksMutex_);
286     auto it = cidNetTypeRecord_.find(info.cid_);
287     if (it == cidNetTypeRecord_.end()) {
288         LOGE("cid %{public}s network is null!",  Utils::GetAnonyString(info.cid_).c_str());
289         return;
290     }
291     it->second->DisconnectDeviceByP2P(info);
292 }
293 
OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo & deviceInfo)294 int32_t DeviceManagerAgent::OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo &deviceInfo)
295 {
296     LOGI("[OnDeviceP2POnline] networkId %{public}s, OnDeviceOnline begin",
297         Utils::GetAnonyString(deviceInfo.networkId).c_str());
298     int32_t ret = IsSupportedDevice(deviceInfo);
299     if (ret != FileManagement::ERR_OK) {
300         LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
301         return P2P_FAILED;
302     }
303     DeviceInfo info(deviceInfo);
304     QueryRelatedGroups(info.udid_, info.cid_);
305 
306     unique_lock<mutex> lock(mpToNetworksMutex_);
307     auto it = cidNetTypeRecord_.find(info.cid_);
308     if (it == cidNetTypeRecord_.end()) {
309         LOGE("[OnDeviceP2POnline] cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
310         return P2P_FAILED;
311     }
312     auto type_ = cidNetworkType_.find(info.cid_);
313     if (type_ == cidNetworkType_.end()) {
314         LOGE("[OnDeviceP2POnline] cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
315         return P2P_FAILED;
316     }
317     auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
318         &NetworkAgentTemplate::ConnectDeviceByP2PAsync, info);
319     cmd->UpdateOption({.tryTimes_ = MAX_RETRY_COUNT});
320     it->second->Recv(move(cmd));
321     LOGI("OnDeviceP2POnline end networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
322     return P2P_SUCCESS;
323 }
324 
OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo & deviceInfo)325 int32_t DeviceManagerAgent::OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo &deviceInfo)
326 {
327     LOGI("OnDeviceP2POffline  begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
328     DeviceInfo info(deviceInfo);
329 
330     unique_lock<mutex> lock(mpToNetworksMutex_);
331     auto it = cidNetTypeRecord_.find(info.cid_);
332     if (it == cidNetTypeRecord_.end()) {
333         LOGE("cid %{public}s network is null!",  Utils::GetAnonyString(info.cid_).c_str());
334         return P2P_FAILED;
335     }
336     auto type_ = cidNetworkType_.find(info.cid_);
337     if (type_ == cidNetworkType_.end()) {
338         LOGE("cid %{public}s network type is null!",  Utils::GetAnonyString(info.cid_).c_str());
339         return P2P_FAILED;
340     }
341     auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
342         &NetworkAgentTemplate::DisconnectDeviceByP2P, info);
343     it->second->Recv(move(cmd));
344     cidNetTypeRecord_.erase(info.cid_);
345     cidNetworkType_.erase(info.cid_);
346     LOGI("OnDeviceP2POffline end");
347     return P2P_SUCCESS;
348 }
349 
MountDfsCountOnly(const std::string & deviceId)350 bool DeviceManagerAgent::MountDfsCountOnly(const std::string &deviceId)
351 {
352     if (deviceId.empty()) {
353         LOGI("deviceId empty");
354         return false;
355     }
356     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
357     auto itCount = mountDfsCount_.find(deviceId);
358     if (itCount == mountDfsCount_.end()) {
359         LOGI("mountDfsCount_ can not find key");
360         return false;
361     }
362     if (itCount->second > 0) {
363         LOGI("[MountDfsCountOnly] deviceId %{public}s has already established a link, count %{public}d, \
364             increase count by one now", Utils::GetAnonyString(deviceId).c_str(), itCount->second);
365         return true;
366     }
367     return false;
368 }
369 
UMountDfsCountOnly(const std::string & deviceId,bool needClear)370 bool DeviceManagerAgent::UMountDfsCountOnly(const std::string &deviceId, bool needClear)
371 {
372     if (deviceId.empty()) {
373         LOGI("deviceId empty");
374         return false;
375     }
376     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
377     auto itCount = mountDfsCount_.find(deviceId);
378     if (itCount == mountDfsCount_.end()) {
379         LOGI("mountDfsCount_ can not find key");
380         return true;
381     }
382     if (needClear) {
383         LOGI("mountDfsCount_ erase");
384         mountDfsCount_.erase(itCount);
385         return false;
386     }
387     if (itCount->second > MOUNT_DFS_COUNT_ONE) {
388         LOGI("[UMountDfsCountOnly] deviceId %{public}s has already established more than one link, \
389             count %{public}d, decrease count by one now",
390             Utils::GetAnonyString(deviceId).c_str(), itCount->second);
391         mountDfsCount_[deviceId]--;
392         return true;
393     }
394     LOGI("[UMountDfsCountOnly] deviceId %{public}s erase count", Utils::GetAnonyString(deviceId).c_str());
395     return false;
396 }
397 
GetCurrentUserId()398 int32_t DeviceManagerAgent::GetCurrentUserId()
399 {
400     std::vector<int32_t> userIds{};
401     auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds);
402     if (ret != NO_ERROR || userIds.empty()) {
403         LOGE("query active os account id failed, ret = %{public}d", ret);
404         return INVALID_USER_ID;
405     }
406     LOGI("DeviceManagerAgent::GetCurrentUserId end.");
407     return userIds[0];
408 }
409 
GetStorageManager()410 void DeviceManagerAgent::GetStorageManager()
411 {
412     auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
413     if (saMgr == nullptr) {
414         LOGE("GetSystemAbilityManager filed");
415         return;
416     }
417 
418     auto storageObj = saMgr->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
419     if (storageObj == nullptr) {
420         LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy");
421         return;
422     }
423 
424     storageMgrProxy_ = iface_cast<StorageManager::IStorageManager>(storageObj);
425     if (storageMgrProxy_ == nullptr) {
426         LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy!");
427         return;
428     }
429 
430     LOGI("GetStorageManager end.");
431     return;
432 }
433 
AddNetworkId(uint32_t tokenId,const std::string & networkId)434 void DeviceManagerAgent::AddNetworkId(uint32_t tokenId, const std::string &networkId)
435 {
436     LOGI("DeviceManagerAgent::AddNetworkId, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str());
437     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
438     networkIdMap_[tokenId].insert(networkId);
439 }
440 
RemoveNetworkId(uint32_t tokenId)441 void DeviceManagerAgent::RemoveNetworkId(uint32_t tokenId)
442 {
443     LOGI("DeviceManagerAgent::RemoveNetworkId start");
444     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
445     networkIdMap_.erase(tokenId);
446 }
447 
RemoveNetworkIdByOne(uint32_t tokenId,const std::string & networkId)448 void DeviceManagerAgent::RemoveNetworkIdByOne(uint32_t tokenId, const std::string &networkId)
449 {
450     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
451     auto it = networkIdMap_.find(tokenId);
452     if (it != networkIdMap_.end()) {
453         (it->second).erase(networkId);
454         if (it->second.empty()) {
455             networkIdMap_.erase(it);
456         }
457         LOGI("DeviceManagerAgent::RemoveNetworkIdByOne success, networkId: %{public}s",
458             Utils::GetAnonyString(networkId).c_str());
459     }
460 }
461 
RemoveNetworkIdForAllToken(const std::string & networkId)462 void DeviceManagerAgent::RemoveNetworkIdForAllToken(const std::string &networkId)
463 {
464     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
465     if (networkId.empty()) {
466         LOGE("networkId is empty");
467         return;
468     }
469     for (auto it = networkIdMap_.begin(); it != networkIdMap_.end();) {
470         it->second.erase(networkId);
471         if (it->second.empty()) {
472             it = networkIdMap_.erase(it);
473         } else {
474             ++it;
475         }
476         LOGI("RemoveNetworkIdForAllToken, networkId: %{public}s",
477             Utils::GetAnonyString(networkId).c_str());
478     }
479 }
480 
ClearNetworkId()481 void DeviceManagerAgent::ClearNetworkId()
482 {
483     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
484     networkIdMap_.clear();
485 }
486 
GetNetworkIds(uint32_t tokenId)487 std::unordered_set<std::string> DeviceManagerAgent::GetNetworkIds(uint32_t tokenId)
488 {
489     std::lock_guard<std::mutex> lock(networkIdMapMutex_);
490     return networkIdMap_[tokenId];
491 }
492 
MountDfsDocs(const std::string & networkId,const std::string & deviceId)493 int32_t DeviceManagerAgent::MountDfsDocs(const std::string &networkId, const std::string &deviceId)
494 {
495     LOGI("MountDfsDocs start");
496     if (networkId.empty() || deviceId.empty()) {
497         LOGE("NetworkId or DeviceId is empty");
498         return INVALID_USER_ID;
499     }
500     int32_t ret = NO_ERROR;
501     if (MountDfsCountOnly(deviceId)) {
502         LOGI("only count plus one, do not need mount");
503         IncreaseMountDfsCount(deviceId);
504         return ret;
505     }
506     int32_t userId = GetCurrentUserId();
507     if (userId == INVALID_USER_ID) {
508         LOGE("GetCurrentUserId Fail");
509         return INVALID_USER_ID;
510     }
511     GetStorageManager();
512     if (storageMgrProxy_ == nullptr) {
513         LOGE("storageMgrProxy_ is null");
514         return INVALID_USER_ID;
515     }
516     ret = storageMgrProxy_->MountDfsDocs(userId, "account", networkId, deviceId);
517     if (ret != NO_ERROR) {
518         LOGE("MountDfsDocs fail, ret = %{public}d", ret);
519     } else {
520         LOGE("MountDfsDocs success, deviceId %{public}s increase count by one now",
521             Utils::GetAnonyString(deviceId).c_str());
522         IncreaseMountDfsCount(deviceId);
523     }
524     LOGI("storageMgr.MountDfsDocs end.");
525     return ret;
526 }
527 
UMountDfsDocs(const std::string & networkId,const std::string & deviceId,bool needClear)528 int32_t DeviceManagerAgent::UMountDfsDocs(const std::string &networkId, const std::string &deviceId, bool needClear)
529 {
530     LOGI("UMountDfsDocs start in OpenP2PConnection, networkId: %{public}s, deviceId: %{public}s",
531         Utils::GetAnonyString(networkId).c_str(), Utils::GetAnonyString(deviceId).c_str());
532     if (networkId.empty() || deviceId.empty()) {
533         LOGE("NetworkId or DeviceId is empty");
534         return INVALID_USER_ID;
535     }
536     int32_t ret = NO_ERROR;
537     if (UMountDfsCountOnly(deviceId, needClear)) {
538         LOGE("do not need umount");
539         return ret;
540     }
541     int32_t userId = GetCurrentUserId();
542     if (userId == INVALID_USER_ID) {
543         LOGE("GetCurrentUserId Fail");
544         return INVALID_USER_ID;
545     }
546     GetStorageManager();
547     if (storageMgrProxy_ == nullptr) {
548         LOGE("storageMgrProxy_ is null");
549         return INVALID_USER_ID;
550     }
551     ret = storageMgrProxy_->UMountDfsDocs(userId, "account", networkId, deviceId);
552     if (ret != NO_ERROR) {
553         LOGE("UMountDfsDocs fail, ret = %{public}d", ret);
554     } else {
555         LOGE("UMountDfsDocs success, deviceId %{public}s erase count",
556             Utils::GetAnonyString(deviceId).c_str());
557         RemoveMountDfsCount(deviceId);
558     }
559     LOGI("storageMgr.UMountDfsDocs end.");
560     return ret;
561 }
562 
IncreaseMountDfsCount(const std::string & deviceId)563 void DeviceManagerAgent::IncreaseMountDfsCount(const std::string &deviceId)
564 {
565     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
566     mountDfsCount_[deviceId]++;
567 }
568 
RemoveMountDfsCount(const std::string & deviceId)569 void DeviceManagerAgent::RemoveMountDfsCount(const std::string &deviceId)
570 {
571     std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
572     mountDfsCount_.erase(deviceId);
573 }
574 
NotifyRemoteReverseObj(const std::string & networkId,int32_t status)575 void DeviceManagerAgent::NotifyRemoteReverseObj(const std::string &networkId, int32_t status)
576 {
577     std::lock_guard<std::mutex> lock(appCallConnectMutex_);
578     for (auto it = appCallConnect_.begin(); it != appCallConnect_.end(); ++it) {
579         auto onstatusReverseProxy = it->second;
580         if (onstatusReverseProxy == nullptr) {
581             LOGI("get onstatusReverseProxy fail");
582             return;
583         }
584         onstatusReverseProxy->OnStatus(networkId, status);
585         LOGI("NotifyRemoteReverseObj, deviceId: %{public}s", Utils::GetAnonyString(networkId).c_str());
586     }
587 }
588 
AddRemoteReverseObj(uint32_t callingTokenId,sptr<IFileDfsListener> remoteReverseObj)589 int32_t DeviceManagerAgent::AddRemoteReverseObj(uint32_t callingTokenId, sptr<IFileDfsListener> remoteReverseObj)
590 {
591     std::lock_guard<std::mutex> lock(appCallConnectMutex_);
592     auto it = appCallConnect_.find(callingTokenId);
593     if (it != appCallConnect_.end()) {
594         LOGE("AddRemoteReverseObj fail");
595         return FileManagement::E_INVAL_ARG;
596     }
597     appCallConnect_[callingTokenId] = remoteReverseObj;
598     LOGI("DeviceManagerAgent::AddRemoteReverseObj::add new value suceess");
599     return FileManagement::E_OK;
600 }
601 
RemoveRemoteReverseObj(bool clear,uint32_t callingTokenId)602 int32_t DeviceManagerAgent::RemoveRemoteReverseObj(bool clear, uint32_t callingTokenId)
603 {
604     LOGI("DeviceManagerAgent::RemoveRemoteReverseObj called");
605     if (clear) {
606         appCallConnect_.clear();
607         return FileManagement::E_OK;
608     }
609 
610     auto it = appCallConnect_.find(callingTokenId);
611     if (it == appCallConnect_.end()) {
612         LOGE("RemoveRemoteReverseObj fail");
613         return FileManagement::E_INVAL_ARG;
614     }
615     appCallConnect_.erase(it);
616     LOGI("DeviceManagerAgent::RemoveRemoteReverseObj end");
617     return FileManagement::E_OK;
618 }
619 
FindListenerByObject(const wptr<IRemoteObject> & remote,uint32_t & tokenId,sptr<IFileDfsListener> & listener)620 int32_t DeviceManagerAgent::FindListenerByObject(const wptr<IRemoteObject> &remote,
621                                                  uint32_t &tokenId, sptr<IFileDfsListener>& listener)
622 {
623     std::lock_guard<std::mutex> lock(appCallConnectMutex_);
624     for (auto it = appCallConnect_.begin(); it != appCallConnect_.end(); ++it) {
625         if (remote != (it->second)->AsObject()) {
626             continue;
627         }
628         tokenId = it->first;
629         listener = it->second;
630         return FileManagement::E_OK;
631     }
632     return FileManagement::E_INVAL_ARG;
633 }
634 
GetDeviceIdByNetworkId(const std::string & networkId)635 std::string DeviceManagerAgent::GetDeviceIdByNetworkId(const std::string &networkId)
636 {
637     LOGI("DeviceManagerAgent::GetDeviceIdByNetworkId called");
638     if (networkId.empty()) {
639         return "";
640     }
641     std::vector<DistributedHardware::DmDeviceInfo> deviceList;
642     DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(IDaemon::SERVICE_NAME, "", deviceList);
643     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
644         LOGE("the size of trust device list is invalid, size=%zu", deviceList.size());
645         return "";
646     }
647     std::string deviceId = "";
648     for (const auto &device : deviceList) {
649         if (std::string(device.networkId) == networkId) {
650             deviceId = std::string(device.deviceId);
651         }
652     }
653     LOGI("DeviceManagerAgent::GetDeviceIdByNetworkId end");
654     return deviceId;
655 }
656 
from_json(const nlohmann::json & jsonObject,GroupInfo & groupInfo)657 void from_json(const nlohmann::json &jsonObject, GroupInfo &groupInfo)
658 {
659     if (jsonObject.find(FIELD_GROUP_NAME) != jsonObject.end() && jsonObject[FIELD_GROUP_NAME].is_string()) {
660         groupInfo.groupName = jsonObject.at(FIELD_GROUP_NAME).get<std::string>();
661     }
662 
663     if (jsonObject.find(FIELD_GROUP_ID) != jsonObject.end() && jsonObject[FIELD_GROUP_ID].is_string()) {
664         groupInfo.groupId = jsonObject.at(FIELD_GROUP_ID).get<std::string>();
665     }
666 
667     if (jsonObject.find(FIELD_GROUP_OWNER) != jsonObject.end() && jsonObject[FIELD_GROUP_OWNER].is_string()) {
668         groupInfo.groupOwner = jsonObject.at(FIELD_GROUP_OWNER).get<std::string>();
669     }
670 
671     if (jsonObject.find(FIELD_GROUP_TYPE) != jsonObject.end() && jsonObject[FIELD_GROUP_TYPE].is_number()) {
672         groupInfo.groupType = jsonObject.at(FIELD_GROUP_TYPE).get<int32_t>();
673     }
674 }
675 
QueryRelatedGroups(const std::string & udid,const std::string & networkId)676 void DeviceManagerAgent::QueryRelatedGroups(const std::string &udid, const std::string &networkId)
677 {
678     auto network = FindNetworkBaseTrustRelation(false);
679     if (network != nullptr) {
680         cidNetTypeRecord_.insert({ networkId, network });
681         cidNetworkType_.insert({ networkId, GetNetworkType(networkId) });
682     }
683 }
684 
CheckIsAccountless(const GroupInfo & group)685 bool DeviceManagerAgent::CheckIsAccountless(const GroupInfo &group)
686 {
687     // because of there no same_account, only for test, del later
688     LOGI("SAME_ACCOUNT_MARK val is %{public}d", system::GetBoolParameter(SAME_ACCOUNT_MARK, false));
689     if (system::GetBoolParameter(SAME_ACCOUNT_MARK, false) == true) { // isaccountless == false
690         LOGI("SAME_ACCOUNT_MARK val is true(same account)");
691         return false;
692     } else { // isaccountless == true
693         return true;
694     }
695 
696     if (group.groupType == PEER_TO_PEER_GROUP || group.groupType == ACROSS_ACCOUNT_AUTHORIZE_GROUP) {
697         return true;
698     }
699     return false;
700 }
701 
OnDeviceChanged(const DistributedHardware::DmDeviceInfo & deviceInfo)702 void DeviceManagerAgent::OnDeviceChanged(const DistributedHardware::DmDeviceInfo &deviceInfo)
703 {
704     LOGI("OnDeviceInfoChanged  begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
705     if (deviceInfo.networkType == -1) {
706         LOGI("OnDeviceInfoChanged end");
707         return;
708     }
709     int32_t ret = IsSupportedDevice(deviceInfo);
710     if (ret != FileManagement::ERR_OK) {
711         LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
712         return;
713     }
714 
715     DeviceInfo info(deviceInfo);
716     unique_lock<mutex> lock(mpToNetworksMutex_);
717 
718     auto it = cidNetTypeRecord_.find(info.cid_);
719     if (it == cidNetTypeRecord_.end()) {
720         LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
721         LOGI("OnDeviceInfoChanged end");
722         return;
723     }
724 
725     auto type_ = cidNetworkType_.find(info.cid_);
726     if (type_ == cidNetworkType_.end()) {
727         LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
728         LOGI("OnDeviceInfoChanged end");
729         return;
730     }
731 
732     int32_t oldNetworkType = type_->second;
733     int32_t newNetworkType = type_->second = deviceInfo.networkType;
734     LOGI("oldNetworkType %{public}d, newNetworkType %{public}d", oldNetworkType, newNetworkType);
735     LOGI("OnDeviceInfoChanged end");
736 }
737 
InitDeviceInfos()738 void DeviceManagerAgent::InitDeviceInfos()
739 {
740     string extra = "";
741     string pkgName = IDaemon::SERVICE_NAME;
742     vector<DistributedHardware::DmDeviceInfo> deviceInfoList;
743 
744     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
745     int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceInfoList);
746     if (errCode) {
747         ThrowException(errCode, "Failed to get info of remote devices");
748     }
749 
750     for (const auto &deviceInfo : deviceInfoList) {
751         int32_t ret = IsSupportedDevice(deviceInfo);
752         if (ret != FileManagement::ERR_OK) {
753             LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
754             continue;
755         }
756         DeviceInfo info(deviceInfo);
757         QueryRelatedGroups(info.udid_, info.cid_);
758     }
759 }
760 
IsSupportedDevice(const DistributedHardware::DmDeviceInfo & deviceInfo)761 int32_t DeviceManagerAgent::IsSupportedDevice(const DistributedHardware::DmDeviceInfo &deviceInfo)
762 {
763     std::vector<DistributedHardware::DmDeviceInfo> deviceList;
764     DistributedHardware::DeviceManager::GetInstance().GetTrustedDeviceList(IDaemon::SERVICE_NAME, "", deviceList);
765     if (deviceList.size() == 0 || deviceList.size() > MAX_ONLINE_DEVICE_SIZE) {
766         LOGE("trust device list size is invalid, size=%zu", deviceList.size());
767         return FileManagement::ERR_BAD_VALUE;
768     }
769     DistributedHardware::DmDeviceInfo infoTemp;
770     for (const auto &info : deviceList) {
771         if (std::string_view(info.networkId) == std::string_view(deviceInfo.networkId)) {
772             infoTemp = info;
773             break;
774         }
775     }
776 
777     if (infoTemp.extraData.empty()) {
778         LOGE("extraData is empty");
779         RADAR_REPORT(RadarReporter::DFX_SET_DFS, RadarReporter::DFX_BUILD__LINK, RadarReporter::DFX_FAILED,
780             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
781             RadarReporter::GET_SAME_ACCOUNT_ERROR, RadarReporter::PACKAGE_NAME, RadarReporter::deviceManager);
782         return FileManagement::ERR_BAD_VALUE;
783     }
784     nlohmann::json entraDataJson = nlohmann::json::parse(infoTemp.extraData, nullptr, false);
785     if (entraDataJson.is_discarded()) {
786         LOGE("entraDataJson parse failed.");
787         return FileManagement::ERR_BAD_VALUE;
788     }
789     if (!Utils::IsInt32(entraDataJson, PARAM_KEY_OS_TYPE)) {
790         LOGE("error json int32_t param.");
791         return FileManagement::ERR_BAD_VALUE;
792     }
793     int32_t osType = entraDataJson[PARAM_KEY_OS_TYPE].get<int32_t>();
794     if (osType != DEVICE_OS_TYPE_OH) {
795         LOGE("%{private}s  the device os type = %{private}d is not openharmony.",
796             Utils::GetAnonyString(infoTemp.deviceId).c_str(), osType);
797         return FileManagement::ERR_BAD_VALUE;
798     }
799     return FileManagement::ERR_OK;
800 }
801 
InitLocalNodeInfo()802 void DeviceManagerAgent::InitLocalNodeInfo()
803 {
804     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
805     DistributedHardware::DmDeviceInfo localDeviceInfo{};
806     int errCode = deviceManager.GetLocalDeviceInfo(IDaemon::SERVICE_NAME, localDeviceInfo);
807     if (errCode != 0) {
808         ThrowException(errCode, "Failed to get info of local devices");
809     }
810     localDeviceInfo_.SetCid(string(localDeviceInfo.networkId));
811 }
812 
OnRemoteDied()813 void DeviceManagerAgent::OnRemoteDied()
814 {
815     LOGI("device manager service died");
816 }
817 
GetLocalDeviceInfo()818 DeviceInfo &DeviceManagerAgent::GetLocalDeviceInfo()
819 {
820     return localDeviceInfo_;
821 }
822 
GetRemoteDevicesInfo()823 vector<DeviceInfo> DeviceManagerAgent::GetRemoteDevicesInfo()
824 {
825     string extra = "";
826     string pkgName = IDaemon::SERVICE_NAME;
827     vector<DistributedHardware::DmDeviceInfo> deviceList;
828 
829     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
830     int errCode = deviceManager.GetTrustedDeviceList(pkgName, extra, deviceList);
831     if (errCode) {
832         ThrowException(errCode, "Failed to get info of remote devices");
833     }
834 
835     vector<DeviceInfo> res;
836     for (const auto &item : deviceList) {
837         res.push_back(DeviceInfo(item));
838     }
839     return res;
840 }
841 
RegisterToExternalDm()842 void DeviceManagerAgent::RegisterToExternalDm()
843 {
844     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
845     string pkgName = IDaemon::SERVICE_NAME;
846     int errCode = deviceManager.InitDeviceManager(pkgName, shared_from_this());
847     if (errCode != 0) {
848         ThrowException(errCode, "Failed to InitDeviceManager");
849     }
850     string extra = "";
851     errCode = deviceManager.RegisterDevStateCallback(pkgName, extra, shared_from_this());
852     if (errCode != 0) {
853         ThrowException(errCode, "Failed to RegisterDevStateCallback");
854     }
855     LOGI("RegisterToExternalDm Succeed");
856 }
857 
UnregisterFromExternalDm()858 void DeviceManagerAgent::UnregisterFromExternalDm()
859 {
860     auto &deviceManager = DistributedHardware::DeviceManager::GetInstance();
861     string pkgName = IDaemon::SERVICE_NAME;
862     int errCode = deviceManager.UnRegisterDevStateCallback(pkgName);
863     if (errCode != 0) {
864         ThrowException(errCode, "Failed to UnRegisterDevStateCallback");
865     }
866     errCode = deviceManager.UnInitDeviceManager(pkgName);
867     if (errCode != 0) {
868         ThrowException(errCode, "Failed to UnInitDeviceManager");
869     }
870     LOGI("UnregisterFromExternalDm Succeed");
871 }
872 } // namespace DistributedFile
873 } // namespace Storage
874 } // namespace OHOS
875