• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <if_system_ability_manager.h>
17 #include <ipc_skeleton.h>
18 #include <iservice_registry.h>
19 #include <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