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