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