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