• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021-2024 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 #include "pasteboard_service.h"
16 
17 #include <dlfcn.h>
18 
19 #include "ability_manager_client.h"
20 #include "accesstoken_kit.h"
21 #include "account_manager.h"
22 #include "calculate_time_consuming.h"
23 #include "common_event_manager.h"
24 #include "dev_profile.h"
25 #include "distributed_file_daemon_manager.h"
26 #ifdef WITH_DLP
27 #include "dlp_permission_kit.h"
28 #include "dlp_permission.h"
29 #endif // WITH_DLP
30 #include "eventcenter/pasteboard_event.h"
31 #include "hiview_adapter.h"
32 #include "input_method_controller.h"
33 #include "iservice_registry.h"
34 #include "mem_mgr_client.h"
35 #include "os_account_manager.h"
36 #include "parameters.h"
37 #include "pasteboard_dialog.h"
38 #include "pasteboard_error.h"
39 #include "pasteboard_hilog.h"
40 #include "pasteboard_event_dfx.h"
41 #include "pasteboard_event_ue.h"
42 #include "pasteboard_trace.h"
43 #include "pasteboard_web_controller.h"
44 #include "remote_file_share.h"
45 #include "res_sched_client.h"
46 #include "reporter.h"
47 #ifdef PB_SCREENLOCK_MGR_ENABLE
48 #include "screenlock_manager.h"
49 #endif
50 #include "tokenid_kit.h"
51 #include "uri_permission_manager_client.h"
52 #ifdef SCENE_BOARD_ENABLE
53 #include "window_manager_lite.h"
54 #else
55 #include "window_manager.h"
56 #endif
57 
58 namespace OHOS {
59 namespace MiscServices {
60 using namespace Rosen;
61 using namespace std::chrono;
62 using namespace Storage::DistributedFile;
63 using namespace RadarReporter;
64 using namespace UeReporter;
65 namespace {
66 constexpr int32_t COMMON_USERID = 0;
67 constexpr int32_t INIT_INTERVAL = 10000L;
68 constexpr uint32_t MAX_IPC_THREAD_NUM = 32;
69 constexpr const char *PASTEBOARD_SERVICE_SA_NAME = "pasteboard_service";
70 constexpr const char *PASTEBOARD_SERVICE_NAME = "PasteboardService";
71 constexpr const char *NLU_SO_PATH = "libai_nlu_innerapi.z.so";
72 constexpr const char *GET_PASTE_DATA_PROCESSOR = "GetPasteDataProcessor";
73 constexpr const char *FAIL_TO_GET_TIME_STAMP = "FAIL_TO_GET_TIME_STAMP";
74 constexpr const char *SECURE_PASTE_PERMISSION = "ohos.permission.SECURE_PASTE";
75 constexpr const char *READ_PASTEBOARD_PERMISSION = "ohos.permission.READ_PASTEBOARD";
76 constexpr const char *TRANSMIT_CONTROL_PROP_KEY = "persist.distributed_scene.datafiles_trans_ctrl";
77 constexpr const char *MANAGE_PASTEBOARD_APP_SHARE_OPTION_PERMISSION =
78     "ohos.permission.MANAGE_PASTEBOARD_APP_SHARE_OPTION";
79 
80 constexpr int32_t INVALID_VERSION = -1;
81 constexpr int32_t ADD_PERMISSION_CHECK_SDK_VERSION = 12;
82 constexpr int32_t CTRLV_EVENT_SIZE = 2;
83 constexpr int32_t CONTROL_TYPE_ALLOW_SEND_RECEIVE = 1;
84 constexpr uint32_t EVENT_TIME_OUT = 2000;
85 constexpr uint32_t MAX_RECOGNITION_LENGTH = 1000;
86 constexpr int32_t DEVICE_COLLABORATION_UID = 5521;
87 
88 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(new PasteboardService());
89 } // namespace
90 using namespace Security::AccessToken;
91 using namespace OHOS::AppFileService::ModuleRemoteFileShare;
92 std::mutex PasteboardService::historyMutex_;
93 std::vector<std::string> PasteboardService::dataHistory_;
94 std::shared_ptr<Command> PasteboardService::copyHistory;
95 std::shared_ptr<Command> PasteboardService::copyData;
96 int32_t PasteboardService::currentUserId_ = ERROR_USERID;
97 ScreenEvent PasteboardService::currentScreenStatus = ScreenEvent::Default;
98 
PasteboardService()99 PasteboardService::PasteboardService()
100     : SystemAbility(PASTEBOARD_SERVICE_ID, true), state_(ServiceRunningState::STATE_NOT_START)
101 {
102     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PasteboardService Start.");
103     ServiceListenerFuncs_[static_cast<int32_t>(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID)] =
104         &PasteboardService::DMAdapterInit;
105     ServiceListenerFuncs_[static_cast<int32_t>(MEMORY_MANAGER_SA_ID)] = &PasteboardService::NotifySaStatus;
106 }
107 
~PasteboardService()108 PasteboardService::~PasteboardService()
109 {
110     clients_.Clear();
111     UnsubscribeAllEntityObserver();
112 }
113 
Init()114 int32_t PasteboardService::Init()
115 {
116     if (!Publish(this)) {
117         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "OnStart register to system ability manager failed.");
118         auto userId = GetCurrentAccountId();
119         Reporter::GetInstance().PasteboardFault().Report({ userId, "ERR_INVALID_OPTION" });
120         return static_cast<int32_t>(PasteboardError::INVALID_OPTION_ERROR);
121     }
122     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Init Success.");
123     state_ = ServiceRunningState::STATE_RUNNING;
124     InitScreenStatus();
125     return ERR_OK;
126 }
127 
InitScreenStatus()128 void PasteboardService::InitScreenStatus()
129 {
130 #ifdef PB_SCREENLOCK_MGR_ENABLE
131     auto isScreenLocked = OHOS::ScreenLock::ScreenLockManager::GetInstance()->IsScreenLocked();
132     PasteboardService::currentScreenStatus = isScreenLocked ? ScreenEvent::ScreenLocked : ScreenEvent::ScreenUnlocked;
133     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "screen status is %{public}d", PasteboardService::currentScreenStatus);
134 #else
135     PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "PB_SCREENLOCK_MGR_ENABLE not defined");
136     return;
137 #endif
138 }
139 
OnStart()140 void PasteboardService::OnStart()
141 {
142     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PasteboardService OnStart.");
143     std::lock_guard<std::mutex> lock(saMutex_);
144     PASTEBOARD_CHECK_AND_RETURN_LOGE(state_ != ServiceRunningState::STATE_RUNNING,
145         PASTEBOARD_MODULE_SERVICE, "PasteboardService is already running.");
146     IPCSkeleton::SetMaxWorkThreadNum(MAX_IPC_THREAD_NUM);
147     InitServiceHandler();
148     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
149     Loader loader;
150     uid_ = loader.LoadUid();
151     moduleConfig_.Init();
152     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "datasl on start ret:%{public}d", DATASL_OnStart());
153     moduleConfig_.Watch(std::bind(&PasteboardService::OnConfigChange, this, std::placeholders::_1));
154     AddSysAbilityListener();
155     if (Init() != ERR_OK) {
156         auto callback = [this]() {
157             Init();
158         };
159         serviceHandler_->PostTask(callback, INIT_INTERVAL);
160         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Init failed. Try again 10s later.");
161         return;
162     }
163     auto callback = [this]() {
164         switch_.Init(GetCurrentAccountId());
165     };
166     serviceHandler_->PostTask(callback);
167     copyHistory = std::make_shared<Command>(std::vector<std::string>{ "--copy-history" },
168         "Dump access history last ten times.",
169         [this](const std::vector<std::string> &input, std::string &output) -> bool {
170             output = DumpHistory();
171             return true;
172         });
173     copyData = std::make_shared<Command>(std::vector<std::string>{ "--data" }, "Show copy data details.",
174         [this](const std::vector<std::string> &input, std::string &output) -> bool {
175             output = DumpData();
176             return true;
177         });
178     PasteboardDumpHelper::GetInstance().RegisterCommand(copyHistory);
179     PasteboardDumpHelper::GetInstance().RegisterCommand(copyData);
180     CommonEventSubscriber();
181     AccountStateSubscriber();
182     PasteboardEventSubscriber();
183     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Start PasteboardService success.");
184     EventCenter::GetInstance().Subscribe(OHOS::MiscServices::Event::EVT_REMOTE_CHANGE, RemotePasteboardChange());
185     HiViewAdapter::StartTimerThread();
186     ffrtTimer_ = std::make_shared<FFRTTimer>("pasteboard_service");
187     return;
188 }
189 
OnStop()190 void PasteboardService::OnStop()
191 {
192     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop Started.");
193     std::lock_guard<std::mutex> lock(saMutex_);
194     if (state_ != ServiceRunningState::STATE_RUNNING) {
195         return;
196     }
197     serviceHandler_ = nullptr;
198     state_ = ServiceRunningState::STATE_NOT_START;
199     DMAdapter::GetInstance().DeInitialize();
200     if (commonEventSubscriber_ != nullptr) {
201         EventFwk::CommonEventManager::UnSubscribeCommonEvent(commonEventSubscriber_);
202     }
203     moduleConfig_.DeInit();
204     switch_.DeInit();
205     EventCenter::GetInstance().Unsubscribe(PasteboardEvent::DISCONNECT);
206     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop End.");
207     EventCenter::GetInstance().Unsubscribe(OHOS::MiscServices::Event::EVT_REMOTE_CHANGE);
208     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 0, PASTEBOARD_SERVICE_ID);
209 }
210 
AddSysAbilityListener()211 void PasteboardService::AddSysAbilityListener()
212 {
213     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "begin.");
214     for (uint32_t i = 0; i < sizeof(LISTENING_SERVICE) / sizeof(LISTENING_SERVICE[0]); i++) {
215         auto ret = AddSystemAbilityListener(LISTENING_SERVICE[i]);
216         if (ret) {
217             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Add listener success, serviceId = %{public}d.",
218                 LISTENING_SERVICE[i]);
219         } else {
220             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Add listener failed, serviceId = %{public}d.",
221                 LISTENING_SERVICE[i]);
222         }
223     }
224 }
225 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)226 void PasteboardService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
227 {
228     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "systemAbilityId = %{public}d added!", systemAbilityId);
229     auto itFunc = ServiceListenerFuncs_.find(systemAbilityId);
230     if (itFunc != ServiceListenerFuncs_.end()) {
231         auto ServiceListenerFunc = itFunc->second;
232         if (ServiceListenerFunc != nullptr) {
233             (this->*ServiceListenerFunc)();
234         }
235     }
236 }
237 
DelayGetterDeathRecipient(int32_t userId,PasteboardService & service)238 PasteboardService::DelayGetterDeathRecipient::DelayGetterDeathRecipient(int32_t userId, PasteboardService &service)
239     : userId_(userId), service_(service)
240 {
241     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Construct Delay Getter Death Recipient");
242 }
243 
OnRemoteDied(const wptr<IRemoteObject> & remote)244 void PasteboardService::DelayGetterDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
245 {
246     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "start");
247     (void)remote;
248     service_.NotifyDelayGetterDied(userId_);
249 }
250 
NotifyDelayGetterDied(int32_t userId)251 void PasteboardService::NotifyDelayGetterDied(int32_t userId)
252 {
253     if (userId == ERROR_USERID) {
254         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "error userId: %{public}d", userId);
255         return;
256     }
257     delayGetters_.Erase(userId);
258 }
259 
EntryGetterDeathRecipient(int32_t userId,PasteboardService & service)260 PasteboardService::EntryGetterDeathRecipient::EntryGetterDeathRecipient(int32_t userId, PasteboardService &service)
261     : userId_(userId), service_(service)
262 {
263     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Construct Entry Getter Death Recipient");
264 }
265 
OnRemoteDied(const wptr<IRemoteObject> & remote)266 void PasteboardService::EntryGetterDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
267 {
268     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "start");
269     (void)remote;
270     service_.NotifyEntryGetterDied(userId_);
271 }
272 
NotifyEntryGetterDied(int32_t userId)273 void PasteboardService::NotifyEntryGetterDied(int32_t userId)
274 {
275     if (userId == ERROR_USERID) {
276         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "error userId: %{public}d", userId);
277         return;
278     }
279     entryGetters_.Erase(userId);
280 }
281 
DMAdapterInit()282 void PasteboardService::DMAdapterInit()
283 {
284     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
285     DMAdapter::GetInstance().Initialize(appInfo.bundleName);
286 }
287 
NotifySaStatus()288 void PasteboardService::NotifySaStatus()
289 {
290     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 1, PASTEBOARD_SERVICE_ID);
291 }
292 
ReportUeCopyEvent(PasteData & pasteData,int32_t result)293 void PasteboardService::ReportUeCopyEvent(PasteData &pasteData, int32_t result)
294 {
295     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
296     auto res = (result == static_cast<int32_t>(PasteboardError::E_OK)) ? UeReporter::E_OK_OPERATION : result;
297     UE_REPORT(UeReporter::UE_COPY, GenerateDataType(pasteData), appInfo.bundleName, res,
298         DMAdapter::GetInstance().GetLocalDeviceType());
299 }
300 
InitServiceHandler()301 void PasteboardService::InitServiceHandler()
302 {
303     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler started.");
304     if (serviceHandler_ != nullptr) {
305         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Already init.");
306         return;
307     }
308     std::shared_ptr<AppExecFwk::EventRunner> runner =
309         AppExecFwk::EventRunner::Create(PASTEBOARD_SERVICE_NAME, AppExecFwk::ThreadMode::FFRT);
310     serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
311 
312     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler Succeeded.");
313 }
314 
Clear()315 void PasteboardService::Clear()
316 {
317     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "enter, clips_.Size=%{public}zu", clips_.Size());
318     auto userId = GetCurrentAccountId();
319     if (userId == ERROR_USERID) {
320         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
321         return;
322     }
323     RADAR_REPORT(DFX_CLEAR_PASTEBOARD, DFX_MANUAL_CLEAR, DFX_SUCCESS);
324     auto it = clips_.Find(userId);
325     if (it.first) {
326         RevokeUriPermission(it.second);
327         clips_.Erase(userId);
328         delayDataId_ = 0;
329         delayTokenId_ = 0;
330         auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
331         std::string bundleName = GetAppBundleName(appInfo);
332         NotifyObservers(bundleName, PasteboardEventStatus::PASTEBOARD_CLEAR);
333     }
334     CleanDistributedData(userId);
335     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "leave, clips_.Size=%{public}zu", clips_.Size());
336 }
337 
GetChangeCount(uint32_t & changeCount)338 int32_t PasteboardService::GetChangeCount(uint32_t &changeCount)
339 {
340     auto tokenId = IPCSkeleton::GetCallingTokenID();
341     auto appInfo = GetAppInfo(tokenId);
342     changeCount = 0;
343     clipChangeCount_.ComputeIfPresent(appInfo.userId, [&changeCount](auto, auto &value) {
344         changeCount = value;
345         PASTEBOARD_HILOGI(
346             PASTEBOARD_MODULE_SERVICE, "Find changeCount succeed, changeCount is %{public}u", changeCount);
347         return true;
348     });
349     return static_cast<int32_t>(PasteboardError::E_OK);
350 }
351 
IncreaseChangeCount(int32_t userId)352 void PasteboardService::IncreaseChangeCount(int32_t userId)
353 {
354     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "IncreaseChangeCount start!");
355     clipChangeCount_.Compute(userId, [](auto userId, uint32_t &changeCount) {
356         changeCount = (changeCount == UINT32_MAX) ? 0 : changeCount + 1;
357         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "userId=%{public}d, changeCount=%{public}u", userId, changeCount);
358         return true;
359     });
360 }
361 
NotifyEntityObservers(std::string & entity,EntityType entityType,uint32_t dataLength)362 void PasteboardService::NotifyEntityObservers(std::string &entity, EntityType entityType, uint32_t dataLength)
363 {
364     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "entityType=%{public}u, dataLength=%{public}u",
365         static_cast<uint32_t>(entityType), dataLength);
366     entityObserverMap_.ForEach([this, &entity, entityType, dataLength](const auto &key, auto &value) {
367         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "pid=%{public}u, listSize=%{public}zu", key, value.size());
368         for (auto entityObserver : value) {
369             if (entityType == entityObserver.entityType && dataLength <= entityObserver.expectedDataLength &&
370                 VerifyPermission(entityObserver.tokenId)) {
371                 entityObserver.observer->OnRecognitionEvent(entityType, entity);
372             }
373         }
374         return false;
375     });
376 }
377 
GetAllEntryPlainText(uint32_t dataId,uint32_t recordId,std::vector<std::shared_ptr<PasteDataEntry>> & entries,std::string & primaryText)378 int32_t PasteboardService::GetAllEntryPlainText(uint32_t dataId, uint32_t recordId,
379     std::vector<std::shared_ptr<PasteDataEntry>> &entries, std::string &primaryText)
380 {
381     for (auto &entry : entries) {
382         if (primaryText.size() > MAX_RECOGNITION_LENGTH) {
383             return static_cast<int32_t>(PasteboardError::EXCEEDING_LIMIT_EXCEPTION);
384         }
385         int32_t result = static_cast<int32_t>(PasteboardError::E_OK);
386         if (entry->GetMimeType() == MIMETYPE_TEXT_PLAIN && !entry->HasContentByMimeType(MIMETYPE_TEXT_PLAIN)) {
387             result = GetRecordValueByType(dataId, recordId, *entry);
388         }
389         if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
390             continue;
391         }
392         std::shared_ptr<std::string> plainTextPtr = entry->ConvertToPlainText();
393         if (plainTextPtr != nullptr) {
394             primaryText += *plainTextPtr;
395         }
396     }
397     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetAllEntryPlainText finished");
398     return static_cast<int32_t>(PasteboardError::E_OK);
399 }
400 
GetAllPrimaryText(const PasteData & pasteData)401 std::string PasteboardService::GetAllPrimaryText(const PasteData &pasteData)
402 {
403     std::string primaryText = "";
404     std::vector<std::shared_ptr<PasteDataRecord>> records = pasteData.AllRecords();
405     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "size of records=%{public}zu", records.size());
406     for (const auto &record : records) {
407         if (primaryText.size() > MAX_RECOGNITION_LENGTH) {
408             primaryText = "";
409             break;
410         }
411         std::shared_ptr<std::string> plainTextPtr = record->GetPlainText();
412         if (plainTextPtr != nullptr) {
413             primaryText += *plainTextPtr;
414             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "primaryText in record");
415             continue;
416         }
417         auto dataId = pasteData.GetDataId();
418         auto recordId = record->GetRecordId();
419         std::vector<std::shared_ptr<PasteDataEntry>> entries = record->GetEntries();
420         int32_t result = GetAllEntryPlainText(dataId, recordId, entries, primaryText);
421         if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
422             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "primaryText exceeded size, result=%{public}d", result);
423             primaryText = "";
424             break;
425         }
426     }
427     return primaryText;
428 }
429 
ExtractEntity(const std::string & entity,std::string & location)430 int32_t PasteboardService::ExtractEntity(const std::string &entity, std::string &location)
431 {
432     nlohmann::json entityJson = nlohmann::json::parse(entity);
433     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!entityJson.is_discarded(),
434         static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR), PASTEBOARD_MODULE_SERVICE,
435         "parse entity to json failed");
436     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(entityJson.contains("code") && entityJson["code"].is_number(),
437         static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR), PASTEBOARD_MODULE_SERVICE,
438         "entity find code failed");
439     int code = entityJson["code"].get<int>();
440     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(
441         code == 0, static_cast<int32_t>(code), PASTEBOARD_MODULE_SERVICE, "failed to get entity");
442     if (entityJson.contains("entity") && entityJson["entity"].contains("location") &&
443         entityJson["entity"]["location"].is_array()) {
444         nlohmann::json locationJson = entityJson["entity"]["location"].get<nlohmann::json>();
445         location = locationJson.dump();
446         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "location dump finished, location=%{private}s", location.c_str());
447         return static_cast<int32_t>(PasteboardError::E_OK);
448     }
449     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PasteData did not contain entity");
450     return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
451 }
452 
RecognizePasteData(PasteData & pasteData)453 void PasteboardService::RecognizePasteData(PasteData &pasteData)
454 {
455     std::string primaryText = GetAllPrimaryText(pasteData);
456     if (primaryText.empty()) {
457         return;
458     }
459     FFRTTask task = [this, primaryText]() {
460         pthread_setname_np(pthread_self(), "PasteDataRecognize");
461         auto handle = dlopen(NLU_SO_PATH, RTLD_NOW);
462         PASTEBOARD_CHECK_AND_RETURN_LOGE(handle != nullptr, PASTEBOARD_MODULE_SERVICE, "Can not get AIEngine handle");
463         GetProcessorFunc GetProcessor = reinterpret_cast<GetProcessorFunc>(dlsym(handle, GET_PASTE_DATA_PROCESSOR));
464         if (GetProcessor == nullptr) {
465             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Can not get ProcessorFunc");
466             dlclose(handle);
467             return;
468         }
469         IPasteDataProcessor &processor = GetProcessor();
470         std::string entity = "";
471         int32_t result = processor.Process(primaryText, entity);
472         if (result != ERR_OK) {
473             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "AI Process failed, result=%{public}d", result);
474             dlclose(handle);
475             return;
476         }
477         std::string location = "";
478         int32_t ret = ExtractEntity(entity, location);
479         if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
480             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ExtractEntity failed, ret=%{public}d", ret);
481             dlclose(handle);
482             return;
483         }
484         NotifyEntityObservers(location, EntityType::ADDRESS, static_cast<uint32_t>(primaryText.size()));
485         dlclose(handle);
486     };
487     FFRTUtils::SubmitTask(task);
488 }
489 
SubscribeEntityObserver(EntityType entityType,uint32_t expectedDataLength,const sptr<IEntityRecognitionObserver> & observer)490 int32_t PasteboardService::SubscribeEntityObserver(
491     EntityType entityType, uint32_t expectedDataLength, const sptr<IEntityRecognitionObserver> &observer)
492 {
493     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE,
494         "start, type=%{public}u, len=%{public}u", static_cast<uint32_t>(entityType), expectedDataLength);
495     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(expectedDataLength <= MAX_RECOGNITION_LENGTH,
496         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
497         "expected data length exceeds limitation");
498     auto tokenId = IPCSkeleton::GetCallingTokenID();
499     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(VerifyPermission(tokenId),
500         static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR), PASTEBOARD_MODULE_SERVICE,
501         "check permission failed");
502     auto callingPid = IPCSkeleton::GetCallingPid();
503     bool result = entityObserverMap_.ComputeIfPresent(
504         callingPid, [entityType, expectedDataLength, tokenId, &observer](auto, auto &observerList) {
505             auto it = std::find_if(observerList.begin(), observerList.end(),
506                 [entityType, expectedDataLength](const EntityObserverInfo &observer) {
507                     return observer.entityType == entityType && observer.expectedDataLength == expectedDataLength;
508                 });
509             if (it != observerList.end()) {
510                 it->tokenId = tokenId;
511                 it->observer = observer;
512                 return true;
513             }
514             observerList.emplace_back(entityType, expectedDataLength, tokenId, observer);
515             return true;
516         });
517     if (!result) {
518         std::vector<EntityObserverInfo> observerList;
519         observerList.emplace_back(entityType, expectedDataLength, tokenId, observer);
520         entityObserverMap_.Emplace(callingPid, observerList);
521     }
522     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "subscribe entityObserver finished");
523     return static_cast<int32_t>(PasteboardError::E_OK);
524 }
525 
UnsubscribeEntityObserver(EntityType entityType,uint32_t expectedDataLength,const sptr<IEntityRecognitionObserver> & observer)526 int32_t PasteboardService::UnsubscribeEntityObserver(
527     EntityType entityType, uint32_t expectedDataLength, const sptr<IEntityRecognitionObserver> &observer)
528 {
529     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(expectedDataLength <= MAX_RECOGNITION_LENGTH,
530         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
531         "expected data length exceeds limitation");
532     auto callingPid = IPCSkeleton::GetCallingPid();
533     auto result = entityObserverMap_.ComputeIfPresent(
534         callingPid, [entityType, expectedDataLength](auto, auto &observerList) {
535             auto it = std::find_if(observerList.begin(), observerList.end(),
536                 [entityType, expectedDataLength](const EntityObserverInfo &observer) {
537                     return observer.entityType == entityType && observer.expectedDataLength == expectedDataLength;
538                 });
539             if (it == observerList.end()) {
540                 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE,
541                     "Failed to unsubscribe, observer not found, type is %{public}u, length is %{public}u.",
542                     static_cast<uint32_t>(entityType), expectedDataLength);
543                 return true;
544             }
545             observerList.erase(it);
546             if (observerList.empty()) {
547                 return false;
548             }
549             return true;
550         });
551     return static_cast<int32_t>(PasteboardError::E_OK);
552 }
553 
UnsubscribeAllEntityObserver()554 void PasteboardService::UnsubscribeAllEntityObserver()
555 {
556     entityObserverMap_.Clear();
557 }
558 
GetRecordValueByType(uint32_t dataId,uint32_t recordId,PasteDataEntry & value)559 int32_t PasteboardService::GetRecordValueByType(uint32_t dataId, uint32_t recordId, PasteDataEntry &value)
560 {
561     auto tokenId = IPCSkeleton::GetCallingTokenID();
562     auto callPid = IPCSkeleton::GetCallingPid();
563     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((dataId == delayDataId_ && tokenId == delayTokenId_) ||
564         VerifyPermission(tokenId), static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR),
565         PASTEBOARD_MODULE_SERVICE, "check permission failed, calling pid is %{public}d", callPid);
566 
567     auto appInfo = GetAppInfo(tokenId);
568     auto [hasData, data] = clips_.Find(appInfo.userId);
569     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasData && data, static_cast<int32_t>(PasteboardError::NO_DATA_ERROR),
570         PASTEBOARD_MODULE_SERVICE, "data not find, userId=%{public}u", appInfo.userId);
571     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(dataId == data->GetDataId(),
572         static_cast<int32_t>(PasteboardError::INVALID_DATA_ID), PASTEBOARD_MODULE_SERVICE,
573         "dataId=%{public}u mismatch, local=%{public}u", dataId, data->GetDataId());
574 
575     auto record = data->GetRecordById(recordId);
576     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(record != nullptr, static_cast<int32_t>(PasteboardError::INVALID_RECORD_ID),
577         PASTEBOARD_MODULE_SERVICE, "recordId=%{public}u invalid, max=%{public}zu", recordId, data->GetRecordCount());
578 
579     std::string utdId = value.GetUtdId();
580     auto entry = record->GetEntry(utdId);
581     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(entry != nullptr, static_cast<int32_t>(PasteboardError::INVALID_MIMETYPE),
582         PASTEBOARD_MODULE_SERVICE, "entry is null, recordId=%{public}u, type=%{public}s", recordId, utdId.c_str());
583 
584     if (data->IsRemote() && !entry->HasContent(utdId)) {
585         int32_t ret = GetRemoteEntryValue(appInfo, *data, *record, value);
586         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
587             PASTEBOARD_MODULE_SERVICE, "get remote entry failed, type=%{public}s, ret=%{public}d", utdId.c_str(), ret);
588         return static_cast<int32_t>(PasteboardError::E_OK);
589     }
590 
591     int32_t ret = GetLocalEntryValue(appInfo.userId, *data, *record, value);
592     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
593         PASTEBOARD_MODULE_SERVICE, "get local entry failed, type=%{public}s, ret=%{public}d", utdId.c_str(), ret);
594 
595     std::string mimeType = value.GetMimeType();
596     if (mimeType == MIMETYPE_TEXT_HTML) {
597         return ProcessDelayHtmlEntry(*data, appInfo.bundleName, value);
598     }
599     if (mimeType == MIMETYPE_TEXT_URI) {
600         std::vector<Uri> grantUris = CheckUriPermission(*data, appInfo.bundleName);
601         return GrantUriPermission(grantUris, appInfo.bundleName);
602     }
603     return static_cast<int32_t>(PasteboardError::E_OK);
604 }
605 
ProcessDelayHtmlEntry(PasteData & data,const std::string & targetBundle,PasteDataEntry & entry)606 int32_t PasteboardService::ProcessDelayHtmlEntry(PasteData &data, const std::string &targetBundle,
607     PasteDataEntry &entry)
608 {
609     if (!PasteboardWebController::GetInstance().SplitWebviewPasteData(data)) {
610         return static_cast<int32_t>(PasteboardError::E_OK);
611     }
612 
613     PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
614     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
615 
616     PasteData tmp;
617     std::shared_ptr<std::string> html = entry.ConvertToHtml();
618     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(html != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
619         PASTEBOARD_MODULE_SERVICE, "convert to html failed");
620 
621     tmp.AddHtmlRecord(*html);
622     tmp.SetOriginAuthority(data.GetOriginAuthority());
623     tmp.SetTokenId(data.GetTokenId());
624     tmp.SetRemote(data.IsRemote());
625     PasteboardWebController::GetInstance().SplitWebviewPasteData(tmp);
626     PasteboardWebController::GetInstance().SetWebviewPasteData(tmp, data.GetOriginAuthority());
627     PasteboardWebController::GetInstance().CheckAppUriPermission(tmp);
628 
629     std::vector<Uri> grantUris = CheckUriPermission(tmp, targetBundle);
630     int32_t ret = GrantUriPermission(grantUris, targetBundle);
631     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
632         PASTEBOARD_MODULE_SERVICE, "grant to %{public}s failed, ret=%{public}d", targetBundle.c_str(), ret);
633 
634     return PostProcessDelayHtmlEntry(tmp, targetBundle, entry);
635 }
636 
PostProcessDelayHtmlEntry(PasteData & data,const std::string & targetBundle,PasteDataEntry & entry)637 int32_t PasteboardService::PostProcessDelayHtmlEntry(PasteData &data, const std::string &targetBundle,
638     PasteDataEntry &entry)
639 {
640     PasteboardWebController::GetInstance().RetainUri(data);
641     PasteboardWebController::GetInstance().RebuildWebviewPasteData(data, targetBundle);
642 
643     std::shared_ptr<std::string> html = data.GetPrimaryHtml();
644     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(html != nullptr, static_cast<int32_t>(PasteboardError::REBUILD_HTML_FAILED),
645         PASTEBOARD_MODULE_SERVICE, "rebuild html failed");
646 
647     auto entryValue = entry.GetValue();
648     if (std::holds_alternative<std::string>(entryValue)) {
649         entry.SetValue(*html);
650     } else if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
651         auto object = std::get<std::shared_ptr<Object>>(entryValue);
652         auto newObject = std::make_shared<Object>();
653         newObject->value_ = object->value_;
654         newObject->value_[UDMF::HTML_CONTENT] = *html;
655         entry.SetValue(newObject);
656     }
657     return static_cast<int32_t>(PasteboardError::E_OK);
658 }
659 
VerifyPermission(uint32_t tokenId)660 bool PasteboardService::VerifyPermission(uint32_t tokenId)
661 {
662     auto version = GetSdkVersion(tokenId);
663     auto callPid = IPCSkeleton::GetCallingPid();
664     if (version == INVALID_VERSION) {
665         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
666             "get hap version failed, callPid is %{public}d, tokenId is %{public}d", callPid, tokenId);
667         return false;
668     }
669     auto isReadGrant = IsPermissionGranted(READ_PASTEBOARD_PERMISSION, tokenId);
670     if (isReadGrant) {
671         return true;
672     }
673     auto isSecureGrant = IsPermissionGranted(SECURE_PASTE_PERMISSION, tokenId);
674     if (isSecureGrant) {
675         return true;
676     }
677     AddPermissionRecord(tokenId, isReadGrant, isSecureGrant);
678     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE,
679         "isReadGrant is %{public}d, isSecureGrant is %{public}d,", isReadGrant, isSecureGrant);
680     bool isCtrlVAction = false;
681     if (inputEventCallback_ != nullptr) {
682         isCtrlVAction = inputEventCallback_->IsCtrlVProcess(callPid, IsFocusedApp(tokenId));
683         inputEventCallback_->Clear();
684     }
685     auto isGrant = isReadGrant || isSecureGrant || isCtrlVAction;
686     if (!isGrant && version >= ADD_PERMISSION_CHECK_SDK_VERSION) {
687         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "no permission, callPid is %{public}d, version is %{public}d",
688             callPid, version);
689         return false;
690     }
691     return true;
692 }
693 
IsDataVaild(PasteData & pasteData,uint32_t tokenId)694 int32_t PasteboardService::IsDataVaild(PasteData &pasteData, uint32_t tokenId)
695 {
696     if (pasteData.IsDraggedData() || !pasteData.IsValid()) {
697         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is invalid");
698         return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
699     }
700     if (IsDataAged()) {
701         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is aged");
702         return static_cast<int32_t>(PasteboardError::DATA_EXPIRED_ERROR);
703     }
704     auto screenStatus = GetCurrentScreenStatus();
705     if (pasteData.GetScreenStatus() > screenStatus) {
706         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "current screen is %{public}d, set data screen is %{public}d.",
707             screenStatus, pasteData.GetScreenStatus());
708         return static_cast<int32_t>(PasteboardError::CROSS_BORDER_ERROR);
709     }
710     switch (pasteData.GetShareOption()) {
711         case ShareOption::InApp: {
712             if (pasteData.GetTokenId() != tokenId) {
713                 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "InApp check failed.");
714                 return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
715             }
716             break;
717         }
718         case ShareOption::LocalDevice: {
719             break;
720         }
721         case ShareOption::CrossDevice: {
722             break;
723         }
724         default: {
725             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "tokenId = 0x%{public}x, shareOption = %{public}d is error.",
726                 tokenId, pasteData.GetShareOption());
727             return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
728         }
729     }
730     return static_cast<int32_t>(PasteboardError::E_OK);
731 }
732 
GetSdkVersion(uint32_t tokenId)733 int32_t PasteboardService::GetSdkVersion(uint32_t tokenId)
734 {
735     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != ATokenTypeEnum::TOKEN_HAP) {
736         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "caller is not application");
737         return 0;
738     }
739     HapTokenInfo hapTokenInfo;
740     auto ret = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
741     if (ret != 0) {
742         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetHapTokenInfo fail, tokenid is %{public}u, ret is %{public}d.",
743             tokenId, ret);
744         return INVALID_VERSION;
745     }
746     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "ver:%{public}d.", hapTokenInfo.apiVersion);
747     return hapTokenInfo.apiVersion;
748 }
749 
IsPermissionGranted(const std::string & perm,uint32_t tokenId)750 bool PasteboardService::IsPermissionGranted(const std::string &perm, uint32_t tokenId)
751 {
752     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "check grant permission, perm=%{public}s", perm.c_str());
753     int32_t result = AccessTokenKit::VerifyAccessToken(tokenId, perm);
754     if (result == PermissionState::PERMISSION_DENIED) {
755         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "permission denied");
756         return false;
757     }
758     return true;
759 }
760 
IsDataAged()761 bool PasteboardService::IsDataAged()
762 {
763     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "IsDataAged start");
764     auto userId = GetCurrentAccountId();
765     if (userId == ERROR_USERID) {
766         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
767         return true;
768     }
769     auto it = copyTime_.Find(userId);
770     if (!it.first) {
771         return true;
772     }
773     uint64_t copyTime = it.second;
774     auto curTime = static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
775     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "copyTime = %{public}" PRIu64 ", curTime = %{public}" PRIu64,
776         copyTime, curTime);
777     if (curTime > copyTime && curTime - copyTime > ONE_HOUR_MILLISECONDS) {
778         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "data is out of the time");
779         auto data = clips_.Find(userId);
780         if (data.first) {
781             RevokeUriPermission(data.second);
782             clips_.Erase(userId);
783             delayDataId_ = 0;
784             delayTokenId_ = 0;
785         }
786         copyTime_.Erase(userId);
787         RADAR_REPORT(DFX_CLEAR_PASTEBOARD, DFX_AUTO_CLEAR, DFX_SUCCESS);
788         return true;
789     }
790     return false;
791 }
792 
GetAppInfo(uint32_t tokenId)793 AppInfo PasteboardService::GetAppInfo(uint32_t tokenId)
794 {
795     AppInfo info;
796     info.tokenId = tokenId;
797     info.tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
798     info.userId = GetCurrentAccountId();
799     switch (info.tokenType) {
800         case ATokenTypeEnum::TOKEN_HAP: {
801             HapTokenInfo hapInfo;
802             if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
803                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get hap token info fail.");
804                 return info;
805             }
806             info.bundleName = hapInfo.bundleName;
807             break;
808         }
809         case ATokenTypeEnum::TOKEN_NATIVE:
810         case ATokenTypeEnum::TOKEN_SHELL: {
811             NativeTokenInfo tokenInfo;
812             if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
813                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get native token info fail.");
814                 return info;
815             }
816             info.bundleName = tokenInfo.processName;
817             break;
818         }
819         default: {
820             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "tokenType = %{public}d not match.", info.tokenType);
821         }
822     }
823     return info;
824 }
825 
GetAppBundleName(const AppInfo & appInfo)826 std::string PasteboardService::GetAppBundleName(const AppInfo &appInfo)
827 {
828     std::string bundleName;
829     if (appInfo.userId != ERROR_USERID) {
830         bundleName = appInfo.bundleName;
831     } else {
832         bundleName = "error";
833         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetAppInfo error");
834     }
835     return bundleName;
836 }
837 
SetLocalPasteFlag(bool isCrossPaste,uint32_t tokenId,PasteData & pasteData)838 void PasteboardService::SetLocalPasteFlag(bool isCrossPaste, uint32_t tokenId, PasteData &pasteData)
839 {
840     pasteData.SetLocalPasteFlag(!isCrossPaste && tokenId == pasteData.GetTokenId());
841     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "isLocalPaste = %{public}d.", pasteData.IsLocalPaste());
842 }
843 
ShowProgress(const std::string & progressKey,const sptr<IRemoteObject> & observer)844 void PasteboardService::ShowProgress(const std::string &progressKey, const sptr<IRemoteObject> &observer)
845 {
846     if (!HasPasteData()) {
847         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "not pastedata, no need to show progress.");
848         return;
849     }
850     auto tokenId = IPCSkeleton::GetCallingTokenID();
851     if (!IsFocusedApp(tokenId)) {
852         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "not focused app, no need to show progress.");
853         return;
854     }
855     PasteBoardDialog::ProgressMessageInfo message;
856     std::string deviceName = "";
857     bool isRemote = false;
858     auto result = (GetRemoteDeviceName(deviceName, isRemote) == static_cast<int32_t>(PasteboardError::E_OK));
859     if (result && isRemote) {
860         message.promptText = "PromptText_PasteBoard_Remote";
861         message.remoteDeviceName = deviceName;
862     } else {
863         message.promptText = "PromptText_PasteBoard_Local";
864         message.remoteDeviceName = "";
865     }
866     message.isRemote = isRemote;
867     message.progressKey = progressKey;
868 
869     FocusedAppInfo appInfo = GetFocusedAppInfo();
870     message.windowId = appInfo.windowId;
871     message.callerToken = appInfo.abilityToken;
872     message.clientCallback = observer;
873     PasteBoardDialog::GetInstance().ShowProgress(message);
874 }
875 
GetPasteData(PasteData & data,int32_t & syncTime)876 int32_t PasteboardService::GetPasteData(PasteData &data, int32_t &syncTime)
877 {
878     PasteboardTrace tracer("PasteboardService GetPasteData");
879     auto tokenId = IPCSkeleton::GetCallingTokenID();
880     auto callPid = IPCSkeleton::GetCallingPid();
881     auto appInfo = GetAppInfo(tokenId);
882     bool developerMode = OHOS::system::GetBoolParameter("const.security.developermode.state", false);
883     bool isTestServerSetPasteData = developerMode && setPasteDataUId_ == TEST_SERVER_UID;
884     if (!VerifyPermission(tokenId) && !isTestServerSetPasteData) {
885         RADAR_REPORT(DFX_GET_PASTEBOARD, DFX_CHECK_GET_AUTHORITY, DFX_SUCCESS, GET_DATA_APP, appInfo.bundleName,
886             RadarReporter::CONCURRENT_ID, data.GetPasteId());
887         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "check permission failed, callingPid is %{public}d", callPid);
888         return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
889     }
890     auto ret = GetData(tokenId, data, syncTime);
891     UE_REPORT(UeReporter::UE_PASTE, GenerateDataType(data), appInfo.bundleName,
892         (ret == static_cast<int32_t>(PasteboardError::E_OK)) ? UeReporter::E_OK_OPERATION : ret,
893         DMAdapter::GetInstance().GetLocalDeviceType(), UeReporter::CROSS_FLAG, data.IsRemote());
894     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
895         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
896             "data is invalid, ret is %{public}d, callPid is %{public}d, tokenId is %{public}d", ret, callPid, tokenId);
897     } else {
898         delayDataId_ = data.GetDataId();
899         delayTokenId_ = tokenId;
900     }
901     return ret;
902 }
903 
AddPermissionRecord(uint32_t tokenId,bool isReadGrant,bool isSecureGrant)904 void PasteboardService::AddPermissionRecord(uint32_t tokenId, bool isReadGrant, bool isSecureGrant)
905 {
906     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
907         return;
908     }
909     bool isGrant = isReadGrant || isSecureGrant;
910     if (!isGrant) {
911         return;
912     }
913     auto permUsedType = static_cast<PermissionUsedType>(AccessTokenKit::GetPermissionUsedType(
914         tokenId, isSecureGrant ? SECURE_PASTE_PERMISSION : READ_PASTEBOARD_PERMISSION));
915     AddPermParamInfo info;
916     info.tokenId = tokenId;
917     info.permissionName = READ_PASTEBOARD_PERMISSION;
918     info.successCount = 1;
919     info.failCount = 0;
920     info.type = permUsedType;
921     int32_t result = PrivacyKit::AddPermissionUsedRecord(info);
922     if (result != RET_SUCCESS) {
923         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "add record failed, result is %{public}d", result);
924     }
925     return;
926 }
927 
GetData(uint32_t tokenId,PasteData & data,int32_t & syncTime)928 int32_t PasteboardService::GetData(uint32_t tokenId, PasteData &data, int32_t &syncTime)
929 {
930     CalculateTimeConsuming::SetBeginTime();
931     auto appInfo = GetAppInfo(tokenId);
932     int32_t result = static_cast<int32_t>(PasteboardError::E_OK);
933     std::string peerNetId = "";
934     std::string peerUdid = "";
935     std::string pasteId = data.GetPasteId();
936     auto [distRet, distEvt] = GetValidDistributeEvent(appInfo.userId);
937     if (distRet != static_cast<int32_t>(PasteboardError::E_OK) ||
938         GetCurrentScreenStatus() != ScreenEvent::ScreenUnlocked) {
939         result = GetLocalData(appInfo, data);
940     } else {
941         result = GetRemoteData(appInfo.userId, distEvt, data, syncTime);
942         peerNetId = distEvt.deviceId;
943         peerUdid = DMAdapter::GetInstance().GetUdidByNetworkId(peerNetId);
944     }
945     if (observerEventMap_.size() != 0) {
946         std::string targetBundleName = GetAppBundleName(appInfo);
947         NotifyObservers(targetBundleName, PasteboardEventStatus::PASTEBOARD_READ);
948     }
949     RADAR_REPORT(DFX_GET_PASTEBOARD, DFX_GET_DATA_INFO, DFX_SUCCESS, CONCURRENT_ID, pasteId, GET_DATA_APP,
950         appInfo.bundleName, GET_DATA_TYPE, GenerateDataType(data), LOCAL_DEV_TYPE,
951         DMAdapter::GetInstance().GetLocalDeviceType(), PEER_NET_ID, PasteboardDfxUntil::GetAnonymousID(peerNetId),
952         PEER_UDID, PasteboardDfxUntil::GetAnonymousID(peerUdid));
953     if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
954         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get local or remote data err:%{public}d", result);
955         return result;
956     }
957     int64_t fileSize = data.GetFileSize();
958     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "fileSize=%{public}" PRId64 ", isRemote=%{public}d", fileSize,
959         static_cast<int>(data.IsRemote()));
960     GetPasteDataDot(data, appInfo.bundleName);
961     std::vector<Uri> grantUris = CheckUriPermission(data, appInfo.bundleName);
962     PASTEBOARD_CHECK_AND_RETURN_RET_LOGD(!grantUris.empty(), static_cast<int32_t>(PasteboardError::E_OK),
963         PASTEBOARD_MODULE_SERVICE, "no uri");
964     if (data.IsRemote()) {
965         data.SetPasteId(pasteId);
966         data.deviceId_ = distEvt.deviceId;
967         EstablishP2PLink(data.deviceId_, data.GetPasteId());
968     }
969     return GrantUriPermission(grantUris, appInfo.bundleName);
970 }
971 
GetRemoteDataTask(const Event & event)972 PasteboardService::RemoteDataTaskManager::DataTask PasteboardService::RemoteDataTaskManager::GetRemoteDataTask(
973     const Event &event)
974 {
975     auto key = event.deviceId + std::to_string(event.seqId);
976     std::lock_guard<std::mutex> lock(mutex_);
977     auto it = dataTasks_.find(key);
978     if (it == dataTasks_.end()) {
979         it = dataTasks_.emplace(key, std::make_shared<TaskContext>()).first;
980     }
981 
982     if (it == dataTasks_.end()) {
983         return std::make_pair(nullptr, false);
984     }
985 
986     return std::make_pair(it->second, it->second->pasting_.exchange(true));
987 }
988 
Notify(const Event & event,std::shared_ptr<PasteDateTime> data)989 void PasteboardService::RemoteDataTaskManager::Notify(const Event &event, std::shared_ptr<PasteDateTime> data)
990 {
991     auto key = event.deviceId + std::to_string(event.seqId);
992     std::lock_guard<std::mutex> lock(mutex_);
993     auto it = dataTasks_.find(key);
994     if (it == dataTasks_.end()) {
995         return;
996     }
997     auto &task = it->second;
998     task->data_ = data;
999     task->getDataBlocks_.ForEach([](const auto &key, auto value) -> bool {
1000         value->SetValue(true);
1001         return false;
1002     });
1003 }
1004 
WaitRemoteData(const Event & event)1005 std::shared_ptr<PasteDateTime> PasteboardService::RemoteDataTaskManager::WaitRemoteData(const Event &event)
1006 {
1007     std::shared_ptr<PasteboardService::RemoteDataTaskManager::TaskContext> task;
1008     {
1009         auto key = event.deviceId + std::to_string(event.seqId);
1010         std::lock_guard<std::mutex> lock(mutex_);
1011         auto it = dataTasks_.find(key);
1012         if (it == dataTasks_.end()) {
1013             return nullptr;
1014         }
1015 
1016         task = it->second;
1017     }
1018 
1019     auto key = ++mapKey_;
1020     auto block = std::make_shared<BlockObject<bool>>(GET_REMOTE_DATA_WAIT_TIME);
1021     task->getDataBlocks_.InsertOrAssign(key, block);
1022     block->GetValue();
1023 
1024     task->getDataBlocks_.Erase(key);
1025     return task->data_;
1026 }
1027 
ClearRemoteDataTask(const Event & event)1028 void PasteboardService::RemoteDataTaskManager::ClearRemoteDataTask(const Event &event)
1029 {
1030     auto key = event.deviceId + std::to_string(event.seqId);
1031     std::lock_guard<std::mutex> lock(mutex_);
1032     dataTasks_.erase(key);
1033 }
1034 
GetRemoteData(int32_t userId,const Event & event,PasteData & data,int32_t & syncTime)1035 int32_t PasteboardService::GetRemoteData(int32_t userId, const Event &event, PasteData &data, int32_t &syncTime)
1036 {
1037     syncTime = -1;
1038     auto [task, isPasting] = taskMgr_.GetRemoteDataTask(event);
1039     if (task == nullptr) {
1040         return static_cast<int32_t>(PasteboardError::REMOTE_TASK_ERROR);
1041     }
1042 
1043     if (isPasting) {
1044         auto value = taskMgr_.WaitRemoteData(event);
1045         if (value != nullptr && value->data != nullptr) {
1046             syncTime = value->syncTime;
1047             data = *(value->data);
1048             return static_cast<int32_t>(PasteboardError::E_OK);
1049         }
1050         return static_cast<int32_t>(PasteboardError::TASK_PROCESSING);
1051     }
1052 
1053     auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1054     if (distRet != static_cast<int32_t>(PasteboardError::E_OK) || !(distEvt == event)) {
1055         int32_t ret = distRet == static_cast<int32_t>(PasteboardError::E_OK) ?
1056             static_cast<int32_t>(PasteboardError::INVALID_EVENT_ERROR) : distRet;
1057         auto it = clips_.Find(userId);
1058         if (it.first) {
1059             data = *it.second;
1060             ret = static_cast<int32_t>(PasteboardError::E_OK);
1061         }
1062         taskMgr_.ClearRemoteDataTask(event);
1063         return ret;
1064     }
1065 
1066     return GetRemotePasteData(userId, event, data, syncTime);
1067 }
1068 
GetRemotePasteData(int32_t userId,const Event & event,PasteData & data,int32_t & syncTime)1069 int32_t PasteboardService::GetRemotePasteData(int32_t userId, const Event &event, PasteData &data, int32_t &syncTime)
1070 {
1071     auto block = std::make_shared<BlockObject<std::shared_ptr<PasteDateTime>>>(GET_REMOTE_DATA_WAIT_TIME);
1072     std::thread thread([this, event, block, userId]() mutable {
1073         auto result = GetDistributedData(event, userId);
1074         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1075         std::shared_ptr<PasteDateTime> pasteDataTime = std::make_shared<PasteDateTime>();
1076         if (result.first != nullptr) {
1077             result.first->SetRemote(true);
1078             if (distEvt == event) {
1079                 clips_.InsertOrAssign(userId, result.first);
1080                 IncreaseChangeCount(userId);
1081                 auto curTime =
1082                     static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
1083                 copyTime_.InsertOrAssign(userId, curTime);
1084             }
1085             pasteDataTime->syncTime = result.second.syncTime;
1086             pasteDataTime->data = result.first;
1087             pasteDataTime->errorCode = result.second.errorCode;
1088             taskMgr_.Notify(event, pasteDataTime);
1089         } else {
1090             pasteDataTime->data = nullptr;
1091             pasteDataTime->errorCode = result.second.errorCode;
1092             taskMgr_.Notify(event, pasteDataTime);
1093         }
1094         block->SetValue(pasteDataTime);
1095         taskMgr_.ClearRemoteDataTask(event);
1096     });
1097     thread.detach();
1098     auto value = block->GetValue();
1099     if (value != nullptr && value->data != nullptr) {
1100         syncTime = value->syncTime;
1101         data = std::move(*(value->data));
1102         return value->errorCode;
1103     } else if (value != nullptr && value->data == nullptr) {
1104         return value->errorCode;
1105     }
1106     return static_cast<int32_t>(PasteboardError::TIMEOUT_ERROR);
1107 }
1108 
GetLocalData(const AppInfo & appInfo,PasteData & data)1109 int32_t PasteboardService::GetLocalData(const AppInfo &appInfo, PasteData &data)
1110 {
1111     std::string pasteId = data.GetPasteId();
1112     auto it = clips_.Find(appInfo.userId);
1113     auto tempTime = copyTime_.Find(appInfo.userId);
1114     if (!it.first || !tempTime.first) {
1115         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "no data userId is %{public}d.", appInfo.userId);
1116         return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
1117     }
1118     auto ret = IsDataVaild(*(it.second), appInfo.tokenId);
1119     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1120         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "paste data is invaild. ret is %{public}d", ret);
1121         return ret;
1122     }
1123     data = *(it.second);
1124     auto originBundleName = it.second->GetBundleName();
1125     if (it.second->IsDelayData()) {
1126         GetDelayPasteData(appInfo.userId, data);
1127         RADAR_REPORT(DFX_GET_PASTEBOARD, DFX_CHECK_GET_DELAY_PASTE, DFX_SUCCESS, CONCURRENT_ID, pasteId);
1128     }
1129     if (it.second->IsDelayRecord()) {
1130         GetDelayPasteRecord(appInfo.userId, data);
1131     }
1132     data.SetBundleName(appInfo.bundleName);
1133     auto result = copyTime_.Find(appInfo.userId);
1134     if (!result.first) {
1135         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId not found userId is %{public}d", appInfo.userId);
1136         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
1137     }
1138     auto curTime = result.second;
1139     if (tempTime.second == curTime) {
1140         bool isNotify = false;
1141         clips_.ComputeIfPresent(appInfo.userId, [&data, &isNotify](auto &key, auto &value) {
1142             if (value->IsDelayData()) {
1143                 value = std::make_shared<PasteData>(data);
1144                 isNotify = true;
1145             }
1146             if (value->IsDelayRecord()) {
1147                 value = std::make_shared<PasteData>(data);
1148             }
1149             return true;
1150         });
1151         if (isNotify) {
1152             NotifyObservers(originBundleName, PasteboardEventStatus::PASTEBOARD_WRITE);
1153         }
1154     }
1155     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "GetPasteData success.");
1156     SetLocalPasteFlag(data.IsRemote(), appInfo.tokenId, data);
1157     return static_cast<int32_t>(PasteboardError::E_OK);
1158 }
1159 
GetDelayPasteData(int32_t userId,PasteData & data)1160 void PasteboardService::GetDelayPasteData(int32_t userId, PasteData &data)
1161 {
1162     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "get delay data start");
1163     delayGetters_.ComputeIfPresent(userId, [this, &data](auto, auto &delayGetter) {
1164         PasteData delayData;
1165         if (delayGetter.first != nullptr) {
1166             delayGetter.first->GetPasteData("", delayData);
1167         }
1168         if (delayGetter.second != nullptr) {
1169             delayGetter.first->AsObject()->RemoveDeathRecipient(delayGetter.second);
1170         }
1171         delayData.SetDelayData(false);
1172         delayData.SetBundleName(data.GetBundleName());
1173         delayData.SetOriginAuthority(data.GetOriginAuthority());
1174         delayData.SetTime(data.GetTime());
1175         delayData.SetTokenId(data.GetTokenId());
1176         PasteboardWebController::GetInstance().SplitWebviewPasteData(delayData);
1177         PasteboardWebController::GetInstance().SetWebviewPasteData(delayData, data.GetOriginAuthority());
1178         PasteboardWebController::GetInstance().CheckAppUriPermission(delayData);
1179         data = delayData;
1180         return false;
1181     });
1182 }
1183 
GetDelayPasteRecord(int32_t userId,PasteData & data)1184 int32_t PasteboardService::GetDelayPasteRecord(int32_t userId, PasteData &data)
1185 {
1186     auto [hasGetter, getter] = entryGetters_.Find(userId);
1187     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasGetter && getter.first,
1188         static_cast<int32_t>(PasteboardError::NO_DELAY_GETTER), PASTEBOARD_MODULE_SERVICE,
1189         "entry getter not find, userId=%{public}d, dataId=%{public}u", userId, data.GetDataId());
1190 
1191     for (auto record : data.AllRecords()) {
1192         if (!(record->HasEmptyEntry())) {
1193             PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "record do not has empty value.");
1194             continue;
1195         }
1196         if (!record->IsDelayRecord()) {
1197             PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "record is not DelayRecord.");
1198             continue;
1199         }
1200         auto entries = record->GetEntries();
1201         if (entries.empty()) {
1202             PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "record size is 0.");
1203             continue;
1204         }
1205         if (!std::holds_alternative<std::monostate>(entries[0]->GetValue())) {
1206             continue;
1207         }
1208         auto result = getter.first->GetRecordValueByType(record->GetRecordId(), *entries[0]);
1209         if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
1210             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1211                 "get record value fail, dataId is %{public}d, recordId is %{public}d", data.GetDataId(),
1212                 record->GetRecordId());
1213             continue;
1214         }
1215         record->AddEntry(entries[0]->GetUtdId(), entries[0]);
1216     }
1217     PasteboardWebController::GetInstance().SplitWebviewPasteData(data);
1218     PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
1219     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
1220     return static_cast<int32_t>(PasteboardError::E_OK);
1221 }
1222 
EstablishP2PLink(const std::string & networkId,const std::string & pasteId)1223 void PasteboardService::EstablishP2PLink(const std::string &networkId, const std::string &pasteId)
1224 {
1225 #ifdef PB_DEVICE_MANAGER_ENABLE
1226     auto callPid = IPCSkeleton::GetCallingPid();
1227     p2pMap_.Compute(networkId, [pasteId, callPid](const auto &key, auto &value) {
1228         value.Compute(pasteId, [callPid](const auto &key, auto &value) {
1229             value = callPid;
1230             return true;
1231         });
1232         return true;
1233     });
1234     if (ffrtTimer_ != nullptr) {
1235         FFRTTask task = [this, networkId, pasteId] {
1236             PasteComplete(networkId, pasteId);
1237         };
1238         ffrtTimer_->SetTimer(pasteId, task, MIN_TRANMISSION_TIME);
1239     }
1240     DmDeviceInfo remoteDevice;
1241     auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(networkId, remoteDevice);
1242     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1243         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist");
1244         p2pMap_.Erase(networkId);
1245         return;
1246     }
1247     auto plugin = GetClipPlugin();
1248     if (plugin == nullptr) {
1249         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "plugin is not exist");
1250         p2pMap_.Erase(networkId);
1251         return;
1252     }
1253     auto status = DistributedFileDaemonManager::GetInstance().OpenP2PConnection(remoteDevice);
1254     if (status != RESULT_OK) {
1255         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "open p2p error, status:%{public}d", status);
1256         p2pMap_.Erase(networkId);
1257         return;
1258     }
1259     status = plugin->PublishServiceState(networkId, ClipPlugin::ServiceStatus::CONNECT_SUCC);
1260     if (status != RESULT_OK) {
1261         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Publish state connect_succ error, status:%{public}d", status);
1262     }
1263 #endif
1264 }
1265 
CloseP2PLink(const std::string & networkId)1266 void PasteboardService::CloseP2PLink(const std::string &networkId)
1267 {
1268 #ifdef PB_DEVICE_MANAGER_ENABLE
1269     DmDeviceInfo remoteDevice;
1270     auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(networkId, remoteDevice);
1271     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1272         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist");
1273         return;
1274     }
1275     auto status = DistributedFileDaemonManager::GetInstance().CloseP2PConnection(remoteDevice);
1276     if (status != RESULT_OK) {
1277         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "close p2p error, status:%{public}d", status);
1278     }
1279     auto plugin = GetClipPlugin();
1280     if (plugin == nullptr) {
1281         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "plugin is not exist");
1282         return;
1283     }
1284     status = plugin->PublishServiceState(networkId, ClipPlugin::ServiceStatus::IDLE);
1285     if (status != RESULT_OK) {
1286         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Publish state idle error, status:%{public}d", status);
1287     }
1288 #endif
1289 }
1290 
PasteStart(const std::string & pasteId)1291 void PasteboardService::PasteStart(const std::string &pasteId)
1292 {
1293     if (ffrtTimer_ != nullptr) {
1294         ffrtTimer_->CancelTimer(pasteId);
1295     }
1296 }
1297 
PasteComplete(const std::string & deviceId,const std::string & pasteId)1298 void PasteboardService::PasteComplete(const std::string &deviceId, const std::string &pasteId)
1299 {
1300     if (deviceId.empty()) {
1301         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "deviceId is empty");
1302         return;
1303     }
1304     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "deviceId is %{public}.6s, taskId is %{public}s", deviceId.c_str(),
1305         pasteId.c_str());
1306     RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_DISTRIBUTED_FILE_END, RadarReporter::DFX_SUCCESS,
1307         RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, pasteId);
1308     p2pMap_.ComputeIfPresent(deviceId, [pasteId, deviceId, this](const auto &key, auto &value) {
1309         value.ComputeIfPresent(pasteId, [deviceId](const auto &key, auto &value) {
1310             return false;
1311         });
1312         if (value.Empty()) {
1313             CloseP2PLink(deviceId);
1314             return false;
1315         }
1316         return true;
1317     });
1318 }
1319 
GetRemoteDeviceName(std::string & deviceName,bool & isRemote)1320 int32_t PasteboardService::GetRemoteDeviceName(std::string &deviceName, bool &isRemote)
1321 {
1322     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "enter");
1323     auto tokenId = IPCSkeleton::GetCallingTokenID();
1324     auto appInfo = GetAppInfo(tokenId);
1325     auto event = GetValidDistributeEvent(appInfo.userId);
1326     DmDeviceInfo remoteDevice;
1327     if (!event.second.deviceId.empty()) {
1328         auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(event.second.deviceId, remoteDevice);
1329         if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1330             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist");
1331             return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
1332         }
1333         deviceName = remoteDevice.deviceName;
1334         isRemote = true;
1335     } else {
1336         deviceName = "local";
1337         isRemote = false;
1338     }
1339     return static_cast<int32_t>(PasteboardError::E_OK);
1340 }
1341 
GrantUriPermission(const std::vector<Uri> & grantUris,const std::string & targetBundleName)1342 int32_t PasteboardService::GrantUriPermission(const std::vector<Uri> &grantUris, const std::string &targetBundleName)
1343 {
1344     PASTEBOARD_CHECK_AND_RETURN_RET_LOGD(!grantUris.empty(), static_cast<int32_t>(PasteboardError::E_OK),
1345         PASTEBOARD_MODULE_SERVICE, "no uri");
1346     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri size=%{public}zu, target=%{public}s",
1347         grantUris.size(), targetBundleName.c_str());
1348     bool hasGranted = false;
1349     int32_t ret = 0;
1350     size_t offset = 0;
1351     size_t length = grantUris.size();
1352     size_t count = PasteData::URI_BATCH_SIZE;
1353     while (length > offset) {
1354         if (length - offset < PasteData::URI_BATCH_SIZE) {
1355             count = length - offset;
1356         }
1357         auto sendValues = std::vector<Uri>(grantUris.begin() + offset, grantUris.begin() + offset + count);
1358         int32_t permissionCode = AAFwk::UriPermissionManagerClient::GetInstance().GrantUriPermissionPrivileged(
1359             sendValues, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, targetBundleName);
1360         hasGranted = hasGranted || (permissionCode == 0);
1361         ret = permissionCode == 0 ? ret : permissionCode;
1362         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "permissionCode is %{public}d", permissionCode);
1363         offset += count;
1364     }
1365     if (hasGranted) {
1366         std::lock_guard<std::mutex> lock(readBundleMutex_);
1367         if (readBundles_.count(targetBundleName) == 0) {
1368             readBundles_.insert(targetBundleName);
1369         }
1370     }
1371     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "leave, ret=%{public}d", ret);
1372     return ret == 0 ? static_cast<int32_t>(PasteboardError::E_OK) : ret;
1373 }
1374 
CheckUriPermission(PasteData & data,const std::string & targetBundleName)1375 std::vector<Uri> PasteboardService::CheckUriPermission(PasteData &data, const std::string &targetBundleName)
1376 {
1377     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "enter");
1378     std::vector<Uri> grantUris;
1379     for (size_t i = 0; i < data.GetRecordCount(); i++) {
1380         auto item = data.GetRecordAt(i);
1381         if (item == nullptr || (!data.IsRemote() && targetBundleName.compare(data.GetOriginAuthority()) == 0)) {
1382             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "local dev & local app");
1383             continue;
1384         }
1385         std::shared_ptr<OHOS::Uri> uri = nullptr;
1386         if (!item->isConvertUriFromRemote && !item->GetConvertUri().empty()) {
1387             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "clear local disUri");
1388             item->SetConvertUri("");
1389         }
1390         if (item->isConvertUriFromRemote && !item->GetConvertUri().empty()) {
1391             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "get remote disUri");
1392             uri = std::make_shared<OHOS::Uri>(item->GetConvertUri());
1393         } else if (!item->isConvertUriFromRemote && item->GetOriginUri() != nullptr) {
1394             uri = item->GetOriginUri();
1395         }
1396         if (uri == nullptr) {
1397             continue;
1398         }
1399         auto hasGrantUriPermission = item->HasGrantUriPermission();
1400         const std::string &bundleName = data.GetOriginAuthority();
1401         if (!IsBundleOwnUriPermission(bundleName, *uri) && !hasGrantUriPermission) {
1402             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri:%{private}s, bundleName:%{public}s, has grant:%{public}d",
1403                 uri->ToString().c_str(), bundleName.c_str(), hasGrantUriPermission);
1404             continue;
1405         }
1406         grantUris.emplace_back(*uri);
1407     }
1408     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "leave, grant:%{public}zu", grantUris.size());
1409     return grantUris;
1410 }
1411 
RevokeUriPermission(std::shared_ptr<PasteData> pasteData)1412 void PasteboardService::RevokeUriPermission(std::shared_ptr<PasteData> pasteData)
1413 {
1414     std::set<std::string> bundles;
1415     {
1416         std::lock_guard<std::mutex> lock(readBundleMutex_);
1417         bundles = std::move(readBundles_);
1418     }
1419     if (pasteData == nullptr) {
1420         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "pasteData is null");
1421         return;
1422     }
1423     if (bundles.empty()) {
1424         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "bundles empty");
1425         return;
1426     }
1427     std::thread thread([pasteData, bundles]() {
1428         auto &permissionClient = AAFwk::UriPermissionManagerClient::GetInstance();
1429         for (size_t i = 0; i < pasteData->GetRecordCount(); i++) {
1430             auto item = pasteData->GetRecordAt(i);
1431             if (item == nullptr || item->GetOriginUri() == nullptr) {
1432                 continue;
1433             }
1434             Uri &uri = *(item->GetOriginUri());
1435             for (std::set<std::string>::iterator it = bundles.begin(); it != bundles.end(); it++) {
1436                 auto permissionCode = permissionClient.RevokeUriPermissionManually(uri, *it);
1437                 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "permissionCode is %{public}d", permissionCode);
1438             }
1439         }
1440     });
1441     thread.detach();
1442 }
1443 
IsBundleOwnUriPermission(const std::string & bundleName,Uri & uri)1444 bool PasteboardService::IsBundleOwnUriPermission(const std::string &bundleName, Uri &uri)
1445 {
1446     return (bundleName.compare(uri.GetAuthority()) == 0);
1447 }
1448 
ShowHintToast(uint32_t tokenId,uint32_t pid)1449 void PasteboardService::ShowHintToast(uint32_t tokenId, uint32_t pid)
1450 {
1451     PasteBoardDialog::ToastMessageInfo message;
1452     message.appName = GetAppLabel(tokenId);
1453     PasteBoardDialog::GetInstance().ShowToast(message);
1454 }
1455 
HasPasteData()1456 bool PasteboardService::HasPasteData()
1457 {
1458     auto userId = GetCurrentAccountId();
1459     if (userId == ERROR_USERID) {
1460         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
1461         return false;
1462     }
1463 
1464     if (GetCurrentScreenStatus() == ScreenEvent::ScreenUnlocked) {
1465         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1466         if (distRet == static_cast<int32_t>(PasteboardError::E_OK)) {
1467             return true;
1468         }
1469     }
1470 
1471     auto it = clips_.Find(userId);
1472     if (it.first && (it.second != nullptr)) {
1473         auto tokenId = IPCSkeleton::GetCallingTokenID();
1474         auto ret = IsDataVaild(*(it.second), tokenId);
1475         if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1476             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1477                 "pasteData is invalid, tokenId: %{public}d, userId: %{public}d,"
1478                 "ret is %{public}d", tokenId, userId, ret);
1479             return false;
1480         }
1481         return true;
1482     }
1483     return false;
1484 }
1485 
SaveData(PasteData & pasteData,const sptr<IPasteboardDelayGetter> delayGetter,const sptr<IPasteboardEntryGetter> entryGetter)1486 int32_t PasteboardService::SaveData(PasteData &pasteData,
1487     const sptr<IPasteboardDelayGetter> delayGetter, const sptr<IPasteboardEntryGetter> entryGetter)
1488 {
1489     PasteboardTrace tracer("PasteboardService, SetPasteData");
1490     auto tokenId = IPCSkeleton::GetCallingTokenID();
1491     if (!IsCopyable(tokenId)) {
1492         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_SET_AUTHORITY, DFX_SUCCESS);
1493         return static_cast<int32_t>(PasteboardError::PROHIBIT_COPY);
1494     }
1495     if (setting_.exchange(true)) {
1496         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "is setting.");
1497         return static_cast<int32_t>(PasteboardError::TASK_PROCESSING);
1498     }
1499     CalculateTimeConsuming::SetBeginTime();
1500     auto appInfo = GetAppInfo(tokenId);
1501     if (appInfo.userId == ERROR_USERID) {
1502         setting_.store(false);
1503         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
1504         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
1505     }
1506     setPasteDataUId_ = IPCSkeleton::GetCallingUid();
1507     RemovePasteData(appInfo);
1508     pasteData.SetBundleName(appInfo.bundleName);
1509     pasteData.SetOriginAuthority(appInfo.bundleName);
1510     std::string time = GetTime();
1511     pasteData.SetTime(time);
1512     pasteData.SetScreenStatus(GetCurrentScreenStatus());
1513     pasteData.SetTokenId(tokenId);
1514     auto dataId = ++dataId_;
1515     pasteData.SetDataId(dataId);
1516     for (auto &record : pasteData.AllRecords()) {
1517         record->SetDataId(dataId);
1518     }
1519     UpdateShareOption(pasteData);
1520     PasteboardWebController::GetInstance().SetWebviewPasteData(pasteData, appInfo.bundleName);
1521     PasteboardWebController::GetInstance().CheckAppUriPermission(pasteData);
1522     clips_.InsertOrAssign(appInfo.userId, std::make_shared<PasteData>(pasteData));
1523     IncreaseChangeCount(appInfo.userId);
1524     RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_SET_DELAY_COPY, static_cast<int>(pasteData.IsDelayData()),
1525         SET_DATA_APP, appInfo.bundleName, LOCAL_DEV_TYPE, DMAdapter::GetInstance().GetLocalDeviceType());
1526     HandleDelayDataAndRecord(pasteData, delayGetter, entryGetter, appInfo);
1527     auto curTime = static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
1528     copyTime_.InsertOrAssign(appInfo.userId, curTime);
1529     if (!(pasteData.IsDelayData())) {
1530         SetDistributedData(appInfo.userId, pasteData);
1531         NotifyObservers(appInfo.bundleName, PasteboardEventStatus::PASTEBOARD_WRITE);
1532     }
1533     SetPasteDataDot(pasteData);
1534     setting_.store(false);
1535     SubscribeKeyboardEvent();
1536     return static_cast<int32_t>(PasteboardError::E_OK);
1537 }
1538 
HandleDelayDataAndRecord(PasteData & pasteData,const sptr<IPasteboardDelayGetter> delayGetter,const sptr<IPasteboardEntryGetter> entryGetter,const AppInfo & appInfo)1539 void PasteboardService::HandleDelayDataAndRecord(PasteData &pasteData, const sptr<IPasteboardDelayGetter> delayGetter,
1540     const sptr<IPasteboardEntryGetter> entryGetter, const AppInfo &appInfo)
1541 {
1542     if (pasteData.IsDelayData() && delayGetter != nullptr) {
1543         sptr<DelayGetterDeathRecipient> deathRecipient = new (std::nothrow)
1544             DelayGetterDeathRecipient(appInfo.userId, *this);
1545         delayGetter->AsObject()->AddDeathRecipient(deathRecipient);
1546         delayGetters_.InsertOrAssign(appInfo.userId, std::make_pair(delayGetter, deathRecipient));
1547     }
1548     if (pasteData.IsDelayRecord() && entryGetter != nullptr) {
1549         sptr<EntryGetterDeathRecipient> deathRecipient = new (std::nothrow)
1550             EntryGetterDeathRecipient(appInfo.userId, *this);
1551         entryGetter->AsObject()->AddDeathRecipient(deathRecipient);
1552         entryGetters_.InsertOrAssign(appInfo.userId, std::make_pair(entryGetter, deathRecipient));
1553     }
1554 }
1555 
IsBasicType(const std::string & mimeType)1556 bool PasteboardService::IsBasicType(const std::string &mimeType)
1557 {
1558     if (mimeType == MIMETYPE_TEXT_HTML || mimeType == MIMETYPE_TEXT_PLAIN || mimeType == MIMETYPE_TEXT_URI) {
1559         return true;
1560     }
1561     return false;
1562 }
1563 
GetMimeTypes()1564 std::vector<std::string> PasteboardService::GetMimeTypes()
1565 {
1566     if (GetCurrentScreenStatus() == ScreenEvent::ScreenUnlocked) {
1567         auto userId = GetCurrentAccountId();
1568         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1569         if (distRet == static_cast<int32_t>(PasteboardError::E_OK)) {
1570             PasteData data;
1571             int32_t syncTime = 0;
1572             int32_t ret = GetRemoteData(userId, distEvt, data, syncTime);
1573             PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), {},
1574                 PASTEBOARD_MODULE_SERVICE, "get remote data failed, ret=%{public}d", ret);
1575         }
1576     }
1577     return GetLocalMimeTypes();
1578 }
1579 
HasDataType(const std::string & mimeType)1580 bool PasteboardService::HasDataType(const std::string &mimeType)
1581 {
1582     if (GetCurrentScreenStatus() == ScreenEvent::ScreenUnlocked) {
1583         auto userId = GetCurrentAccountId();
1584         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1585         if (distRet == static_cast<int32_t>(PasteboardError::E_OK)) {
1586             auto it = std::find(distEvt.dataType.begin(), distEvt.dataType.end(), mimeType);
1587             if (it != distEvt.dataType.end()) {
1588                 return true;
1589             }
1590             if (IsBasicType(mimeType)) {
1591                 return false;
1592             }
1593             PasteData data;
1594             int32_t syncTime = 0;
1595             if (GetRemoteData(userId, distEvt, data, syncTime) != static_cast<int32_t>(PasteboardError::E_OK)) {
1596                 return false;
1597             }
1598         }
1599     }
1600     return HasLocalDataType(mimeType);
1601 }
1602 
DetectPatterns(const std::set<Pattern> & patternsToCheck)1603 std::set<Pattern> PasteboardService::DetectPatterns(const std::set<Pattern> &patternsToCheck)
1604 {
1605     bool hasPlain = HasLocalDataType(MIMETYPE_TEXT_PLAIN);
1606     bool hasHTML = HasLocalDataType(MIMETYPE_TEXT_HTML);
1607     if (!hasHTML && !hasPlain) {
1608         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "no text");
1609         return {};
1610     }
1611     int32_t userId = GetCurrentAccountId();
1612     auto it = clips_.Find(userId);
1613     if (!it.first) {
1614         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "error, no PasteData!");
1615         return {};
1616     }
1617     std::shared_ptr<PasteData> pasteData = it.second;
1618     return OHOS::MiscServices::PatternDetection::Detect(patternsToCheck, *pasteData, hasHTML, hasPlain);
1619 }
1620 
GetValidDistributeEvent(int32_t user)1621 std::pair<int32_t, ClipPlugin::GlobalEvent> PasteboardService::GetValidDistributeEvent(int32_t user)
1622 {
1623     Event evt;
1624     auto plugin = GetClipPlugin();
1625     if (plugin == nullptr) {
1626         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "plugin is null");
1627         return std::make_pair(static_cast<int32_t>(PasteboardError::PLUGIN_IS_NULL), evt);
1628     }
1629     auto events = plugin->GetTopEvents(1, user);
1630     if (events.empty()) {
1631         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "plugin event is empty");
1632         return std::make_pair(static_cast<int32_t>(PasteboardError::PLUGIN_EVENT_EMPTY), evt);
1633     }
1634 
1635     evt = events[0];
1636     if (evt.deviceId == DMAdapter::GetInstance().GetLocalNetworkId() || evt.expiration < currentEvent_.expiration) {
1637         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get local data");
1638         return std::make_pair(static_cast<int32_t>(PasteboardError::GET_LOCAL_DATA), evt);
1639     }
1640     if (evt.account != AccountManager::GetInstance().GetCurrentAccount()) {
1641         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "account error");
1642         return std::make_pair(static_cast<int32_t>(PasteboardError::INVALID_EVENT_ACCOUNT), evt);
1643     }
1644     DmDeviceInfo remoteDevice;
1645     int32_t ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(evt.deviceId, remoteDevice);
1646     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1647         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "deviceId: %{public}.6s is offline", evt.deviceId.c_str());
1648         return std::make_pair(ret, evt);
1649     }
1650 
1651     if (evt.deviceId == currentEvent_.deviceId && evt.seqId == currentEvent_.seqId &&
1652         evt.expiration == currentEvent_.expiration) {
1653         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get same remote data");
1654         return std::make_pair(static_cast<int32_t>(PasteboardError::GET_SAME_REMOTE_DATA), evt);
1655     }
1656 
1657     uint64_t curTime =
1658         static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
1659     ret = evt.status == ClipPlugin::EVT_NORMAL ? ret : static_cast<int32_t>(PasteboardError::INVALID_EVENT_STATUS);
1660     ret = curTime < evt.expiration ? ret : static_cast<int32_t>(PasteboardError::DATA_EXPIRED_ERROR);
1661     return std::make_pair(ret, evt);
1662 }
1663 
GetLocalMimeTypes()1664 std::vector<std::string> PasteboardService::GetLocalMimeTypes()
1665 {
1666     auto userId = GetCurrentAccountId();
1667     auto it = clips_.Find(userId);
1668     if (!it.first) {
1669         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "can not find data. userId: %{public}d", userId);
1670         return {};
1671     }
1672     if (it.second == nullptr) {
1673         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is nullptr. userId: %{public}d", userId);
1674         return {};
1675     }
1676     auto tokenId = IPCSkeleton::GetCallingTokenID();
1677     auto ret = IsDataVaild(*(it.second), tokenId);
1678     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1679         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1680             "pasteData is invalid, tokenId is %{public}d, userId: %{public}d, ret is %{public}d",
1681             tokenId, userId, ret);
1682         return {};
1683     }
1684     return it.second->GetMimeTypes();
1685 }
1686 
HasLocalDataType(const std::string & mimeType)1687 bool PasteboardService::HasLocalDataType(const std::string &mimeType)
1688 {
1689     auto userId = GetCurrentAccountId();
1690     auto it = clips_.Find(userId);
1691     if (!it.first) {
1692         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "can not find data. userId: %{public}d, mimeType: %{public}s",
1693             userId, mimeType.c_str());
1694         return false;
1695     }
1696     if (it.second == nullptr) {
1697         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is nullptr. userId: %{public}d, mimeType: %{public}s",
1698             userId, mimeType.c_str());
1699         return false;
1700     }
1701     auto tokenId = IPCSkeleton::GetCallingTokenID();
1702     auto ret = IsDataVaild(*(it.second), tokenId);
1703     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1704         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1705             "pasteData is invalid, tokenId is %{public}d, userId: %{public}d,"
1706             "mimeType: %{public}s, ret is %{public}d",
1707             tokenId, userId, mimeType.c_str(), ret);
1708         return false;
1709     }
1710     auto screenStatus = GetCurrentScreenStatus();
1711     if (it.second->GetScreenStatus() > screenStatus) {
1712         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1713             "current screen is %{public}d, set data screen is %{public}d."
1714             "userId: %{public}d, mimeType: %{public}s",
1715             screenStatus, it.second->GetScreenStatus(), userId, mimeType.c_str());
1716         return false;
1717     }
1718     std::vector<std::string> mimeTypes = it.second->GetMimeTypes();
1719     auto isExistType = std::find(mimeTypes.begin(), mimeTypes.end(), mimeType) != mimeTypes.end();
1720     return isExistType;
1721 }
1722 
IsRemoteData()1723 bool PasteboardService::IsRemoteData()
1724 {
1725     auto userId = GetCurrentAccountId();
1726     if (userId == ERROR_USERID) {
1727         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId is error.");
1728         return false;
1729     }
1730     auto it = clips_.Find(userId);
1731     if (!it.first) {
1732         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1733         return distRet == static_cast<int32_t>(PasteboardError::E_OK);
1734     }
1735     return it.second->IsRemote();
1736 }
1737 
GetDataSource(std::string & bundleName)1738 int32_t PasteboardService::GetDataSource(std::string &bundleName)
1739 {
1740     auto userId = GetCurrentAccountId();
1741     if (userId == ERROR_USERID) {
1742         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
1743     }
1744     auto it = clips_.Find(userId);
1745     if (!it.first) {
1746         return static_cast<int32_t>(PasteboardError::NO_USER_DATA_ERROR);
1747     }
1748     auto data = it.second;
1749     if (data->IsRemote()) {
1750         return static_cast<int32_t>(PasteboardError::REMOTE_EXCEPTION);
1751     }
1752     auto tokenId = data->GetTokenId();
1753     bundleName = GetAppLabel(tokenId);
1754     return static_cast<int32_t>(PasteboardError::E_OK);
1755 }
1756 
SetPasteData(PasteData & pasteData,const sptr<IPasteboardDelayGetter> delayGetter,const sptr<IPasteboardEntryGetter> entryGetter)1757 int32_t PasteboardService::SetPasteData(PasteData &pasteData,
1758     const sptr<IPasteboardDelayGetter> delayGetter, const sptr<IPasteboardEntryGetter> entryGetter)
1759 {
1760     PasteboardWebController::GetInstance().SplitWebviewPasteData(pasteData);
1761     auto ret = SaveData(pasteData, delayGetter, entryGetter);
1762     if (entityObserverMap_.Size() != 0 && pasteData.HasMimeType(MIMETYPE_TEXT_PLAIN)) {
1763         RecognizePasteData(pasteData);
1764     }
1765     ReportUeCopyEvent(pasteData, ret);
1766     return ret;
1767 }
1768 
RemovePasteData(const AppInfo & appInfo)1769 void PasteboardService::RemovePasteData(const AppInfo &appInfo)
1770 {
1771     clips_.ComputeIfPresent(appInfo.userId, [this](auto, auto &clip) {
1772         RevokeUriPermission(clip);
1773         return false;
1774     });
1775     delayGetters_.ComputeIfPresent(appInfo.userId, [](auto, auto &delayGetter) {
1776         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_SET_DELAY_COPY, DFX_SUCCESS, COVER_DELAY_DATA, DFX_SUCCESS);
1777         if (delayGetter.first != nullptr && delayGetter.second != nullptr) {
1778             delayGetter.first->AsObject()->RemoveDeathRecipient(delayGetter.second);
1779         }
1780         return false;
1781     });
1782     entryGetters_.ComputeIfPresent(appInfo.userId, [](auto, auto &entryGetter) {
1783         if (entryGetter.first != nullptr && entryGetter.second != nullptr) {
1784             entryGetter.first->AsObject()->RemoveDeathRecipient(entryGetter.second);
1785         }
1786         return false;
1787     });
1788 }
1789 
GetCurrentAccountId()1790 int32_t PasteboardService::GetCurrentAccountId()
1791 {
1792     if (currentUserId_ != ERROR_USERID) {
1793         return currentUserId_;
1794     }
1795     std::vector<int32_t> accountIds;
1796     auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(accountIds);
1797     if (ret != ERR_OK || accountIds.empty()) {
1798         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed errCode=%{public}d", ret);
1799         return ERROR_USERID;
1800     }
1801     currentUserId_ = accountIds.front();
1802     return currentUserId_;
1803 }
1804 
GetCurrentScreenStatus()1805 ScreenEvent PasteboardService::GetCurrentScreenStatus()
1806 {
1807     if (currentScreenStatus != ScreenEvent::Default) {
1808         return currentScreenStatus;
1809     }
1810 
1811     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query current screen status failed.");
1812     return ScreenEvent::Default;
1813 }
1814 
IsCopyable(uint32_t tokenId) const1815 bool PasteboardService::IsCopyable(uint32_t tokenId) const
1816 {
1817 #ifdef WITH_DLP
1818     bool copyable = false;
1819     auto ret = Security::DlpPermission::DlpPermissionKit::QueryDlpFileCopyableByTokenId(copyable, tokenId);
1820     if (ret != Security::DlpPermission::DLP_OK || !copyable) {
1821         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "tokenId = 0x%{public}x ret = %{public}d, copyable = %{public}d.",
1822             tokenId, ret, copyable);
1823         return false;
1824     }
1825 #endif
1826     return true;
1827 }
1828 
SetInputMethodPid(pid_t callPid)1829 void PasteboardService::SetInputMethodPid(pid_t callPid)
1830 {
1831     auto imc = InputMethodController::GetInstance();
1832     if (imc == nullptr) {
1833         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "InputMethodController is nullptr!");
1834         return;
1835     }
1836     auto isImePid = imc->IsCurrentImeByPid(callPid);
1837     if (isImePid) {
1838         std::lock_guard lock(imeMutex_);
1839         imePid_ = callPid;
1840         hasImeObserver_ = true;
1841     }
1842 }
1843 
ClearInputMethodPidByPid(pid_t callPid)1844 void PasteboardService::ClearInputMethodPidByPid(pid_t callPid)
1845 {
1846     if (callPid == imePid_) {
1847         std::lock_guard lock(imeMutex_);
1848         imePid_ = -1;
1849         hasImeObserver_ = false;
1850     }
1851 }
1852 
ClearInputMethodPid()1853 void PasteboardService::ClearInputMethodPid()
1854 {
1855     std::lock_guard lock(imeMutex_);
1856     imePid_ = -1;
1857     hasImeObserver_ = false;
1858 }
1859 
SubscribeObserver(PasteboardObserverType type,const sptr<IPasteboardChangedObserver> & observer)1860 void PasteboardService::SubscribeObserver(PasteboardObserverType type, const sptr<IPasteboardChangedObserver> &observer)
1861 {
1862     auto callPid = IPCSkeleton::GetCallingPid();
1863     SetInputMethodPid(callPid);
1864     bool isEventType = static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_EVENT);
1865     int32_t userId = isEventType ? COMMON_USERID : GetCurrentAccountId();
1866     if (userId == ERROR_USERID) {
1867         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
1868         return;
1869     }
1870     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_LOCAL)) {
1871         AddObserver(userId, observer, observerLocalChangedMap_);
1872     }
1873 
1874     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_REMOTE)) {
1875         AddObserver(userId, observer, observerRemoteChangedMap_);
1876     }
1877 
1878     if (isEventType && IsCallerUidValid()) {
1879         AddObserver(userId, observer, observerEventMap_);
1880     }
1881 }
1882 
UnsubscribeObserver(PasteboardObserverType type,const sptr<IPasteboardChangedObserver> & observer)1883 void PasteboardService::UnsubscribeObserver(
1884     PasteboardObserverType type, const sptr<IPasteboardChangedObserver> &observer)
1885 {
1886     auto callPid = IPCSkeleton::GetCallingPid();
1887     ClearInputMethodPidByPid(callPid);
1888     bool isEventType = static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_EVENT);
1889     int32_t userId = isEventType ? COMMON_USERID : GetCurrentAccountId();
1890     if (userId == ERROR_USERID) {
1891         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
1892         return;
1893     }
1894     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_LOCAL)) {
1895         RemoveSingleObserver(userId, observer, observerLocalChangedMap_);
1896     }
1897 
1898     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_REMOTE)) {
1899         RemoveSingleObserver(userId, observer, observerRemoteChangedMap_);
1900     }
1901 
1902     if (isEventType && IsCallerUidValid()) {
1903         RemoveSingleObserver(userId, observer, observerEventMap_);
1904     }
1905 }
1906 
UnsubscribeAllObserver(PasteboardObserverType type)1907 void PasteboardService::UnsubscribeAllObserver(PasteboardObserverType type)
1908 {
1909     ClearInputMethodPid();
1910     bool isEventType = static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_EVENT);
1911     int32_t userId = isEventType ? COMMON_USERID : GetCurrentAccountId();
1912     if (userId == ERROR_USERID) {
1913         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
1914         return;
1915     }
1916     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_LOCAL)) {
1917         RemoveAllObserver(userId, observerLocalChangedMap_);
1918     }
1919 
1920     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_REMOTE)) {
1921         RemoveAllObserver(userId, observerRemoteChangedMap_);
1922     }
1923 
1924     if (isEventType && IsCallerUidValid()) {
1925         RemoveAllObserver(userId, observerEventMap_);
1926     }
1927 }
1928 
GetAllObserversSize(int32_t userId,pid_t pid)1929 uint32_t PasteboardService::GetAllObserversSize(int32_t userId, pid_t pid)
1930 {
1931     auto localObserverSize = GetObserversSize(userId, pid, observerLocalChangedMap_);
1932     auto remoteObserverSize = GetObserversSize(userId, pid, observerRemoteChangedMap_);
1933     auto eventObserverSize = GetObserversSize(COMMON_USERID, pid, observerEventMap_);
1934     return localObserverSize + remoteObserverSize + eventObserverSize;
1935 }
1936 
GetObserversSize(int32_t userId,pid_t pid,ObserverMap & observerMap)1937 uint32_t PasteboardService::GetObserversSize(int32_t userId, pid_t pid, ObserverMap &observerMap)
1938 {
1939     auto countKey = std::make_pair(userId, pid);
1940     auto it = observerMap.find(countKey);
1941     if (it != observerMap.end()) {
1942         return it->second->size();
1943     }
1944     return 0;
1945 }
1946 
AddObserver(int32_t userId,const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)1947 void PasteboardService::AddObserver(
1948     int32_t userId, const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
1949 {
1950     if (observer == nullptr) {
1951         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
1952         return;
1953     }
1954     std::lock_guard<std::mutex> lock(observerMutex_);
1955     auto callPid = IPCSkeleton::GetCallingPid();
1956     auto callObserverKey = std::make_pair(userId, callPid);
1957     auto it = observerMap.find(callObserverKey);
1958     std::shared_ptr<std::set<sptr<IPasteboardChangedObserver>, classcomp>> observers;
1959     if (it != observerMap.end()) {
1960         observers = it->second;
1961     } else {
1962         observers = std::make_shared<std::set<sptr<IPasteboardChangedObserver>, classcomp>>();
1963         observerMap.insert(std::make_pair(callObserverKey, observers));
1964     }
1965     auto allObserverCount = GetAllObserversSize(userId, callPid);
1966     if (allObserverCount >= MAX_OBSERVER_COUNT) {
1967         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer count over limit. callPid:%{public}d", callPid);
1968         return;
1969     }
1970     observers->insert(observer);
1971     RADAR_REPORT(DFX_OBSERVER, DFX_ADD_OBSERVER, DFX_SUCCESS);
1972     PASTEBOARD_HILOGI(
1973         PASTEBOARD_MODULE_SERVICE, "observers->size = %{public}u.", static_cast<unsigned int>(observers->size()));
1974 }
1975 
RemoveSingleObserver(int32_t userId,const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)1976 void PasteboardService::RemoveSingleObserver(
1977     int32_t userId, const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
1978 {
1979     if (observer == nullptr) {
1980         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
1981         return;
1982     }
1983     std::lock_guard<std::mutex> lock(observerMutex_);
1984     auto callPid = IPCSkeleton::GetCallingPid();
1985     auto callObserverKey = std::make_pair(userId, callPid);
1986     auto it = observerMap.find(callObserverKey);
1987     if (it == observerMap.end()) {
1988         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "user id not found userId is %{public}d", userId);
1989         return;
1990     }
1991     auto observers = it->second;
1992     PASTEBOARD_HILOGD(
1993         PASTEBOARD_MODULE_SERVICE, "observers size: %{public}u.", static_cast<unsigned int>(observers->size()));
1994     auto eraseNum = observers->erase(observer);
1995     RADAR_REPORT(DFX_OBSERVER, DFX_REMOVE_SINGLE_OBSERVER, DFX_SUCCESS);
1996     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers size = %{public}u, eraseNum = %{public}zu",
1997         static_cast<unsigned int>(observers->size()), eraseNum);
1998 }
1999 
RemoveAllObserver(int32_t userId,ObserverMap & observerMap)2000 void PasteboardService::RemoveAllObserver(int32_t userId, ObserverMap &observerMap)
2001 {
2002     std::lock_guard<std::mutex> lock(observerMutex_);
2003     for (auto it = observerMap.begin(); it != observerMap.end();) {
2004         if (it->first.first == userId) {
2005             it = observerMap.erase(it);
2006         } else {
2007             ++it;
2008         }
2009     }
2010     RADAR_REPORT(DFX_OBSERVER, DFX_REMOVE_ALL_OBSERVER, DFX_SUCCESS);
2011 }
2012 
SetGlobalShareOption(const std::map<uint32_t,ShareOption> & globalShareOptions)2013 int32_t PasteboardService::SetGlobalShareOption(const std::map<uint32_t, ShareOption> &globalShareOptions)
2014 {
2015     if (!IsCallerUidValid()) {
2016         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No Permission");
2017         return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2018     }
2019     for (const auto &[tokenId, shareOption] : globalShareOptions) {
2020         GlobalShareOption option = {.source = MDM, .shareOption = shareOption};
2021         globalShareOptions_.InsertOrAssign(tokenId, option);
2022     }
2023     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Set %{public}zu global shareOption.", globalShareOptions.size());
2024     return ERR_OK;
2025 }
2026 
RemoveGlobalShareOption(const std::vector<uint32_t> & tokenIds)2027 int32_t PasteboardService::RemoveGlobalShareOption(const std::vector<uint32_t> &tokenIds)
2028 {
2029     if (!IsCallerUidValid()) {
2030         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No Permission");
2031         return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2032     }
2033     int32_t count = 0;
2034     for (const uint32_t &tokenId : tokenIds) {
2035         globalShareOptions_.ComputeIfPresent(tokenId, [&count](const uint32_t &key, GlobalShareOption &value) {
2036             count++;
2037             return false;
2038         });
2039     }
2040     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Remove %{public}d global shareOption.", count);
2041     return ERR_OK;
2042 }
2043 
GetGlobalShareOption(const std::vector<uint32_t> & tokenIds)2044 std::map<uint32_t, ShareOption> PasteboardService::GetGlobalShareOption(const std::vector<uint32_t> &tokenIds)
2045 {
2046     if (!IsCallerUidValid()) {
2047         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No Permission");
2048         return {};
2049     }
2050     std::map<uint32_t, ShareOption> result;
2051     if (tokenIds.empty()) {
2052         globalShareOptions_.ForEach([&result](const uint32_t &key, GlobalShareOption &value) {
2053             result[key] = value.shareOption;
2054             return false;
2055         });
2056         return result;
2057     }
2058     for (const uint32_t &tokenId : tokenIds) {
2059         globalShareOptions_.ComputeIfPresent(tokenId, [&result](const uint32_t &key, GlobalShareOption &value) {
2060             result[key] = value.shareOption;
2061             return true;
2062         });
2063     }
2064     return result;
2065 }
2066 
SetAppShareOptions(const ShareOption & shareOptions)2067 int32_t PasteboardService::SetAppShareOptions(const ShareOption &shareOptions)
2068 {
2069     auto fullTokenId = IPCSkeleton::GetCallingFullTokenID();
2070     auto tokenId = IPCSkeleton::GetCallingTokenID();
2071     if (!OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
2072         if (shareOptions != InApp) {
2073             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "param is invalid");
2074             return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
2075         }
2076         auto isManageGrant = IsPermissionGranted(MANAGE_PASTEBOARD_APP_SHARE_OPTION_PERMISSION, tokenId);
2077         if (!isManageGrant) {
2078             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No permission, token id: 0x%{public}x.", tokenId);
2079             return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2080         }
2081     }
2082     GlobalShareOption option = {.source = APP, .shareOption = shareOptions};
2083     auto isAbsent = globalShareOptions_.ComputeIfAbsent(tokenId, [&option](const uint32_t &tokenId) {
2084         return option;
2085     });
2086     if (!isAbsent) {
2087         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Settings already exist, token id: 0x%{public}x.", tokenId);
2088         return static_cast<int32_t>(PasteboardError::INVALID_OPERATION_ERROR);
2089     }
2090     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Set token id: 0x%{public}x share options: %{public}d success.",
2091         tokenId, shareOptions);
2092     return 0;
2093 }
2094 
RemoveAppShareOptions()2095 int32_t PasteboardService::RemoveAppShareOptions()
2096 {
2097     auto fullTokenId = IPCSkeleton::GetCallingFullTokenID();
2098     auto tokenId = IPCSkeleton::GetCallingTokenID();
2099     if (!OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
2100         auto isManageGrant = IsPermissionGranted(MANAGE_PASTEBOARD_APP_SHARE_OPTION_PERMISSION, tokenId);
2101         if (!isManageGrant) {
2102             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No permission, token id: 0x%{public}x.", tokenId);
2103             return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2104         }
2105     }
2106     std::map<uint32_t, GlobalShareOption> result;
2107     globalShareOptions_.ComputeIfPresent(tokenId, [&result](const uint32_t &key, GlobalShareOption &value) {
2108         result[key] = value;
2109         return true;
2110     });
2111     if (!result.empty()) {
2112         if (result[tokenId].source == APP) {
2113             globalShareOptions_.Erase(tokenId);
2114             PASTEBOARD_HILOGI(
2115                 PASTEBOARD_MODULE_SERVICE, "Remove token id: 0x%{public}x share options success.", tokenId);
2116             return 0;
2117         } else {
2118             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Can not remove token id: 0x%{public}x.", tokenId);
2119             return 0;
2120         }
2121     }
2122     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "This token id: 0x%{public}x not set.", tokenId);
2123     return 0;
2124 }
2125 
UpdateShareOption(PasteData & pasteData)2126 void PasteboardService::UpdateShareOption(PasteData &pasteData)
2127 {
2128     globalShareOptions_.ComputeIfPresent(
2129         pasteData.GetTokenId(), [&pasteData](const uint32_t &tokenId, GlobalShareOption &option) {
2130             pasteData.SetShareOption(option.shareOption);
2131             return true;
2132         });
2133 }
2134 
CheckMdmShareOption(PasteData & pasteData)2135 bool PasteboardService::CheckMdmShareOption(PasteData &pasteData)
2136 {
2137     bool result = false;
2138     globalShareOptions_.ComputeIfPresent(
2139         pasteData.GetTokenId(), [&result](const uint32_t &tokenId, GlobalShareOption &option) {
2140             if (option.source == MDM) {
2141                 result = true;
2142             }
2143             return true;
2144         });
2145     return result;
2146 }
2147 
IsCallerUidValid()2148 inline bool PasteboardService::IsCallerUidValid()
2149 {
2150     pid_t callingUid = IPCSkeleton::GetCallingUid();
2151     if (callingUid == EDM_UID || (uid_ != -1 && callingUid == uid_)) {
2152         return true;
2153     }
2154     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "callingUid error: %{public}d.", callingUid);
2155     return false;
2156 }
2157 
ThawInputMethod()2158 void PasteboardService::ThawInputMethod()
2159 {
2160     auto type = ResourceSchedule::ResType::RES_TYPE_SA_CONTROL_APP_EVENT;
2161     auto status = ResourceSchedule::ResType::SaControlAppStatus::SA_START_APP;
2162     pid_t imePid = -1;
2163     {
2164         std::lock_guard lock(imeMutex_);
2165         imePid = imePid_;
2166     }
2167     std::unordered_map<std::string, std::string> payload = {
2168         { "saId", std::to_string(PASTEBOARD_SERVICE_ID) },
2169         { "saName", PASTEBOARD_SERVICE_SA_NAME },
2170         { "extensionType", std::to_string(static_cast<int32_t>(AppExecFwk::ExtensionAbilityType::INPUTMETHOD)) },
2171         { "pid", std::to_string(imePid) },
2172         { "isDelay", std::to_string(true) } };
2173     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "report RSS need thaw:pid = %{public}d", imePid);
2174     ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, status, payload);
2175 }
2176 
IsNeedThaw()2177 bool PasteboardService::IsNeedThaw()
2178 {
2179     auto imc = InputMethodController::GetInstance();
2180     if (imc == nullptr) {
2181         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "InputMethodController is nullptr!");
2182         return false;
2183     }
2184 
2185     std::shared_ptr<Property> property;
2186     int32_t ret = imc->GetDefaultInputMethod(property);
2187     if (ret != ErrorCode::NO_ERROR || property == nullptr) {
2188         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "default input method is nullptr!");
2189         return false;
2190     }
2191     return true;
2192 }
NotifyObservers(std::string bundleName,PasteboardEventStatus status)2193 void PasteboardService::NotifyObservers(std::string bundleName, PasteboardEventStatus status)
2194 {
2195     if (hasImeObserver_ && IsNeedThaw()) {
2196         ThawInputMethod();
2197     }
2198     std::thread thread([this, bundleName, status]() {
2199         std::lock_guard<std::mutex> lock(observerMutex_);
2200         for (auto &observers : observerLocalChangedMap_) {
2201             for (const auto &observer : *(observers.second)) {
2202                 if (status != PasteboardEventStatus::PASTEBOARD_READ) {
2203                     observer->OnPasteboardChanged();
2204                 }
2205             }
2206         }
2207         for (auto &observers : observerEventMap_) {
2208             for (const auto &observer : *(observers.second)) {
2209                 observer->OnPasteboardEvent(bundleName, static_cast<int32_t>(status));
2210             }
2211         }
2212     });
2213     thread.detach();
2214 }
2215 
GetDataSize(PasteData & data) const2216 size_t PasteboardService::GetDataSize(PasteData &data) const
2217 {
2218     if (data.GetRecordCount() != 0) {
2219         size_t counts = data.GetRecordCount() - 1;
2220         std::shared_ptr<PasteDataRecord> records = data.GetRecordAt(counts);
2221         std::string text = records->ConvertToText();
2222         size_t textSize = text.size();
2223         return textSize;
2224     }
2225     return 0; // get wrong size
2226 }
2227 
SetPasteboardHistory(HistoryInfo & info)2228 bool PasteboardService::SetPasteboardHistory(HistoryInfo &info)
2229 {
2230     std::string history = std::move(info.time) + " " + std::move(info.bundleName) + " " + std::move(info.state) + " " +
2231                           " " + std::move(info.remote);
2232     constexpr const size_t DATA_HISTORY_SIZE = 10;
2233     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
2234     if (dataHistory_.size() == DATA_HISTORY_SIZE) {
2235         dataHistory_.erase(dataHistory_.begin());
2236     }
2237     dataHistory_.push_back(std::move(history));
2238     return true;
2239 }
2240 
Dump(int fd,const std::vector<std::u16string> & args)2241 int PasteboardService::Dump(int fd, const std::vector<std::u16string> &args)
2242 {
2243     int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
2244     const int maxUid = 10000;
2245     if (uid > maxUid) {
2246         return 0;
2247     }
2248 
2249     std::vector<std::string> argsStr;
2250     for (auto item : args) {
2251         argsStr.emplace_back(Str16ToStr8(item));
2252     }
2253 
2254     if (PasteboardDumpHelper::GetInstance().Dump(fd, argsStr)) {
2255         return 0;
2256     }
2257     return 0;
2258 }
2259 
GetTime()2260 std::string PasteboardService::GetTime()
2261 {
2262     constexpr int USEC_TO_MSEC = 1000;
2263     time_t timeSeconds = time(0);
2264     if (timeSeconds == -1) {
2265         return FAIL_TO_GET_TIME_STAMP;
2266     }
2267     struct tm nowTime;
2268     localtime_r(&timeSeconds, &nowTime);
2269 
2270     struct timeval timeVal = { 0, 0 };
2271     gettimeofday(&timeVal, nullptr);
2272 
2273     std::string targetTime = std::to_string(nowTime.tm_year + 1900) + "-" + std::to_string(nowTime.tm_mon + 1) + "-" +
2274                              std::to_string(nowTime.tm_mday) + " " + std::to_string(nowTime.tm_hour) + ":" +
2275                              std::to_string(nowTime.tm_min) + ":" + std::to_string(nowTime.tm_sec) + "." +
2276                              std::to_string(timeVal.tv_usec / USEC_TO_MSEC);
2277     return targetTime;
2278 }
2279 
DumpHistory() const2280 std::string PasteboardService::DumpHistory() const
2281 {
2282     std::string result;
2283     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
2284     if (!dataHistory_.empty()) {
2285         result.append("Access history last ten times: ").append("\n");
2286         for (auto iter = dataHistory_.rbegin(); iter != dataHistory_.rend(); ++iter) {
2287             result.append("          ").append(*iter).append("\n");
2288         }
2289     } else {
2290         result.append("Access history fail! dataHistory_ no data.").append("\n");
2291     }
2292     return result;
2293 }
2294 
DumpData()2295 std::string PasteboardService::DumpData()
2296 {
2297     auto userId = GetCurrentAccountId();
2298     if (userId == ERROR_USERID) {
2299         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed.");
2300         return "";
2301     }
2302     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "id = %{public}d", userId);
2303     auto it = clips_.Find(userId);
2304     std::string result;
2305     if (it.first && it.second != nullptr) {
2306         size_t recordCounts = it.second->GetRecordCount();
2307         auto property = it.second->GetProperty();
2308         std::string shareOption;
2309         PasteData::ShareOptionToString(property.shareOption, shareOption);
2310         std::string sourceDevice;
2311         if (property.isRemote) {
2312             sourceDevice = "remote";
2313         } else {
2314             sourceDevice = "local";
2315         }
2316         result.append("|Owner       :  ")
2317             .append(property.bundleName)
2318             .append("\n")
2319             .append("|Timestamp   :  ")
2320             .append(property.setTime)
2321             .append("\n")
2322             .append("|Share Option:  ")
2323             .append(shareOption)
2324             .append("\n")
2325             .append("|Record Count:  ")
2326             .append(std::to_string(recordCounts))
2327             .append("\n")
2328             .append("|Mime types  :  {");
2329         if (!property.mimeTypes.empty()) {
2330             for (size_t i = 0; i < property.mimeTypes.size(); ++i) {
2331                 result.append(property.mimeTypes[i]).append(",");
2332             }
2333         }
2334         result.append("}").append("\n").append("|source device:  ").append(sourceDevice);
2335     } else {
2336         result.append("No copy data.").append("\n");
2337     }
2338     return result;
2339 }
2340 
IsFocusedApp(uint32_t tokenId)2341 bool PasteboardService::IsFocusedApp(uint32_t tokenId)
2342 {
2343     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != ATokenTypeEnum::TOKEN_HAP) {
2344         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "caller is not application");
2345         return true;
2346     }
2347     FocusChangeInfo info;
2348 #ifdef SCENE_BOARD_ENABLE
2349     WindowManagerLite::GetInstance().GetFocusWindowInfo(info);
2350 #else
2351     WindowManager::GetInstance().GetFocusWindowInfo(info);
2352 #endif
2353     auto callPid = IPCSkeleton::GetCallingPid();
2354     if (callPid == info.pid_) {
2355         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "pid is same, it is focused app");
2356         return true;
2357     }
2358     bool isFocused = false;
2359     auto ret = AAFwk::AbilityManagerClient::GetInstance()->CheckUIExtensionIsFocused(tokenId, isFocused);
2360     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "check result:%{public}d, isFocused:%{public}d", ret, isFocused);
2361     return ret == NO_ERROR && isFocused;
2362 }
2363 
GetFocusedAppInfo(void) const2364 FocusedAppInfo PasteboardService::GetFocusedAppInfo(void) const
2365 {
2366     FocusedAppInfo appInfo = { 0 };
2367     FocusChangeInfo info;
2368 #ifdef SCENE_BOARD_ENABLE
2369     WindowManagerLite::GetInstance().GetFocusWindowInfo(info);
2370 #else
2371     WindowManager::GetInstance().GetFocusWindowInfo(info);
2372 #endif
2373     appInfo.windowId = info.windowId_;
2374     appInfo.abilityToken = info.abilityToken_;
2375     return appInfo;
2376 }
2377 
SetPasteDataDot(PasteData & pasteData)2378 void PasteboardService::SetPasteDataDot(PasteData &pasteData)
2379 {
2380     auto bundleName = pasteData.GetBundleName();
2381     HistoryInfo info{ pasteData.GetTime(), bundleName, "set", "" };
2382     SetPasteboardHistory(info);
2383 
2384     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData Report!");
2385     Reporter::GetInstance().PasteboardBehaviour().Report(
2386         { static_cast<int>(BehaviourPasteboardState::BPS_COPY_STATE), bundleName });
2387 
2388     int state = static_cast<int>(StatisticPasteboardState::SPS_COPY_STATE);
2389     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData GetDataSize!");
2390     size_t dataSize = GetDataSize(pasteData);
2391     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData timeC!");
2392     CalculateTimeConsuming timeC(dataSize, state);
2393 }
2394 
GetPasteDataDot(PasteData & pasteData,const std::string & bundleName)2395 void PasteboardService::GetPasteDataDot(PasteData &pasteData, const std::string &bundleName)
2396 {
2397     std::string remote;
2398     if (pasteData.IsRemote()) {
2399         remote = "remote";
2400     }
2401     std::string time = GetTime();
2402     HistoryInfo info{ time, bundleName, "get", remote };
2403     SetPasteboardHistory(info);
2404     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData Report!");
2405     int pState = StatisticPasteboardState::SPS_INVALID_STATE;
2406     int bState = BehaviourPasteboardState::BPS_INVALID_STATE;
2407     if (pasteData.IsRemote()) {
2408         pState = static_cast<int>(StatisticPasteboardState::SPS_REMOTE_PASTE_STATE);
2409         bState = static_cast<int>(BehaviourPasteboardState::BPS_REMOTE_PASTE_STATE);
2410     } else {
2411         pState = static_cast<int>(StatisticPasteboardState::SPS_PASTE_STATE);
2412         bState = static_cast<int>(BehaviourPasteboardState::BPS_PASTE_STATE);
2413     };
2414 
2415     Reporter::GetInstance().PasteboardBehaviour().Report({ bState, bundleName });
2416     size_t dataSize = GetDataSize(pasteData);
2417     CalculateTimeConsuming timeC(dataSize, pState);
2418 }
2419 
GetDistributedData(const Event & event,int32_t user)2420 std::pair<std::shared_ptr<PasteData>, PasteDateResult> PasteboardService::GetDistributedData(
2421     const Event &event, int32_t user)
2422 {
2423     auto clipPlugin = GetClipPlugin();
2424     PasteDateResult pasteDateResult;
2425     if (clipPlugin == nullptr) {
2426         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
2427         pasteDateResult.syncTime = -1;
2428         pasteDateResult.errorCode = static_cast<int32_t>(PasteboardError::REMOTE_TASK_ERROR);
2429         return std::make_pair(nullptr, pasteDateResult);
2430     }
2431     std::vector<uint8_t> rawData;
2432     auto result = clipPlugin->GetPasteData(event, rawData);
2433     if (result.first != 0) {
2434         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get data failed");
2435         Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
2436         pasteDateResult.syncTime = -1;
2437         pasteDateResult.errorCode = result.first;
2438         return std::make_pair(nullptr, pasteDateResult);
2439     }
2440 
2441     currentEvent_ = std::move(event);
2442     std::shared_ptr<PasteData> pasteData = std::make_shared<PasteData>();
2443     pasteData->Decode(rawData);
2444     pasteData->SetOriginAuthority(pasteData->GetBundleName());
2445     for (size_t i = 0; i < pasteData->GetRecordCount(); i++) {
2446         auto item = pasteData->GetRecordAt(i);
2447         if (item == nullptr || item->GetConvertUri().empty()) {
2448             continue;
2449         }
2450         item->isConvertUriFromRemote = true;
2451     }
2452     pasteDateResult.syncTime = result.second;
2453     pasteDateResult.errorCode = static_cast<int32_t>(PasteboardError::E_OK);
2454     return std::make_pair(pasteData, pasteDateResult);
2455 }
2456 
IsAllowSendData()2457 bool PasteboardService::IsAllowSendData()
2458 {
2459     auto controlType =
2460         system::GetIntParameter(TRANSMIT_CONTROL_PROP_KEY, CONTROL_TYPE_ALLOW_SEND_RECEIVE, INT_MIN, INT_MAX);
2461     if (controlType != CONTROL_TYPE_ALLOW_SEND_RECEIVE) {
2462         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "control type is: %{public}d.", controlType);
2463         return false;
2464     }
2465     return true;
2466 }
2467 
GenerateDataType(PasteData & data)2468 uint8_t PasteboardService::GenerateDataType(PasteData &data)
2469 {
2470     std::vector<std::string> mimeTypes = data.GetMimeTypes();
2471     if (mimeTypes.empty()) {
2472         return 0;
2473     }
2474     std::bitset<MAX_INDEX_LENGTH> dataType(0);
2475     for (size_t i = 0; i < mimeTypes.size(); i++) {
2476         auto it = typeMap_.find(mimeTypes[i]);
2477         if (it == typeMap_.end()) {
2478             continue;
2479         }
2480         auto index = it->second;
2481         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "mimetype is exist index=%{public}d", index);
2482         if (it->second == HTML_INDEX && data.GetTag() == PasteData::WEBVIEW_PASTEDATA_TAG) {
2483             dataType.reset();
2484             dataType.set(index);
2485             break;
2486         }
2487         dataType.set(index);
2488     }
2489     auto types = dataType.to_ulong();
2490     uint8_t value = types & 0xff;
2491     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "value = %{public}d", value);
2492     return value;
2493 }
2494 
IsDisallowDistributed()2495 bool PasteboardService::IsDisallowDistributed()
2496 {
2497     pid_t uid = IPCSkeleton::GetCallingUid();
2498     if (uid == DEVICE_COLLABORATION_UID) {
2499         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uid from device collaboration");
2500         return true;
2501     }
2502     return false;
2503 }
2504 
SetDistributedData(int32_t user,PasteData & data)2505 bool PasteboardService::SetDistributedData(int32_t user, PasteData &data)
2506 {
2507     if (!IsAllowSendData() || IsDisallowDistributed()) {
2508         return false;
2509     }
2510     auto clipPlugin = GetClipPlugin();
2511     if (clipPlugin == nullptr) {
2512         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_ONLINE_DEVICE, DFX_SUCCESS);
2513         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clip plugin is null, dataId:%{public}u", data.GetDataId());
2514         return false;
2515     }
2516     ShareOption shareOpt = data.GetShareOption();
2517     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(shareOpt != InApp, false, PASTEBOARD_MODULE_SERVICE,
2518         "data share option is in app, dataId:%{public}u", data.GetDataId());
2519     if (CheckMdmShareOption(data)) {
2520         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(shareOpt != LocalDevice, false, PASTEBOARD_MODULE_SERVICE,
2521             "data share option is local device, dataId:%{public}u", data.GetDataId());
2522     }
2523     auto networkId = DMAdapter::GetInstance().GetLocalNetworkId();
2524     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!networkId.empty(), false, PASTEBOARD_MODULE_SERVICE, "networkId is empty.");
2525     Event event;
2526     event.user = user;
2527     event.seqId = ++sequenceId_;
2528     auto expiration =
2529         duration_cast<milliseconds>((system_clock::now() + minutes(EXPIRATION_INTERVAL)).time_since_epoch()).count();
2530     event.expiration = static_cast<uint64_t>(expiration);
2531     event.deviceId = networkId;
2532     event.account = AccountManager::GetInstance().GetCurrentAccount();
2533     event.status = ClipPlugin::EVT_NORMAL;
2534     event.dataType = data.GetMimeTypes();
2535     event.isDelay = data.IsDelayRecord();
2536     event.dataId = data.GetDataId();
2537     currentEvent_ = event;
2538     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "dataId:%{public}u, seqId:%{public}hu, isDelay:%{public}d,"
2539         "expiration:%{public}" PRIu64, event.dataId, event.seqId, event.isDelay, event.expiration);
2540     return SetCurrentDistributedData(data, event);
2541 }
2542 
SetCurrentDistributedData(PasteData & data,Event event)2543 bool PasteboardService::SetCurrentDistributedData(PasteData &data, Event event)
2544 {
2545     std::thread thread([this, data, event]() mutable {
2546         {
2547             std::lock_guard<std::mutex> lock(setDistributedMemory_.mutex);
2548             setDistributedMemory_.event = event;
2549             setDistributedMemory_.data = std::make_shared<PasteData>(data);
2550             if (setDistributedMemory_.isRunning) {
2551                 return;
2552             }
2553             setDistributedMemory_.isRunning = true;
2554         }
2555         bool isNeedCheck = false;
2556         while (true) {
2557             auto block = std::make_shared<BlockObject<bool>>(SET_DISTRIBUTED_DATA_INTERVAL, false);
2558             {
2559                 std::lock_guard<std::mutex> lock(setDistributedMemory_.mutex);
2560                 if ((event.seqId == setDistributedMemory_.event.seqId && isNeedCheck) ||
2561                     setDistributedMemory_.data == nullptr) {
2562                     setDistributedMemory_.data = nullptr;
2563                     setDistributedMemory_.isRunning = false;
2564                     break;
2565                 }
2566                 if (!isNeedCheck) {
2567                     isNeedCheck = true;
2568                 }
2569                 std::thread thread([this, &event, &block]() mutable {
2570                     PasteData data;
2571                     {
2572                         std::lock_guard<std::mutex> lock(setDistributedMemory_.mutex);
2573                         if (setDistributedMemory_.data == nullptr) {
2574                             block->SetValue(true);
2575                             return;
2576                         }
2577                         event = setDistributedMemory_.event;
2578                         data = *setDistributedMemory_.data;
2579                     }
2580                     auto result = SetCurrentData(event, data);
2581                     block->SetValue(true);
2582                 });
2583                 thread.detach();
2584             }
2585             bool ret = block->GetValue();
2586             if (!ret) {
2587                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "SetCurrentData timeout,seqId:%{public}hu", event.seqId);
2588             }
2589         }
2590     });
2591     thread.detach();
2592     return true;
2593 }
2594 
SetCurrentData(Event event,PasteData & data)2595 bool PasteboardService::SetCurrentData(Event event, PasteData &data)
2596 {
2597     auto clipPlugin = GetClipPlugin();
2598     if (clipPlugin == nullptr) {
2599         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_ONLINE_DEVICE, DFX_SUCCESS);
2600         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clip plugin is null, dataId:%{public}u", data.GetDataId());
2601         return false;
2602     }
2603     RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_LOAD_DISTRIBUTED_PLUGIN, DFX_SUCCESS);
2604     bool needFull = data.IsDelayRecord() && moduleConfig_.GetRemoteDeviceMinVersion() == DevProfile::FIRST_VERSION;
2605     if (needFull) {
2606         GetFullDelayPasteData(event.user, data);
2607         event.isDelay = false;
2608         PasteboardWebController::GetInstance().SplitWebviewPasteData(data);
2609         PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
2610         PasteboardWebController::GetInstance().CheckAppUriPermission(data);
2611     }
2612     GenerateDistributedUri(data);
2613     std::vector<uint8_t> rawData;
2614     if (!data.Encode(rawData)) {
2615         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
2616             "distributed data encode failed, dataId:%{public}u, seqId:%{public}hu", event.dataId, event.seqId);
2617         return false;
2618     }
2619     if (data.IsDelayRecord() && !needFull) {
2620         clipPlugin->RegisterDelayCallback(
2621             std::bind(&PasteboardService::GetDistributedDelayData, this, std::placeholders::_1,
2622                 std::placeholders::_2, std::placeholders::_3),
2623             std::bind(&PasteboardService::GetDistributedDelayEntry, this, std::placeholders::_1,
2624                 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
2625     }
2626     clipPlugin->SetPasteData(event, rawData);
2627     return true;
2628 }
2629 
GetDistributedDelayEntry(const Event & evt,uint32_t recordId,const std::string & utdId,std::vector<uint8_t> & rawData)2630 int32_t PasteboardService::GetDistributedDelayEntry(const Event &evt, uint32_t recordId, const std::string &utdId,
2631     std::vector<uint8_t> &rawData)
2632 {
2633     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "dataId:%{public}u, seqId:%{public}hu, expiration:%{public}" PRIu64
2634         ", recordId:%{public}u, type:%{public}s", evt.dataId, evt.seqId, evt.expiration, recordId, utdId.c_str());
2635     auto [hasData, data] = clips_.Find(evt.user);
2636     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasData && data, static_cast<int32_t>(PasteboardError::NO_DATA_ERROR),
2637         PASTEBOARD_MODULE_SERVICE, "data not find, userId=%{public}u", evt.user);
2638     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(evt.dataId == data->GetDataId(),
2639         static_cast<int32_t>(PasteboardError::INVALID_DATA_ID), PASTEBOARD_MODULE_SERVICE,
2640         "dataId=%{public}u mismatch, local=%{public}u", evt.dataId, data->GetDataId());
2641 
2642     auto record = data->GetRecordById(recordId);
2643     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(record != nullptr, static_cast<int32_t>(PasteboardError::INVALID_RECORD_ID),
2644         PASTEBOARD_MODULE_SERVICE, "recordId=%{public}u invalid, max=%{public}zu", recordId, data->GetRecordCount());
2645 
2646     PasteDataEntry entry;
2647     entry.SetUtdId(utdId);
2648     int32_t ret = GetLocalEntryValue(evt.user, *data, *record, entry);
2649     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2650         PASTEBOARD_MODULE_SERVICE, "get local entry failed, seqId=%{public}hu, dataId=%{public}u, recordId=%{public}u"
2651         ", type=%{public}s, ret=%{public}d", evt.seqId, evt.dataId, recordId, utdId.c_str(), ret);
2652 
2653     std::string mimeType = entry.GetMimeType();
2654     if (mimeType == MIMETYPE_TEXT_URI) {
2655         ret = ProcessDistributedDelayUri(evt.user, *data, entry, rawData);
2656     } else if (mimeType == MIMETYPE_TEXT_HTML) {
2657         ret = ProcessDistributedDelayHtml(*data, entry, rawData);
2658     } else {
2659         ret = ProcessDistributedDelayEntry(entry, rawData);
2660     }
2661     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2662         PASTEBOARD_MODULE_SERVICE, "process distributed entry failed, seqId=%{public}hu, dataId=%{public}u, "
2663         "recordId=%{public}u, type=%{public}s, ret=%{public}d", evt.seqId, evt.dataId, recordId, utdId.c_str(), ret);
2664 
2665     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "type=%{public}s, size=%{public}zu", utdId.c_str(), rawData.size());
2666     return static_cast<int32_t>(PasteboardError::E_OK);
2667 }
2668 
ProcessDistributedDelayUri(int32_t userId,PasteData & data,PasteDataEntry & entry,std::vector<uint8_t> & rawData)2669 int32_t PasteboardService::ProcessDistributedDelayUri(int32_t userId, PasteData &data, PasteDataEntry &entry,
2670     std::vector<uint8_t> &rawData)
2671 {
2672     auto uri = entry.ConvertToUri();
2673     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(uri != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
2674         PASTEBOARD_MODULE_SERVICE, "convert entry to uri failed");
2675 
2676     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
2677     std::string localUri = uri->ToString();
2678     HmdfsUriInfo dfsUri;
2679     int32_t ret = RemoteFileShare::GetDfsUriFromLocal(localUri, userId, dfsUri);
2680     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == 0, ret, PASTEBOARD_MODULE_SERVICE,
2681         "generate distributed uri failed, uri=%{private}s", localUri.c_str());
2682 
2683     std::string distributedUri = dfsUri.uriStr;
2684     size_t fileSize = dfsUri.fileSize;
2685     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri: %{private}s -> %{private}s, fileSize=%{public}zu",
2686         localUri.c_str(), distributedUri.c_str(), fileSize);
2687 
2688     auto entryValue = entry.GetValue();
2689     if (std::holds_alternative<std::string>(entryValue)) {
2690         entry.SetValue(distributedUri);
2691     } else if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
2692         auto object = std::get<std::shared_ptr<Object>>(entryValue);
2693         auto newObject = std::make_shared<Object>();
2694         newObject->value_ = object->value_;
2695         newObject->value_[UDMF::FILE_URI_PARAM] = distributedUri;
2696         entry.SetValue(newObject);
2697         entry.SetFileSize(static_cast<int64_t>(fileSize));
2698     }
2699 
2700     bool encodeSucc = entry.Encode(rawData);
2701     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
2702         PASTEBOARD_MODULE_SERVICE, "encode uri failed");
2703     return static_cast<int32_t>(PasteboardError::E_OK);
2704 }
2705 
ProcessDistributedDelayHtml(PasteData & data,PasteDataEntry & entry,std::vector<uint8_t> & rawData)2706 int32_t PasteboardService::ProcessDistributedDelayHtml(PasteData &data, PasteDataEntry &entry,
2707     std::vector<uint8_t> &rawData)
2708 {
2709     if (PasteboardWebController::GetInstance().SplitWebviewPasteData(data)) {
2710         PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
2711         PasteboardWebController::GetInstance().CheckAppUriPermission(data);
2712     }
2713 
2714     PasteData tmp;
2715     std::shared_ptr<std::string> html = entry.ConvertToHtml();
2716     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(html != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
2717         PASTEBOARD_MODULE_SERVICE, "convert to html failed");
2718 
2719     tmp.AddHtmlRecord(*html);
2720     tmp.SetBundleName(data.GetBundleName());
2721     tmp.SetOriginAuthority(data.GetOriginAuthority());
2722     tmp.SetTokenId(data.GetTokenId());
2723     if (PasteboardWebController::GetInstance().SplitWebviewPasteData(tmp)) {
2724         PasteboardWebController::GetInstance().SetWebviewPasteData(tmp, data.GetOriginAuthority());
2725         PasteboardWebController::GetInstance().CheckAppUriPermission(tmp);
2726         GenerateDistributedUri(tmp);
2727     }
2728 
2729     bool encodeSucc = tmp.Encode(rawData);
2730     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
2731         PASTEBOARD_MODULE_SERVICE, "encode html failed");
2732     return static_cast<int32_t>(PasteboardError::E_OK);
2733 }
2734 
ProcessDistributedDelayEntry(PasteDataEntry & entry,std::vector<uint8_t> & rawData)2735 int32_t PasteboardService::ProcessDistributedDelayEntry(PasteDataEntry &entry, std::vector<uint8_t> &rawData)
2736 {
2737     bool encodeSucc = entry.Encode(rawData);
2738     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
2739         PASTEBOARD_MODULE_SERVICE, "encode entry failed, type=%{public}s", entry.GetUtdId().c_str());
2740     return static_cast<int32_t>(PasteboardError::E_OK);
2741 }
2742 
GetDistributedDelayData(const Event & evt,uint8_t version,std::vector<uint8_t> & rawData)2743 int32_t PasteboardService::GetDistributedDelayData(const Event &evt, uint8_t version, std::vector<uint8_t> &rawData)
2744 {
2745     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "dataId:%{public}u, seqId:%{public}hu, expiration:%{public}" PRIu64,
2746         evt.dataId, evt.seqId, evt.expiration);
2747     auto [hasData, data] = clips_.Find(evt.user);
2748     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasData && data, static_cast<int32_t>(PasteboardError::NO_DATA_ERROR),
2749         PASTEBOARD_MODULE_SERVICE, "data not find, userId=%{public}u", evt.user);
2750     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(evt.dataId == data->GetDataId(),
2751         static_cast<int32_t>(PasteboardError::INVALID_DATA_ID), PASTEBOARD_MODULE_SERVICE,
2752         "dataId=%{public}u mismatch, local=%{public}u", evt.dataId, data->GetDataId());
2753 
2754     int32_t ret = static_cast<int32_t>(PasteboardError::E_OK);
2755     if (version == 0) {
2756         ret = GetFullDelayPasteData(evt.user, *data);
2757     } else if (version == 1) {
2758         ret = GetDelayPasteRecord(evt.user, *data);
2759     }
2760     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2761         PASTEBOARD_MODULE_SERVICE, "get delay data failed, version=%{public}hhu", version);
2762 
2763     data->SetBundleName(data->GetOriginAuthority());
2764     PasteboardWebController::GetInstance().SplitWebviewPasteData(*data);
2765     PasteboardWebController::GetInstance().SetWebviewPasteData(*data, data->GetOriginAuthority());
2766     PasteboardWebController::GetInstance().CheckAppUriPermission(*data);
2767     GenerateDistributedUri(*data);
2768 
2769     bool encodeSucc = data->Encode(rawData);
2770     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
2771         PASTEBOARD_MODULE_SERVICE, "encode data failed, dataId:%{public}u, seqId:%{public}hu", evt.dataId, evt.seqId);
2772 
2773     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "size=%{public}zu", rawData.size());
2774     return static_cast<int32_t>(PasteboardError::E_OK);
2775 }
2776 
GetLocalEntryValue(int32_t userId,PasteData & data,PasteDataRecord & record,PasteDataEntry & value)2777 int32_t PasteboardService::GetLocalEntryValue(int32_t userId, PasteData &data, PasteDataRecord &record,
2778     PasteDataEntry &value)
2779 {
2780     std::string utdId = value.GetUtdId();
2781     auto entry = record.GetEntry(utdId);
2782     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(entry != nullptr, static_cast<int32_t>(PasteboardError::INVALID_MIMETYPE),
2783         PASTEBOARD_MODULE_SERVICE, "entry is null, recordId=%{public}u, type=%{public}s", record.GetRecordId(),
2784         utdId.c_str());
2785 
2786     std::string mimeType = entry->GetMimeType();
2787     value.SetMimeType(mimeType);
2788     if (entry->HasContent(utdId)) {
2789         value.SetValue(entry->GetValue());
2790         return static_cast<int32_t>(PasteboardError::E_OK);
2791     }
2792 
2793     auto [hasGetter, getter] = entryGetters_.Find(userId);
2794     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasGetter && getter.first,
2795         static_cast<int32_t>(PasteboardError::NO_DELAY_GETTER), PASTEBOARD_MODULE_SERVICE,
2796         "entry getter not find, userId=%{public}d, dataId=%{public}u", userId, data.GetDataId());
2797 
2798     int32_t ret = getter.first->GetRecordValueByType(record.GetRecordId(), value);
2799     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2800         PASTEBOARD_MODULE_SERVICE, "get local entry failed, type=%{public}s, ret=%{public}d", utdId.c_str(), ret);
2801 
2802     record.AddEntry(utdId, std::make_shared<PasteDataEntry>(value));
2803     return static_cast<int32_t>(PasteboardError::E_OK);
2804 }
2805 
GetRemoteEntryValue(const AppInfo & appInfo,PasteData & data,PasteDataRecord & record,PasteDataEntry & entry)2806 int32_t PasteboardService::GetRemoteEntryValue(const AppInfo &appInfo, PasteData &data, PasteDataRecord &record,
2807     PasteDataEntry &entry)
2808 {
2809     auto clipPlugin = GetClipPlugin();
2810     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(clipPlugin != nullptr, static_cast<int32_t>(PasteboardError::PLUGIN_IS_NULL),
2811         PASTEBOARD_MODULE_SERVICE, "plugin is null");
2812 
2813     auto [distRet, distEvt] = GetValidDistributeEvent(appInfo.userId);
2814     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(distRet == static_cast<int32_t>(PasteboardError::E_OK) ||
2815         distRet == static_cast<int32_t>(PasteboardError::GET_SAME_REMOTE_DATA), distRet,
2816         PASTEBOARD_MODULE_SERVICE, "get distribute event failed, ret=%{public}d", distRet);
2817 
2818     std::vector<uint8_t> rawData;
2819     std::string utdId = entry.GetUtdId();
2820     int32_t ret = clipPlugin->GetPasteDataEntry(distEvt, record.GetRecordId(), utdId, rawData);
2821     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == 0, ret, PASTEBOARD_MODULE_SERVICE, "get remote raw data failed");
2822 
2823     std::string mimeType = entry.GetMimeType();
2824     if (mimeType == MIMETYPE_TEXT_HTML) {
2825         ret = ProcessRemoteDelayHtml(distEvt.deviceId, appInfo.bundleName, rawData, data, record, entry);
2826         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2827             PASTEBOARD_MODULE_SERVICE, "process remote delay html failed");
2828         return static_cast<int32_t>(PasteboardError::E_OK);
2829     }
2830 
2831     PasteDataEntry tmpEntry;
2832     tmpEntry.Decode(rawData);
2833     entry.SetValue(tmpEntry.GetValue());
2834     record.AddEntry(utdId, std::make_shared<PasteDataEntry>(entry));
2835 
2836     if (mimeType != MIMETYPE_TEXT_URI) {
2837         return static_cast<int32_t>(PasteboardError::E_OK);
2838     }
2839 
2840     auto uri = entry.ConvertToUri();
2841     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(uri != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
2842         PASTEBOARD_MODULE_SERVICE, "convert entry to uri failed");
2843     std::string distributedUri = uri->ToString();
2844     record.SetConvertUri(distributedUri);
2845     record.isConvertUriFromRemote = true;
2846     record.SetGrantUriPermission(true);
2847 
2848     int64_t uriFileSize = entry.GetFileSize();
2849     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri=%{private}s, fileSize=%{public}" PRId64,
2850         distributedUri.c_str(), uriFileSize);
2851     if (uriFileSize > 0) {
2852         int64_t dataFileSize = data.GetFileSize();
2853         int64_t fileSize = (uriFileSize > INT64_MAX - dataFileSize) ? INT64_MAX : uriFileSize + dataFileSize;
2854         data.SetFileSize(fileSize);
2855     }
2856     std::vector<Uri> grantUris = CheckUriPermission(data, appInfo.bundleName);
2857     if (!grantUris.empty()) {
2858         EstablishP2PLink(distEvt.deviceId, data.GetPasteId());
2859         ret = GrantUriPermission(grantUris, appInfo.bundleName);
2860         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2861             PASTEBOARD_MODULE_SERVICE, "grant remote uri failed, uri=%{private}s, ret=%{public}d",
2862             distributedUri.c_str(), ret);
2863     }
2864     return static_cast<int32_t>(PasteboardError::E_OK);
2865 }
2866 
ProcessRemoteDelayHtml(const std::string & remoteDeviceId,const std::string & bundleName,const std::vector<uint8_t> & rawData,PasteData & data,PasteDataRecord & record,PasteDataEntry & entry)2867 int32_t PasteboardService::ProcessRemoteDelayHtml(const std::string &remoteDeviceId, const std::string &bundleName,
2868     const std::vector<uint8_t> &rawData, PasteData &data, PasteDataRecord &record, PasteDataEntry &entry)
2869 {
2870     PasteData tmpData;
2871     tmpData.Decode(rawData);
2872     auto htmlRecord = tmpData.GetRecordById(1);
2873     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(htmlRecord != nullptr,
2874         static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED), PASTEBOARD_MODULE_SERVICE, "record is null");
2875     auto entryValue = htmlRecord->GetUDMFValue();
2876     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(entryValue != nullptr,
2877         static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED), PASTEBOARD_MODULE_SERVICE, "udmfValue is null");
2878     entry.SetValue(*entryValue);
2879     record.AddEntry(entry.GetUtdId(), std::make_shared<PasteDataEntry>(entry));
2880 
2881     if (htmlRecord->GetFrom() == 0) {
2882         return static_cast<int32_t>(PasteboardError::E_OK);
2883     }
2884 
2885     data.SetTag(PasteData::WEBVIEW_PASTEDATA_TAG);
2886     uint32_t htmlRecordId = record.GetRecordId();
2887     record.SetFrom(htmlRecordId);
2888     for (auto &recordItem : tmpData.AllRecords()) {
2889         if (recordItem == nullptr) {
2890             continue;
2891         }
2892         if (!recordItem->GetConvertUri().empty()) {
2893             recordItem->isConvertUriFromRemote = true;
2894         }
2895         if (recordItem->GetFrom() > 0 && recordItem->GetRecordId() != recordItem->GetFrom()) {
2896             recordItem->SetFrom(htmlRecordId);
2897             data.AddRecord(*recordItem);
2898         }
2899     }
2900 
2901     int64_t htmlFileSize = tmpData.GetFileSize();
2902     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "htmlFileSize=%{public}" PRId64, htmlFileSize);
2903     if (htmlFileSize > 0) {
2904         int64_t dataFileSize = data.GetFileSize();
2905         int64_t fileSize = (htmlFileSize > INT64_MAX - dataFileSize) ? INT64_MAX : htmlFileSize + dataFileSize;
2906         data.SetFileSize(fileSize);
2907     }
2908 
2909     std::vector<Uri> grantUris = CheckUriPermission(data, bundleName);
2910     if (!grantUris.empty()) {
2911         EstablishP2PLink(remoteDeviceId, data.GetPasteId());
2912         int32_t ret = GrantUriPermission(grantUris, bundleName);
2913         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2914             PASTEBOARD_MODULE_SERVICE, "grant to %{public}s failed, ret=%{public}d", bundleName.c_str(), ret);
2915     }
2916 
2917     tmpData.SetOriginAuthority(data.GetOriginAuthority());
2918     tmpData.SetTokenId(data.GetTokenId());
2919     tmpData.SetRemote(data.IsRemote());
2920     int32_t ret = PostProcessDelayHtmlEntry(tmpData, bundleName, entry);
2921     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2922         PASTEBOARD_MODULE_SERVICE, "post process remote html failed, ret=%{public}d", ret);
2923     return static_cast<int32_t>(PasteboardError::E_OK);
2924 }
2925 
GetFullDelayPasteData(int32_t userId,PasteData & data)2926 int32_t PasteboardService::GetFullDelayPasteData(int32_t userId, PasteData &data)
2927 {
2928     auto [hasGetter, getter] = entryGetters_.Find(userId);
2929     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasGetter && getter.first,
2930         static_cast<int32_t>(PasteboardError::NO_DELAY_GETTER), PASTEBOARD_MODULE_SERVICE,
2931         "entry getter not find, userId=%{public}d, dataId=%{public}u", userId, data.GetDataId());
2932 
2933     for (auto record : data.AllRecords()) {
2934         if (!record->IsDelayRecord()) {
2935             continue;
2936         }
2937         auto recordId = record->GetRecordId();
2938         auto mimeType = record->GetMimeType();
2939         for (auto entry : record->GetEntries()) {
2940             if (!std::holds_alternative<std::monostate>(entry->GetValue())) {
2941                 continue;
2942             }
2943             auto result = getter.first->GetRecordValueByType(recordId, *entry);
2944             if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
2945                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
2946                     "get record value fail, dataId is %{public}d, recordId is %{public}d, mimeType is %{public}s",
2947                     data.GetDataId(), record->GetRecordId(), entry->GetMimeType().c_str());
2948                 continue;
2949             }
2950             if (entry->GetMimeType() == mimeType) {
2951                 record->AddEntry(entry->GetUtdId(), std::make_shared<PasteDataEntry>(*entry));
2952             }
2953         }
2954     }
2955     PasteboardWebController::GetInstance().SplitWebviewPasteData(data);
2956     PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
2957     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
2958     clips_.ComputeIfPresent(userId, [&data](auto, auto &value) {
2959         if (data.GetDataId() != value->GetDataId()) {
2960             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
2961                 "set data fail, data is out time, pre dataId is %{public}d, cur dataId is %{public}d",
2962                 data.GetDataId(), value->GetDataId());
2963             return true;
2964         }
2965         value = std::make_shared<PasteData>(data);
2966         return true;
2967     });
2968     return static_cast<int32_t>(PasteboardError::E_OK);
2969 }
2970 
GenerateDistributedUri(PasteData & data)2971 void PasteboardService::GenerateDistributedUri(PasteData &data)
2972 {
2973     std::vector<std::string> uris;
2974     std::vector<size_t> indexes;
2975     auto userId = GetCurrentAccountId();
2976     PASTEBOARD_CHECK_AND_RETURN_LOGE(userId != ERROR_USERID, PASTEBOARD_MODULE_SERVICE, "invalid userId");
2977     for (size_t i = 0; i < data.GetRecordCount(); i++) {
2978         auto item = data.GetRecordAt(i);
2979         if (item == nullptr) {
2980             continue;
2981         }
2982         const auto &uri = item->GetOriginUri();
2983         if (uri == nullptr) {
2984             continue;
2985         }
2986         auto hasGrantUriPermission = item->HasGrantUriPermission();
2987         const std::string &bundleName = data.GetOriginAuthority();
2988         if (!IsBundleOwnUriPermission(bundleName, *uri) && !hasGrantUriPermission) {
2989             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "uri:%{private}s, bundleName:%{public}s, has grant:%{public}d",
2990                 uri->ToString().c_str(), bundleName.c_str(), hasGrantUriPermission);
2991             continue;
2992         }
2993         uris.emplace_back(uri->ToString());
2994         indexes.emplace_back(i);
2995     }
2996     size_t fileSize = 0;
2997     std::unordered_map<std::string, HmdfsUriInfo> dfsUris;
2998     if (!uris.empty()) {
2999         int ret = RemoteFileShare::GetDfsUrisFromLocal(uris, userId, dfsUris);
3000         PASTEBOARD_CHECK_AND_RETURN_LOGE((ret == 0 && !dfsUris.empty()), PASTEBOARD_MODULE_SERVICE,
3001             "Get remoteUri failed, ret:%{public}d, userId:%{public}d, uri size:%{public}zu.", ret, userId, uris.size());
3002         for (size_t i = 0; i < indexes.size(); i++) {
3003             auto item = data.GetRecordAt(indexes[i]);
3004             if (item == nullptr || item->GetOriginUri() == nullptr) {
3005                 continue;
3006             }
3007             auto it = dfsUris.find(item->GetOriginUri()->ToString());
3008             if (it != dfsUris.end()) {
3009                 item->SetConvertUri(it->second.uriStr);
3010                 fileSize += it->second.fileSize;
3011             }
3012         }
3013     }
3014     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "file size: %{public}zu", fileSize);
3015     data.SetFileSize(static_cast<int64_t>(fileSize));
3016 }
3017 
GetClipPlugin()3018 std::shared_ptr<ClipPlugin> PasteboardService::GetClipPlugin()
3019 {
3020     auto isOn = moduleConfig_.IsOn();
3021     if (isOn) {
3022         auto securityLevel = securityLevel_.GetDeviceSecurityLevel();
3023         if (securityLevel < DATA_SEC_LEVEL3) {
3024             return nullptr;
3025         }
3026     }
3027     std::lock_guard<decltype(mutex)> lockGuard(mutex);
3028     if (!isOn || clipPlugin_ != nullptr) {
3029         return clipPlugin_;
3030     }
3031     Loader loader;
3032     loader.LoadComponents();
3033     auto release = [this](ClipPlugin *plugin) {
3034         std::lock_guard<decltype(mutex)> lockGuard(mutex);
3035         ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
3036     };
3037 
3038     clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
3039     return clipPlugin_;
3040 }
3041 
CleanDistributedData(int32_t user)3042 void PasteboardService::CleanDistributedData(int32_t user)
3043 {
3044     auto clipPlugin = GetClipPlugin();
3045     if (clipPlugin == nullptr) {
3046         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
3047         return;
3048     }
3049     clipPlugin->Clear(user);
3050 }
3051 
CloseDistributedStore(int32_t user,bool isNeedClear)3052 void PasteboardService::CloseDistributedStore(int32_t user, bool isNeedClear)
3053 {
3054     auto clipPlugin = GetClipPlugin();
3055     if (clipPlugin == nullptr) {
3056         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
3057         return;
3058     }
3059     clipPlugin->Close(user, isNeedClear);
3060 }
3061 
OnConfigChange(bool isOn)3062 void PasteboardService::OnConfigChange(bool isOn)
3063 {
3064     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "ConfigChange isOn: %{public}d.", isOn);
3065     p2pMap_.Clear();
3066     std::lock_guard<decltype(mutex)> lockGuard(mutex);
3067     if (!isOn) {
3068         int32_t userId = GetCurrentAccountId();
3069         clipPlugin_->Close(userId, false);
3070         clipPlugin_ = nullptr;
3071         return;
3072     }
3073     auto securityLevel = securityLevel_.GetDeviceSecurityLevel();
3074     if (securityLevel < DATA_SEC_LEVEL3) {
3075         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "device sec level is %{public}u less than 3.", securityLevel);
3076         return;
3077     }
3078     if (clipPlugin_ != nullptr) {
3079         return;
3080     }
3081     SubscribeKeyboardEvent();
3082     Loader loader;
3083     loader.LoadComponents();
3084     auto release = [this](ClipPlugin *plugin) {
3085         std::lock_guard<decltype(mutex)> lockGuard(mutex);
3086         ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
3087     };
3088 
3089     clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
3090 }
3091 
GetAppLabel(uint32_t tokenId)3092 std::string PasteboardService::GetAppLabel(uint32_t tokenId)
3093 {
3094     auto iBundleMgr = GetAppBundleManager();
3095     if (iBundleMgr == nullptr) {
3096         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to cast bundle mgr service.");
3097         return PasteBoardDialog::DEFAULT_LABEL;
3098     }
3099     AppInfo info = GetAppInfo(tokenId);
3100     AppExecFwk::ApplicationInfo appInfo;
3101     auto result = iBundleMgr->GetApplicationInfo(info.bundleName, 0, info.userId, appInfo);
3102     if (!result) {
3103         return PasteBoardDialog::DEFAULT_LABEL;
3104     }
3105     auto &resource = appInfo.labelResource;
3106     auto label = iBundleMgr->GetStringById(resource.bundleName, resource.moduleName, resource.id, info.userId);
3107     return label.empty() ? PasteBoardDialog::DEFAULT_LABEL : label;
3108 }
3109 
GetAppBundleManager()3110 sptr<AppExecFwk::IBundleMgr> PasteboardService::GetAppBundleManager()
3111 {
3112     auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
3113     if (systemAbilityManager == nullptr) {
3114         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get SystemAbilityManager.");
3115         return nullptr;
3116     }
3117     auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
3118     if (remoteObject == nullptr) {
3119         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get bundle mgr service.");
3120         return nullptr;
3121     }
3122     return OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
3123 }
3124 
ChangeStoreStatus(int32_t userId)3125 void PasteboardService::ChangeStoreStatus(int32_t userId)
3126 {
3127     PasteboardService::currentUserId_ = userId;
3128     auto clipPlugin = GetClipPlugin();
3129     if (clipPlugin == nullptr) {
3130         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
3131         return;
3132     }
3133     clipPlugin->ChangeStoreStatus(userId);
3134 }
3135 
OnReceiveEvent(const EventFwk::CommonEventData & data)3136 void PasteBoardCommonEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
3137 {
3138     auto want = data.GetWant();
3139     std::string action = want.GetAction();
3140     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
3141         std::lock_guard<std::mutex> lock(mutex_);
3142         int32_t userId = data.GetCode();
3143         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "user id switched: %{public}d", userId);
3144         if (pasteboardService_ != nullptr) {
3145             pasteboardService_->ChangeStoreStatus(userId);
3146         }
3147         auto accountId = pasteboardService_->GetCurrentAccountId();
3148         pasteboardService_->switch_.DeInit();
3149         pasteboardService_->switch_.Init(accountId);
3150         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "SetSwitch end");
3151     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_STOPPING) {
3152         std::lock_guard<std::mutex> lock(mutex_);
3153         int32_t userId = data.GetCode();
3154         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "user id is stopping: %{public}d", userId);
3155         if (pasteboardService_ != nullptr) {
3156             pasteboardService_->Clear();
3157         }
3158     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED) {
3159         std::lock_guard<std::mutex> lock(mutex_);
3160         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "screen is locked");
3161         PasteboardService::currentScreenStatus = ScreenEvent::ScreenLocked;
3162     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
3163         std::lock_guard<std::mutex> lock(mutex_);
3164         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "screen is unlocked");
3165         PasteboardService::currentScreenStatus = ScreenEvent::ScreenUnlocked;
3166     }
3167 }
3168 
OnStateChanged(const AccountSA::OsAccountStateData & data)3169 void PasteBoardAccountStateSubscriber::OnStateChanged(const AccountSA::OsAccountStateData &data)
3170 {
3171     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "state: %{public}d, fromId: %{public}d, toId: %{public}d,"
3172         "callback is nullptr: %{public}d", data.state, data.fromId, data.toId, data.callback == nullptr);
3173     if (data.state == AccountSA::OsAccountState::STOPPING && pasteboardService_ != nullptr) {
3174         std::lock_guard<std::mutex> lock(mutex_);
3175         pasteboardService_->CloseDistributedStore(data.fromId, true);
3176     }
3177     if (data.callback != nullptr) {
3178         data.callback->OnComplete();
3179     }
3180 }
3181 
SubscribeKeyboardEvent()3182 bool PasteboardService::SubscribeKeyboardEvent()
3183 {
3184     std::lock_guard<std::mutex> lock(eventMutex_);
3185     if (inputEventCallback_ != nullptr) {
3186         return true;
3187     }
3188     inputEventCallback_ = std::make_shared<InputEventCallback>();
3189     int32_t monitorId = MMI::InputManager::GetInstance()->AddMonitor(
3190         std::static_pointer_cast<MMI::IInputEventConsumer>(inputEventCallback_), MMI::HANDLE_EVENT_TYPE_KEY);
3191     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "add monitor ret is: %{public}d", monitorId);
3192     return monitorId >= 0;
3193 }
3194 
PasteboardEventSubscriber()3195 void PasteboardService::PasteboardEventSubscriber()
3196 {
3197     EventCenter::GetInstance().Subscribe(PasteboardEvent::DISCONNECT, [this](const OHOS::MiscServices::Event &event) {
3198         auto &evt = static_cast<const PasteboardEvent &>(event);
3199         auto networkId = evt.GetNetworkId();
3200         if (networkId.empty()) {
3201             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "networkId is empty.");
3202             return;
3203         }
3204         p2pMap_.EraseIf([networkId, this](auto &key, auto &value) {
3205             if (key == networkId) {
3206                 CloseP2PLink(networkId);
3207                 return true;
3208             }
3209             return false;
3210         });
3211     });
3212 }
3213 
CommonEventSubscriber()3214 void PasteboardService::CommonEventSubscriber()
3215 {
3216     if (commonEventSubscriber_ != nullptr) {
3217         return;
3218     }
3219     EventFwk::MatchingSkills matchingSkills;
3220     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
3221     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_STOPPING);
3222     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED);
3223     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
3224     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
3225     commonEventSubscriber_ = std::make_shared<PasteBoardCommonEventSubscriber>(subscribeInfo, this);
3226     EventFwk::CommonEventManager::SubscribeCommonEvent(commonEventSubscriber_);
3227 }
3228 
AccountStateSubscriber()3229 void PasteboardService::AccountStateSubscriber()
3230 {
3231     if (accountStateSubscriber_ != nullptr) {
3232         return;
3233     }
3234     std::set<AccountSA::OsAccountState> states = { AccountSA::OsAccountState::STOPPING,
3235         AccountSA::OsAccountState::CREATED, AccountSA::OsAccountState::SWITCHING,
3236         AccountSA::OsAccountState::SWITCHED, AccountSA::OsAccountState::UNLOCKED,
3237         AccountSA::OsAccountState::STOPPED, AccountSA::OsAccountState::REMOVED };
3238     AccountSA::OsAccountSubscribeInfo subscribeInfo(states, true);
3239     accountStateSubscriber_ = std::make_shared<PasteBoardAccountStateSubscriber>(subscribeInfo, this);
3240     AccountSA::OsAccountManager::SubscribeOsAccount(accountStateSubscriber_);
3241 }
3242 
RemoveObserverByPid(int32_t userId,pid_t pid,ObserverMap & observerMap)3243 void PasteboardService::RemoveObserverByPid(int32_t userId, pid_t pid, ObserverMap &observerMap)
3244 {
3245     std::lock_guard<std::mutex> lock(observerMutex_);
3246     auto callObserverKey = std::make_pair(userId, pid);
3247     auto it = observerMap.find(callObserverKey);
3248     if (it == observerMap.end()) {
3249         return;
3250     }
3251     observerMap.erase(callObserverKey);
3252 }
3253 
AppExit(pid_t pid)3254 int32_t PasteboardService::AppExit(pid_t pid)
3255 {
3256     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "pid %{public}d exit.", pid);
3257     int32_t userId = GetCurrentAccountId();
3258     RemoveObserverByPid(userId, pid, observerLocalChangedMap_);
3259     RemoveObserverByPid(userId, pid, observerRemoteChangedMap_);
3260     RemoveObserverByPid(COMMON_USERID, pid, observerEventMap_);
3261     entityObserverMap_.Erase(pid);
3262     std::vector<std::string> networkIds;
3263     p2pMap_.EraseIf([pid, &networkIds, this](auto &networkId, auto &pidMap) {
3264         pidMap.EraseIf([pid, this](const auto &key, const auto &value) {
3265             if (value == pid) {
3266                 PasteStart(key);
3267                 return true;
3268             }
3269             return false;
3270         });
3271         if (pidMap.Empty()) {
3272             networkIds.emplace_back(networkId);
3273             return true;
3274         }
3275         return false;
3276     });
3277     for (const auto &id : networkIds) {
3278         CloseP2PLink(id);
3279     }
3280     clients_.Erase(pid);
3281     return ERR_OK;
3282 }
3283 
OnRemoteDied(const wptr<IRemoteObject> & remote)3284 void PasteboardService::PasteboardDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
3285 {
3286     (void)remote;
3287     service_.AppExit(pid_);
3288 }
3289 
PasteboardDeathRecipient(PasteboardService & service,sptr<IRemoteObject> observer,pid_t pid)3290 PasteboardService::PasteboardDeathRecipient::PasteboardDeathRecipient(
3291     PasteboardService &service, sptr<IRemoteObject> observer, pid_t pid)
3292     : service_(service), observer_(observer), pid_(pid)
3293 {
3294     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Construct Pasteboard Client Death Recipient, pid: %{public}d", pid);
3295 }
3296 
RegisterClientDeathObserver(sptr<IRemoteObject> observer)3297 int32_t PasteboardService::RegisterClientDeathObserver(sptr<IRemoteObject> observer)
3298 {
3299     pid_t pid = IPCSkeleton::GetCallingPid();
3300     sptr<PasteboardDeathRecipient> deathRecipient = new (std::nothrow) PasteboardDeathRecipient(*this, observer, pid);
3301     observer->AddDeathRecipient(deathRecipient);
3302     clients_.InsertOrAssign(pid, std::move(deathRecipient));
3303     return ERR_OK;
3304 }
3305 
RemotePasteboardChange()3306 std::function<void(const OHOS::MiscServices::Event &)> PasteboardService::RemotePasteboardChange()
3307 {
3308     return [this](const OHOS::MiscServices::Event &event) {
3309         (void)event;
3310         std::lock_guard<std::mutex> lock(observerMutex_);
3311         for (auto &observers : observerRemoteChangedMap_) {
3312             for (const auto &observer : *(observers.second)) {
3313                 observer->OnPasteboardChanged();
3314             }
3315         }
3316     };
3317 }
3318 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const3319 void InputEventCallback::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
3320 {
3321     auto keyItems = keyEvent->GetKeyItems();
3322     if (keyItems.size() != CTRLV_EVENT_SIZE) {
3323         return;
3324     }
3325     if ((keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_DOWN) &&
3326         ((keyItems[0].GetKeyCode() == MMI::KeyEvent::KEYCODE_CTRL_LEFT) ||
3327         (keyItems[0].GetKeyCode() == MMI::KeyEvent::KEYCODE_CTRL_RIGHT)) &&
3328         keyItems[1].GetKeyCode() == MMI::KeyEvent::KEYCODE_V) {
3329         int32_t windowId = keyEvent->GetTargetWindowId();
3330         std::unique_lock<std::shared_mutex> lock(inputEventMutex_);
3331         windowPid_ = MMI::InputManager::GetInstance()->GetWindowPid(windowId);
3332         actionTime_ =
3333             static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
3334         std::shared_ptr<BlockObject<bool>> block = nullptr;
3335         {
3336             std::unique_lock<std::shared_mutex> blockMapLock(blockMapMutex_);
3337             auto it = blockMap_.find(windowPid_);
3338             if (it != blockMap_.end()) {
3339                 block = it->second;
3340             } else {
3341                 block = std::make_shared<BlockObject<bool>>(WAIT_TIME_OUT, false);
3342                 blockMap_.insert(std::make_pair(windowPid_, block));
3343             }
3344         }
3345         if (block != nullptr) {
3346             block->SetValue(true);
3347         }
3348     }
3349 }
3350 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const3351 void InputEventCallback::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const {}
3352 
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const3353 void InputEventCallback::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const {}
3354 
IsCtrlVProcess(uint32_t callingPid,bool isFocused)3355 bool InputEventCallback::IsCtrlVProcess(uint32_t callingPid, bool isFocused)
3356 {
3357     std::shared_ptr<BlockObject<bool>> block = nullptr;
3358     {
3359         std::unique_lock<std::shared_mutex> blockMapLock(blockMapMutex_);
3360         auto it = blockMap_.find(callingPid);
3361         if (it != blockMap_.end()) {
3362             block = it->second;
3363         } else {
3364             block = std::make_shared<BlockObject<bool>>(WAIT_TIME_OUT, false);
3365             blockMap_.insert(std::make_pair(callingPid, block));
3366         }
3367     }
3368     if (block != nullptr) {
3369         block->GetValue();
3370     }
3371     std::shared_lock<std::shared_mutex> lock(inputEventMutex_);
3372     auto curTime = static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
3373     auto ret = (callingPid == static_cast<uint32_t>(windowPid_) || isFocused) && curTime - actionTime_ < EVENT_TIME_OUT;
3374     if (!ret) {
3375         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "windowPid is: %{public}d, callingPid is: %{public}d,"
3376             "curTime is: %{public}" PRIu64 ", actionTime is: %{public}" PRIu64 ", isFocused is: %{public}d",
3377             windowPid_, callingPid, curTime, actionTime_, isFocused);
3378     }
3379     return ret;
3380 }
3381 
Clear()3382 void InputEventCallback::Clear()
3383 {
3384     std::unique_lock<std::shared_mutex> lock(inputEventMutex_);
3385     actionTime_ = 0;
3386     windowPid_ = 0;
3387     std::unique_lock<std::shared_mutex> blockMapLock(blockMapMutex_);
3388     blockMap_.clear();
3389 }
3390 } // namespace MiscServices
3391 } // namespace OHOS
3392