1 /*
2  * Copyright (c) 2021-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 
16 #include <if_system_ability_manager.h>
17 #include <ipc_skeleton.h>
18 #include <iservice_registry.h>
19 #include <algorithm>
20 #include <chrono>
21 #include <memory>
22 #include "convert_utils.h"
23 #include "file_uri.h"
24 #include "hiview_adapter.h"
25 #include "hitrace_meter.h"
26 #include "pasteboard_client.h"
27 #include "pasteboard_deduplicate_memory.h"
28 #include "pasteboard_delay_getter_client.h"
29 #include "pasteboard_entry_getter_client.h"
30 #include "pasteboard_error.h"
31 #include "pasteboard_event_dfx.h"
32 #include "pasteboard_load_callback.h"
33 #include "pasteboard_observer.h"
34 #include "string_ex.h"
35 #include "system_ability_definition.h"
36 #include "pasteboard_web_controller.h"
37 #include "pasteboard_utils.h"
38 #include "ipasteboard_client_death_observer.h"
39 using namespace OHOS::Media;
40 
41 namespace OHOS {
42 namespace MiscServices {
43 constexpr const int32_t HITRACE_GETPASTEDATA = 0;
44 constexpr int32_t LOADSA_TIMEOUT_MS = 10000;
45 constexpr int64_t REPORT_DUPLICATE_TIMEOUT = 2 * 60 * 1000; // 2 minutes
46 sptr<IPasteboardService> PasteboardClient::pasteboardServiceProxy_;
47 PasteboardClient::StaticDestoryMonitor PasteboardClient::staticDestoryMonitor_;
48 std::mutex PasteboardClient::instanceLock_;
49 std::condition_variable PasteboardClient::proxyConVar_;
50 sptr<IRemoteObject> clientDeathObserverPtr_;
51 
52 struct RadarReportIdentity {
53     pid_t pid;
54     int32_t errorCode;
55 };
56 
operator ==(const RadarReportIdentity & lhs,const RadarReportIdentity & rhs)57 bool operator==(const RadarReportIdentity &lhs, const RadarReportIdentity &rhs)
58 {
59     return lhs.pid == rhs.pid && lhs.errorCode == rhs.errorCode;
60 }
61 
PasteboardClient()62 PasteboardClient::PasteboardClient()
63 {
64     Init();
65 };
~PasteboardClient()66 PasteboardClient::~PasteboardClient()
67 {
68     if (!staticDestoryMonitor_.IsDestoryed()) {
69         auto pasteboardServiceProxy = GetPasteboardServiceProxy();
70         if (pasteboardServiceProxy != nullptr) {
71             auto remoteObject = pasteboardServiceProxy->AsObject();
72             if (remoteObject != nullptr) {
73                 remoteObject->RemoveDeathRecipient(deathRecipient_);
74             }
75         }
76     }
77 }
78 
Init()79 void PasteboardClient::Init()
80 {
81     auto proxyService = GetPasteboardService();
82     if (proxyService == nullptr) {
83         return;
84     }
85     if (clientDeathObserverPtr_ == nullptr) {
86         clientDeathObserverPtr_ = new (std::nothrow) PasteboardClientDeathObserverStub();
87     }
88     if (clientDeathObserverPtr_ == nullptr) {
89         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "create ClientDeathObserver failed.");
90         return;
91     }
92     auto ret = proxyService->RegisterClientDeathObserver(clientDeathObserverPtr_);
93     if (ret != ERR_OK) {
94         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "failed. ret is %{public}d", ret);
95     }
96 }
97 
CreateHtmlTextRecord(const std::string & htmlText)98 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateHtmlTextRecord(const std::string &htmlText)
99 {
100     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New text record");
101     return PasteDataRecord::NewHtmlRecord(htmlText);
102 }
103 
CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)104 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
105 {
106     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New want record");
107     return PasteDataRecord::NewWantRecord(std::move(want));
108 }
109 
CreatePlainTextRecord(const std::string & text)110 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePlainTextRecord(const std::string &text)
111 {
112     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New text record");
113     return PasteDataRecord::NewPlaintTextRecord(text);
114 }
115 
CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)116 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
117 {
118     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New pixelMap record");
119     return PasteDataRecord::NewPixelMapRecord(std::move(pixelMap));
120 }
121 
CreateUriRecord(const OHOS::Uri & uri)122 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateUriRecord(const OHOS::Uri &uri)
123 {
124     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New uri record");
125     return PasteDataRecord::NewUriRecord(uri);
126 }
127 
CreateKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)128 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateKvRecord(
129     const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
130 {
131     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New kv record");
132     return PasteDataRecord::NewKvRecord(mimeType, arrayBuffer);
133 }
134 
CreateMultiDelayRecord(std::vector<std::string> mimeTypes,const std::shared_ptr<UDMF::EntryGetter> entryGetter)135 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateMultiDelayRecord(
136     std::vector<std::string> mimeTypes, const std::shared_ptr<UDMF::EntryGetter> entryGetter)
137 {
138     return PasteDataRecord::NewMultiTypeDelayRecord(mimeTypes, entryGetter);
139 }
140 
CreateHtmlData(const std::string & htmlText)141 std::shared_ptr<PasteData> PasteboardClient::CreateHtmlData(const std::string &htmlText)
142 {
143     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New htmlText data");
144     auto pasteData = std::make_shared<PasteData>();
145     pasteData->AddHtmlRecord(htmlText);
146     return pasteData;
147 }
148 
CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)149 std::shared_ptr<PasteData> PasteboardClient::CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)
150 {
151     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New want data");
152     auto pasteData = std::make_shared<PasteData>();
153     pasteData->AddWantRecord(std::move(want));
154     return pasteData;
155 }
156 
CreatePlainTextData(const std::string & text)157 std::shared_ptr<PasteData> PasteboardClient::CreatePlainTextData(const std::string &text)
158 {
159     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New plain data");
160     auto pasteData = std::make_shared<PasteData>();
161     pasteData->AddTextRecord(text);
162     return pasteData;
163 }
164 
CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)165 std::shared_ptr<PasteData> PasteboardClient::CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)
166 {
167     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New pixelMap data");
168     auto pasteData = std::make_shared<PasteData>();
169     pasteData->AddPixelMapRecord(std::move(pixelMap));
170     return pasteData;
171 }
172 
CreateUriData(const OHOS::Uri & uri)173 std::shared_ptr<PasteData> PasteboardClient::CreateUriData(const OHOS::Uri &uri)
174 {
175     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New uri data");
176     auto pasteData = std::make_shared<PasteData>();
177     pasteData->AddUriRecord(uri);
178     return pasteData;
179 }
180 
CreateKvData(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)181 std::shared_ptr<PasteData> PasteboardClient::CreateKvData(
182     const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
183 {
184     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New Kv data");
185     auto pasteData = std::make_shared<PasteData>();
186     pasteData->AddKvRecord(mimeType, arrayBuffer);
187     return pasteData;
188 }
189 
CreateMultiTypeData(std::shared_ptr<std::map<std::string,std::shared_ptr<EntryValue>>> typeValueMap,const std::string & recordMimeType)190 std::shared_ptr<PasteData> PasteboardClient::CreateMultiTypeData(
191     std::shared_ptr<std::map<std::string, std::shared_ptr<EntryValue>>> typeValueMap, const std::string &recordMimeType)
192 {
193     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New multiType data");
194     auto pasteData = std::make_shared<PasteData>();
195     pasteData->AddRecord(PasteDataRecord::NewMultiTypeRecord(std::move(typeValueMap), recordMimeType));
196     return pasteData;
197 }
198 
CreateMultiTypeDelayData(std::vector<std::string> mimeTypes,std::shared_ptr<UDMF::EntryGetter> entryGetter)199 std::shared_ptr<PasteData> PasteboardClient::CreateMultiTypeDelayData(std::vector<std::string> mimeTypes,
200     std::shared_ptr<UDMF::EntryGetter> entryGetter)
201 {
202     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New multiTypeDelay data");
203     auto pasteData = std::make_shared<PasteData>();
204     pasteData->AddRecord(PasteDataRecord::NewMultiTypeDelayRecord(mimeTypes, entryGetter));
205     return pasteData;
206 }
207 
GetRecordValueByType(uint32_t dataId,uint32_t recordId,PasteDataEntry & value)208 int32_t PasteboardClient::GetRecordValueByType(uint32_t dataId, uint32_t recordId, PasteDataEntry &value)
209 {
210     auto proxyService = GetPasteboardService();
211     if (proxyService == nullptr) {
212         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
213     }
214     return proxyService->GetRecordValueByType(dataId, recordId, value);
215 }
Clear()216 void PasteboardClient::Clear()
217 {
218     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Clear start.");
219     auto proxyService = GetPasteboardService();
220     if (proxyService == nullptr) {
221         return;
222     }
223     proxyService->Clear();
224     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Clear end.");
225     return;
226 }
227 
GetPasteData(PasteData & pasteData)228 int32_t PasteboardClient::GetPasteData(PasteData &pasteData)
229 {
230     static DeduplicateMemory<RadarReportIdentity> reportMemory(REPORT_DUPLICATE_TIMEOUT);
231     pid_t pid = getpid();
232     std::string currentPid = std::to_string(pid);
233     uint32_t tmpSequenceId = getSequenceId_++;
234     std::string currentId = "GetPasteData_" + currentPid + "_" + std::to_string(tmpSequenceId);
235     pasteData.SetPasteId(currentId);
236     RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_GET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
237         RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN, RadarReporter::CONCURRENT_ID, currentId,
238         RadarReporter::PACKAGE_NAME, currentPid);
239     StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
240     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetPasteData start.");
241     auto proxyService = GetPasteboardService();
242     if (proxyService == nullptr) {
243         RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_CHECK_GET_SERVER, RadarReporter::DFX_FAILED,
244             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId,
245             RadarReporter::PACKAGE_NAME, currentPid, RadarReporter::ERROR_CODE,
246             static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR));
247         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
248     }
249     int32_t syncTime = 0;
250     int32_t ret = proxyService->GetPasteData(pasteData, syncTime);
251     int32_t bizStage = (syncTime == 0) ? RadarReporter::DFX_LOCAL_PASTE_END : RadarReporter::DFX_DISTRIBUTED_PASTE_END;
252     RetainUri(pasteData);
253     RebuildWebviewPasteData(pasteData);
254     FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
255     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetPasteData end.");
256     if (ret == static_cast<int32_t>(PasteboardError::E_OK)) {
257         if (pasteData.deviceId_.empty()) {
258             RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_SUCCESS,
259                 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId,
260                 RadarReporter::DIS_SYNC_TIME, syncTime, RadarReporter::PACKAGE_NAME, currentPid);
261         } else {
262             RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_SUCCESS,
263                 RadarReporter::CONCURRENT_ID, currentId, RadarReporter::DIS_SYNC_TIME, syncTime,
264                 RadarReporter::PACKAGE_NAME, currentPid);
265         }
266     } else if (ret != static_cast<int32_t>(PasteboardError::TASK_PROCESSING) &&
267                !reportMemory.IsDuplicate({.pid = pid, .errorCode = ret})) {
268         RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_FAILED, RadarReporter::BIZ_STATE,
269             RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId, RadarReporter::DIS_SYNC_TIME,
270             syncTime, RadarReporter::PACKAGE_NAME, currentPid, RadarReporter::ERROR_CODE, ret);
271     } else {
272         RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_CANCELLED,
273             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId,
274             RadarReporter::DIS_SYNC_TIME, syncTime, RadarReporter::PACKAGE_NAME, currentPid,
275             RadarReporter::ERROR_CODE, ret);
276     }
277     return ret;
278 }
279 
GetUnifiedData(UDMF::UnifiedData & unifiedData)280 int32_t PasteboardClient::GetUnifiedData(UDMF::UnifiedData& unifiedData)
281 {
282     StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUnifiedData", HITRACE_GETPASTEDATA);
283     PasteData pasteData;
284     int32_t ret = GetPasteData(pasteData);
285     unifiedData = *(PasteboardUtils::GetInstance().Convert(pasteData));
286     FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUnifiedData", HITRACE_GETPASTEDATA);
287     return ret;
288 }
289 
GetUdsdData(UDMF::UnifiedData & unifiedData)290 int32_t PasteboardClient::GetUdsdData(UDMF::UnifiedData &unifiedData)
291 {
292     StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUdsdData", HITRACE_GETPASTEDATA);
293     PasteData pasteData;
294     int32_t ret = GetPasteData(pasteData);
295     unifiedData = *(ConvertUtils::Convert(pasteData));
296     FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUdsdData", HITRACE_GETPASTEDATA);
297     return ret;
298 }
299 
RefreshUri(std::shared_ptr<PasteDataRecord> & record)300 void PasteboardClient::RefreshUri(std::shared_ptr<PasteDataRecord> &record)
301 {
302     if (record->GetUri() == nullptr || record->GetFrom() == 0 || record->GetRecordId() == record->GetFrom()) {
303         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Rebuild webview one of uri is null or not extra uri.");
304         return;
305     }
306     std::shared_ptr<Uri> uri = record->GetUri();
307     std::string puri = uri->ToString();
308     std::string realUri = puri;
309     if (puri.substr(0, PasteData::FILE_SCHEME_PREFIX.size()) == PasteData::FILE_SCHEME_PREFIX) {
310         AppFileService::ModuleFileUri::FileUri fileUri(puri);
311         realUri = PasteData::FILE_SCHEME_PREFIX + fileUri.GetRealPath();
312         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "RebuildWebview uri is file uri: %{public}s", realUri.c_str());
313     }
314     if (realUri.find(PasteData::DISTRIBUTEDFILES_TAG) != std::string::npos) {
315         record->SetConvertUri(realUri);
316     } else {
317         record->SetUri(std::make_shared<OHOS::Uri>(realUri));
318     }
319 }
320 
RebuildWebviewPasteData(PasteData & pasteData)321 void PasteboardClient::RebuildWebviewPasteData(PasteData &pasteData)
322 {
323     if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG) {
324         return;
325     }
326     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Rebuild webview PasteData start.");
327     auto justSplitHtml = false;
328     auto details = std::make_shared<Details>();
329     std::string textContent;
330     for (auto &item : pasteData.AllRecords()) {
331         justSplitHtml = justSplitHtml || item->GetFrom() > 0;
332         if (!item->GetTextContent().empty() && textContent.empty()) {
333             details = item->GetDetails();
334             textContent = item->GetTextContent();
335         }
336         RefreshUri(item);
337     }
338     if (justSplitHtml) {
339         PasteboardWebController::GetInstance().MergeExtraUris2Html(pasteData);
340         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Rebuild webview PasteData end, merged uris into html.");
341         return;
342     }
343     if (pasteData.GetPrimaryHtml() == nullptr) {
344         return;
345     }
346 
347     auto webData = std::make_shared<PasteData>(pasteData);
348     PasteboardWebController::GetInstance().RebuildHtml(webData);
349     PasteDataRecord::Builder builder(MIMETYPE_TEXT_HTML);
350     std::shared_ptr<PasteDataRecord> pasteDataRecord = builder.SetMimeType(MIMETYPE_TEXT_HTML).
351         SetPlainText(pasteData.GetPrimaryText()).SetHtmlText(webData->GetPrimaryHtml()).Build();
352     if (details) {
353         pasteDataRecord->SetDetails(*details);
354     }
355     pasteDataRecord->SetUDType(UDMF::HTML);
356     pasteDataRecord->SetTextContent(textContent);
357     webData->AddRecord(pasteDataRecord);
358     std::size_t recordCnt = webData->GetRecordCount();
359     if (recordCnt >= 1) {
360         webData->RemoveRecordAt(recordCnt - 1);
361     }
362     pasteData = *webData;
363     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Rebuild webview PasteData end.");
364 }
365 
RetainUri(PasteData & pasteData)366 void PasteboardClient::RetainUri(PasteData &pasteData)
367 {
368     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "RetainUri start.");
369     if (!pasteData.IsLocalPaste()) {
370         return;
371     }
372     // clear convert uri
373     for (size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
374         auto record = pasteData.GetRecordAt(i);
375         if (record != nullptr) {
376             record->SetConvertUri("");
377         }
378     }
379     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "RetainUri end.");
380 }
381 
HasPasteData()382 bool PasteboardClient::HasPasteData()
383 {
384     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "HasPasteData start.");
385     auto proxyService = GetPasteboardService();
386     if (proxyService == nullptr) {
387         return false;
388     }
389     return proxyService->HasPasteData();
390 }
391 
SetPasteData(PasteData & pasteData,std::shared_ptr<PasteboardDelayGetter> delayGetter,std::map<uint32_t,std::shared_ptr<UDMF::EntryGetter>> entryGetters)392 int32_t PasteboardClient::SetPasteData(PasteData &pasteData, std::shared_ptr <PasteboardDelayGetter> delayGetter,
393                                        std::map <uint32_t, std::shared_ptr<UDMF::EntryGetter>> entryGetters)
394 {
395     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SetPasteData start.");
396     RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
397         RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
398     auto proxyService = GetPasteboardService();
399     if (proxyService == nullptr) {
400         RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_CHECK_SET_SERVER, RadarReporter::DFX_FAILED,
401             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
402             static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR));
403         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
404     }
405     sptr<PasteboardDelayGetterClient> delayGetterAgent;
406     if (delayGetter != nullptr) {
407         pasteData.SetDelayData(true);
408         delayGetterAgent = new (std::nothrow) PasteboardDelayGetterClient(delayGetter);
409     }
410     sptr <PasteboardEntryGetterClient> entryGetterAgent;
411     if (!(entryGetters.empty())) {
412         pasteData.SetDelayRecord(true);
413         entryGetterAgent = new(std::nothrow) PasteboardEntryGetterClient(entryGetters);
414     }
415 
416     SplitWebviewPasteData(pasteData);
417 
418     auto ret = proxyService->SetPasteData(pasteData, delayGetterAgent, entryGetterAgent);
419     if (ret == static_cast<int32_t>(PasteboardError::E_OK)) {
420         RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
421             RadarReporter::BIZ_STATE, RadarReporter::DFX_END);
422     } else {
423         RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
424             RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, ret);
425     }
426     return ret;
427 }
428 
SetUnifiedData(const UDMF::UnifiedData & unifiedData,std::shared_ptr<PasteboardDelayGetter> delayGetter)429 int32_t PasteboardClient::SetUnifiedData(const UDMF::UnifiedData &unifiedData,
430     std::shared_ptr<PasteboardDelayGetter> delayGetter)
431 {
432     auto pasteData = PasteboardUtils::GetInstance().Convert(unifiedData);
433     return SetPasteData(*pasteData, delayGetter);
434 }
435 
SetUdsdData(const UDMF::UnifiedData & unifiedData)436 int32_t PasteboardClient::SetUdsdData(const UDMF::UnifiedData &unifiedData)
437 {
438     auto pasteData = ConvertUtils::Convert(unifiedData);
439     std::map <uint32_t, std::shared_ptr<UDMF::EntryGetter>> entryGetters;
440     for (auto record : unifiedData.GetRecords()) {
441         if (record != nullptr && record->GetEntryGetter() != nullptr) {
442             entryGetters.emplace(record->GetRecordId(), record->GetEntryGetter());
443         }
444     }
445     return SetPasteData(*pasteData, nullptr, entryGetters);
446 }
447 
SplitWebviewPasteData(PasteData & pasteData)448 void PasteboardClient::SplitWebviewPasteData(PasteData &pasteData)
449 {
450     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SplitWebviewPasteData start.");
451     auto hasExtraRecord = false;
452     for (const auto &record : pasteData.AllRecords()) {
453         auto htmlEntry = record->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
454         if (htmlEntry == nullptr) {
455             continue;
456         }
457         std::shared_ptr<std::string> html = htmlEntry->ConvertToHtml();
458         if (html == nullptr || html->empty()) {
459             continue;
460         }
461         std::vector<std::shared_ptr<PasteDataRecord>> extraUriRecords =
462                 PasteboardWebController::GetInstance().SplitHtml2Records(html, record->GetRecordId());
463         if (extraUriRecords.empty()) {
464             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "SplitWebviewPasteData extraUriRecords is empty.");
465             continue;
466         }
467         hasExtraRecord = true;
468         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "extraUriRecords number: %{public}zu", extraUriRecords.size());
469         for (const auto &item : extraUriRecords) {
470             pasteData.AddRecord(item);
471         }
472         record->SetFrom(record->GetRecordId());
473     }
474     if (hasExtraRecord) {
475         pasteData.SetTag(PasteData::WEBVIEW_PASTEDATA_TAG);
476     }
477     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SplitWebviewPasteData end.");
478 }
479 
Subscribe(PasteboardObserverType type,sptr<PasteboardObserver> callback)480 void PasteboardClient::Subscribe(PasteboardObserverType type, sptr<PasteboardObserver> callback)
481 {
482     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
483     if (callback == nullptr) {
484         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "input nullptr.");
485         return;
486     }
487     auto proxyService = GetPasteboardService();
488     if (proxyService == nullptr) {
489         return;
490     }
491     proxyService->SubscribeObserver(type, callback);
492 }
493 
AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)494 void PasteboardClient::AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)
495 {
496     Subscribe(PasteboardObserverType::OBSERVER_LOCAL, callback);
497 }
498 
AddPasteboardEventObserver(sptr<PasteboardObserver> callback)499 void PasteboardClient::AddPasteboardEventObserver(sptr<PasteboardObserver> callback)
500 {
501     Subscribe(PasteboardObserverType::OBSERVER_EVENT, callback);
502 }
503 
Unsubscribe(PasteboardObserverType type,sptr<PasteboardObserver> callback)504 void PasteboardClient::Unsubscribe(PasteboardObserverType type, sptr<PasteboardObserver> callback)
505 {
506     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
507     auto proxyService = GetPasteboardService();
508     if (proxyService == nullptr) {
509         return;
510     }
511     if (callback == nullptr) {
512         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "remove all.");
513         proxyService->UnsubscribeAllObserver(type);
514         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
515         return;
516     }
517     proxyService->UnsubscribeObserver(type, callback);
518     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
519 }
520 
RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)521 void PasteboardClient::RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)
522 {
523     Unsubscribe(PasteboardObserverType::OBSERVER_LOCAL, callback);
524 }
525 
RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)526 void PasteboardClient::RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)
527 {
528     Unsubscribe(PasteboardObserverType::OBSERVER_EVENT, callback);
529 }
530 
SetGlobalShareOption(const std::map<uint32_t,ShareOption> & globalShareOptions)531 int32_t PasteboardClient::SetGlobalShareOption(const std::map<uint32_t, ShareOption> &globalShareOptions)
532 {
533     auto proxyService = GetPasteboardService();
534     if (proxyService == nullptr) {
535         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
536     }
537     return proxyService->SetGlobalShareOption(globalShareOptions);
538 }
539 
RemoveGlobalShareOption(const std::vector<uint32_t> & tokenIds)540 int32_t PasteboardClient::RemoveGlobalShareOption(const std::vector<uint32_t> &tokenIds)
541 {
542     auto proxyService = GetPasteboardService();
543     if (proxyService == nullptr) {
544         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
545     }
546     return proxyService->RemoveGlobalShareOption(tokenIds);
547 }
548 
GetGlobalShareOption(const std::vector<uint32_t> & tokenIds)549 std::map<uint32_t, ShareOption> PasteboardClient::GetGlobalShareOption(const std::vector<uint32_t> &tokenIds)
550 {
551     auto proxyService = GetPasteboardService();
552     if (proxyService == nullptr) {
553         return {};
554     }
555     return proxyService->GetGlobalShareOption(tokenIds);
556 }
557 
SetAppShareOptions(const ShareOption & shareOptions)558 int32_t PasteboardClient::SetAppShareOptions(const ShareOption &shareOptions)
559 {
560     auto proxyService = GetPasteboardService();
561     if (proxyService == nullptr) {
562         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
563     }
564     return proxyService->SetAppShareOptions(shareOptions);
565 }
566 
RemoveAppShareOptions()567 int32_t PasteboardClient::RemoveAppShareOptions()
568 {
569     auto proxyService = GetPasteboardService();
570     if (proxyService == nullptr) {
571         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
572     }
573     return proxyService->RemoveAppShareOptions();
574 }
575 
IsRemoteData()576 bool PasteboardClient::IsRemoteData()
577 {
578     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "IsRemoteData start.");
579     auto proxyService = GetPasteboardService();
580     if (proxyService == nullptr) {
581         return false;
582     }
583     auto ret = proxyService->IsRemoteData();
584     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "IsRemoteData end.");
585     return ret;
586 }
587 
GetDataSource(std::string & bundleName)588 int32_t PasteboardClient::GetDataSource(std::string &bundleName)
589 {
590     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetDataSource start.");
591     auto proxyService = GetPasteboardService();
592     if (proxyService == nullptr) {
593         return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
594     }
595     int32_t ret = proxyService->GetDataSource(bundleName);
596     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetDataSource end.");
597     return ret;
598 }
599 
GetMimeTypes()600 std::vector<std::string> PasteboardClient::GetMimeTypes()
601 {
602     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetMimeTypes start.");
603     auto proxyService = GetPasteboardService();
604     if (proxyService == nullptr) {
605         return {};
606     }
607     return proxyService->GetMimeTypes();
608 }
609 
HasDataType(const std::string & mimeType)610 bool PasteboardClient::HasDataType(const std::string &mimeType)
611 {
612     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "HasDataType start.");
613     auto proxyService = GetPasteboardService();
614     if (proxyService == nullptr) {
615         return false;
616     }
617     if (mimeType.empty()) {
618         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "parameter is invalid");
619         return false;
620     }
621     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "type is %{public}s", mimeType.c_str());
622     bool ret = proxyService->HasDataType(mimeType);
623     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "HasDataType end.");
624     return ret;
625 }
626 
DetectPatterns(const std::set<Pattern> & patternsToCheck)627 std::set<Pattern> PasteboardClient::DetectPatterns(const std::set<Pattern> &patternsToCheck)
628 {
629     if (!PatternDetection::IsValid(patternsToCheck)) {
630         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Invalid number in Pattern set!");
631         return {};
632     }
633 
634     auto proxyService = GetPasteboardService();
635     if (proxyService == nullptr) {
636         return {};
637     }
638     return proxyService->DetectPatterns(patternsToCheck);
639 }
640 
GetPasteboardService()641 sptr<IPasteboardService> PasteboardClient::GetPasteboardService()
642 {
643     std::unique_lock<std::mutex> lock(instanceLock_);
644     if (pasteboardServiceProxy_ != nullptr) {
645         return pasteboardServiceProxy_;
646     }
647     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "GetPasteboardService start.");
648     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
649     if (samgrProxy == nullptr) {
650         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Get SystemAbilityManager failed.");
651         pasteboardServiceProxy_ = nullptr;
652         return nullptr;
653     }
654     sptr<IRemoteObject> remoteObject = samgrProxy->CheckSystemAbility(PASTEBOARD_SERVICE_ID);
655     if (remoteObject != nullptr) {
656         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Get PasteboardServiceProxy succeed.");
657         if (deathRecipient_ == nullptr) {
658             deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
659         }
660         remoteObject->AddDeathRecipient(deathRecipient_);
661         pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
662         return pasteboardServiceProxy_;
663     }
664     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "remoteObject is null.");
665     sptr<PasteboardLoadCallback> loadCallback = new PasteboardLoadCallback();
666     if (loadCallback == nullptr) {
667         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "loadCallback is nullptr.");
668         return nullptr;
669     }
670     int32_t ret = samgrProxy->LoadSystemAbility(PASTEBOARD_SERVICE_ID, loadCallback);
671     if (ret != ERR_OK) {
672         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Failed to load systemAbility.");
673         return nullptr;
674     }
675     auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(LOADSA_TIMEOUT_MS),
676         [this]() { return pasteboardServiceProxy_ != nullptr; });
677     if (!waitStatus) {
678         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Load systemAbility timeout.");
679         return nullptr;
680     }
681     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Getting PasteboardServiceProxy succeeded.");
682     return pasteboardServiceProxy_;
683 }
684 
GetPasteboardServiceProxy()685 sptr<IPasteboardService> PasteboardClient::GetPasteboardServiceProxy()
686 {
687     std::lock_guard<std::mutex> lock(instanceLock_);
688     return pasteboardServiceProxy_;
689 }
690 
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)691 void PasteboardClient::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
692 {
693     std::lock_guard<std::mutex> lock(instanceLock_);
694     if (deathRecipient_ == nullptr) {
695         deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
696     }
697     if (remoteObject != nullptr) {
698         remoteObject->AddDeathRecipient(deathRecipient_);
699         pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
700     }
701     proxyConVar_.notify_one();
702 }
703 
LoadSystemAbilityFail()704 void PasteboardClient::LoadSystemAbilityFail()
705 {
706     std::lock_guard<std::mutex> lock(instanceLock_);
707     pasteboardServiceProxy_ = nullptr;
708     proxyConVar_.notify_one();
709 }
710 
OnRemoteSaDied(const wptr<IRemoteObject> & remote)711 void PasteboardClient::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
712 {
713     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "OnRemoteSaDied start.");
714     std::lock_guard<std::mutex> lock(instanceLock_);
715     pasteboardServiceProxy_ = nullptr;
716 }
717 
PasteStart(const std::string & pasteId)718 void PasteboardClient::PasteStart(const std::string &pasteId)
719 {
720     RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_DISTRIBUTED_FILE_START,
721         RadarReporter::DFX_SUCCESS, RadarReporter::CONCURRENT_ID, pasteId);
722     auto proxyService = GetPasteboardService();
723     if (proxyService == nullptr) {
724         return;
725     }
726     proxyService->PasteStart(pasteId);
727 }
728 
PasteComplete(const std::string & deviceId,const std::string & pasteId)729 void PasteboardClient::PasteComplete(const std::string &deviceId, const std::string &pasteId)
730 {
731     auto proxyService = GetPasteboardService();
732     if (proxyService == nullptr) {
733         return;
734     }
735     proxyService->PasteComplete(deviceId, pasteId);
736 }
737 
PasteboardSaDeathRecipient()738 PasteboardSaDeathRecipient::PasteboardSaDeathRecipient()
739 {
740 }
741 
OnRemoteDied(const wptr<IRemoteObject> & object)742 void PasteboardSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
743 {
744     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "PasteboardSaDeathRecipient on remote systemAbility died.");
745     PasteboardClient::GetInstance()->OnRemoteSaDied(object);
746 }
747 } // namespace MiscServices
748 } // namespace OHOS
749