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