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_profile.h"
16
17 #include <cstring>
18 #include <thread>
19
20 #include "cJSON.h"
21 #include "dev_manager.h"
22 #include "distributed_module_config.h"
23 #include "dm_adapter.h"
24 #include "para_handle.h"
25 #include "pasteboard_hilog.h"
26 #include "service_characteristic_profile.h"
27 #include "subscribe_info.h"
28
29 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
30 #include "distributed_device_profile_client.h"
31 #endif // PB_DEVICE_INFO_MANAGER_ENABLE
32
33 namespace OHOS {
34 namespace MiscServices {
35 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
36 using namespace OHOS::DeviceProfile;
37 constexpr const int32_t HANDLE_OK = 0;
38 constexpr const uint32_t NOT_SUPPORT = 0;
39 constexpr const uint32_t SUPPORT = 1;
40
41 constexpr const char *SERVICE_ID = "pasteboardService";
42 constexpr const char *CHARACTER_ID = "supportDistributedPasteboard";
43 constexpr const char *VERSION_ID = "PasteboardVersionId";
44
OnSyncCompleted(const SyncResult & syncResults)45 void DevProfile::PasteboardProfileEventCallback::OnSyncCompleted(const SyncResult &syncResults)
46 {
47 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnSyncCompleted.");
48 }
49
OnProfileChanged(const ProfileChangeNotification & changeNotification)50 void DevProfile::PasteboardProfileEventCallback::OnProfileChanged(const ProfileChangeNotification &changeNotification)
51 {
52 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnProfileChanged start.");
53 }
54 #endif
55
DevProfile()56 DevProfile::DevProfile()
57 {
58 }
59
GetInstance()60 DevProfile &DevProfile::GetInstance()
61 {
62 static DevProfile instance;
63 return instance;
64 }
65
Init()66 void DevProfile::Init()
67 {
68 ParaHandle::GetInstance().WatchEnabledStatus(ParameterChange);
69 }
70
OnReady()71 void DevProfile::OnReady()
72 {
73 }
74
ParameterChange(const char * key,const char * value,void * context)75 void DevProfile::ParameterChange(const char *key, const char *value, void *context)
76 {
77 auto enabledKey = ParaHandle::DISTRIBUTED_PASTEBOARD_ENABLED_KEY;
78 if (strncmp(key, enabledKey, strlen(enabledKey)) != 0) {
79 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "key is error.");
80 return;
81 }
82 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "ParameterChange, key = %{public}s, value = %{public}s.", key, value);
83 DevProfile::GetInstance().PutEnabledStatus(value);
84 }
85
PutEnabledStatus(const std::string & enabledStatus)86 void DevProfile::PutEnabledStatus(const std::string &enabledStatus)
87 {
88 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
89 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PutEnabledStatus, start");
90 ServiceCharacteristicProfile profile;
91 profile.SetServiceId(SERVICE_ID);
92 profile.SetServiceType(SERVICE_ID);
93 cJSON *jsonObject = cJSON_CreateObject();
94 cJSON_AddNumberToObject(jsonObject, CHARACTER_ID, NOT_SUPPORT);
95 localEnable_ = false;
96 if (enabledStatus == "true") {
97 cJSON_ReplaceItemInObject(jsonObject, CHARACTER_ID, cJSON_CreateNumber(SUPPORT));
98 localEnable_ = true;
99 }
100 cJSON_AddNumberToObject(jsonObject, VERSION_ID, FIRST_VERSION);
101 char *jsonString = cJSON_PrintUnformatted((jsonObject));
102 profile.SetCharacteristicProfileJson(jsonString);
103 cJSON_Delete(jsonObject);
104 free(jsonString);
105 int32_t errNo = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile);
106 if (errNo != HANDLE_OK) {
107 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PutDeviceProfile failed, %{public}d", errNo);
108 return;
109 }
110 #else
111 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
112 return;
113 #endif
114 }
115
GetEnabledStatus(const std::string & networkId,std::string & enabledStatus)116 void DevProfile::GetEnabledStatus(const std::string &networkId, std::string &enabledStatus)
117 {
118 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
119 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetEnabledStatus start.");
120 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
121 if (udid.empty()) {
122 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed");
123 return;
124 }
125 ServiceCharacteristicProfile profile;
126 int32_t ret = DistributedDeviceProfileClient::GetInstance().GetDeviceProfile(udid, SERVICE_ID, profile);
127 if (ret != HANDLE_OK) {
128 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetDeviceProfile failed, %{public}.5s.", udid.c_str());
129 return;
130 }
131 const auto &jsonData = profile.GetCharacteristicProfileJson();
132 cJSON *jsonObject = cJSON_Parse(jsonData.c_str());
133 if (jsonObject == nullptr) {
134 cJSON_Delete(jsonObject);
135 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "json parse failed.");
136 return;
137 }
138
139 enabledStatus = "false";
140 if (cJSON_GetNumberValue(cJSON_GetObjectItem(jsonObject, CHARACTER_ID)) == SUPPORT) {
141 enabledStatus = "true";
142 }
143 cJSON_Delete(jsonObject);
144 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "GetEnabledStatus success %{public}s.", enabledStatus.c_str());
145 #else
146 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
147 return;
148 #endif
149 }
150
GetRemoteDeviceVersion(const std::string & networkId,uint32_t & versionId)151 void DevProfile::GetRemoteDeviceVersion(const std::string &networkId, uint32_t &versionId)
152 {
153 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
154 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetRemoteDeviceVersion start.");
155 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
156 if (udid.empty()) {
157 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed.");
158 return;
159 }
160 ServiceCharacteristicProfile profile;
161 int32_t ret = DistributedDeviceProfileClient::GetInstance().GetDeviceProfile(udid, SERVICE_ID, profile);
162 if (ret != HANDLE_OK) {
163 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetDeviceProfile failed, %{public}.5s.", udid.c_str());
164 return;
165 }
166 const auto &jsonData = profile.GetCharacteristicProfileJson();
167 cJSON *jsonObject = cJSON_Parse(jsonData.c_str());
168 if (jsonObject == nullptr) {
169 cJSON_Delete(jsonObject);
170 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "json parse failed.");
171 return;
172 }
173 if (cJSON_GetNumberValue(cJSON_GetObjectItem(jsonObject, VERSION_ID)) == FIRST_VERSION) {
174 versionId = FIRST_VERSION;
175 }
176 cJSON_Delete(jsonObject);
177 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetRemoteDeviceVersion success, versionId = %{public}d.", versionId);
178 #else
179 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
180 return;
181 #endif
182 }
183
SubscribeProfileEvent(const std::string & networkId)184 void DevProfile::SubscribeProfileEvent(const std::string &networkId)
185 {
186 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
187 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start, networkId = %{public}.5s", networkId.c_str());
188 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
189 if (udid.empty()) {
190 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed");
191 return;
192 }
193 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
194 if (callback_.find(udid) != callback_.end()) {
195 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "networkId = %{public}.5s already exists.", udid.c_str());
196 return;
197 }
198 auto profileCallback = std::make_shared<PasteboardProfileEventCallback>();
199 callback_[udid] = profileCallback;
200 std::list<std::string> serviceIds = { SERVICE_ID };
201 ExtraInfo extraInfo;
202 extraInfo["deviceId"] = udid;
203 extraInfo["serviceIds"] = serviceIds;
204
205 std::list<SubscribeInfo> subscribeInfos;
206 SubscribeInfo changeEventInfo;
207 changeEventInfo.profileEvent = ProfileEvent::EVENT_PROFILE_CHANGED;
208 changeEventInfo.extraInfo = std::move(extraInfo);
209 subscribeInfos.emplace_back(changeEventInfo);
210
211 SubscribeInfo syncEventInfo;
212 syncEventInfo.profileEvent = ProfileEvent::EVENT_SYNC_COMPLETED;
213 subscribeInfos.emplace_back(syncEventInfo);
214
215 std::list<ProfileEvent> failedEvents;
216 int32_t errCode = DistributedDeviceProfileClient::GetInstance().SubscribeProfileEvents(subscribeInfos,
217 profileCallback, failedEvents);
218 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SubscribeProfileEvent result, errCode = %{public}d.", errCode);
219 #else
220 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
221 return;
222 #endif
223 }
224
UnSubscribeProfileEvent(const std::string & networkId)225 void DevProfile::UnSubscribeProfileEvent(const std::string &networkId)
226 {
227 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
228 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start, networkId = %{public}.5s", networkId.c_str());
229 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
230 if (udid.empty()) {
231 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed, %{public}.5s.", udid.c_str());
232 return;
233 }
234 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
235 auto it = callback_.find(udid);
236 if (it == callback_.end()) {
237 return;
238 }
239 std::list<ProfileEvent> profileEvents;
240 profileEvents.emplace_back(ProfileEvent::EVENT_PROFILE_CHANGED);
241 std::list<ProfileEvent> failedEvents;
242 int32_t errCode = DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvents(profileEvents,
243 it->second, failedEvents);
244 callback_.erase(it);
245 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "UnsubscribeProfileEvent result, errCode = %{public}d.", errCode);
246 #else
247 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
248 return;
249 #endif
250 }
251
UnsubscribeAllProfileEvents()252 void DevProfile::UnsubscribeAllProfileEvents()
253 {
254 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
255 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "UnsubscribeAllProfileEvents start.");
256 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
257 for (auto it = callback_.begin(); it != callback_.end(); ++it) {
258 std::list<ProfileEvent> profileEvents;
259 profileEvents.emplace_back(ProfileEvent::EVENT_PROFILE_CHANGED);
260 std::list<ProfileEvent> failedEvents;
261 int32_t ret = DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvents(profileEvents,
262 it->second, failedEvents);
263 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "errCode = %{public}d.", ret);
264 it = callback_.erase(it);
265 }
266 #else
267 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
268 return;
269 #endif
270 }
271
GetLocalEnable()272 bool DevProfile::GetLocalEnable()
273 {
274 return localEnable_;
275 }
276
277 } // namespace MiscServices
278 } // namespace OHOS
279