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
16 #include "dev_profile.h"
17
18 #include "cJSON.h"
19 #include "dm_adapter.h"
20 #include "pasteboard_error.h"
21 #include "pasteboard_event_ue.h"
22 #include "pasteboard_hilog.h"
23
24 namespace OHOS {
25 namespace MiscServices {
26 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
27 using namespace OHOS::DistributedDeviceProfile;
28 using namespace UeReporter;
29 constexpr const int32_t HANDLE_OK = 0;
30 constexpr const int32_t PASTEBOARD_SA_ID = 3701;
31
32 constexpr const char *SERVICE_ID = "pasteboardService";
33 constexpr const char *STATIC_CHARACTER_ID = "static_capability";
34 constexpr const char *VERSION_ID = "PasteboardVersionId";
35 constexpr const char *CHARACTERISTIC_VALUE = "characteristicValue";
36 constexpr const char *SUPPORT_STATUS = "1";
37 constexpr const char *SWITCH_ID = "SwitchStatus_Key_Distributed_Pasteboard";
38 constexpr const char *CHARACTER_ID = "SwitchStatus";
39
SubscribeDPChangeListener()40 DevProfile::SubscribeDPChangeListener::SubscribeDPChangeListener() { }
41
~SubscribeDPChangeListener()42 DevProfile::SubscribeDPChangeListener::~SubscribeDPChangeListener() { }
43
OnTrustDeviceProfileAdd(const TrustDeviceProfile & profile)44 int32_t DevProfile::SubscribeDPChangeListener::OnTrustDeviceProfileAdd(const TrustDeviceProfile &profile)
45 {
46 (void)profile;
47 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnTrustDeviceProfileAdd start.");
48 return HANDLE_OK;
49 }
50
OnTrustDeviceProfileDelete(const TrustDeviceProfile & profile)51 int32_t DevProfile::SubscribeDPChangeListener::OnTrustDeviceProfileDelete(const TrustDeviceProfile &profile)
52 {
53 (void)profile;
54 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnTrustDeviceProfileDelete start.");
55 return HANDLE_OK;
56 }
57
OnTrustDeviceProfileUpdate(const TrustDeviceProfile & oldProfile,const TrustDeviceProfile & newProfile)58 int32_t DevProfile::SubscribeDPChangeListener::OnTrustDeviceProfileUpdate(
59 const TrustDeviceProfile &oldProfile, const TrustDeviceProfile &newProfile)
60 {
61 (void)oldProfile;
62 (void)newProfile;
63 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnTrustDeviceProfileUpdate start.");
64 return HANDLE_OK;
65 }
66
OnDeviceProfileAdd(const DeviceProfile & profile)67 int32_t DevProfile::SubscribeDPChangeListener::OnDeviceProfileAdd(const DeviceProfile &profile)
68 {
69 (void)profile;
70 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnDeviceProfileAdd start.");
71 return HANDLE_OK;
72 }
73
OnDeviceProfileDelete(const DeviceProfile & profile)74 int32_t DevProfile::SubscribeDPChangeListener::OnDeviceProfileDelete(const DeviceProfile &profile)
75 {
76 (void)profile;
77 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnDeviceProfileDelete start.");
78 return HANDLE_OK;
79 }
80
OnDeviceProfileUpdate(const DeviceProfile & oldProfile,const DeviceProfile & newProfile)81 int32_t DevProfile::SubscribeDPChangeListener::OnDeviceProfileUpdate(
82 const DeviceProfile &oldProfile, const DeviceProfile &newProfile)
83 {
84 (void)oldProfile;
85 (void)newProfile;
86 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnDeviceProfileUpdate start.");
87 return HANDLE_OK;
88 }
89
OnServiceProfileAdd(const ServiceProfile & profile)90 int32_t DevProfile::SubscribeDPChangeListener::OnServiceProfileAdd(const ServiceProfile &profile)
91 {
92 (void)profile;
93 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnServiceProfileAdd start.");
94 return HANDLE_OK;
95 }
96
OnServiceProfileDelete(const ServiceProfile & profile)97 int32_t DevProfile::SubscribeDPChangeListener::OnServiceProfileDelete(const ServiceProfile &profile)
98 {
99 (void)profile;
100 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnServiceProfileDelete start.");
101 return HANDLE_OK;
102 }
103
OnServiceProfileUpdate(const ServiceProfile & oldProfile,const ServiceProfile & newProfile)104 int32_t DevProfile::SubscribeDPChangeListener::OnServiceProfileUpdate(
105 const ServiceProfile &oldProfile, const ServiceProfile &newProfile)
106 {
107 (void)oldProfile;
108 (void)newProfile;
109 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnServiceProfileUpdate start.");
110 return HANDLE_OK;
111 }
112
OnCharacteristicProfileAdd(const CharacteristicProfile & profile)113 int32_t DevProfile::SubscribeDPChangeListener::OnCharacteristicProfileAdd(const CharacteristicProfile &profile)
114 {
115 (void)profile;
116 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnCharacteristicProfileAdd start.");
117 return HANDLE_OK;
118 }
119
OnCharacteristicProfileDelete(const CharacteristicProfile & profile)120 int32_t DevProfile::SubscribeDPChangeListener::OnCharacteristicProfileDelete(const CharacteristicProfile &profile)
121 {
122 (void)profile;
123 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnCharacteristicProfileDelete start.");
124 return HANDLE_OK;
125 }
126
OnCharacteristicProfileUpdate(const CharacteristicProfile & oldProfile,const CharacteristicProfile & newProfile)127 int32_t DevProfile::SubscribeDPChangeListener::OnCharacteristicProfileUpdate(
128 const CharacteristicProfile &oldProfile, const CharacteristicProfile &newProfile)
129 {
130 std::string id = newProfile.GetDeviceId();
131 std::string status = newProfile.GetCharacteristicValue();
132 PASTEBOARD_HILOGI(
133 PASTEBOARD_MODULE_SERVICE, "status is %{public}s, id is %{public}.5s.", status.c_str(), id.c_str());
134 DevProfile::GetInstance().UpdateEnabledStatus(id, status);
135 DevProfile::GetInstance().Notify(status == SUPPORT_STATUS);
136 return HANDLE_OK;
137 }
138 #endif
139
DevProfile()140 DevProfile::DevProfile() { }
141
GetInstance()142 DevProfile &DevProfile::GetInstance()
143 {
144 static DevProfile instance;
145 return instance;
146 }
147
OnReady()148 void DevProfile::OnReady() { }
149
PutEnabledStatus(const std::string & enabledStatus)150 void DevProfile::PutEnabledStatus(const std::string &enabledStatus)
151 {
152 Notify(enabledStatus == SUPPORT_STATUS);
153 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
154 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PutEnabledStatus, start");
155 std::string networkId = DMAdapter::GetInstance().GetLocalNetworkId();
156 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
157 if (udid.empty()) {
158 PASTEBOARD_HILOGE(
159 PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed, networkId is %{public}.5s", networkId.c_str());
160 return;
161 }
162 UpdateEnabledStatus(udid, enabledStatus);
163 UE_SWITCH(UeReporter::UE_SWITCH_OPERATION, UeReporter::UE_OPERATION_TYPE,
164 (enabledStatus == SUPPORT_STATUS) ? UeReporter::SwitchStatus::SWITCH_OPEN :
165 UeReporter::SwitchStatus::SWITCH_CLOSE);
166 DistributedDeviceProfile::CharacteristicProfile profile;
167 profile.SetDeviceId(udid);
168 profile.SetServiceName(SWITCH_ID);
169 profile.SetCharacteristicKey(CHARACTER_ID);
170 profile.SetCharacteristicValue(enabledStatus);
171 int32_t errNo = DistributedDeviceProfileClient::GetInstance().PutCharacteristicProfile(profile);
172 if (errNo != DistributedDeviceProfile::DP_SUCCESS && errNo != DistributedDeviceProfile::DP_CACHE_EXIST) {
173 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "PutCharacteristicProfile failed, %{public}d", errNo);
174 return;
175 }
176 #else
177 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
178 return;
179 #endif
180 }
181
GetEnabledStatus(const std::string & networkId,std::string & enabledStatus)182 int32_t DevProfile::GetEnabledStatus(const std::string &networkId, std::string &enabledStatus)
183 {
184 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
185 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
186 if (udid.empty()) {
187 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed, %{public}.5s", networkId.c_str());
188 return static_cast<int32_t>(PasteboardError::GET_LOCAL_DEVICE_ID_ERROR);
189 }
190 bool cachedStatus = enabledStatusCache_.ComputeIfPresent(udid, [&enabledStatus](const auto &key, auto &value) {
191 enabledStatus = value;
192 return true;
193 });
194 if (cachedStatus) {
195 return static_cast<int32_t>(PasteboardError::E_OK);
196 }
197 DistributedDeviceProfile::CharacteristicProfile profile;
198 int32_t ret =
199 DistributedDeviceProfileClient::GetInstance().GetCharacteristicProfile(udid, SWITCH_ID, CHARACTER_ID, profile);
200 if (ret == DistributedDeviceProfile::DP_SUCCESS) {
201 enabledStatus = profile.GetCharacteristicValue();
202 UpdateEnabledStatus(udid, enabledStatus);
203 return static_cast<int32_t>(PasteboardError::E_OK);
204 }
205 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Get status failed, %{public}.5s. ret:%{public}d", udid.c_str(), ret);
206 return static_cast<int32_t>(PasteboardError::DP_LOAD_SERVICE_ERROR);
207 #else
208 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
209 #endif
210 return static_cast<int32_t>(PasteboardError::NO_TRUST_DEVICE_ERROR);
211 }
212
GetRemoteDeviceVersion(const std::string & networkId,uint32_t & versionId)213 bool DevProfile::GetRemoteDeviceVersion(const std::string &networkId, uint32_t &versionId)
214 {
215 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
216 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "netid=%{public}.5s", networkId.c_str());
217 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
218 if (udid.empty()) {
219 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get udid failed, netid=%{public}.5s", networkId.c_str());
220 return false;
221 }
222
223 DistributedDeviceProfile::CharacteristicProfile profile;
224 int32_t ret = DistributedDeviceProfileClient::GetInstance().GetCharacteristicProfile(
225 udid, SERVICE_ID, STATIC_CHARACTER_ID, profile);
226 if (ret != DistributedDeviceProfile::DP_SUCCESS) {
227 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get profile failed, udid=%{public}.5s", udid.c_str());
228 return false;
229 }
230
231 const std::string &jsonStr = profile.GetCharacteristicValue();
232 cJSON *jsonObj = cJSON_Parse(jsonStr.c_str());
233 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(jsonObj != nullptr,
234 false,
235 PASTEBOARD_MODULE_CLIENT, "parse profile failed, profile=%{public}s", jsonStr.c_str());
236
237 cJSON *version = cJSON_GetObjectItemCaseSensitive(jsonObj, VERSION_ID);
238 if (version == nullptr || !cJSON_IsNumber(version) || (version->valuedouble < 0)) {
239 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "version not found, profile=%{public}s", jsonStr.c_str());
240 cJSON_Delete(jsonObj);
241 return false;
242 }
243
244 versionId = static_cast<uint32_t>(version->valuedouble);
245 cJSON_Delete(jsonObj);
246 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "netid=%{public}.5s, udid=%{public}.5s, version=%{public}u",
247 networkId.c_str(), udid.c_str(), versionId);
248 return true;
249 #else
250 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
251 return true;
252 #endif
253 }
254
SubscribeProfileEvent(const std::string & networkId)255 void DevProfile::SubscribeProfileEvent(const std::string &networkId)
256 {
257 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
258 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start, networkId = %{public}.5s", networkId.c_str());
259 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
260 if (udid.empty()) {
261 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed, %{public}.5s", networkId.c_str());
262 return;
263 }
264 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
265 if (subscribeInfoCache_.find(udid) != subscribeInfoCache_.end()) {
266 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "networkId = %{public}.5s already exists.", udid.c_str());
267 return;
268 }
269 DistributedDeviceProfile::SubscribeInfo subscribeInfo;
270 subscribeInfo.SetSaId(PASTEBOARD_SA_ID);
271 subscribeInfo.SetSubscribeKey(udid, SWITCH_ID, CHARACTER_ID, CHARACTERISTIC_VALUE);
272 subscribeInfo.AddProfileChangeType(ProfileChangeType::CHAR_PROFILE_ADD);
273 subscribeInfo.AddProfileChangeType(ProfileChangeType::CHAR_PROFILE_UPDATE);
274 subscribeInfo.AddProfileChangeType(ProfileChangeType::CHAR_PROFILE_DELETE);
275 sptr<IProfileChangeListener> subscribeDPChangeListener = new (std::nothrow) SubscribeDPChangeListener;
276 subscribeInfo.SetListener(subscribeDPChangeListener);
277 subscribeInfoCache_[udid] = subscribeInfo;
278 int32_t errCode = DistributedDeviceProfileClient::GetInstance().SubscribeDeviceProfile(subscribeInfo);
279 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SubscribeDeviceProfile result, errCode = %{public}d.", errCode);
280 #else
281 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
282 return;
283 #endif
284 }
285
UnSubscribeProfileEvent(const std::string & networkId)286 void DevProfile::UnSubscribeProfileEvent(const std::string &networkId)
287 {
288 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
289 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start, networkId = %{public}.5s", networkId.c_str());
290 std::string udid = DMAdapter::GetInstance().GetUdidByNetworkId(networkId);
291 if (udid.empty()) {
292 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetUdidByNetworkId failed, %{public}.5s.", udid.c_str());
293 return;
294 }
295 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
296 auto it = subscribeInfoCache_.find(udid);
297 if (it == subscribeInfoCache_.end()) {
298 return;
299 }
300 int32_t errCode = DistributedDeviceProfileClient::GetInstance().UnSubscribeDeviceProfile(it->second);
301 subscribeInfoCache_.erase(it);
302 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "UnsubscribeProfileEvent result, errCode = %{public}d.", errCode);
303 #else
304 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
305 return;
306 #endif
307 }
308
UnsubscribeAllProfileEvents()309 void DevProfile::UnsubscribeAllProfileEvents()
310 {
311 #ifdef PB_DEVICE_INFO_MANAGER_ENABLE
312 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "UnsubscribeAllProfileEvents start.");
313 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
314 for (auto it = subscribeInfoCache_.begin(); it != subscribeInfoCache_.end(); ++it) {
315 int32_t ret = DistributedDeviceProfileClient::GetInstance().UnSubscribeDeviceProfile(it->second);
316 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "errCode = %{public}d.", ret);
317 it = subscribeInfoCache_.erase(it);
318 }
319 #else
320 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PB_DEVICE_INFO_MANAGER_ENABLE not defined");
321 return;
322 #endif
323 }
324
Watch(Observer observer)325 void DevProfile::Watch(Observer observer)
326 {
327 observer_ = std::move(observer);
328 }
329
Notify(bool isEnable)330 void DevProfile::Notify(bool isEnable)
331 {
332 if (observer_ != nullptr) {
333 observer_(isEnable);
334 }
335 }
336
UpdateEnabledStatus(const std::string & udid,const std::string & res)337 void DevProfile::UpdateEnabledStatus(const std::string &udid, const std::string &res)
338 {
339 enabledStatusCache_.Compute(udid, [&res](const auto &key, auto &value) {
340 value = res;
341 return true;
342 });
343 }
344
EraseEnabledStatus(const std::string & udid)345 void DevProfile::EraseEnabledStatus(const std::string &udid)
346 {
347 enabledStatusCache_.Erase(udid);
348 }
349 } // namespace MiscServices
350 } // namespace OHOS
351