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