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