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