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