• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "device/distributed_module_config.h"
16 
17 #include <thread>
18 #include "device/dev_profile.h"
19 #include "pasteboard_error.h"
20 #include "pasteboard_hilog.h"
21 
22 namespace OHOS {
23 namespace MiscServices {
24 constexpr uint32_t RETRY_TIMES = 30;
25 constexpr uint32_t RETRY_INTERVAL = 1000; // milliseconds
26 constexpr uint32_t RANDOM_MAX = 500;
27 constexpr uint32_t RANDOM_MIN = 5;
IsOn()28 bool DistributedModuleConfig::IsOn()
29 {
30     if (GetDeviceNum() != 0) {
31         Notify();
32     }
33     return status_;
34 }
35 
Watch(const Observer & observer)36 void DistributedModuleConfig::Watch(const Observer &observer)
37 {
38     observer_ = std::move(observer);
39 }
40 
Notify()41 void DistributedModuleConfig::Notify()
42 {
43     auto status = GetEnabledStatus();
44     if (status == static_cast<int32_t>(PasteboardError::DP_LOAD_SERVICE_ERROR)) {
45         if (!retrying_.exchange(true)) {
46             GetRetryTask();
47         }
48         return;
49     }
50     bool newStatus = (status == static_cast<int32_t>(PasteboardError::E_OK));
51     if (newStatus != status_) {
52         status_ = newStatus;
53         if (observer_ != nullptr) {
54             observer_(newStatus);
55         }
56     }
57 }
58 
GetRetryTask()59 void DistributedModuleConfig::GetRetryTask()
60 {
61     std::thread remover([this]() {
62         retrying_.store(true);
63         uint32_t retry = 0;
64         auto status = static_cast<int32_t>(PasteboardError::REMOTE_TASK_ERROR);
65         while (retry < RETRY_TIMES) {
66             ++retry;
67             status = GetEnabledStatus();
68             if (status == static_cast<int32_t>(PasteboardError::DP_LOAD_SERVICE_ERROR)) {
69                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
70                     "dp load err, retry:%{public}d, status_:%{public}d"
71                     "newStatus:%{public}d",
72                     retry, status_, status);
73                 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL));
74                 continue;
75             }
76             break;
77         }
78         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE,
79             "Retry end. count:%{public}d, status_:%{public}d"
80             "newStatus:%{public}d",
81             retry, status_, status);
82         bool newStatus = (status == static_cast<int32_t>(PasteboardError::E_OK));
83         if (newStatus != status_) {
84             status_ = newStatus;
85             if (observer_ != nullptr) {
86                 observer_(newStatus);
87             }
88         }
89         retrying_.store(false);
90     });
91     remover.detach();
92 }
93 
GetDeviceNum()94 size_t DistributedModuleConfig::GetDeviceNum()
95 {
96     auto networkIds = DMAdapter::GetInstance().GetNetworkIds();
97     return networkIds.size();
98 }
99 
GetEnabledStatus()100 int32_t DistributedModuleConfig::GetEnabledStatus()
101 {
102     auto localNetworkId = DMAdapter::GetInstance().GetLocalNetworkId();
103     bool localEnable = false;
104     auto status = DevProfile::GetInstance().GetDeviceStatus(localNetworkId, localEnable);
105     if (status != static_cast<int32_t>(PasteboardError::E_OK) || !localEnable) {
106         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetLocalEnable false, ret:%{public}d, switch:%{public}d",
107             status, localEnable);
108         return static_cast<int32_t>(PasteboardError::LOCAL_SWITCH_NOT_TURNED_ON);
109     }
110     auto networkIds = DMAdapter::GetInstance().GetNetworkIds();
111     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "device online nums: %{public}zu", networkIds.size());
112     for (auto &id : networkIds) {
113         bool remoteEnable = false;
114         auto res = DevProfile::GetInstance().GetDeviceStatus(id, remoteEnable);
115         if (res == static_cast<int32_t>(PasteboardError::E_OK) && remoteEnable) {
116             return static_cast<int32_t>(PasteboardError::E_OK);
117         }
118     }
119     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "remoteEnabledStatus is false.");
120     return static_cast<int32_t>(PasteboardError::NO_TRUST_DEVICE_ERROR);
121 }
122 
GetRemoteDeviceMinVersion()123 uint32_t DistributedModuleConfig::GetRemoteDeviceMinVersion()
124 {
125     auto [minVersion, maxVersion] = GetRemoteDeviceVersion();
126     return minVersion;
127 }
128 
GetRemoteDeviceMaxVersion()129 uint32_t DistributedModuleConfig::GetRemoteDeviceMaxVersion()
130 {
131     auto [minVersion, maxVersion] = GetRemoteDeviceVersion();
132     return maxVersion;
133 }
134 
GetRemoteDeviceVersion()135 std::pair<uint32_t, uint32_t> DistributedModuleConfig::GetRemoteDeviceVersion()
136 {
137     uint32_t minVersion = UINT_MAX;
138     uint32_t maxVersion = 0;
139 
140     const auto &networkIds = DMAdapter::GetInstance().GetNetworkIds();
141     for (const auto &networkId : networkIds) {
142         bool remoteEnable = false;
143         auto res = DevProfile::GetInstance().GetDeviceStatus(networkId, remoteEnable);
144         if (res != static_cast<int32_t>(PasteboardError::E_OK) || !remoteEnable) {
145             continue;
146         }
147 
148         uint32_t deviceVersion = 0;
149         if (!DevProfile::GetInstance().GetDeviceVersion(networkId, deviceVersion)) {
150             continue;
151         }
152 
153         minVersion = minVersion < deviceVersion ? minVersion : deviceVersion;
154         maxVersion = maxVersion > deviceVersion ? maxVersion : deviceVersion;
155     }
156     return std::make_pair(minVersion, maxVersion);
157 }
158 
Online(const std::string & device)159 void DistributedModuleConfig::Online(const std::string &device)
160 {
161     srand(time(nullptr));
162     std::this_thread::sleep_for(std::chrono::milliseconds((int32_t(rand() % (RANDOM_MAX - RANDOM_MIN)))));
163     DevProfile::GetInstance().SubscribeProfileEvent(device);
164     bool remoteEnable = false;
165     DevProfile::GetInstance().GetDeviceStatus(device, remoteEnable);
166     Notify();
167 }
168 
Offline(const std::string & device)169 void DistributedModuleConfig::Offline(const std::string &device)
170 {
171     srand(time(nullptr));
172     std::this_thread::sleep_for(std::chrono::milliseconds((int32_t(rand() % (RANDOM_MAX - RANDOM_MIN)))));
173     DevProfile::GetInstance().UnSubscribeProfileEvent(device);
174     std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(device);
175     DevProfile::GetInstance().EraseEnabledStatus(udid);
176     Notify();
177 }
178 
OnReady(const std::string & device)179 void DistributedModuleConfig::OnReady(const std::string &device)
180 {
181     (void)device;
182 }
183 
Init()184 void DistributedModuleConfig::Init()
185 {
186     DMAdapter::GetInstance().Register(this);
187     DevProfile::GetInstance().Watch([this](bool isEnable) -> void {
188         Notify();
189     });
190 }
191 
DeInit()192 void DistributedModuleConfig::DeInit()
193 {
194     DMAdapter::GetInstance().Unregister(this);
195 }
196 
197 } // namespace MiscServices
198 } // namespace OHOS