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 delete pasteboard;
115 }
116
OH_Pasteboard_Subscribe(OH_Pasteboard * pasteboard,int type,const OH_PasteboardObserver * observer)117 int OH_Pasteboard_Subscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer)
118 {
119 if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE
120 || type > NOTIFY_REMOTE_DATA_CHANGE) {
121 return ERR_INVALID_PARAMETER;
122 }
123 std::lock_guard<std::mutex> lock(pasteboard->mutex);
124 auto iter = pasteboard->observers_.find(observer);
125 if (iter != pasteboard->observers_.end()) {
126 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "observer exist.");
127 return ERR_OK;
128 }
129 OHOS::sptr<PasteboardObserverCapiImpl> observerBox = new (std::nothrow) PasteboardObserverCapiImpl();
130 if (observerBox == nullptr) {
131 return ERR_INNER_ERROR;
132 }
133 observerBox->SetInnerObserver(observer);
134 observerBox->SetType(static_cast<Pasteboard_NotifyType>(type));
135 pasteboard->observers_[observer] = observerBox;
136 PasteboardClient::GetInstance()->Subscribe(static_cast<PasteboardObserverType>(type), observerBox);
137 return ERR_OK;
138 }
139
OH_Pasteboard_Unsubscribe(OH_Pasteboard * pasteboard,int type,const OH_PasteboardObserver * observer)140 int OH_Pasteboard_Unsubscribe(OH_Pasteboard* pasteboard, int type, const OH_PasteboardObserver* observer)
141 {
142 if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE
143 || type > NOTIFY_REMOTE_DATA_CHANGE) {
144 return ERR_INVALID_PARAMETER;
145 }
146 std::lock_guard<std::mutex> lock(pasteboard->mutex);
147 auto iter = pasteboard->observers_.find(observer);
148 if (iter == pasteboard->observers_.end()) {
149 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "couldn't find this observer");
150 return ERR_OK;
151 }
152 PasteboardClient::GetInstance()->Unsubscribe(static_cast<PasteboardObserverType>(type), iter->second);
153 pasteboard->observers_.erase(iter);
154 return ERR_OK;
155 }
156
OH_Pasteboard_IsRemoteData(OH_Pasteboard * pasteboard)157 bool OH_Pasteboard_IsRemoteData(OH_Pasteboard* pasteboard)
158 {
159 if (!IsPasteboardValid(pasteboard)) {
160 return ERR_INVALID_PARAMETER;
161 }
162 return PasteboardClient::GetInstance()->IsRemoteData();
163 }
164
OH_Pasteboard_GetDataSource(OH_Pasteboard * pasteboard,char * source,unsigned int len)165 int OH_Pasteboard_GetDataSource(OH_Pasteboard* pasteboard, char* source, unsigned int len)
166 {
167 if (!IsPasteboardValid(pasteboard) || source == nullptr || len == 0) {
168 return ERR_INVALID_PARAMETER;
169 }
170 std::string bundleName;
171 auto ret = PasteboardClient::GetInstance()->GetDataSource(bundleName);
172 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
173 PASTEBOARD_HILOGE(
174 PASTEBOARD_MODULE_CAPI, "client getDataSource return invalid, result is %{public}d", ret);
175 return GetMappedCode(ret);
176 }
177 if (strcpy_s(source, len, bundleName.c_str()) != EOK) {
178 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "copy string fail");
179 return ERR_INNER_ERROR;
180 }
181 return ERR_OK;
182 }
183
OH_Pasteboard_HasType(OH_Pasteboard * pasteboard,const char * type)184 bool OH_Pasteboard_HasType(OH_Pasteboard* pasteboard, const char* type)
185 {
186 if (!IsPasteboardValid(pasteboard) || type == nullptr) {
187 return ERR_INVALID_PARAMETER;
188 }
189 return PasteboardClient::GetInstance()->HasDataType(std::string(type));
190 }
191
OH_Pasteboard_HasData(OH_Pasteboard * pasteboard)192 bool OH_Pasteboard_HasData(OH_Pasteboard* pasteboard)
193 {
194 if (!IsPasteboardValid(pasteboard)) {
195 return ERR_INVALID_PARAMETER;
196 }
197 return PasteboardClient::GetInstance()->HasPasteData();
198 }
199
OH_Pasteboard_GetData(OH_Pasteboard * pasteboard,int * status)200 OH_UdmfData* OH_Pasteboard_GetData(OH_Pasteboard* pasteboard, int* status)
201 {
202 if (!IsPasteboardValid(pasteboard) || status == nullptr) {
203 return nullptr;
204 }
205 auto unifiedData = std::make_shared<OHOS::UDMF::UnifiedData>();
206 int32_t ret = PasteboardClient::GetInstance()->GetUdsdData(*unifiedData);
207 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
208 PASTEBOARD_HILOGE(
209 PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_GetData return invalid, result is %{public}d", ret);
210 *status = GetMappedCode(ret);
211 return nullptr;
212 }
213 OH_UdmfData* data = OH_UdmfData_Create();
214 data->unifiedData_ = std::move(unifiedData);
215 *status = ERR_OK;
216 return data;
217 }
218
OH_Pasteboard_SetData(OH_Pasteboard * pasteboard,OH_UdmfData * data)219 int OH_Pasteboard_SetData(OH_Pasteboard* pasteboard, OH_UdmfData* data)
220 {
221 if (!IsPasteboardValid(pasteboard) || data == nullptr) {
222 return ERR_INVALID_PARAMETER;
223 }
224 int32_t ret = PasteboardClient::GetInstance()->SetUdsdData(*(data->unifiedData_));
225 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
226 PASTEBOARD_HILOGE(
227 PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_SetData return invalid, result is %{public}d", ret);
228 return GetMappedCode(ret);
229 }
230 return ERR_OK;
231 }
232
OH_Pasteboard_ClearData(OH_Pasteboard * pasteboard)233 int OH_Pasteboard_ClearData(OH_Pasteboard* pasteboard)
234 {
235 if (!IsPasteboardValid(pasteboard)) {
236 return ERR_INVALID_PARAMETER;
237 }
238 PasteboardClient::GetInstance()->Clear();
239 return ERR_OK;
240 }