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 <thread>
23
24 #include "convert_utils.h"
25 #include "ffrt_utils.h"
26 #include "file_uri.h"
27 #include "hitrace_meter.h"
28 #include "hiview_adapter.h"
29 #include "in_process_call_wrapper.h"
30 #include "ipasteboard_client_death_observer.h"
31 #include "pasteboard_client.h"
32 #include "pasteboard_copy.h"
33 #include "pasteboard_deduplicate_memory.h"
34 #include "pasteboard_delay_getter_client.h"
35 #include "pasteboard_entry_getter_client.h"
36 #include "pasteboard_error.h"
37 #include "pasteboard_event_dfx.h"
38 #include "pasteboard_load_callback.h"
39 #include "pasteboard_observer.h"
40 #include "pasteboard_progress.h"
41 #include "pasteboard_signal_callback.h"
42 #include "pasteboard_utils.h"
43 #include "pasteboard_web_controller.h"
44 #include "string_ex.h"
45 #include "system_ability_definition.h"
46 #include "udmf_client.h"
47 using namespace OHOS::Media;
48
49 namespace OHOS {
50 namespace MiscServices {
51 constexpr const int32_t HITRACE_GETPASTEDATA = 0;
52 std::string g_progressKey;
53 constexpr int32_t LOADSA_TIMEOUT_MS = 10000;
54 constexpr int32_t PASTEBOARD_PROGRESS_UPDATE_PERCENT = 5;
55 constexpr int32_t UPDATE_PERCENT_WITHOUT_FILE = 10;
56 constexpr int32_t PASTEBOARD_PROGRESS_TWENTY_PERCENT = 20;
57 constexpr int32_t PASTEBOARD_PROGRESS_FINISH_PERCENT = 100;
58 constexpr int32_t PASTEBOARD_PROGRESS_SLEEP_TIME = 100; // ms
59 constexpr int32_t SLEEP_TIME_WITHOUT_FILE = 50; // ms
60 constexpr int32_t PASTEBOARD_PROGRESS_RETRY_TIMES = 10;
61 constexpr int64_t REPORT_DUPLICATE_TIMEOUT = 2 * 60 * 1000; // 2 minutes
62 static constexpr int32_t HAP_PULL_UP_TIME = 500; // ms
63 sptr<IPasteboardService> PasteboardClient::pasteboardServiceProxy_;
64 PasteboardClient::StaticDestoryMonitor PasteboardClient::staticDestoryMonitor_;
65 std::mutex PasteboardClient::instanceLock_;
66 std::condition_variable PasteboardClient::proxyConVar_;
67 sptr<IRemoteObject> clientDeathObserverPtr_;
68 std::atomic<bool> PasteboardClient::remoteTask_(false);
69 std::atomic<bool> PasteboardClient::isPasting_(false);
70
71 struct RadarReportIdentity {
72 pid_t pid;
73 int32_t errorCode;
74 };
75
operator ==(const RadarReportIdentity & lhs,const RadarReportIdentity & rhs)76 bool operator==(const RadarReportIdentity &lhs, const RadarReportIdentity &rhs)
77 {
78 return lhs.pid == rhs.pid && lhs.errorCode == rhs.errorCode;
79 }
80
PasteboardClient()81 PasteboardClient::PasteboardClient()
82 {
83 Init();
84 };
~PasteboardClient()85 PasteboardClient::~PasteboardClient()
86 {
87 if (!staticDestoryMonitor_.IsDestoryed()) {
88 auto pasteboardServiceProxy = GetPasteboardServiceProxy();
89 if (pasteboardServiceProxy != nullptr) {
90 auto remoteObject = pasteboardServiceProxy->AsObject();
91 if (remoteObject != nullptr) {
92 remoteObject->RemoveDeathRecipient(deathRecipient_);
93 }
94 }
95 }
96 }
97
Init()98 void PasteboardClient::Init()
99 {
100 auto proxyService = GetPasteboardService();
101 if (proxyService == nullptr) {
102 return;
103 }
104 if (clientDeathObserverPtr_ == nullptr) {
105 clientDeathObserverPtr_ = new (std::nothrow) PasteboardClientDeathObserverStub();
106 }
107 if (clientDeathObserverPtr_ == nullptr) {
108 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "create ClientDeathObserver failed.");
109 return;
110 }
111 auto ret = proxyService->RegisterClientDeathObserver(clientDeathObserverPtr_);
112 if (ret != ERR_OK) {
113 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "failed. ret is %{public}d", ret);
114 }
115 }
116
CreateHtmlTextRecord(const std::string & htmlText)117 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateHtmlTextRecord(const std::string &htmlText)
118 {
119 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New text record");
120 return PasteDataRecord::NewHtmlRecord(htmlText);
121 }
122
CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)123 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
124 {
125 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New want record");
126 return PasteDataRecord::NewWantRecord(std::move(want));
127 }
128
CreatePlainTextRecord(const std::string & text)129 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePlainTextRecord(const std::string &text)
130 {
131 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New text record");
132 return PasteDataRecord::NewPlaintTextRecord(text);
133 }
134
CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)135 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
136 {
137 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New pixelMap record");
138 return PasteDataRecord::NewPixelMapRecord(std::move(pixelMap));
139 }
140
CreateUriRecord(const OHOS::Uri & uri)141 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateUriRecord(const OHOS::Uri &uri)
142 {
143 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New uri record");
144 return PasteDataRecord::NewUriRecord(uri);
145 }
146
CreateKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)147 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateKvRecord(
148 const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
149 {
150 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New kv record");
151 return PasteDataRecord::NewKvRecord(mimeType, arrayBuffer);
152 }
153
CreateMultiDelayRecord(std::vector<std::string> mimeTypes,const std::shared_ptr<UDMF::EntryGetter> entryGetter)154 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateMultiDelayRecord(
155 std::vector<std::string> mimeTypes, const std::shared_ptr<UDMF::EntryGetter> entryGetter)
156 {
157 return PasteDataRecord::NewMultiTypeDelayRecord(mimeTypes, entryGetter);
158 }
159
CreateHtmlData(const std::string & htmlText)160 std::shared_ptr<PasteData> PasteboardClient::CreateHtmlData(const std::string &htmlText)
161 {
162 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New htmlText data");
163 auto pasteData = std::make_shared<PasteData>();
164 pasteData->AddHtmlRecord(htmlText);
165 return pasteData;
166 }
167
CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)168 std::shared_ptr<PasteData> PasteboardClient::CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)
169 {
170 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New want data");
171 auto pasteData = std::make_shared<PasteData>();
172 pasteData->AddWantRecord(std::move(want));
173 return pasteData;
174 }
175
CreatePlainTextData(const std::string & text)176 std::shared_ptr<PasteData> PasteboardClient::CreatePlainTextData(const std::string &text)
177 {
178 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New plain data");
179 auto pasteData = std::make_shared<PasteData>();
180 pasteData->AddTextRecord(text);
181 return pasteData;
182 }
183
CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)184 std::shared_ptr<PasteData> PasteboardClient::CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)
185 {
186 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New pixelMap data");
187 auto pasteData = std::make_shared<PasteData>();
188 pasteData->AddPixelMapRecord(std::move(pixelMap));
189 return pasteData;
190 }
191
CreateUriData(const OHOS::Uri & uri)192 std::shared_ptr<PasteData> PasteboardClient::CreateUriData(const OHOS::Uri &uri)
193 {
194 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New uri data");
195 auto pasteData = std::make_shared<PasteData>();
196 pasteData->AddUriRecord(uri);
197 return pasteData;
198 }
199
CreateKvData(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)200 std::shared_ptr<PasteData> PasteboardClient::CreateKvData(
201 const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
202 {
203 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New Kv data");
204 auto pasteData = std::make_shared<PasteData>();
205 pasteData->AddKvRecord(mimeType, arrayBuffer);
206 return pasteData;
207 }
208
CreateMultiTypeData(std::shared_ptr<std::map<std::string,std::shared_ptr<EntryValue>>> typeValueMap,const std::string & recordMimeType)209 std::shared_ptr<PasteData> PasteboardClient::CreateMultiTypeData(
210 std::shared_ptr<std::map<std::string, std::shared_ptr<EntryValue>>> typeValueMap, const std::string &recordMimeType)
211 {
212 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New multiType data");
213 auto pasteData = std::make_shared<PasteData>();
214 pasteData->AddRecord(PasteDataRecord::NewMultiTypeRecord(std::move(typeValueMap), recordMimeType));
215 return pasteData;
216 }
217
CreateMultiTypeDelayData(std::vector<std::string> mimeTypes,std::shared_ptr<UDMF::EntryGetter> entryGetter)218 std::shared_ptr<PasteData> PasteboardClient::CreateMultiTypeDelayData(std::vector<std::string> mimeTypes,
219 std::shared_ptr<UDMF::EntryGetter> entryGetter)
220 {
221 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New multiTypeDelay data");
222 auto pasteData = std::make_shared<PasteData>();
223 pasteData->AddRecord(PasteDataRecord::NewMultiTypeDelayRecord(mimeTypes, entryGetter));
224 return pasteData;
225 }
226
GetRecordValueByType(uint32_t dataId,uint32_t recordId,PasteDataEntry & value)227 int32_t PasteboardClient::GetRecordValueByType(uint32_t dataId, uint32_t recordId, PasteDataEntry &value)
228 {
229 auto proxyService = GetPasteboardService();
230 if (proxyService == nullptr) {
231 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
232 }
233 return proxyService->GetRecordValueByType(dataId, recordId, value);
234 }
Clear()235 void PasteboardClient::Clear()
236 {
237 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Clear start.");
238 auto proxyService = GetPasteboardService();
239 if (proxyService == nullptr) {
240 return;
241 }
242 proxyService->Clear();
243 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Clear end.");
244 return;
245 }
246
GetPasteData(PasteData & pasteData)247 int32_t PasteboardClient::GetPasteData(PasteData &pasteData)
248 {
249 static DeduplicateMemory<RadarReportIdentity> reportMemory(REPORT_DUPLICATE_TIMEOUT);
250 pid_t pid = getpid();
251 std::string currentPid = std::to_string(pid);
252 uint32_t tmpSequenceId = getSequenceId_++;
253 std::string currentId = "GetPasteData_" + currentPid + "_" + std::to_string(tmpSequenceId);
254 pasteData.SetPasteId(currentId);
255 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_GET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
256 RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN, RadarReporter::CONCURRENT_ID, currentId,
257 RadarReporter::PACKAGE_NAME, currentPid);
258 StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
259 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetPasteData start.");
260 auto proxyService = GetPasteboardService();
261 if (proxyService == nullptr) {
262 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_CHECK_GET_SERVER, RadarReporter::DFX_FAILED,
263 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId,
264 RadarReporter::PACKAGE_NAME, currentPid, RadarReporter::ERROR_CODE,
265 static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR));
266 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
267 }
268 int32_t syncTime = 0;
269 int32_t ret = proxyService->GetPasteData(pasteData, syncTime);
270 int32_t bizStage = (syncTime == 0) ? RadarReporter::DFX_LOCAL_PASTE_END : RadarReporter::DFX_DISTRIBUTED_PASTE_END;
271 RetainUri(pasteData);
272 RebuildWebviewPasteData(pasteData);
273 FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
274 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetPasteData end.");
275 if (ret == static_cast<int32_t>(PasteboardError::E_OK)) {
276 if (pasteData.deviceId_.empty()) {
277 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_SUCCESS,
278 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId,
279 RadarReporter::DIS_SYNC_TIME, syncTime, RadarReporter::PACKAGE_NAME, currentPid);
280 } else {
281 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_SUCCESS,
282 RadarReporter::CONCURRENT_ID, currentId, RadarReporter::DIS_SYNC_TIME, syncTime,
283 RadarReporter::PACKAGE_NAME, currentPid);
284 }
285 } else if (ret != static_cast<int32_t>(PasteboardError::TASK_PROCESSING) &&
286 !reportMemory.IsDuplicate({.pid = pid, .errorCode = ret})) {
287 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_FAILED, RadarReporter::BIZ_STATE,
288 RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId, RadarReporter::DIS_SYNC_TIME,
289 syncTime, RadarReporter::PACKAGE_NAME, currentPid, RadarReporter::ERROR_CODE, ret);
290 } else {
291 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_CANCELLED,
292 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, currentId,
293 RadarReporter::DIS_SYNC_TIME, syncTime, RadarReporter::PACKAGE_NAME, currentPid,
294 RadarReporter::ERROR_CODE, ret);
295 }
296 return ret;
297 }
298
GetProgressByProgressInfo(std::shared_ptr<GetDataParams> params)299 void PasteboardClient::GetProgressByProgressInfo(std::shared_ptr<GetDataParams> params)
300 {
301 if (params == nullptr) {
302 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "params is null!");
303 return;
304 }
305
306 if (params->info == nullptr) {
307 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "params->info is null!");
308 return;
309 }
310 std::unique_lock<std::mutex> lock(instanceLock_);
311 std::string progressKey = g_progressKey;
312 lock.unlock();
313 std::string currentValue = std::to_string(params->info->percentage);
314 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "pasteboard progress percent = %{public}s", currentValue.c_str());
315 PasteBoardProgress::GetInstance().UpdateValue(progressKey, currentValue);
316 }
317
SetProgressWithoutFile(std::string & progressKey,std::shared_ptr<GetDataParams> params)318 int32_t PasteboardClient::SetProgressWithoutFile(std::string &progressKey, std::shared_ptr<GetDataParams> params)
319 {
320 int progressValue = PASTEBOARD_PROGRESS_TWENTY_PERCENT;
321 std::string currentValue = std::to_string(PASTEBOARD_PROGRESS_TWENTY_PERCENT);
322 while (progressValue < PASTEBOARD_PROGRESS_FINISH_PERCENT && !remoteTask_.load()) {
323 if (ProgressSignalClient::GetInstance().CheckCancelIfNeed()) {
324 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "progress cancel success!");
325 return static_cast<int32_t>(PasteboardError::E_OK);
326 }
327 std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_WITHOUT_FILE));
328 progressValue += UPDATE_PERCENT_WITHOUT_FILE;
329 currentValue = std::to_string(progressValue);
330 if (params->info != nullptr) {
331 params->info->percentage = progressValue;
332 }
333 if (params->listener.ProgressNotify != nullptr) {
334 params->listener.ProgressNotify(params);
335 }
336 }
337 return static_cast<int32_t>(PasteboardError::E_OK);
338 }
339
ProgressSmoothToTwentyPercent(PasteData & pasteData,std::string & progressKey,std::shared_ptr<GetDataParams> params)340 void PasteboardClient::ProgressSmoothToTwentyPercent(PasteData &pasteData, std::string &progressKey,
341 std::shared_ptr<GetDataParams> params)
342 {
343 if (pasteData.GetRecordCount() <= 0) {
344 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "no pasteData, progress no need to twenty");
345 return;
346 }
347 int progressValue = 0;
348 std::string currentValue = "0";
349 while (progressValue < PASTEBOARD_PROGRESS_TWENTY_PERCENT && !remoteTask_.load()) {
350 if (ProgressSignalClient::GetInstance().CheckCancelIfNeed()) {
351 return;
352 }
353 std::this_thread::sleep_for(std::chrono::milliseconds(PASTEBOARD_PROGRESS_SLEEP_TIME));
354 progressValue += PASTEBOARD_PROGRESS_UPDATE_PERCENT;
355 currentValue = std::to_string(progressValue);
356 if (params->info != nullptr) {
357 params->info->percentage = progressValue;
358 }
359 if (params->listener.ProgressNotify != nullptr) {
360 params->listener.ProgressNotify(params);
361 }
362 }
363 }
364
OnProgressAbnormal(int32_t result)365 void PasteboardClient::OnProgressAbnormal(int32_t result)
366 {
367 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "The progress is reported abnormal.");
368 remoteTask_.store(true);
369 }
370
GetPasteDataFromService(PasteData & pasteData,PasteDataFromServiceInfo & pasteDataFromServiceInfo,std::string progressKey,std::shared_ptr<GetDataParams> params)371 int32_t PasteboardClient::GetPasteDataFromService(PasteData &pasteData,
372 PasteDataFromServiceInfo &pasteDataFromServiceInfo, std::string progressKey, std::shared_ptr<GetDataParams> params)
373 {
374 static DeduplicateMemory<RadarReportIdentity> reportMemory(REPORT_DUPLICATE_TIMEOUT);
375 auto proxyService = GetPasteboardService();
376 if (proxyService == nullptr) {
377 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_CHECK_GET_SERVER,
378 RadarReporter::DFX_FAILED, RadarReporter::BIZ_STATE, RadarReporter::DFX_END,
379 RadarReporter::CONCURRENT_ID, pasteDataFromServiceInfo.currentId,
380 RadarReporter::PACKAGE_NAME, pasteDataFromServiceInfo.currentId, RadarReporter::ERROR_CODE,
381 static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR));
382 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
383 }
384 int32_t syncTime = 0;
385 int32_t ret = proxyService->GetPasteData(pasteData, syncTime);
386 ProgressSmoothToTwentyPercent(pasteData, progressKey, params);
387 int32_t bizStage = (syncTime == 0) ? RadarReporter::DFX_LOCAL_PASTE_END : RadarReporter::DFX_DISTRIBUTED_PASTE_END;
388 RetainUri(pasteData);
389 if (ret == static_cast<int32_t>(PasteboardError::E_OK)) {
390 if (pasteData.deviceId_.empty()) {
391 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_SUCCESS,
392 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID,
393 pasteDataFromServiceInfo.currentId, RadarReporter::DIS_SYNC_TIME, syncTime,
394 RadarReporter::PACKAGE_NAME, pasteDataFromServiceInfo.currentPid);
395 } else {
396 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_SUCCESS,
397 RadarReporter::CONCURRENT_ID, pasteDataFromServiceInfo.currentId,
398 RadarReporter::DIS_SYNC_TIME, syncTime, RadarReporter::PACKAGE_NAME,
399 pasteDataFromServiceInfo.currentId);
400 }
401 } else if (ret != static_cast<int32_t>(PasteboardError::TASK_PROCESSING) &&
402 !reportMemory.IsDuplicate({.pid = pasteDataFromServiceInfo.pid, .errorCode = ret})) {
403 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_FAILED,
404 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID,
405 pasteDataFromServiceInfo.currentId, RadarReporter::DIS_SYNC_TIME, syncTime,
406 RadarReporter::PACKAGE_NAME, pasteDataFromServiceInfo.currentPid, RadarReporter::ERROR_CODE, ret);
407 } else {
408 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, bizStage, RadarReporter::DFX_CANCELLED,
409 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID,
410 pasteDataFromServiceInfo.currentId, RadarReporter::DIS_SYNC_TIME, syncTime,
411 RadarReporter::PACKAGE_NAME, pasteDataFromServiceInfo.currentPid, RadarReporter::ERROR_CODE, ret);
412 }
413 return ret;
414 }
415
ProgressRadarReport(PasteData & pasteData,PasteDataFromServiceInfo & pasteDataFromServiceInfo)416 void PasteboardClient::ProgressRadarReport(PasteData &pasteData, PasteDataFromServiceInfo &pasteDataFromServiceInfo)
417 {
418 pasteDataFromServiceInfo.pid = getpid();
419 pasteDataFromServiceInfo.currentPid = std::to_string(pasteDataFromServiceInfo.pid);
420 uint32_t tmpSequenceId = getSequenceId_++;
421 pasteDataFromServiceInfo.currentId = "GetDataWithProgress_" + pasteDataFromServiceInfo.currentPid
422 + "_" + std::to_string(tmpSequenceId);
423 pasteData.SetPasteId(pasteDataFromServiceInfo.currentId);
424 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_GET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
425 RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN, RadarReporter::CONCURRENT_ID,
426 pasteDataFromServiceInfo.currentId, RadarReporter::PACKAGE_NAME,
427 pasteDataFromServiceInfo.currentPid);
428 }
429
ProgressAfterTwentyPercent(PasteData & pasteData,std::shared_ptr<GetDataParams> params,std::string progressKey)430 int32_t PasteboardClient::ProgressAfterTwentyPercent(PasteData &pasteData, std::shared_ptr<GetDataParams> params,
431 std::string progressKey)
432 {
433 if (pasteData.GetRecordCount() <= 0) {
434 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "no pasteData, no need progress");
435 return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
436 }
437 int32_t ret = 0;
438 int32_t recordSize = (int32_t)pasteData.GetRecordCount();
439 bool hasUri = false;
440 std::shared_ptr<PasteDataRecord> record = std::make_shared<PasteDataRecord>();
441 if (recordSize <= 0) {
442 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Invalid records size");
443 return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
444 }
445 for (int i = 0; i < recordSize; i++) {
446 record = pasteData.GetRecordAt(i);
447 if (record == nullptr) {
448 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Record is nullptr");
449 return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
450 }
451 std::shared_ptr<OHOS::Uri> uri = record->GetUri();
452 if (uri == nullptr) {
453 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Record has no uri");
454 continue;
455 }
456 hasUri = true;
457 break;
458 }
459 if (hasUri) {
460 ret = PasteBoardCopyFile::GetInstance().CopyPasteData(pasteData, params);
461 } else {
462 ret = SetProgressWithoutFile(progressKey, params);
463 }
464 return ret;
465 }
466
CheckProgressParam(std::shared_ptr<GetDataParams> params)467 int32_t PasteboardClient::CheckProgressParam(std::shared_ptr<GetDataParams> params)
468 {
469 if (params == nullptr) {
470 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Invalid param!");
471 return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
472 }
473 if (isPasting_) {
474 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "task copying!");
475 return static_cast<int32_t>(PasteboardError::TASK_PROCESSING);
476 }
477 ProgressSignalClient::GetInstance().Init();
478 return static_cast<int32_t>(PasteboardError::E_OK);
479 }
480
GetDataWithProgress(PasteData & pasteData,std::shared_ptr<GetDataParams> params)481 int32_t PasteboardClient::GetDataWithProgress(PasteData &pasteData, std::shared_ptr<GetDataParams> params)
482 {
483 int32_t ret = CheckProgressParam(params);
484 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
485 return ret;
486 }
487 isPasting_.store(true);
488 std::string progressKey;
489 std::string keyDefaultValue = "0";
490 std::shared_ptr<FFRTTimer> ffrtTimer;
491 ffrtTimer = std::make_shared<FFRTTimer>("pasteboard_progress");
492 if (params->progressIndicator != NONE_PROGRESS_INDICATOR) {
493 PasteBoardProgress::GetInstance().InsertValue(progressKey, keyDefaultValue); // 0%
494 std::unique_lock<std::mutex> lock(instanceLock_);
495 g_progressKey = progressKey;
496 lock.unlock();
497 params->listener.ProgressNotify = GetProgressByProgressInfo;
498 if (ffrtTimer != nullptr) {
499 FFRTTask task = [this, progressKey] {
500 ShowProgress(progressKey);
501 };
502 ffrtTimer->SetTimer(progressKey, task, HAP_PULL_UP_TIME);
503 }
504 }
505 PasteDataFromServiceInfo pasteDataFromServiceInfo;
506 ProgressRadarReport(pasteData, pasteDataFromServiceInfo);
507 StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetDataWithProgress", HITRACE_GETPASTEDATA);
508 ret = GetPasteDataFromService(pasteData, pasteDataFromServiceInfo, progressKey, params);
509 if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
510 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "GetPasteDataFromService is failed: ret=%{public}d.", ret);
511 remoteTask_.store(false);
512 isPasting_.store(false);
513 return ret;
514 }
515 FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetDataWithProgress", HITRACE_GETPASTEDATA);
516 ret = ProgressAfterTwentyPercent(pasteData, params, progressKey);
517 RebuildWebviewPasteData(pasteData);
518 if (ffrtTimer != nullptr) {
519 ffrtTimer->CancelTimer(progressKey);
520 }
521 if (remoteTask_.load()) {
522 ret = static_cast<int32_t>(PasteboardError::PROGRESS_ABNORMAL);
523 remoteTask_.store(false);
524 }
525 isPasting_.store(false);
526 return ret;
527 }
528
GetUnifiedDataWithProgress(UDMF::UnifiedData & unifiedData,std::shared_ptr<GetDataParams> params)529 int32_t PasteboardClient::GetUnifiedDataWithProgress(UDMF::UnifiedData &unifiedData,
530 std::shared_ptr<GetDataParams> params)
531 {
532 StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUdsdData", HITRACE_GETPASTEDATA);
533 PasteData pasteData;
534 int32_t ret = GetDataWithProgress(pasteData, params);
535 unifiedData = *(ConvertUtils::Convert(pasteData));
536 FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUdsdData", HITRACE_GETPASTEDATA);
537 return ret;
538 }
539
GetUnifiedData(UDMF::UnifiedData & unifiedData)540 int32_t PasteboardClient::GetUnifiedData(UDMF::UnifiedData &unifiedData)
541 {
542 StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUnifiedData", HITRACE_GETPASTEDATA);
543 PasteData pasteData;
544 int32_t ret = GetPasteData(pasteData);
545 unifiedData = *(PasteboardUtils::GetInstance().Convert(pasteData));
546 FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUnifiedData", HITRACE_GETPASTEDATA);
547 return ret;
548 }
549
GetUdsdData(UDMF::UnifiedData & unifiedData)550 int32_t PasteboardClient::GetUdsdData(UDMF::UnifiedData &unifiedData)
551 {
552 StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUdsdData", HITRACE_GETPASTEDATA);
553 PasteData pasteData;
554 int32_t ret = GetPasteData(pasteData);
555 unifiedData = *(ConvertUtils::Convert(pasteData));
556 FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetUdsdData", HITRACE_GETPASTEDATA);
557 return ret;
558 }
559
RefreshUri(std::shared_ptr<PasteDataRecord> & record)560 void PasteboardClient::RefreshUri(std::shared_ptr<PasteDataRecord> &record)
561 {
562 if (record->GetUri() == nullptr || record->GetFrom() == 0 || record->GetRecordId() == record->GetFrom()) {
563 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Rebuild webview one of uri is null or not extra uri.");
564 return;
565 }
566 std::shared_ptr<Uri> uri = record->GetUri();
567 std::string puri = uri->ToString();
568 std::string realUri = puri;
569 if (puri.substr(0, PasteData::FILE_SCHEME_PREFIX.size()) == PasteData::FILE_SCHEME_PREFIX) {
570 AppFileService::ModuleFileUri::FileUri fileUri(puri);
571 realUri = PasteData::FILE_SCHEME_PREFIX + fileUri.GetRealPath();
572 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "RebuildWebview uri is file uri: %{public}s", realUri.c_str());
573 }
574 if (realUri.find(PasteData::DISTRIBUTEDFILES_TAG) != std::string::npos) {
575 record->SetConvertUri(realUri);
576 } else {
577 record->SetUri(std::make_shared<OHOS::Uri>(realUri));
578 }
579 }
580
RebuildWebviewPasteData(PasteData & pasteData)581 void PasteboardClient::RebuildWebviewPasteData(PasteData &pasteData)
582 {
583 if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG) {
584 return;
585 }
586 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Rebuild webview PasteData start.");
587 auto justSplitHtml = false;
588 auto details = std::make_shared<Details>();
589 std::string textContent;
590 for (auto &item : pasteData.AllRecords()) {
591 justSplitHtml = justSplitHtml || item->GetFrom() > 0;
592 if (!item->GetTextContent().empty() && textContent.empty()) {
593 details = item->GetDetails();
594 textContent = item->GetTextContent();
595 }
596 RefreshUri(item);
597 }
598 if (justSplitHtml) {
599 PasteboardWebController::GetInstance().MergeExtraUris2Html(pasteData);
600 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Rebuild webview PasteData end, merged uris into html.");
601 return;
602 }
603 if (pasteData.GetPrimaryHtml() == nullptr) {
604 return;
605 }
606
607 auto webData = std::make_shared<PasteData>(pasteData);
608 PasteboardWebController::GetInstance().RebuildHtml(webData);
609 PasteDataRecord::Builder builder(MIMETYPE_TEXT_HTML);
610 std::shared_ptr<PasteDataRecord> pasteDataRecord = builder.SetMimeType(MIMETYPE_TEXT_HTML).
611 SetPlainText(pasteData.GetPrimaryText()).SetHtmlText(webData->GetPrimaryHtml()).Build();
612 if (details) {
613 pasteDataRecord->SetDetails(*details);
614 }
615 pasteDataRecord->SetUDType(UDMF::HTML);
616 pasteDataRecord->SetTextContent(textContent);
617 webData->AddRecord(pasteDataRecord);
618 std::size_t recordCnt = webData->GetRecordCount();
619 if (recordCnt >= 1) {
620 webData->RemoveRecordAt(recordCnt - 1);
621 }
622 pasteData = *webData;
623 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Rebuild webview PasteData end.");
624 }
625
RetainUri(PasteData & pasteData)626 void PasteboardClient::RetainUri(PasteData &pasteData)
627 {
628 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "RetainUri start.");
629 if (!pasteData.IsLocalPaste()) {
630 return;
631 }
632 // clear convert uri
633 for (size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
634 auto record = pasteData.GetRecordAt(i);
635 if (record != nullptr) {
636 record->SetConvertUri("");
637 }
638 }
639 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "RetainUri end.");
640 }
641
HasPasteData()642 bool PasteboardClient::HasPasteData()
643 {
644 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "HasPasteData start.");
645 auto proxyService = GetPasteboardService();
646 if (proxyService == nullptr) {
647 return false;
648 }
649 return proxyService->HasPasteData();
650 }
651
SetPasteData(PasteData & pasteData,std::shared_ptr<PasteboardDelayGetter> delayGetter,std::map<uint32_t,std::shared_ptr<UDMF::EntryGetter>> entryGetters)652 int32_t PasteboardClient::SetPasteData(PasteData &pasteData, std::shared_ptr <PasteboardDelayGetter> delayGetter,
653 std::map <uint32_t, std::shared_ptr<UDMF::EntryGetter>> entryGetters)
654 {
655 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SetPasteData start.");
656 RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
657 RadarReporter::BIZ_STATE, RadarReporter::DFX_BEGIN);
658 auto proxyService = GetPasteboardService();
659 if (proxyService == nullptr) {
660 RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_CHECK_SET_SERVER, RadarReporter::DFX_FAILED,
661 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE,
662 static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR));
663 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
664 }
665 sptr<PasteboardDelayGetterClient> delayGetterAgent;
666 if (delayGetter != nullptr) {
667 pasteData.SetDelayData(true);
668 delayGetterAgent = new (std::nothrow) PasteboardDelayGetterClient(delayGetter);
669 }
670 sptr <PasteboardEntryGetterClient> entryGetterAgent;
671 if (!(entryGetters.empty())) {
672 pasteData.SetDelayRecord(true);
673 entryGetterAgent = new(std::nothrow) PasteboardEntryGetterClient(entryGetters);
674 }
675
676 SplitWebviewPasteData(pasteData);
677
678 auto ret = proxyService->SetPasteData(pasteData, delayGetterAgent, entryGetterAgent);
679 if (ret == static_cast<int32_t>(PasteboardError::E_OK)) {
680 RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
681 RadarReporter::BIZ_STATE, RadarReporter::DFX_END);
682 } else {
683 RADAR_REPORT(RadarReporter::DFX_SET_PASTEBOARD, RadarReporter::DFX_SET_BIZ_SCENE, RadarReporter::DFX_SUCCESS,
684 RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::ERROR_CODE, ret);
685 }
686 return ret;
687 }
688
SetUnifiedData(const UDMF::UnifiedData & unifiedData,std::shared_ptr<PasteboardDelayGetter> delayGetter)689 int32_t PasteboardClient::SetUnifiedData(const UDMF::UnifiedData &unifiedData,
690 std::shared_ptr<PasteboardDelayGetter> delayGetter)
691 {
692 auto pasteData = PasteboardUtils::GetInstance().Convert(unifiedData);
693 return SetPasteData(*pasteData, delayGetter);
694 }
695
SetUdsdData(const UDMF::UnifiedData & unifiedData)696 int32_t PasteboardClient::SetUdsdData(const UDMF::UnifiedData &unifiedData)
697 {
698 auto pasteData = ConvertUtils::Convert(unifiedData);
699 std::map <uint32_t, std::shared_ptr<UDMF::EntryGetter>> entryGetters;
700 for (auto record : unifiedData.GetRecords()) {
701 if (record != nullptr && record->GetEntryGetter() != nullptr) {
702 entryGetters.emplace(record->GetRecordId(), record->GetEntryGetter());
703 }
704 }
705 return SetPasteData(*pasteData, nullptr, entryGetters);
706 }
707
SplitWebviewPasteData(PasteData & pasteData)708 void PasteboardClient::SplitWebviewPasteData(PasteData &pasteData)
709 {
710 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SplitWebviewPasteData start.");
711 auto hasExtraRecord = false;
712 for (const auto &record : pasteData.AllRecords()) {
713 auto htmlEntry = record->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
714 if (htmlEntry == nullptr) {
715 continue;
716 }
717 std::shared_ptr<std::string> html = htmlEntry->ConvertToHtml();
718 if (html == nullptr || html->empty()) {
719 continue;
720 }
721 std::vector<std::shared_ptr<PasteDataRecord>> extraUriRecords =
722 PasteboardWebController::GetInstance().SplitHtml2Records(html, record->GetRecordId());
723 if (extraUriRecords.empty()) {
724 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "SplitWebviewPasteData extraUriRecords is empty.");
725 continue;
726 }
727 hasExtraRecord = true;
728 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "extraUriRecords number: %{public}zu", extraUriRecords.size());
729 for (const auto &item : extraUriRecords) {
730 pasteData.AddRecord(item);
731 }
732 record->SetFrom(record->GetRecordId());
733 }
734 if (hasExtraRecord) {
735 pasteData.SetTag(PasteData::WEBVIEW_PASTEDATA_TAG);
736 }
737 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SplitWebviewPasteData end.");
738 }
739
Subscribe(PasteboardObserverType type,sptr<PasteboardObserver> callback)740 void PasteboardClient::Subscribe(PasteboardObserverType type, sptr<PasteboardObserver> callback)
741 {
742 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
743 if (callback == nullptr) {
744 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "input nullptr.");
745 return;
746 }
747 auto proxyService = GetPasteboardService();
748 if (proxyService == nullptr) {
749 return;
750 }
751 proxyService->SubscribeObserver(type, callback);
752 }
753
AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)754 void PasteboardClient::AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)
755 {
756 Subscribe(PasteboardObserverType::OBSERVER_LOCAL, callback);
757 }
758
AddPasteboardEventObserver(sptr<PasteboardObserver> callback)759 void PasteboardClient::AddPasteboardEventObserver(sptr<PasteboardObserver> callback)
760 {
761 Subscribe(PasteboardObserverType::OBSERVER_EVENT, callback);
762 }
763
Unsubscribe(PasteboardObserverType type,sptr<PasteboardObserver> callback)764 void PasteboardClient::Unsubscribe(PasteboardObserverType type, sptr<PasteboardObserver> callback)
765 {
766 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
767 auto proxyService = GetPasteboardService();
768 if (proxyService == nullptr) {
769 return;
770 }
771 if (callback == nullptr) {
772 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "remove all.");
773 proxyService->UnsubscribeAllObserver(type);
774 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
775 return;
776 }
777 proxyService->UnsubscribeObserver(type, callback);
778 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
779 }
780
RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)781 void PasteboardClient::RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)
782 {
783 Unsubscribe(PasteboardObserverType::OBSERVER_LOCAL, callback);
784 }
785
RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)786 void PasteboardClient::RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)
787 {
788 Unsubscribe(PasteboardObserverType::OBSERVER_EVENT, callback);
789 }
790
SetGlobalShareOption(const std::map<uint32_t,ShareOption> & globalShareOptions)791 int32_t PasteboardClient::SetGlobalShareOption(const std::map<uint32_t, ShareOption> &globalShareOptions)
792 {
793 auto proxyService = GetPasteboardService();
794 if (proxyService == nullptr) {
795 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
796 }
797 return proxyService->SetGlobalShareOption(globalShareOptions);
798 }
799
RemoveGlobalShareOption(const std::vector<uint32_t> & tokenIds)800 int32_t PasteboardClient::RemoveGlobalShareOption(const std::vector<uint32_t> &tokenIds)
801 {
802 auto proxyService = GetPasteboardService();
803 if (proxyService == nullptr) {
804 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
805 }
806 return proxyService->RemoveGlobalShareOption(tokenIds);
807 }
808
GetGlobalShareOption(const std::vector<uint32_t> & tokenIds)809 std::map<uint32_t, ShareOption> PasteboardClient::GetGlobalShareOption(const std::vector<uint32_t> &tokenIds)
810 {
811 auto proxyService = GetPasteboardService();
812 if (proxyService == nullptr) {
813 return {};
814 }
815 return proxyService->GetGlobalShareOption(tokenIds);
816 }
817
SetAppShareOptions(const ShareOption & shareOptions)818 int32_t PasteboardClient::SetAppShareOptions(const ShareOption &shareOptions)
819 {
820 auto proxyService = GetPasteboardService();
821 if (proxyService == nullptr) {
822 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
823 }
824 return proxyService->SetAppShareOptions(shareOptions);
825 }
826
RemoveAppShareOptions()827 int32_t PasteboardClient::RemoveAppShareOptions()
828 {
829 auto proxyService = GetPasteboardService();
830 if (proxyService == nullptr) {
831 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
832 }
833 return proxyService->RemoveAppShareOptions();
834 }
835
IsRemoteData()836 bool PasteboardClient::IsRemoteData()
837 {
838 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "IsRemoteData start.");
839 auto proxyService = GetPasteboardService();
840 if (proxyService == nullptr) {
841 return false;
842 }
843 auto ret = proxyService->IsRemoteData();
844 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "IsRemoteData end.");
845 return ret;
846 }
847
GetDataSource(std::string & bundleName)848 int32_t PasteboardClient::GetDataSource(std::string &bundleName)
849 {
850 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetDataSource start.");
851 auto proxyService = GetPasteboardService();
852 if (proxyService == nullptr) {
853 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
854 }
855 int32_t ret = proxyService->GetDataSource(bundleName);
856 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetDataSource end.");
857 return ret;
858 }
859
GetMimeTypes()860 std::vector<std::string> PasteboardClient::GetMimeTypes()
861 {
862 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetMimeTypes start.");
863 auto proxyService = GetPasteboardService();
864 if (proxyService == nullptr) {
865 return {};
866 }
867 return proxyService->GetMimeTypes();
868 }
869
HasDataType(const std::string & mimeType)870 bool PasteboardClient::HasDataType(const std::string &mimeType)
871 {
872 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "HasDataType start.");
873 auto proxyService = GetPasteboardService();
874 if (proxyService == nullptr) {
875 return false;
876 }
877 if (mimeType.empty()) {
878 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "parameter is invalid");
879 return false;
880 }
881 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "type is %{public}s", mimeType.c_str());
882 bool ret = proxyService->HasDataType(mimeType);
883 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "HasDataType end.");
884 return ret;
885 }
886
DetectPatterns(const std::set<Pattern> & patternsToCheck)887 std::set<Pattern> PasteboardClient::DetectPatterns(const std::set<Pattern> &patternsToCheck)
888 {
889 if (!PatternDetection::IsValid(patternsToCheck)) {
890 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Invalid number in Pattern set!");
891 return {};
892 }
893
894 auto proxyService = GetPasteboardService();
895 if (proxyService == nullptr) {
896 return {};
897 }
898 return proxyService->DetectPatterns(patternsToCheck);
899 }
900
GetPasteboardService()901 sptr<IPasteboardService> PasteboardClient::GetPasteboardService()
902 {
903 std::unique_lock<std::mutex> lock(instanceLock_);
904 if (pasteboardServiceProxy_ != nullptr) {
905 return pasteboardServiceProxy_;
906 }
907 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "GetPasteboardService start.");
908 sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
909 if (samgrProxy == nullptr) {
910 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Get SystemAbilityManager failed.");
911 pasteboardServiceProxy_ = nullptr;
912 return nullptr;
913 }
914 sptr<IRemoteObject> remoteObject = samgrProxy->CheckSystemAbility(PASTEBOARD_SERVICE_ID);
915 if (remoteObject != nullptr) {
916 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Get PasteboardServiceProxy succeed.");
917 if (deathRecipient_ == nullptr) {
918 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
919 }
920 remoteObject->AddDeathRecipient(deathRecipient_);
921 pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
922 return pasteboardServiceProxy_;
923 }
924 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "remoteObject is null.");
925 sptr<PasteboardLoadCallback> loadCallback = new PasteboardLoadCallback();
926 if (loadCallback == nullptr) {
927 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "loadCallback is nullptr.");
928 return nullptr;
929 }
930 int32_t ret = samgrProxy->LoadSystemAbility(PASTEBOARD_SERVICE_ID, loadCallback);
931 if (ret != ERR_OK) {
932 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Failed to load systemAbility.");
933 return nullptr;
934 }
935 auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(LOADSA_TIMEOUT_MS),
936 [this]() { return pasteboardServiceProxy_ != nullptr; });
937 if (!waitStatus) {
938 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Load systemAbility timeout.");
939 return nullptr;
940 }
941 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Getting PasteboardServiceProxy succeeded.");
942 return pasteboardServiceProxy_;
943 }
944
GetPasteboardServiceProxy()945 sptr<IPasteboardService> PasteboardClient::GetPasteboardServiceProxy()
946 {
947 std::lock_guard<std::mutex> lock(instanceLock_);
948 return pasteboardServiceProxy_;
949 }
950
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)951 void PasteboardClient::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
952 {
953 std::lock_guard<std::mutex> lock(instanceLock_);
954 if (deathRecipient_ == nullptr) {
955 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
956 }
957 if (remoteObject != nullptr) {
958 remoteObject->AddDeathRecipient(deathRecipient_);
959 pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
960 }
961 proxyConVar_.notify_one();
962 }
963
LoadSystemAbilityFail()964 void PasteboardClient::LoadSystemAbilityFail()
965 {
966 std::lock_guard<std::mutex> lock(instanceLock_);
967 pasteboardServiceProxy_ = nullptr;
968 proxyConVar_.notify_one();
969 }
970
OnRemoteSaDied(const wptr<IRemoteObject> & remote)971 void PasteboardClient::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
972 {
973 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "OnRemoteSaDied start.");
974 std::lock_guard<std::mutex> lock(instanceLock_);
975 pasteboardServiceProxy_ = nullptr;
976 }
977
PasteStart(const std::string & pasteId)978 void PasteboardClient::PasteStart(const std::string &pasteId)
979 {
980 RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_DISTRIBUTED_FILE_START,
981 RadarReporter::DFX_SUCCESS, RadarReporter::CONCURRENT_ID, pasteId);
982 auto proxyService = GetPasteboardService();
983 if (proxyService == nullptr) {
984 return;
985 }
986 proxyService->PasteStart(pasteId);
987 }
988
PasteComplete(const std::string & deviceId,const std::string & pasteId)989 void PasteboardClient::PasteComplete(const std::string &deviceId, const std::string &pasteId)
990 {
991 auto proxyService = GetPasteboardService();
992 if (proxyService == nullptr) {
993 return;
994 }
995 proxyService->PasteComplete(deviceId, pasteId);
996 }
997
GetRemoteDeviceName(std::string & deviceName,bool & isRemote)998 int32_t PasteboardClient::GetRemoteDeviceName(std::string &deviceName, bool &isRemote)
999 {
1000 auto proxyService = GetPasteboardService();
1001 if (proxyService == nullptr) {
1002 return static_cast<int32_t>(PasteboardError::OBTAIN_SERVER_SA_ERROR);
1003 }
1004 return proxyService->GetRemoteDeviceName(deviceName, isRemote);
1005 }
1006
HandleSignalValue(const std::string & signalValue)1007 int32_t PasteboardClient::HandleSignalValue(const std::string &signalValue)
1008 {
1009 int32_t progressStatusValue = 0;
1010 std::shared_ptr<ProgressReportLintener> progressReport = std::make_shared<ProgressReportLintener>();
1011 progressReport->OnProgressFail = OnProgressAbnormal;
1012 try {
1013 progressStatusValue = std::stoi(signalValue);
1014 } catch (const std::invalid_argument &e) {
1015 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT,
1016 "progressStatusValue invalid = %{public}s", e.what());
1017 return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
1018 } catch (const std::out_of_range &e) {
1019 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT,
1020 "progressStatusValue out of range = %{public}s", e.what());
1021 return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
1022 }
1023 if (progressStatusValue == NORMAL_PASTE) {
1024 return static_cast<int32_t>(PasteboardError::E_OK);
1025 }
1026 if (progressStatusValue == CANCEL_PASTE) {
1027 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "progress cancel paste");
1028 ProgressSignalClient::GetInstance().Cancel();
1029 } else if (progressStatusValue == PASTE_TIME_OUT) {
1030 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "pasteboard progress time out");
1031 progressReport->OnProgressFail(static_cast<int32_t>(PasteboardError::PROGRESS_PASTE_TIME_OUT));
1032 } else {
1033 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "pasteboard progress invalid status");
1034 progressReport->OnProgressFail(static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR));
1035 }
1036 return static_cast<int32_t>(PasteboardError::E_OK);
1037 }
1038
ShowProgress(const std::string & progressKey)1039 void PasteboardClient::ShowProgress(const std::string &progressKey)
1040 {
1041 auto proxyService = GetPasteboardService();
1042 if (proxyService == nullptr) {
1043 return;
1044 }
1045 sptr<PasteboardSignalCallback> callback = new PasteboardSignalCallback();
1046 proxyService->ShowProgress(progressKey, callback);
1047 }
1048
PasteboardSaDeathRecipient()1049 PasteboardSaDeathRecipient::PasteboardSaDeathRecipient() {}
1050
OnRemoteDied(const wptr<IRemoteObject> & object)1051 void PasteboardSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
1052 {
1053 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "PasteboardSaDeathRecipient on remote systemAbility died.");
1054 PasteboardClient::GetInstance()->OnRemoteSaDied(object);
1055 }
1056 } // namespace MiscServices
1057 } // namespace OHOS
1058