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 "dev_manager.h"
16
17 #include <thread>
18
19 #include "dev_profile.h"
20 #include "distributed_module_config.h"
21 #include "pasteboard_hilog.h"
22 #ifdef PB_DEVICE_MANAGER_ENABLE
23 #include "device_manager.h"
24 #include "device_manager_callback.h"
25 #endif
26 namespace OHOS {
27 namespace MiscServices {
28 constexpr const char *PKG_NAME = "pasteboard_service";
29 constexpr int32_t DM_OK = 0;
30 constexpr const int32_t DELAY_TIME = 200;
31 constexpr const uint32_t FIRST_VERSION = 4;
32 #ifdef PB_DEVICE_MANAGER_ENABLE
33 using namespace OHOS::DistributedHardware;
34
35 class PasteboardDevStateCallback : public DistributedHardware::DeviceStateCallback {
36 public:
37 void OnDeviceOnline(const DistributedHardware::DmDeviceInfo &deviceInfo) override;
38 void OnDeviceOffline(const DmDeviceInfo &deviceInfo) override;
39 void OnDeviceChanged(const DmDeviceInfo &deviceInfo) override;
40 void OnDeviceReady(const DmDeviceInfo &deviceInfo) override;
41 };
42
43 class PasteboardDmInitCallback : public DistributedHardware::DmInitCallback {
44 public:
45 void OnRemoteDied() override;
46 };
47
OnDeviceOnline(const DmDeviceInfo & deviceInfo)48 void PasteboardDevStateCallback::OnDeviceOnline(const DmDeviceInfo &deviceInfo)
49 {
50 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
51 DevManager::GetInstance().Online(deviceInfo.networkId);
52 }
53
OnDeviceOffline(const DmDeviceInfo & deviceInfo)54 void PasteboardDevStateCallback::OnDeviceOffline(const DmDeviceInfo &deviceInfo)
55 {
56 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
57 DevManager::GetInstance().Offline(deviceInfo.networkId);
58 }
59
OnDeviceChanged(const DmDeviceInfo & deviceInfo)60 void PasteboardDevStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
61 {
62 }
63
OnDeviceReady(const DmDeviceInfo & deviceInfo)64 void PasteboardDevStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
65 {
66 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
67 (void)deviceInfo;
68 DevManager::GetInstance().OnReady();
69 }
70
OnRemoteDied()71 void PasteboardDmInitCallback::OnRemoteDied()
72 {
73 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "dm device manager died, init it again");
74 DevManager::GetInstance().Init();
75 }
76 #endif
77
DevManager()78 DevManager::DevManager()
79 {
80 }
81
UnregisterDevCallback()82 void DevManager::UnregisterDevCallback()
83 {
84 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "start");
85 auto &deviceManager = DeviceManager::GetInstance();
86 deviceManager.UnRegisterDevStateCallback(PKG_NAME);
87 deviceManager.UnInitDeviceManager(PKG_NAME);
88 DevProfile::GetInstance().UnsubscribeAllProfileEvents();
89 }
90
Init()91 int32_t DevManager::Init()
92 {
93 #ifdef PB_DEVICE_MANAGER_ENABLE
94 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start");
95 RetryInBlocking([]() -> bool {
96 auto initCallback = std::make_shared<PasteboardDmInitCallback>();
97 int32_t errNo = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, initCallback);
98 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "InitDeviceManager ret %{public}d", errNo);
99 return errNo == DM_OK;
100 });
101 RetryInBlocking([]() -> bool {
102 auto stateCallback = std::make_shared<PasteboardDevStateCallback>();
103 auto errNo = DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "", stateCallback);
104 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "RegisterDevStateCallback ret %{public}d", errNo);
105 return errNo == DM_OK;
106 });
107 #endif
108 return DM_OK;
109 }
110
GetInstance()111 DevManager &DevManager::GetInstance()
112 {
113 static DevManager instance;
114 return instance;
115 }
116
Online(const std::string & networkId)117 void DevManager::Online(const std::string &networkId)
118 {
119 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
120 DevProfile::GetInstance().SubscribeProfileEvent(networkId);
121 DistributedModuleConfig::ForceNotify();
122 DistributedModuleConfig::Notify();
123 }
124
Offline(const std::string & networkId)125 void DevManager::Offline(const std::string &networkId)
126 {
127 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
128 DevProfile::GetInstance().UnSubscribeProfileEvent(networkId);
129 DistributedModuleConfig::Notify();
130 }
131
OnReady()132 void DevManager::OnReady()
133 {
134 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
135 DevProfile::GetInstance().OnReady();
136 }
137
RetryInBlocking(DevManager::Function func) const138 void DevManager::RetryInBlocking(DevManager::Function func) const
139 {
140 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "retry start");
141 constexpr int32_t RETRY_TIMES = 300;
142 for (int32_t i = 0; i < RETRY_TIMES; ++i) {
143 if (func()) {
144 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "retry result: %{public}d times", i);
145 return;
146 }
147 std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_TIME));
148 }
149 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "retry failed");
150 }
151
GetNetworkIds()152 std::vector<std::string> DevManager::GetNetworkIds()
153 {
154 #ifdef PB_DEVICE_MANAGER_ENABLE
155 std::vector<DmDeviceInfo> devices;
156 int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", devices);
157 if (ret != 0) {
158 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetTrustedDeviceList failed!");
159 return {};
160 }
161 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "devicesNums = %{public}zu.", devices.size());
162 if (devices.empty()) {
163 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "no device online!");
164 return {};
165 }
166 std::vector<std::string> networkIds;
167 for (auto &item : devices) {
168 networkIds.emplace_back(item.networkId);
169 }
170 return networkIds;
171 #else
172 return {};
173 #endif
174 }
175
GetOldNetworkIds()176 std::vector<std::string> DevManager::GetOldNetworkIds()
177 {
178 #ifdef PB_DEVICE_MANAGER_ENABLE
179 std::vector<std::string> networkIds = GetNetworkIds();
180 if (networkIds.empty()) {
181 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "no device online!");
182 return {};
183 }
184 std::vector<std::string> oldNetworkIds;
185 for (auto &item : networkIds) {
186 uint32_t versionId = 3;
187 DevProfile::GetInstance().GetRemoteDeviceVersion(item, versionId);
188 if (versionId >= FIRST_VERSION) {
189 continue;
190 }
191 oldNetworkIds.emplace_back(item);
192 }
193 return oldNetworkIds;
194 #else
195 return {};
196 #endif
197 }
198 } // namespace MiscServices
199 } // namespace OHOS
200