1 /*
2 * Copyright (c) 2024 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 #define LOG_TAG "Pasteboard_Capi"
17
18 #include "oh_pasteboard.h"
19 #include <string>
20 #include <memory>
21 #include <thread>
22 #include <map>
23 #include "udmf.h"
24 #include "oh_pasteboard_err_code.h"
25 #include "oh_pasteboard_observer_impl.h"
26 #include "pasteboard_client.h"
27 #include "pasteboard_hilog.h"
28 #include "pasteboard_error.h"
29 #include "udmf_capi_common.h"
30 #include "i_pasteboard_observer.h"
31
32 using namespace OHOS::MiscServices;
IsPasteboardValid(OH_Pasteboard * pasteboard)33 static bool IsPasteboardValid(OH_Pasteboard* pasteboard)
34 {
35 return pasteboard != nullptr && pasteboard->cid == PASTEBOARD_STRUCT_ID;
36 }
37
IsSubscriberValid(OH_PasteboardObserver * observer)38 static bool IsSubscriberValid(OH_PasteboardObserver* observer)
39 {
40 return observer != nullptr && observer->cid == SUBSCRIBER_STRUCT_ID;
41 }
42
GetMappedCode(int32_t code)43 static PASTEBOARD_ErrCode GetMappedCode(int32_t code)
44 {
45 auto iter = errCodeMap.find(static_cast<PasteboardError>(code));
46 if (iter != errCodeMap.end()) {
47 return iter->second;
48 }
49 return ERR_INNER_ERROR;
50 }
51
OH_PasteboardObserver_Create()52 OH_PasteboardObserver* OH_PasteboardObserver_Create()
53 {
54 OH_PasteboardObserver* observer = new(std::nothrow) OH_PasteboardObserver();
55 if (observer == nullptr) {
56 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "allocate memory fail.");
57 return nullptr;
58 }
59 return observer;
60 }
61
OH_PasteboardObserver_Destroy(OH_PasteboardObserver * observer)62 int OH_PasteboardObserver_Destroy(OH_PasteboardObserver* observer)
63 {
64 if (!IsSubscriberValid(observer)) {
65 return ERR_INVALID_PARAMETER;
66 }
67 if (observer->finalize != nullptr) {
68 (observer->finalize)(observer->context);
69 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CAPI, "context finalized");
70 }
71 delete observer;
72 return ERR_OK;
73 }
74
OH_PasteboardObserver_SetData(OH_PasteboardObserver * observer,void * context,const Pasteboard_Notify callback,const Pasteboard_Finalize finalize)75 int OH_PasteboardObserver_SetData(OH_PasteboardObserver* observer, void* context,
76 const Pasteboard_Notify callback, const Pasteboard_Finalize finalize)
77 {
78 if (observer == nullptr || callback == nullptr) {
79 return ERR_INVALID_PARAMETER;
80 }
81 observer->callback = callback;
82 if (context != nullptr && finalize == nullptr) {
83 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "finalize is null");
84 return ERR_INVALID_PARAMETER;
85 }
86 observer->context = context;
87 observer->finalize = finalize;
88 return ERR_OK;
89 }
90
OH_Pasteboard_Create()91 OH_Pasteboard* OH_Pasteboard_Create()
92 {
93 OH_Pasteboard* pasteboard = new (std::nothrow) OH_Pasteboard();
94 if (pasteboard == nullptr) {
95 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "allocate memory fail.");
96 return nullptr;
97 }
98 return pasteboard;
99 }
100
OH_Pasteboard_Destroy(OH_Pasteboard * pasteboard)101 void OH_Pasteboard_Destroy(OH_Pasteboard* pasteboard)
102 {
103 if (!IsPasteboardValid(pasteboard)) {
104 return;
105 }
106 std::lock_guard<std::mutex> lock(pasteboard->mutex);
107 for (auto iter : pasteboard->observers_) {
108 if (iter.second != nullptr) {
109 PasteboardClient::GetInstance()->Unsubscribe(
110 static_cast<PasteboardObserverType>(iter.second->GetType()), iter.second);
111 }
112 }
113 pasteboard->observers_.clear();
114 pasteboard->mimeTypes_.clear();
115 delete[] pasteboard->mimeTypesPtr;
116 pasteboard->mimeTypesPtr = nullptr;
117 delete pasteboard;
118 }
119
OH_Pasteboard_Subscribe(OH_Pasteboard * pasteboard,int type,const OH_PasteboardObserver * observer)120 int OH_Pasteboard_Subscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer)
121 {
122 if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE
123 || type > NOTIFY_REMOTE_DATA_CHANGE) {
124 return ERR_INVALID_PARAMETER;
125 }
126 std::lock_guard<std::mutex> lock(pasteboard->mutex);
127 auto iter = pasteboard->observers_.find(observer);
128 if (iter != pasteboard->observers_.end()) {
129 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "observer exist.");
130 return ERR_OK;
131 }
132 OHOS::sptr<PasteboardObserverCapiImpl> observerBox = new (std::nothrow) PasteboardObserverCapiImpl();
133 if (observerBox == nullptr) {
134 return ERR_INNER_ERROR;
135 }
136 observerBox->SetInnerObserver(observer);
137 observerBox->SetType(static_cast<Pasteboard_NotifyType>(type));
138 pasteboard->observers_[observer] = observerBox;
139 PasteboardClient::GetInstance()->Subscribe(static_cast<PasteboardObserverType>(type), observerBox);
140 return ERR_OK;
141 }
142
OH_Pasteboard_Unsubscribe(OH_Pasteboard * pasteboard,int type,const OH_PasteboardObserver * observer)143 int OH_Pasteboard_Unsubscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer)
144 {
145 if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE
146 || type > NOTIFY_REMOTE_DATA_CHANGE) {
147 return ERR_INVALID_PARAMETER;
148 }
149 std::lock_guard<std::mutex> lock(pasteboard->mutex);
150 auto iter = pasteboard->observers_.find(observer);
151 if (iter == pasteboard->observers_.end()) {
152 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "couldn't find this observer");
153 return ERR_OK;
154 }
155 PasteboardClient::GetInstance()->Unsubscribe(static_cast<PasteboardObserverType>(type), iter->second);
156 pasteboard->observers_.erase(iter);
157 return ERR_OK;
158 }
159
OH_Pasteboard_IsRemoteData(OH_Pasteboard * pasteboard)160 bool OH_Pasteboard_IsRemoteData(OH_Pasteboard* pasteboard)
161 {
162 if (!IsPasteboardValid(pasteboard)) {
163 return ERR_INVALID_PARAMETER;
164 }
165 return PasteboardClient::GetInstance()->IsRemoteData();
166 }
167
OH_Pasteboard_GetDataSource(OH_Pasteboard * pasteboard,char * source,unsigned int len)168 int OH_Pasteboard_GetDataSource(OH_Pasteboard* pasteboard, char* source, unsigned int len)
169 {
170 if (!IsPasteboardValid(pasteboard) || source == nullptr || len == 0) {
171 return ERR_INVALID_PARAMETER;
172 }
173 std::string bundleName;
174 auto ret = PasteboardClient::GetInstance()->GetDataSource(bundleName);
175 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
176 PASTEBOARD_HILOGE(
177 PASTEBOARD_MODULE_CAPI, "client getDataSource return invalid, result is %{public}d", ret);
178 return GetMappedCode(ret);
179 }
180 if (strcpy_s(source, len, bundleName.c_str()) != EOK) {
181 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "copy string fail");
182 return ERR_INNER_ERROR;
183 }
184 return ERR_OK;
185 }
186
OH_Pasteboard_GetMimeTypes(OH_Pasteboard * pasteboard,unsigned int * count)187 char **OH_Pasteboard_GetMimeTypes(OH_Pasteboard *pasteboard, unsigned int *count)
188 {
189 if (!IsPasteboardValid(pasteboard) || count == nullptr) {
190 return nullptr;
191 }
192 std::lock_guard<std::mutex> lock(pasteboard->mutex);
193 pasteboard->mimeTypes_ = PasteboardClient::GetInstance()->GetMimeTypes();
194 unsigned int typeNum = pasteboard->mimeTypes_.size();
195 if (typeNum == 0 || typeNum > MAX_MIMETYPES_NUM) {
196 *count = 0;
197 return nullptr;
198 }
199 *count = typeNum;
200 delete[] pasteboard->mimeTypesPtr;
201 pasteboard->mimeTypesPtr = new char *[typeNum];
202 for (unsigned int i = 0; i < typeNum; ++i) {
203 pasteboard->mimeTypesPtr[i] = const_cast<char*>(pasteboard->mimeTypes_[i].c_str());
204 }
205 return pasteboard->mimeTypesPtr;
206 }
207
OH_Pasteboard_HasType(OH_Pasteboard * pasteboard,const char * type)208 bool OH_Pasteboard_HasType(OH_Pasteboard* pasteboard, const char* type)
209 {
210 if (!IsPasteboardValid(pasteboard) || type == nullptr) {
211 return ERR_INVALID_PARAMETER;
212 }
213 return PasteboardClient::GetInstance()->HasDataType(std::string(type));
214 }
215
OH_Pasteboard_HasData(OH_Pasteboard * pasteboard)216 bool OH_Pasteboard_HasData(OH_Pasteboard* pasteboard)
217 {
218 if (!IsPasteboardValid(pasteboard)) {
219 return ERR_INVALID_PARAMETER;
220 }
221 return PasteboardClient::GetInstance()->HasPasteData();
222 }
223
OH_Pasteboard_GetData(OH_Pasteboard * pasteboard,int * status)224 OH_UdmfData* OH_Pasteboard_GetData(OH_Pasteboard* pasteboard, int* status)
225 {
226 if (!IsPasteboardValid(pasteboard) || status == nullptr) {
227 return nullptr;
228 }
229 auto unifiedData = std::make_shared<OHOS::UDMF::UnifiedData>();
230 int32_t ret = PasteboardClient::GetInstance()->GetUdsdData(*unifiedData);
231 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
232 PASTEBOARD_HILOGE(
233 PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_GetData return invalid, result is %{public}d", ret);
234 *status = GetMappedCode(ret);
235 return nullptr;
236 }
237 OH_UdmfData* data = OH_UdmfData_Create();
238 data->unifiedData_ = std::move(unifiedData);
239 *status = ERR_OK;
240 return data;
241 }
242
OH_Pasteboard_SetData(OH_Pasteboard * pasteboard,OH_UdmfData * data)243 int OH_Pasteboard_SetData(OH_Pasteboard* pasteboard, OH_UdmfData* data)
244 {
245 if (!IsPasteboardValid(pasteboard) || data == nullptr) {
246 return ERR_INVALID_PARAMETER;
247 }
248 int32_t ret = PasteboardClient::GetInstance()->SetUdsdData(*(data->unifiedData_));
249 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
250 PASTEBOARD_HILOGE(
251 PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_SetData return invalid, result is %{public}d", ret);
252 return GetMappedCode(ret);
253 }
254 return ERR_OK;
255 }
256
OH_Pasteboard_ClearData(OH_Pasteboard * pasteboard)257 int OH_Pasteboard_ClearData(OH_Pasteboard* pasteboard)
258 {
259 if (!IsPasteboardValid(pasteboard)) {
260 return ERR_INVALID_PARAMETER;
261 }
262 PasteboardClient::GetInstance()->Clear();
263 return ERR_OK;
264 }