1 /*
2  * Copyright (C) 2022-2023 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 "distributed_module_config.h"
16 #include "dev_profile.h"
17 #include "pasteboard_error.h"
18 #include "pasteboard_hilog.h"
19 #include <thread>
20 
21 namespace OHOS {
22 namespace MiscServices {
IsOn()23 bool DistributedModuleConfig::IsOn()
24 {
25     if (GetDeviceNum() != 0) {
26         Notify();
27     }
28     return status_;
29 }
30 
Watch(Observer observer)31 void DistributedModuleConfig::Watch(Observer observer)
32 {
33     observer_ = std::move(observer);
34 }
35 
Notify()36 void DistributedModuleConfig::Notify()
37 {
38     auto status = GetEnabledStatus();
39     if (status == static_cast<int32_t>(PasteboardError::DP_LOAD_SERVICE_ERROR)) {
40         if (!retrying_.exchange(true)) {
41             GetRetryTask();
42         }
43         return;
44     }
45     bool newStatus = (status == static_cast<int32_t>(PasteboardError::E_OK));
46     if (newStatus != status_) {
47         status_ = newStatus;
48         if (observer_ != nullptr) {
49             observer_(newStatus);
50         }
51     }
52 }
53 
GetRetryTask()54 void DistributedModuleConfig::GetRetryTask()
55 {
56     std::thread remover([this]() {
57         retrying_.store(true);
58         uint32_t retry = 0;
59         auto status = static_cast<int32_t>(PasteboardError::REMOTE_TASK_ERROR);
60         while (retry < RETRY_TIMES) {
61             ++retry;
62             status = GetEnabledStatus();
63             if (status == static_cast<int32_t>(PasteboardError::DP_LOAD_SERVICE_ERROR)) {
64                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "dp load err, retry:%{public}d, status_:%{public}d"
65                     "newStatus:%{public}d", retry, status_, status);
66                 std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_INTERVAL));
67                 continue;
68             }
69             break;
70         }
71         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Retry end. count:%{public}d, status_:%{public}d"
72             "newStatus:%{public}d", retry, status_, status);
73         bool newStatus = (status == static_cast<int32_t>(PasteboardError::E_OK));
74         if (newStatus != status_) {
75             status_ = newStatus;
76             if (observer_ != nullptr) {
77                 observer_(newStatus);
78             }
79         }
80         retrying_.store(false);
81     });
82     remover.detach();
83 }
84 
GetDeviceNum()85 size_t DistributedModuleConfig::GetDeviceNum()
86 {
87     auto networkIds = DMAdapter::GetInstance().GetNetworkIds();
88     return networkIds.size();
89 }
90 
GetEnabledStatus()91 int32_t DistributedModuleConfig::GetEnabledStatus()
92 {
93     auto localNetworkId = DMAdapter::GetInstance().GetLocalNetworkId();
94     auto status = DevProfile::GetInstance().GetEnabledStatus(localNetworkId);
95     if (status.first != static_cast<int32_t>(PasteboardError::E_OK) || status.second != SUPPORT_STATUS) {
96         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetLocalEnable false, status:%{public}d, switch:%{public}s",
97             status.first, status.second.c_str());
98         return static_cast<int32_t>(PasteboardError::LOCAL_SWITCH_NOT_TURNED_ON);
99     }
100     auto networkIds = DMAdapter::GetInstance().GetNetworkIds();
101     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "device online nums: %{public}zu", networkIds.size());
102     for (auto &id : networkIds) {
103         auto res = DevProfile::GetInstance().GetEnabledStatus(id);
104         if (res.first == static_cast<int32_t>(PasteboardError::E_OK) && res.second == SUPPORT_STATUS) {
105             return static_cast<int32_t>(PasteboardError::E_OK);
106         }
107     }
108     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "remoteEnabledStatus is false.");
109     return static_cast<int32_t>(PasteboardError::NO_TRUST_DEVICE_ERROR);
110 }
111 
Online(const std::string & device)112 void DistributedModuleConfig::Online(const std::string &device)
113 {
114     std::this_thread::sleep_for(std::chrono::milliseconds((int32_t(rand() % (RANDOM_MAX - RANDOM_MIN)))));
115     DevProfile::GetInstance().SubscribeProfileEvent(device);
116     Notify();
117 }
118 
Offline(const std::string & device)119 void DistributedModuleConfig::Offline(const std::string &device)
120 {
121     std::this_thread::sleep_for(std::chrono::milliseconds((int32_t(rand() % (RANDOM_MAX - RANDOM_MIN)))));
122     DevProfile::GetInstance().UnSubscribeProfileEvent(device);
123     Notify();
124 }
125 
OnReady(const std::string & device)126 void DistributedModuleConfig::OnReady(const std::string &device)
127 {
128     DevProfile::GetInstance().OnReady();
129 }
130 
Init()131 void DistributedModuleConfig::Init()
132 {
133     DMAdapter::GetInstance().Register(this);
134     DevProfile::GetInstance().Watch([this](bool isEnable)-> void {
135         Notify();
136     });
137 }
138 
DeInit()139 void DistributedModuleConfig::DeInit()
140 {
141     DMAdapter::GetInstance().Unregister(this);
142 }
143 
144 } // namespace MiscServices
145 } // namespace OHOS