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