1bc03f14fSopenharmony_ci/*
2bc03f14fSopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3bc03f14fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4bc03f14fSopenharmony_ci * you may not use this file except in compliance with the License.
5bc03f14fSopenharmony_ci * You may obtain a copy of the License at
6bc03f14fSopenharmony_ci *
7bc03f14fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8bc03f14fSopenharmony_ci *
9bc03f14fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10bc03f14fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11bc03f14fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12bc03f14fSopenharmony_ci * See the License for the specific language governing permissions and
13bc03f14fSopenharmony_ci * limitations under the License.
14bc03f14fSopenharmony_ci */
15bc03f14fSopenharmony_ci
16bc03f14fSopenharmony_ci#define LOG_TAG "Pasteboard_Capi"
17bc03f14fSopenharmony_ci
18bc03f14fSopenharmony_ci#include <map>
19bc03f14fSopenharmony_ci#include <memory>
20bc03f14fSopenharmony_ci#include <string>
21bc03f14fSopenharmony_ci#include <thread>
22bc03f14fSopenharmony_ci
23bc03f14fSopenharmony_ci#include "i_pasteboard_observer.h"
24bc03f14fSopenharmony_ci#include "oh_pasteboard.h"
25bc03f14fSopenharmony_ci#include "oh_pasteboard_err_code.h"
26bc03f14fSopenharmony_ci#include "oh_pasteboard_observer_impl.h"
27bc03f14fSopenharmony_ci#include "pasteboard_client.h"
28bc03f14fSopenharmony_ci#include "pasteboard_error.h"
29bc03f14fSopenharmony_ci#include "pasteboard_hilog.h"
30bc03f14fSopenharmony_ci#include "udmf.h"
31bc03f14fSopenharmony_ci#include "udmf_capi_common.h"
32bc03f14fSopenharmony_ci
33bc03f14fSopenharmony_ciusing namespace OHOS::MiscServices;
34bc03f14fSopenharmony_cistatic bool IsPasteboardValid(OH_Pasteboard *pasteboard)
35bc03f14fSopenharmony_ci{
36bc03f14fSopenharmony_ci    return pasteboard != nullptr && pasteboard->cid == PASTEBOARD_STRUCT_ID;
37bc03f14fSopenharmony_ci}
38bc03f14fSopenharmony_ci
39bc03f14fSopenharmony_cistatic bool IsSubscriberValid(OH_PasteboardObserver *observer)
40bc03f14fSopenharmony_ci{
41bc03f14fSopenharmony_ci    return observer != nullptr && observer->cid == SUBSCRIBER_STRUCT_ID;
42bc03f14fSopenharmony_ci}
43bc03f14fSopenharmony_ci
44bc03f14fSopenharmony_cistatic PASTEBOARD_ErrCode GetMappedCode(int32_t code)
45bc03f14fSopenharmony_ci{
46bc03f14fSopenharmony_ci    auto iter = errCodeMap.find(static_cast<PasteboardError>(code));
47bc03f14fSopenharmony_ci    if (iter != errCodeMap.end()) {
48bc03f14fSopenharmony_ci        return iter->second;
49bc03f14fSopenharmony_ci    }
50bc03f14fSopenharmony_ci    return ERR_INNER_ERROR;
51bc03f14fSopenharmony_ci}
52bc03f14fSopenharmony_ci
53bc03f14fSopenharmony_ciOH_PasteboardObserver *OH_PasteboardObserver_Create()
54bc03f14fSopenharmony_ci{
55bc03f14fSopenharmony_ci    OH_PasteboardObserver *observer = new (std::nothrow) OH_PasteboardObserver();
56bc03f14fSopenharmony_ci    if (observer == nullptr) {
57bc03f14fSopenharmony_ci        PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "allocate memory fail.");
58bc03f14fSopenharmony_ci        return nullptr;
59bc03f14fSopenharmony_ci    }
60bc03f14fSopenharmony_ci    return observer;
61bc03f14fSopenharmony_ci}
62bc03f14fSopenharmony_ci
63bc03f14fSopenharmony_ciint OH_PasteboardObserver_Destroy(OH_PasteboardObserver *observer)
64bc03f14fSopenharmony_ci{
65bc03f14fSopenharmony_ci    if (!IsSubscriberValid(observer)) {
66bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
67bc03f14fSopenharmony_ci    }
68bc03f14fSopenharmony_ci    if (observer->finalize != nullptr) {
69bc03f14fSopenharmony_ci        (observer->finalize)(observer->context);
70bc03f14fSopenharmony_ci        PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CAPI, "context finalized");
71bc03f14fSopenharmony_ci    }
72bc03f14fSopenharmony_ci    delete observer;
73bc03f14fSopenharmony_ci    return ERR_OK;
74bc03f14fSopenharmony_ci}
75bc03f14fSopenharmony_ci
76bc03f14fSopenharmony_ciint OH_PasteboardObserver_SetData(OH_PasteboardObserver *observer, void *context, const Pasteboard_Notify callback,
77bc03f14fSopenharmony_ci    const Pasteboard_Finalize finalize)
78bc03f14fSopenharmony_ci{
79bc03f14fSopenharmony_ci    if (observer == nullptr || callback == nullptr) {
80bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
81bc03f14fSopenharmony_ci    }
82bc03f14fSopenharmony_ci    observer->callback = callback;
83bc03f14fSopenharmony_ci    if (context != nullptr && finalize == nullptr) {
84bc03f14fSopenharmony_ci        PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "finalize is null");
85bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
86bc03f14fSopenharmony_ci    }
87bc03f14fSopenharmony_ci    observer->context = context;
88bc03f14fSopenharmony_ci    observer->finalize = finalize;
89bc03f14fSopenharmony_ci    return ERR_OK;
90bc03f14fSopenharmony_ci}
91bc03f14fSopenharmony_ci
92bc03f14fSopenharmony_ciOH_Pasteboard *OH_Pasteboard_Create()
93bc03f14fSopenharmony_ci{
94bc03f14fSopenharmony_ci    OH_Pasteboard *pasteboard = new (std::nothrow) OH_Pasteboard();
95bc03f14fSopenharmony_ci    if (pasteboard == nullptr) {
96bc03f14fSopenharmony_ci        PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "allocate memory fail.");
97bc03f14fSopenharmony_ci        return nullptr;
98bc03f14fSopenharmony_ci    }
99bc03f14fSopenharmony_ci    return pasteboard;
100bc03f14fSopenharmony_ci}
101bc03f14fSopenharmony_ci
102bc03f14fSopenharmony_civoid OH_Pasteboard_Destroy(OH_Pasteboard *pasteboard)
103bc03f14fSopenharmony_ci{
104bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard)) {
105bc03f14fSopenharmony_ci        return;
106bc03f14fSopenharmony_ci    }
107bc03f14fSopenharmony_ci    std::lock_guard<std::mutex> lock(pasteboard->mutex);
108bc03f14fSopenharmony_ci    for (auto iter : pasteboard->observers_) {
109bc03f14fSopenharmony_ci        if (iter.second != nullptr) {
110bc03f14fSopenharmony_ci            PasteboardClient::GetInstance()->Unsubscribe(
111bc03f14fSopenharmony_ci                static_cast<PasteboardObserverType>(iter.second->GetType()), iter.second);
112bc03f14fSopenharmony_ci        }
113bc03f14fSopenharmony_ci    }
114bc03f14fSopenharmony_ci    pasteboard->observers_.clear();
115bc03f14fSopenharmony_ci    delete pasteboard;
116bc03f14fSopenharmony_ci}
117bc03f14fSopenharmony_ci
118bc03f14fSopenharmony_ciint OH_Pasteboard_Subscribe(OH_Pasteboard *pasteboard, int type, const OH_PasteboardObserver *observer)
119bc03f14fSopenharmony_ci{
120bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE ||
121bc03f14fSopenharmony_ci        type > NOTIFY_REMOTE_DATA_CHANGE) {
122bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
123bc03f14fSopenharmony_ci    }
124bc03f14fSopenharmony_ci    std::lock_guard<std::mutex> lock(pasteboard->mutex);
125bc03f14fSopenharmony_ci    auto iter = pasteboard->observers_.find(observer);
126bc03f14fSopenharmony_ci    if (iter != pasteboard->observers_.end()) {
127bc03f14fSopenharmony_ci        PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "observer exist.");
128bc03f14fSopenharmony_ci        return ERR_OK;
129bc03f14fSopenharmony_ci    }
130bc03f14fSopenharmony_ci    OHOS::sptr<PasteboardObserverCapiImpl> observerBox = new (std::nothrow) PasteboardObserverCapiImpl();
131bc03f14fSopenharmony_ci    if (observerBox == nullptr) {
132bc03f14fSopenharmony_ci        return ERR_INNER_ERROR;
133bc03f14fSopenharmony_ci    }
134bc03f14fSopenharmony_ci    observerBox->SetInnerObserver(observer);
135bc03f14fSopenharmony_ci    observerBox->SetType(static_cast<Pasteboard_NotifyType>(type));
136bc03f14fSopenharmony_ci    pasteboard->observers_[observer] = observerBox;
137bc03f14fSopenharmony_ci    PasteboardClient::GetInstance()->Subscribe(static_cast<PasteboardObserverType>(type), observerBox);
138bc03f14fSopenharmony_ci    return ERR_OK;
139bc03f14fSopenharmony_ci}
140bc03f14fSopenharmony_ci
141bc03f14fSopenharmony_ciint OH_Pasteboard_Unsubscribe(OH_Pasteboard *pasteboard, int type, const OH_PasteboardObserver *observer)
142bc03f14fSopenharmony_ci{
143bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard) || observer == nullptr || type < NOTIFY_LOCAL_DATA_CHANGE ||
144bc03f14fSopenharmony_ci        type > NOTIFY_REMOTE_DATA_CHANGE) {
145bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
146bc03f14fSopenharmony_ci    }
147bc03f14fSopenharmony_ci    std::lock_guard<std::mutex> lock(pasteboard->mutex);
148bc03f14fSopenharmony_ci    auto iter = pasteboard->observers_.find(observer);
149bc03f14fSopenharmony_ci    if (iter == pasteboard->observers_.end()) {
150bc03f14fSopenharmony_ci        PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CAPI, "couldn't find this observer");
151bc03f14fSopenharmony_ci        return ERR_OK;
152bc03f14fSopenharmony_ci    }
153bc03f14fSopenharmony_ci    PasteboardClient::GetInstance()->Unsubscribe(static_cast<PasteboardObserverType>(type), iter->second);
154bc03f14fSopenharmony_ci    pasteboard->observers_.erase(iter);
155bc03f14fSopenharmony_ci    return ERR_OK;
156bc03f14fSopenharmony_ci}
157bc03f14fSopenharmony_ci
158bc03f14fSopenharmony_cibool OH_Pasteboard_IsRemoteData(OH_Pasteboard *pasteboard)
159bc03f14fSopenharmony_ci{
160bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard)) {
161bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
162bc03f14fSopenharmony_ci    }
163bc03f14fSopenharmony_ci    return PasteboardClient::GetInstance()->IsRemoteData();
164bc03f14fSopenharmony_ci}
165bc03f14fSopenharmony_ci
166bc03f14fSopenharmony_ciint OH_Pasteboard_GetDataSource(OH_Pasteboard *pasteboard, char *source, unsigned int len)
167bc03f14fSopenharmony_ci{
168bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard) || source == nullptr || len == 0) {
169bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
170bc03f14fSopenharmony_ci    }
171bc03f14fSopenharmony_ci    std::string bundleName;
172bc03f14fSopenharmony_ci    auto ret = PasteboardClient::GetInstance()->GetDataSource(bundleName);
173bc03f14fSopenharmony_ci    if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
174bc03f14fSopenharmony_ci        PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "client getDataSource return invalid, result is %{public}d", ret);
175bc03f14fSopenharmony_ci        return GetMappedCode(ret);
176bc03f14fSopenharmony_ci    }
177bc03f14fSopenharmony_ci    if (strcpy_s(source, len, bundleName.c_str()) != EOK) {
178bc03f14fSopenharmony_ci        PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CAPI, "copy string fail");
179bc03f14fSopenharmony_ci        return ERR_INNER_ERROR;
180bc03f14fSopenharmony_ci    }
181bc03f14fSopenharmony_ci    return ERR_OK;
182bc03f14fSopenharmony_ci}
183bc03f14fSopenharmony_ci
184bc03f14fSopenharmony_cibool OH_Pasteboard_HasType(OH_Pasteboard *pasteboard, const char *type)
185bc03f14fSopenharmony_ci{
186bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard) || type == nullptr) {
187bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
188bc03f14fSopenharmony_ci    }
189bc03f14fSopenharmony_ci    return PasteboardClient::GetInstance()->HasDataType(std::string(type));
190bc03f14fSopenharmony_ci}
191bc03f14fSopenharmony_ci
192bc03f14fSopenharmony_cibool OH_Pasteboard_HasData(OH_Pasteboard *pasteboard)
193bc03f14fSopenharmony_ci{
194bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard)) {
195bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
196bc03f14fSopenharmony_ci    }
197bc03f14fSopenharmony_ci    return PasteboardClient::GetInstance()->HasPasteData();
198bc03f14fSopenharmony_ci}
199bc03f14fSopenharmony_ci
200bc03f14fSopenharmony_ciOH_UdmfData *OH_Pasteboard_GetData(OH_Pasteboard *pasteboard, int *status)
201bc03f14fSopenharmony_ci{
202bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard) || status == nullptr) {
203bc03f14fSopenharmony_ci        return nullptr;
204bc03f14fSopenharmony_ci    }
205bc03f14fSopenharmony_ci    auto unifiedData = std::make_shared<OHOS::UDMF::UnifiedData>();
206bc03f14fSopenharmony_ci    int32_t ret = PasteboardClient::GetInstance()->GetUdsdData(*unifiedData);
207bc03f14fSopenharmony_ci    if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
208bc03f14fSopenharmony_ci        PASTEBOARD_HILOGE(
209bc03f14fSopenharmony_ci            PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_GetData return invalid, result is %{public}d", ret);
210bc03f14fSopenharmony_ci        *status = GetMappedCode(ret);
211bc03f14fSopenharmony_ci        return nullptr;
212bc03f14fSopenharmony_ci    }
213bc03f14fSopenharmony_ci    OH_UdmfData *data = OH_UdmfData_Create();
214bc03f14fSopenharmony_ci    data->unifiedData_ = std::move(unifiedData);
215bc03f14fSopenharmony_ci    *status = ERR_OK;
216bc03f14fSopenharmony_ci    return data;
217bc03f14fSopenharmony_ci}
218bc03f14fSopenharmony_ci
219bc03f14fSopenharmony_ciint OH_Pasteboard_SetData(OH_Pasteboard *pasteboard, OH_UdmfData *data)
220bc03f14fSopenharmony_ci{
221bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard) || data == nullptr) {
222bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
223bc03f14fSopenharmony_ci    }
224bc03f14fSopenharmony_ci    int32_t ret = PasteboardClient::GetInstance()->SetUdsdData(*(data->unifiedData_));
225bc03f14fSopenharmony_ci    if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
226bc03f14fSopenharmony_ci        PASTEBOARD_HILOGE(
227bc03f14fSopenharmony_ci            PASTEBOARD_MODULE_CAPI, "client OH_Pasteboard_SetData return invalid, result is %{public}d", ret);
228bc03f14fSopenharmony_ci        return GetMappedCode(ret);
229bc03f14fSopenharmony_ci    }
230bc03f14fSopenharmony_ci    return ERR_OK;
231bc03f14fSopenharmony_ci}
232bc03f14fSopenharmony_ci
233bc03f14fSopenharmony_ciint OH_Pasteboard_ClearData(OH_Pasteboard *pasteboard)
234bc03f14fSopenharmony_ci{
235bc03f14fSopenharmony_ci    if (!IsPasteboardValid(pasteboard)) {
236bc03f14fSopenharmony_ci        return ERR_INVALID_PARAMETER;
237bc03f14fSopenharmony_ci    }
238bc03f14fSopenharmony_ci    PasteboardClient::GetInstance()->Clear();
239bc03f14fSopenharmony_ci    return ERR_OK;
240bc03f14fSopenharmony_ci} // namespace OHOS