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_profile.h"
16
17 #include <cstring>
18 #include <thread>
19
20 #include "dev_manager.h"
21 #include "device_manager.h"
22 #include "distributed_device_profile_client.h"
23 #include "distributed_module_config.h"
24 #include "nlohmann/json.hpp"
25 #include "para_handle.h"
26 #include "pasteboard_hilog.h"
27 #include "service_characteristic_profile.h"
28 #include "subscribe_info.h"
29 namespace OHOS {
30 namespace MiscServices {
31 using namespace OHOS::DeviceProfile;
32 using namespace OHOS::DistributedHardware;
33 constexpr int32_t HANDLE_OK = 0;
34 constexpr const char *SERVICE_ID = "pasteboard_service";
35 constexpr const char *PROFILE_CONTENT_KEY = "distributed_pasteboard_enabled";
36
OnSyncCompleted(const SyncResult & syncResults)37 void DevProfile::PasteboardProfileEventCallback::OnSyncCompleted(const SyncResult &syncResults)
38 {
39 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnSyncCompleted.");
40 }
41
OnProfileChanged(const ProfileChangeNotification & changeNotification)42 void DevProfile::PasteboardProfileEventCallback::OnProfileChanged(const ProfileChangeNotification &changeNotification)
43 {
44 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "OnProfileChanged start.");
45 DistributedModuleConfig::Notify();
46 }
47
DevProfile()48 DevProfile::DevProfile()
49 {
50 }
51
GetInstance()52 DevProfile &DevProfile::GetInstance()
53 {
54 static DevProfile instance;
55 return instance;
56 }
57
Init()58 void DevProfile::Init()
59 {
60 ParaHandle::GetInstance().WatchEnabledStatus(ParameterChange);
61 auto status = ParaHandle::GetInstance().GetEnabledStatus();
62 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "status = %{public}s.", status.c_str());
63 PutEnabledStatus(status);
64 }
65
ParameterChange(const char * key,const char * value,void * context)66 void DevProfile::ParameterChange(const char *key, const char *value, void *context)
67 {
68 auto enabledKey = ParaHandle::DISTRIBUTED_PASTEBOARD_ENABLED_KEY;
69 if (strncmp(key, enabledKey, strlen(enabledKey)) != 0) {
70 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "key is error.");
71 return;
72 }
73 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "ParameterChange, key = %{public}s, value = %{public}s.", key, value);
74 DevProfile::GetInstance().PutEnabledStatus(value);
75 DistributedModuleConfig::Notify();
76 }
77
PutEnabledStatus(const std::string & enabledStatus)78 void DevProfile::PutEnabledStatus(const std::string &enabledStatus)
79 {
80 ServiceCharacteristicProfile profile;
81 profile.SetServiceId(SERVICE_ID);
82 profile.SetServiceType(SERVICE_ID);
83 nlohmann::json jsonObject;
84 jsonObject[PROFILE_CONTENT_KEY] = enabledStatus;
85 profile.SetCharacteristicProfileJson(jsonObject.dump());
86 int32_t errNo = DistributedDeviceProfileClient::GetInstance().PutDeviceProfile(profile);
87 if (errNo != HANDLE_OK) {
88 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PutDeviceProfile failed, %{public}d", errNo);
89 return;
90 }
91 SyncEnabledStatus();
92 }
93
GetEnabledStatus(const std::string & deviceId,std::string & enabledStatus)94 void DevProfile::GetEnabledStatus(const std::string &deviceId, std::string &enabledStatus)
95 {
96 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetEnabledStatus start.");
97 ServiceCharacteristicProfile profile;
98 int32_t ret = DistributedDeviceProfileClient::GetInstance().GetDeviceProfile(deviceId, SERVICE_ID, profile);
99 if (ret != HANDLE_OK) {
100 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetDeviceProfile failed, %{public}.5s.", deviceId.c_str());
101 return;
102 }
103 const auto &jsonData = profile.GetCharacteristicProfileJson();
104 nlohmann::json jsonObject = nlohmann::json::parse(jsonData, nullptr, false);
105 if (jsonObject.is_discarded()) {
106 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "json parse failed.");
107 return;
108 }
109
110 enabledStatus = jsonObject[PROFILE_CONTENT_KEY];
111 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "GetEnabledStatus success %{public}s.", enabledStatus.c_str());
112 }
113
SubscribeProfileEvent(const std::string & deviceId)114 void DevProfile::SubscribeProfileEvent(const std::string &deviceId)
115 {
116 if (deviceId.empty()) {
117 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "deviceId is empty.");
118 return;
119 }
120 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
121 if (callback_.find(deviceId) != callback_.end()) {
122 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "deviceId = %{public}.5s already exists.", deviceId.c_str());
123 return;
124 }
125 auto profileCallback = std::make_shared<PasteboardProfileEventCallback>();
126 callback_[deviceId] = profileCallback;
127 std::list<std::string> serviceIds = { SERVICE_ID };
128 ExtraInfo extraInfo;
129 extraInfo["deviceId"] = deviceId;
130 extraInfo["serviceIds"] = serviceIds;
131
132 SubscribeInfo subscribeInfo;
133 subscribeInfo.profileEvent = ProfileEvent::EVENT_PROFILE_CHANGED;
134 subscribeInfo.extraInfo = std::move(extraInfo);
135 int32_t errCode =
136 DistributedDeviceProfileClient::GetInstance().SubscribeProfileEvent(subscribeInfo, profileCallback);
137 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SubscribeProfileEvent result, errCode = %{public}d.", errCode);
138 }
139
UnSubscribeProfileEvent(const std::string & deviceId)140 void DevProfile::UnSubscribeProfileEvent(const std::string &deviceId)
141 {
142 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start, deviceId = %{public}.5s", deviceId.c_str());
143 ProfileEvent profileEvent = EVENT_PROFILE_CHANGED;
144 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
145 auto it = callback_.find(deviceId);
146 if (it == callback_.end()) {
147 return;
148 }
149 int32_t errCode = DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvent(profileEvent, it->second);
150 callback_.erase(it);
151 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "UnsubscribeProfileEvent result, errCode = %{public}d.", errCode);
152 }
153
SyncEnabledStatus()154 void DevProfile::SyncEnabledStatus()
155 {
156 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SyncEnabledStatus start.");
157 SyncOptions syncOptions;
158 auto deviceIds = DevManager::GetInstance().GetDeviceIds();
159 if (deviceIds.empty()) {
160 return;
161 }
162 for (auto &id : deviceIds) {
163 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "id = %{public}.5s.", id.c_str());
164 syncOptions.AddDevice(id);
165 }
166 syncOptions.SetSyncMode(SyncMode::PUSH_PULL);
167 auto syncCallback = std::make_shared<PasteboardProfileEventCallback>();
168 int32_t errCode = DistributedDeviceProfileClient::GetInstance().SyncDeviceProfile(syncOptions, syncCallback);
169 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SyncEnabledStatus, ret = %{public}d.", errCode);
170 }
171
UnsubscribeAllProfileEvents()172 void DevProfile::UnsubscribeAllProfileEvents()
173 {
174 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "UnsubscribeAllProfileEvents start.");
175 std::lock_guard<std::mutex> mutexLock(callbackMutex_);
176 for (auto it = callback_.begin(); it != callback_.end(); ++it) {
177 ProfileEvent profileEvent = EVENT_PROFILE_CHANGED;
178 int32_t errCode =
179 DistributedDeviceProfileClient::GetInstance().UnsubscribeProfileEvent(profileEvent, it->second);
180 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "errCode = %{public}d.", errCode);
181 it = callback_.erase(it);
182 }
183 }
184 } // namespace MiscServices
185 } // namespace OHOS
186