1 /*
2 * Copyright (C) 2022 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 using namespace OHOS::DistributedHardware;
29
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.deviceId);
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.deviceId);
53 }
OnDeviceChanged(const DmDeviceInfo & deviceInfo)54 void PasteboardDevStateCallback::OnDeviceChanged(const DmDeviceInfo &deviceInfo)
55 {
56 }
OnDeviceReady(const DmDeviceInfo & deviceInfo)57 void PasteboardDevStateCallback::OnDeviceReady(const DmDeviceInfo &deviceInfo)
58 {
59 }
60
OnRemoteDied()61 void PasteboardDmInitCallback::OnRemoteDied()
62 {
63 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "dm device manager died, init it again");
64 DevManager::GetInstance().Init();
65 }
66
DevManager()67 DevManager::DevManager()
68 {
69 }
70
UnregisterDevCallback()71 void DevManager::UnregisterDevCallback()
72 {
73 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "start");
74 auto &deviceManager = DeviceManager::GetInstance();
75 deviceManager.UnRegisterDevStateCallback(PKG_NAME);
76 deviceManager.UnInitDeviceManager(PKG_NAME);
77 DevProfile::GetInstance().UnsubscribeAllProfileEvents();
78 }
79
Init()80 int32_t DevManager::Init()
81 {
82 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start");
83 RetryInBlocking([]() -> bool {
84 auto initCallback = std::make_shared<PasteboardDmInitCallback>();
85 int32_t errNo = DeviceManager::GetInstance().InitDeviceManager(PKG_NAME, initCallback);
86 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "InitDeviceManager ret %{public}d", errNo);
87 return errNo == DM_OK;
88 });
89 RetryInBlocking([]() -> bool {
90 auto stateCallback = std::make_shared<PasteboardDevStateCallback>();
91 auto errNo = DeviceManager::GetInstance().RegisterDevStateCallback(PKG_NAME, "", stateCallback);
92 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "RegisterDevStateCallback ret %{public}d", errNo);
93 return errNo == DM_OK;
94 });
95 return DM_OK;
96 }
97
GetInstance()98 DevManager &DevManager::GetInstance()
99 {
100 static DevManager instance;
101 return instance;
102 }
103
Online(const std::string & deviceId)104 void DevManager::Online(const std::string &deviceId)
105 {
106 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
107 DevProfile::GetInstance().SubscribeProfileEvent(deviceId);
108 DistributedModuleConfig::Notify();
109 }
110
Offline(const std::string & deviceId)111 void DevManager::Offline(const std::string &deviceId)
112 {
113 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
114 DevProfile::GetInstance().UnSubscribeProfileEvent(deviceId);
115 DistributedModuleConfig::Notify();
116 }
RetryInBlocking(DevManager::Function func) const117 void DevManager::RetryInBlocking(DevManager::Function func) const
118 {
119 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "retry start");
120 constexpr int32_t RETRY_TIMES = 300;
121 for (int32_t i = 0; i < RETRY_TIMES; ++i) {
122 if (func()) {
123 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "retry result: %{public}d times", i);
124 return;
125 }
126 std::this_thread::sleep_for(std::chrono::milliseconds(DELAY_TIME));
127 }
128 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "retry failed");
129 }
GetDeviceIds()130 std::vector<std::string> DevManager::GetDeviceIds()
131 {
132 std::vector<DmDeviceInfo> devices;
133 int32_t ret = DeviceManager::GetInstance().GetTrustedDeviceList(PKG_NAME, "", devices);
134 if (ret != 0) {
135 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetTrustedDeviceList failed!");
136 return {};
137 }
138 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "devicesNums = %{public}zu.", devices.size());
139 if (devices.empty()) {
140 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "no device online!");
141 return {};
142 }
143 std::vector<std::string> deviceIds;
144 for (auto &item : devices) {
145 deviceIds.emplace_back(item.deviceId);
146 }
147 return deviceIds;
148 }
149 } // namespace MiscServices
150 } // namespace OHOS