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 UMountDfsDocs(networkId, deviceId, true);
271 }
272
273 auto cmd2 = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
274 &NetworkAgentTemplate::DisconnectDeviceByP2PHmdfs, info);
275 it->second->Recv(move(cmd2));
276
277 cidNetTypeRecord_.erase(info.cid_);
278 cidNetworkType_.erase(info.cid_);
279 LOGI("OnDeviceOffline end");
280 }
281
ClearCount(const DistributedHardware::DmDeviceInfo & deviceInfo)282 void DeviceManagerAgent::ClearCount(const DistributedHardware::DmDeviceInfo &deviceInfo)
283 {
284 LOGI("ClearCount networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
285 DeviceInfo info(deviceInfo);
286 unique_lock<mutex> lock(mpToNetworksMutex_);
287 auto it = cidNetTypeRecord_.find(info.cid_);
288 if (it == cidNetTypeRecord_.end()) {
289 LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
290 return;
291 }
292 it->second->DisconnectDeviceByP2P(info);
293 }
294
OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo & deviceInfo)295 int32_t DeviceManagerAgent::OnDeviceP2POnline(const DistributedHardware::DmDeviceInfo &deviceInfo)
296 {
297 LOGI("[OnDeviceP2POnline] networkId %{public}s, OnDeviceOnline begin",
298 Utils::GetAnonyString(deviceInfo.networkId).c_str());
299 int32_t ret = IsSupportedDevice(deviceInfo);
300 if (ret != FileManagement::ERR_OK) {
301 LOGI("not support device, networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
302 return P2P_FAILED;
303 }
304 DeviceInfo info(deviceInfo);
305 QueryRelatedGroups(info.udid_, info.cid_);
306
307 unique_lock<mutex> lock(mpToNetworksMutex_);
308 auto it = cidNetTypeRecord_.find(info.cid_);
309 if (it == cidNetTypeRecord_.end()) {
310 LOGE("[OnDeviceP2POnline] cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
311 return P2P_FAILED;
312 }
313 auto type_ = cidNetworkType_.find(info.cid_);
314 if (type_ == cidNetworkType_.end()) {
315 LOGE("[OnDeviceP2POnline] cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
316 return P2P_FAILED;
317 }
318 auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
319 &NetworkAgentTemplate::ConnectDeviceByP2PAsync, info);
320 cmd->UpdateOption({.tryTimes_ = MAX_RETRY_COUNT});
321 it->second->Recv(move(cmd));
322 LOGI("OnDeviceP2POnline end networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
323 return P2P_SUCCESS;
324 }
325
OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo & deviceInfo)326 int32_t DeviceManagerAgent::OnDeviceP2POffline(const DistributedHardware::DmDeviceInfo &deviceInfo)
327 {
328 LOGI("OnDeviceP2POffline begin networkId %{public}s", Utils::GetAnonyString(deviceInfo.networkId).c_str());
329 DeviceInfo info(deviceInfo);
330
331 unique_lock<mutex> lock(mpToNetworksMutex_);
332 auto it = cidNetTypeRecord_.find(info.cid_);
333 if (it == cidNetTypeRecord_.end()) {
334 LOGE("cid %{public}s network is null!", Utils::GetAnonyString(info.cid_).c_str());
335 return P2P_FAILED;
336 }
337 auto type_ = cidNetworkType_.find(info.cid_);
338 if (type_ == cidNetworkType_.end()) {
339 LOGE("cid %{public}s network type is null!", Utils::GetAnonyString(info.cid_).c_str());
340 return P2P_FAILED;
341 }
342 auto cmd = make_unique<DfsuCmd<NetworkAgentTemplate, const DeviceInfo>>(
343 &NetworkAgentTemplate::DisconnectDeviceByP2P, info);
344 it->second->Recv(move(cmd));
345 cidNetTypeRecord_.erase(info.cid_);
346 cidNetworkType_.erase(info.cid_);
347 LOGI("OnDeviceP2POffline end");
348 return P2P_SUCCESS;
349 }
350
MountDfsCountOnly(const std::string & deviceId)351 bool DeviceManagerAgent::MountDfsCountOnly(const std::string &deviceId)
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 false;
362 }
363 if (itCount->second > 0) {
364 LOGI("[MountDfsCountOnly] deviceId %{public}s has already established a link, count %{public}d, \
365 increase count by one now", Utils::GetAnonyString(deviceId).c_str(), itCount->second);
366 return true;
367 }
368 return false;
369 }
370
UMountDfsCountOnly(const std::string & deviceId,bool needClear)371 bool DeviceManagerAgent::UMountDfsCountOnly(const std::string &deviceId, bool needClear)
372 {
373 if (deviceId.empty()) {
374 LOGI("deviceId empty");
375 return false;
376 }
377 std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
378 auto itCount = mountDfsCount_.find(deviceId);
379 if (itCount == mountDfsCount_.end()) {
380 LOGI("mountDfsCount_ can not find key");
381 return true;
382 }
383 if (needClear) {
384 LOGI("mountDfsCount_ erase");
385 mountDfsCount_.erase(itCount);
386 return false;
387 }
388 if (itCount->second > MOUNT_DFS_COUNT_ONE) {
389 LOGI("[UMountDfsCountOnly] deviceId %{public}s has already established more than one link, \
390 count %{public}d, decrease count by one now",
391 Utils::GetAnonyString(deviceId).c_str(), itCount->second);
392 mountDfsCount_[deviceId]--;
393 return true;
394 }
395 LOGI("[UMountDfsCountOnly] deviceId %{public}s erase count", Utils::GetAnonyString(deviceId).c_str());
396 return false;
397 }
398
GetCurrentUserId()399 int32_t DeviceManagerAgent::GetCurrentUserId()
400 {
401 std::vector<int32_t> userIds{};
402 auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(userIds);
403 if (ret != NO_ERROR || userIds.empty()) {
404 LOGE("query active os account id failed, ret = %{public}d", ret);
405 return INVALID_USER_ID;
406 }
407 LOGI("DeviceManagerAgent::GetCurrentUserId end.");
408 return userIds[0];
409 }
410
GetStorageManager()411 void DeviceManagerAgent::GetStorageManager()
412 {
413 auto saMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
414 if (saMgr == nullptr) {
415 LOGE("GetSystemAbilityManager filed");
416 return;
417 }
418
419 auto storageObj = saMgr->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
420 if (storageObj == nullptr) {
421 LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy");
422 return;
423 }
424
425 storageMgrProxy_ = iface_cast<StorageManager::IStorageManager>(storageObj);
426 if (storageMgrProxy_ == nullptr) {
427 LOGE("filed to get STORAGE_MANAGER_MANAGER_ID proxy!");
428 return;
429 }
430
431 LOGI("GetStorageManager end.");
432 return;
433 }
434
AddNetworkId(uint32_t tokenId,const std::string & networkId)435 void DeviceManagerAgent::AddNetworkId(uint32_t tokenId, const std::string &networkId)
436 {
437 LOGI("DeviceManagerAgent::AddNetworkId, networkId: %{public}s", Utils::GetAnonyString(networkId).c_str());
438 std::lock_guard<std::mutex> lock(networkIdMapMutex_);
439 networkIdMap_[tokenId].insert(networkId);
440 }
441
RemoveNetworkId(uint32_t tokenId)442 void DeviceManagerAgent::RemoveNetworkId(uint32_t tokenId)
443 {
444 LOGI("DeviceManagerAgent::RemoveNetworkId start");
445 std::lock_guard<std::mutex> lock(networkIdMapMutex_);
446 networkIdMap_.erase(tokenId);
447 }
448
RemoveNetworkIdByOne(uint32_t tokenId,const std::string & networkId)449 void DeviceManagerAgent::RemoveNetworkIdByOne(uint32_t tokenId, const std::string &networkId)
450 {
451 std::lock_guard<std::mutex> lock(networkIdMapMutex_);
452 auto it = networkIdMap_.find(tokenId);
453 if (it != networkIdMap_.end()) {
454 (it->second).erase(networkId);
455 if (it->second.empty()) {
456 networkIdMap_.erase(it);
457 }
458 LOGI("DeviceManagerAgent::RemoveNetworkIdByOne success, networkId: %{public}s",
459 Utils::GetAnonyString(networkId).c_str());
460 }
461 }
462
RemoveNetworkIdForAllToken(const std::string & networkId)463 void DeviceManagerAgent::RemoveNetworkIdForAllToken(const std::string &networkId)
464 {
465 std::lock_guard<std::mutex> lock(networkIdMapMutex_);
466 if (networkId.empty()) {
467 LOGE("networkId is empty");
468 return;
469 }
470 for (auto it = networkIdMap_.begin(); it != networkIdMap_.end();) {
471 it->second.erase(networkId);
472 if (it->second.empty()) {
473 it = networkIdMap_.erase(it);
474 } else {
475 ++it;
476 }
477 LOGI("RemoveNetworkIdForAllToken, networkId: %{public}s",
478 Utils::GetAnonyString(networkId).c_str());
479 }
480 }
481
ClearNetworkId()482 void DeviceManagerAgent::ClearNetworkId()
483 {
484 std::lock_guard<std::mutex> lock(networkIdMapMutex_);
485 networkIdMap_.clear();
486 }
487
GetNetworkIds(uint32_t tokenId)488 std::unordered_set<std::string> DeviceManagerAgent::GetNetworkIds(uint32_t tokenId)
489 {
490 std::lock_guard<std::mutex> lock(networkIdMapMutex_);
491 return networkIdMap_[tokenId];
492 }
493
MountDfsDocs(const std::string & networkId,const std::string & deviceId)494 int32_t DeviceManagerAgent::MountDfsDocs(const std::string &networkId, const std::string &deviceId)
495 {
496 LOGI("MountDfsDocs start");
497 if (networkId.empty() || deviceId.empty()) {
498 LOGE("NetworkId or DeviceId is empty");
499 return INVALID_USER_ID;
500 }
501 int32_t ret = NO_ERROR;
502 if (MountDfsCountOnly(deviceId)) {
503 LOGI("only count plus one, do not need mount");
504 IncreaseMountDfsCount(deviceId);
505 return ret;
506 }
507 int32_t userId = GetCurrentUserId();
508 if (userId == INVALID_USER_ID) {
509 LOGE("GetCurrentUserId Fail");
510 return INVALID_USER_ID;
511 }
512 GetStorageManager();
513 if (storageMgrProxy_ == nullptr) {
514 LOGE("storageMgrProxy_ is null");
515 return INVALID_USER_ID;
516 }
517 ret = storageMgrProxy_->MountDfsDocs(userId, "account", networkId, deviceId);
518 if (ret != NO_ERROR) {
519 LOGE("MountDfsDocs fail, ret = %{public}d", ret);
520 } else {
521 LOGE("MountDfsDocs success, deviceId %{public}s increase count by one now",
522 Utils::GetAnonyString(deviceId).c_str());
523 IncreaseMountDfsCount(deviceId);
524 }
525 LOGI("storageMgr.MountDfsDocs end.");
526 return ret;
527 }
528
UMountDfsDocs(const std::string & networkId,const std::string & deviceId,bool needClear)529 int32_t DeviceManagerAgent::UMountDfsDocs(const std::string &networkId, const std::string &deviceId, bool needClear)
530 {
531 LOGI("UMountDfsDocs start in OpenP2PConnection, networkId: %{public}s, deviceId: %{public}s",
532 Utils::GetAnonyString(networkId).c_str(), Utils::GetAnonyString(deviceId).c_str());
533 if (networkId.empty() || deviceId.empty()) {
534 LOGE("NetworkId or DeviceId is empty");
535 return INVALID_USER_ID;
536 }
537 int32_t ret = NO_ERROR;
538 if (UMountDfsCountOnly(deviceId, needClear)) {
539 LOGE("do not need umount");
540 return ret;
541 }
542 int32_t userId = GetCurrentUserId();
543 if (userId == INVALID_USER_ID) {
544 LOGE("GetCurrentUserId Fail");
545 return INVALID_USER_ID;
546 }
547 GetStorageManager();
548 if (storageMgrProxy_ == nullptr) {
549 LOGE("storageMgrProxy_ is null");
550 return INVALID_USER_ID;
551 }
552 ret = storageMgrProxy_->UMountDfsDocs(userId, "account", networkId, deviceId);
553 if (ret != NO_ERROR) {
554 LOGE("UMountDfsDocs fail, ret = %{public}d", ret);
555 } else {
556 LOGE("UMountDfsDocs success, deviceId %{public}s erase count",
557 Utils::GetAnonyString(deviceId).c_str());
558 RemoveMountDfsCount(deviceId);
559 }
560 LOGI("storageMgr.UMountDfsDocs end.");
561 return ret;
562 }
563
IncreaseMountDfsCount(const std::string & deviceId)564 void DeviceManagerAgent::IncreaseMountDfsCount(const std::string &deviceId)
565 {
566 std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
567 mountDfsCount_[deviceId]++;
568 }
569
RemoveMountDfsCount(const std::string & deviceId)570 void DeviceManagerAgent::RemoveMountDfsCount(const std::string &deviceId)
571 {
572 std::lock_guard<std::mutex> lock(mountDfsCountMutex_);
573 mountDfsCount_.erase(deviceId);
574 }
575
NotifyRemoteReverseObj(const std::string & networkId,int32_t status)576 void DeviceManagerAgent::NotifyRemoteReverseObj(const std::string &networkId, int32_t status)
577 {
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