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