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