• 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 #include <sys/mman.h>
19 
20 #include "ashmem.h"
21 #include "ability_manager_client.h"
22 #include "accesstoken_kit.h"
23 #include "account_manager.h"
24 #include "calculate_time_consuming.h"
25 #include "common_event_manager.h"
26 #include "device/dev_profile.h"
27 #include "distributed_file_daemon_manager.h"
28 #ifdef WITH_DLP
29 #include "dlp_permission_kit.h"
30 #include "dlp_permission.h"
31 #endif // WITH_DLP
32 #include "eventcenter/pasteboard_event.h"
33 #include "hiview_adapter.h"
34 #include "input_method_controller.h"
35 #include "iservice_registry.h"
36 #include "mem_mgr_client.h"
37 #include "message_parcel_warp.h"
38 #include "os_account_manager.h"
39 #include "parameters.h"
40 #include "pasteboard_common.h"
41 #include "pasteboard_dialog.h"
42 #include "pasteboard_disposable_manager.h"
43 #include "pasteboard_error.h"
44 #include "pasteboard_hilog.h"
45 #include "pasteboard_event_dfx.h"
46 #include "pasteboard_event_ue.h"
47 #include "pasteboard_pattern.h"
48 #include "pasteboard_time.h"
49 #include "pasteboard_trace.h"
50 #include "pasteboard_web_controller.h"
51 #include "permission/permission_utils.h"
52 #include "remote_file_share.h"
53 #include "res_sched_client.h"
54 #include "reporter.h"
55 #include "distributed_module_config.h"
56 #ifdef PB_SCREENLOCK_MGR_ENABLE
57 #include "screenlock_manager.h"
58 #include "file_mount_manager.h"
59 #endif // PB_SCREENLOCK_MGR_ENABLE
60 #include "tokenid_kit.h"
61 #include "uri_permission_manager_client.h"
62 #ifdef SCENE_BOARD_ENABLE
63 #include "window_manager_lite.h"
64 #else
65 #include "window_manager.h"
66 #endif // SCENE_BOARD_ENABLE
67 
68 namespace OHOS {
69 namespace MiscServices {
70 using namespace Rosen;
71 using namespace std::chrono;
72 using namespace Storage::DistributedFile;
73 using namespace RadarReporter;
74 using namespace UeReporter;
75 namespace {
76 constexpr int32_t COMMON_USERID = 0;
77 constexpr int32_t INIT_INTERVAL = 10000L;
78 constexpr uint32_t MAX_IPC_THREAD_NUM = 32;
79 constexpr const char *PASTEBOARD_SERVICE_SA_NAME = "pasteboard_service";
80 constexpr const char *PASTEBOARD_SERVICE_NAME = "PasteboardService";
81 constexpr const char *NLU_SO_PATH = "libai_nlu_innerapi.z.so";
82 constexpr const char *GET_PASTE_DATA_PROCESSOR = "GetPasteDataProcessor";
83 constexpr const char *FAIL_TO_GET_TIME_STAMP = "FAIL_TO_GET_TIME_STAMP";
84 constexpr const char *SECURE_PASTE_PERMISSION = "ohos.permission.SECURE_PASTE";
85 constexpr const char *READ_PASTEBOARD_PERMISSION = "ohos.permission.READ_PASTEBOARD";
86 constexpr const char *TRANSMIT_CONTROL_PROP_KEY = "persist.distributed_scene.datafiles_trans_ctrl";
87 constexpr const char *MANAGE_PASTEBOARD_APP_SHARE_OPTION_PERMISSION =
88     "ohos.permission.MANAGE_PASTEBOARD_APP_SHARE_OPTION";
89 constexpr const char *GET_DATA_APP = "GET_DATA_APP";
90 constexpr const char *NETWORK_DEV_NUM = "NETWORK_DEV_NUM";
91 constexpr const char *COVER_DELAY_DATA = "COVER_DELAY_DATA";
92 constexpr const char *UE_COPY = "DISTRIBUTED_PASTEBOARD_COPY";
93 constexpr const char *UE_PASTE = "DISTRIBUTED_PASTEBOARD_PASTE";
94 
95 constexpr int32_t INVALID_VERSION = -1;
96 constexpr int32_t ADD_PERMISSION_CHECK_SDK_VERSION = 12;
97 constexpr int32_t CTRLV_EVENT_SIZE = 2;
98 constexpr int32_t CONTROL_TYPE_ALLOW_SEND_RECEIVE = 1;
99 constexpr uint32_t EVENT_TIME_OUT = 2000;
100 constexpr uint32_t MAX_RECOGNITION_LENGTH = 1000;
101 constexpr int32_t DEVICE_COLLABORATION_UID = 5521;
102 constexpr uint64_t SYSTEM_APP_MASK = (static_cast<uint64_t>(1) << 32);
103 constexpr uint32_t MAX_BUNDLE_NAME_LENGTH = 127;
104 constexpr int64_t MIN_ASHMEM_DATA_SIZE = 32 * 1024;
105 constexpr int32_t E_OK_OPERATION = 0;
106 constexpr int32_t SET_VALUE_SUCCESS = 1;
107 
108 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(new PasteboardService());
109 } // namespace
110 using namespace Security::AccessToken;
111 using namespace OHOS::AppFileService::ModuleRemoteFileShare;
112 std::mutex PasteboardService::historyMutex_;
113 std::vector<std::string> PasteboardService::dataHistory_;
114 std::shared_ptr<Command> PasteboardService::copyHistory;
115 std::shared_ptr<Command> PasteboardService::copyData;
116 int32_t PasteboardService::currentUserId_ = ERROR_USERID;
117 ScreenEvent PasteboardService::currentScreenStatus = ScreenEvent::Default;
118 const std::string PasteboardService::REGISTER_PRESYNC_MONITOR = "RegisterPresyncMonitor";
119 const std::string PasteboardService::UNREGISTER_PRESYNC_MONITOR = "UnregisterPresyncMonitor";
120 const std::string PasteboardService::P2P_ESTABLISH_STR = "P2pEstablish";
121 const std::string PasteboardService::P2P_PRESYNC_ID = "P2pPreSyncId_";
122 
PasteboardService()123 PasteboardService::PasteboardService(): SystemAbility(PASTEBOARD_SERVICE_ID, true)
124 {
125     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PasteboardService Start.");
126     PasteboardService::state_ = ServiceRunningState::STATE_NOT_START;
127     p2pEstablishInfo_.pasteBlock = nullptr;
128 }
129 
~PasteboardService()130 PasteboardService::~PasteboardService()
131 {
132     clients_.Clear();
133     UnsubscribeAllEntityObserver();
134 }
135 
Init()136 int32_t PasteboardService::Init()
137 {
138     if (!Publish(this)) {
139         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "OnStart register to system ability manager failed.");
140         auto userId = GetCurrentAccountId();
141         Reporter::GetInstance().PasteboardFault().Report({ userId, "ERR_INVALID_OPTION" });
142         return static_cast<int32_t>(PasteboardError::INVALID_OPTION_ERROR);
143     }
144     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Init Success.");
145     PasteboardService::state_ = ServiceRunningState::STATE_RUNNING;
146     InitScreenStatus();
147     return ERR_OK;
148 }
149 
InitScreenStatus()150 void PasteboardService::InitScreenStatus()
151 {
152 #ifdef PB_SCREENLOCK_MGR_ENABLE
153     auto screenLockManager = OHOS::ScreenLock::ScreenLockManager::GetInstance();
154     PASTEBOARD_CHECK_AND_RETURN_LOGE(screenLockManager != nullptr, PASTEBOARD_MODULE_SERVICE,
155         "ScreenLockManager instance is null.");
156     auto isScreenLocked = screenLockManager->IsScreenLocked();
157     PasteboardService::currentScreenStatus = isScreenLocked ? ScreenEvent::ScreenLocked : ScreenEvent::ScreenUnlocked;
158     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "screen status is %{public}d", PasteboardService::currentScreenStatus);
159 #else
160     PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "PB_SCREENLOCK_MGR_ENABLE not defined");
161     return;
162 #endif
163 }
164 
OnStart()165 void PasteboardService::OnStart()
166 {
167     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PasteboardService OnStart.");
168     std::lock_guard<std::mutex> lock(saMutex_);
169     PASTEBOARD_CHECK_AND_RETURN_LOGE(PasteboardService::state_ != ServiceRunningState::STATE_RUNNING,
170         PASTEBOARD_MODULE_SERVICE, "PasteboardService is already running.");
171     IPCSkeleton::SetMaxWorkThreadNum(MAX_IPC_THREAD_NUM);
172     InitServiceHandler();
173     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
174     Loader loader;
175     uid_ = loader.LoadUid();
176     moduleConfig_.Init();
177     auto status = DATASL_OnStart();
178     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "datasl on start ret:%{public}d", status);
179     moduleConfig_.Watch(std::bind(&PasteboardService::OnConfigChange, this, std::placeholders::_1));
180     ffrtTimer_ = FFRTPool::GetTimer("pasteboard_service");
181     UpdateAgedTime();
182     AddSysAbilityListener();
183     if (Init() != ERR_OK && serviceHandler_ != nullptr) {
184         auto callback = [this]() {
185             Init();
186         };
187         serviceHandler_->PostTask(callback, INIT_INTERVAL);
188         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Init failed. Try again 10s later.");
189         return;
190     }
191     auto callback = [this]() {
192         switch_.Init(GetCurrentAccountId());
193     };
194     serviceHandler_->PostTask(callback);
195     copyHistory = std::make_shared<Command>(std::vector<std::string>{ "--copy-history" },
196         "Dump access history last ten times.",
197         [this](const std::vector<std::string> &input, std::string &output) -> bool {
198             output = DumpHistory();
199             return true;
200         });
201     copyData = std::make_shared<Command>(std::vector<std::string>{ "--data" }, "Show copy data details.",
202         [this](const std::vector<std::string> &input, std::string &output) -> bool {
203             output = DumpData();
204             return true;
205         });
206     PasteboardDumpHelper::GetInstance().RegisterCommand(copyHistory);
207     PasteboardDumpHelper::GetInstance().RegisterCommand(copyData);
208     CommonEventSubscriber();
209     AccountStateSubscriber();
210     PasteboardEventSubscriber();
211     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Start PasteboardService success.");
212     EventCenter::GetInstance().Subscribe(OHOS::MiscServices::Event::EVT_REMOTE_CHANGE, RemotePasteboardChange());
213     HiViewAdapter::StartTimerThread();
214     return;
215 }
216 
OnStop()217 void PasteboardService::OnStop()
218 {
219     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop Started.");
220     std::lock_guard<std::mutex> lock(saMutex_);
221     if (PasteboardService::state_ != ServiceRunningState::STATE_RUNNING) {
222         return;
223     }
224     serviceHandler_ = nullptr;
225     PasteboardService::state_ = ServiceRunningState::STATE_NOT_START;
226     DMAdapter::GetInstance().DeInitialize();
227     if (commonEventSubscriber_ != nullptr) {
228         EventFwk::CommonEventManager::UnSubscribeCommonEvent(commonEventSubscriber_);
229     }
230     moduleConfig_.DeInit();
231     switch_.DeInit();
232     DATASL_OnStop();
233     EventCenter::GetInstance().Unsubscribe(PasteboardEvent::DISCONNECT);
234     EventCenter::GetInstance().Unsubscribe(OHOS::MiscServices::Event::EVT_REMOTE_CHANGE);
235     CancelCriticalTimer();
236     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 0, PASTEBOARD_SERVICE_ID);
237     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop End.");
238 }
239 
AddSysAbilityListener()240 void PasteboardService::AddSysAbilityListener()
241 {
242     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "begin.");
243     for (uint32_t i = 0; i < sizeof(LISTENING_SERVICE) / sizeof(LISTENING_SERVICE[0]); i++) {
244         auto ret = AddSystemAbilityListener(LISTENING_SERVICE[i]);
245         if (ret) {
246             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Add listener success, serviceId = %{public}d.",
247                 LISTENING_SERVICE[i]);
248         } else {
249             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Add listener failed, serviceId = %{public}d.",
250                 LISTENING_SERVICE[i]);
251         }
252     }
253 }
254 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)255 void PasteboardService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
256 {
257     (void)deviceId;
258     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "systemAbilityId=%{public}d", systemAbilityId);
259 
260     switch (systemAbilityId) {
261         case DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID:
262             OnAddDeviceManager();
263             break;
264         case MEMORY_MANAGER_SA_ID:
265             OnAddMemoryManager();
266             break;
267         case DISTRIBUTED_DEVICE_PROFILE_SA_ID:
268             OnAddDeviceProfile();
269             break;
270         default:
271             break;
272     }
273 }
274 
OnRemoveSystemAbility(int32_t systemAbilityId,const std::string & deviceId)275 void PasteboardService::OnRemoveSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
276 {
277     (void)deviceId;
278     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "systemAbilityId=%{public}d", systemAbilityId);
279 
280     switch (systemAbilityId) {
281         case DISTRIBUTED_DEVICE_PROFILE_SA_ID:
282             OnRemoveDeviceProfile();
283             break;
284         default:
285             break;
286     }
287 }
288 
DelayGetterDeathRecipient(int32_t userId,PasteboardService & service)289 PasteboardService::DelayGetterDeathRecipient::DelayGetterDeathRecipient(int32_t userId, PasteboardService &service)
290     : userId_(userId), service_(service)
291 {
292     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Construct Delay Getter Death Recipient");
293 }
294 
OnRemoteDied(const wptr<IRemoteObject> & remote)295 void PasteboardService::DelayGetterDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
296 {
297     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "start");
298     (void)remote;
299     service_.NotifyDelayGetterDied(userId_);
300 }
301 
NotifyDelayGetterDied(int32_t userId)302 void PasteboardService::NotifyDelayGetterDied(int32_t userId)
303 {
304     if (userId == ERROR_USERID) {
305         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "error userId: %{public}d", userId);
306         return;
307     }
308     delayGetters_.Erase(userId);
309 }
310 
EntryGetterDeathRecipient(int32_t userId,PasteboardService & service)311 PasteboardService::EntryGetterDeathRecipient::EntryGetterDeathRecipient(int32_t userId, PasteboardService &service)
312     : userId_(userId), service_(service)
313 {
314     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Construct Entry Getter Death Recipient");
315 }
316 
OnRemoteDied(const wptr<IRemoteObject> & remote)317 void PasteboardService::EntryGetterDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
318 {
319     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "start");
320     (void)remote;
321     service_.NotifyEntryGetterDied(userId_);
322 }
323 
NotifyEntryGetterDied(int32_t userId)324 void PasteboardService::NotifyEntryGetterDied(int32_t userId)
325 {
326     if (userId == ERROR_USERID) {
327         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "error userId: %{public}d", userId);
328         return;
329     }
330     entryGetters_.Erase(userId);
331 }
332 
UpdateAgedTime()333 void PasteboardService::UpdateAgedTime()
334 {
335     static bool developerMode = OHOS::system::GetBoolParameter("const.security.developermode.state", false);
336     int32_t agedTime = developerMode ? system::GetIntParameter("const.pasteboard.rd_test_aged_time",
337         ONE_HOUR_MINUTES, MIN_AGED_TIME, MAX_AGED_TIME) : ONE_HOUR_MINUTES;
338     agedTime_ = agedTime * MINUTES_TO_MILLISECONDS;
339     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "agedTime_: %{public}d", agedTime_);
340 }
341 
CancelCriticalTimer()342 void PasteboardService::CancelCriticalTimer()
343 {
344     if (!ffrtTimer_) {
345         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ffrtTimer_ is null");
346         return;
347     }
348     ffrtTimer_->CancelTimer(SET_CRITICAL_ID);
349     Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, PASTEBOARD_SERVICE_ID);
350     isCritical_ = false;
351 }
352 
SetCriticalTimer()353 void PasteboardService::SetCriticalTimer()
354 {
355     if (!ffrtTimer_) {
356         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ffrtTimer_ is null");
357         return;
358     }
359     if (!isCritical_) {
360         Memory::MemMgrClient::GetInstance().SetCritical(getpid(), true, PASTEBOARD_SERVICE_ID);
361         isCritical_ = true;
362     }
363     FFRTTask task = [this] {
364         std::thread thread([=]() {
365             Memory::MemMgrClient::GetInstance().SetCritical(getpid(), false, PASTEBOARD_SERVICE_ID);
366             isCritical_ = false;
367         });
368         thread.detach();
369     };
370     ffrtTimer_->SetTimer(SET_CRITICAL_ID, task, static_cast<uint32_t>(agedTime_));
371 }
372 
OnAddDeviceManager()373 void PasteboardService::OnAddDeviceManager()
374 {
375     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
376     DMAdapter::GetInstance().Initialize(appInfo.bundleName);
377 }
378 
OnAddMemoryManager()379 void PasteboardService::OnAddMemoryManager()
380 {
381     Memory::MemMgrClient::GetInstance().NotifyProcessStatus(getpid(), 1, 1, PASTEBOARD_SERVICE_ID);
382     SetCriticalTimer();
383 }
384 
OnAddDeviceProfile()385 void PasteboardService::OnAddDeviceProfile()
386 {
387     DevProfile::GetInstance().SendSubscribeInfos();
388 }
389 
OnRemoveDeviceProfile()390 void PasteboardService::OnRemoveDeviceProfile()
391 {
392     DevProfile::GetInstance().ClearDeviceProfileService();
393 }
394 
ReportUeCopyEvent(PasteData & pasteData,int64_t dataSize,int32_t result)395 void PasteboardService::ReportUeCopyEvent(PasteData &pasteData, int64_t dataSize, int32_t result)
396 {
397     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
398     auto res = (result == static_cast<int32_t>(PasteboardError::E_OK)) ? E_OK_OPERATION : result;
399     UeReportInfo reportInfo;
400     reportInfo.ret = res;
401     reportInfo.bundleName = appInfo.bundleName;
402     reportInfo.description = pasteData.GetReportDescription();
403     reportInfo.commonInfo = GetCommonState(dataSize);
404     UE_REPORT(UE_COPY, reportInfo);
405 }
406 
InitServiceHandler()407 void PasteboardService::InitServiceHandler()
408 {
409     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler started.");
410     if (serviceHandler_ != nullptr) {
411         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Already init.");
412         return;
413     }
414     std::shared_ptr<AppExecFwk::EventRunner> runner =
415         AppExecFwk::EventRunner::Create(PASTEBOARD_SERVICE_NAME, AppExecFwk::ThreadMode::FFRT);
416     serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
417 
418     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler Succeeded.");
419 }
420 
Clear()421 int32_t PasteboardService::Clear()
422 {
423     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "enter, clips_.Size=%{public}zu", clips_.Size());
424     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
425     auto userId = appInfo.userId;
426     if (userId == ERROR_USERID) {
427         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
428         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
429     }
430     RADAR_REPORT(DFX_CLEAR_PASTEBOARD, DFX_MANUAL_CLEAR, DFX_SUCCESS);
431     auto it = clips_.Find(userId);
432     if (it.first) {
433         clips_.Erase(userId);
434         delayDataId_ = 0;
435         delayTokenId_ = 0;
436         std::string bundleName = GetAppBundleName(appInfo);
437         NotifyObservers(bundleName, userId, PasteboardEventStatus::PASTEBOARD_CLEAR);
438     }
439     CleanDistributedData(userId);
440     CancelCriticalTimer();
441     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "leave, clips_.Size=%{public}zu, appInfo.userId = %{public}d",
442         clips_.Size(), userId);
443     return ERR_OK;
444 }
445 
GetChangeCount(uint32_t & changeCount)446 int32_t PasteboardService::GetChangeCount(uint32_t &changeCount)
447 {
448     auto tokenId = IPCSkeleton::GetCallingTokenID();
449     auto appInfo = GetAppInfo(tokenId);
450     changeCount = 0;
451     clipChangeCount_.ComputeIfPresent(appInfo.userId, [&changeCount](auto, auto &value) {
452         changeCount = value;
453         PASTEBOARD_HILOGI(
454             PASTEBOARD_MODULE_SERVICE, "Find changeCount succeed, changeCount is %{public}u", changeCount);
455         return true;
456     });
457     return ERR_OK;
458 }
459 
IncreaseChangeCount(int32_t userId)460 void PasteboardService::IncreaseChangeCount(int32_t userId)
461 {
462     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "IncreaseChangeCount start!");
463     clipChangeCount_.Compute(userId, [](auto userId, uint32_t &changeCount) {
464         changeCount = (changeCount == UINT32_MAX) ? 0 : changeCount + 1;
465         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "userId=%{public}d, changeCount=%{public}u", userId, changeCount);
466         return true;
467     });
468 }
469 
NotifyEntityObservers(std::string & entity,EntityType entityType,uint32_t dataLength)470 void PasteboardService::NotifyEntityObservers(std::string &entity, EntityType entityType, uint32_t dataLength)
471 {
472     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "entityType=%{public}u, dataLength=%{public}u",
473         static_cast<uint32_t>(entityType), dataLength);
474     entityObserverMap_.ForEach([this, &entity, entityType, dataLength](const auto &key, auto &value) {
475         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "pid=%{public}u, listSize=%{public}zu", key, value.size());
476         for (auto entityObserver : value) {
477             if (entityType == entityObserver.entityType && dataLength <= entityObserver.expectedDataLength &&
478                 VerifyPermission(entityObserver.tokenId)) {
479                 entityObserver.observer->OnRecognitionEvent(entityType, entity);
480             }
481         }
482         return false;
483     });
484 }
485 
GetAllEntryPlainText(uint32_t dataId,uint32_t recordId,std::vector<std::shared_ptr<PasteDataEntry>> & entries,std::string & primaryText)486 int32_t PasteboardService::GetAllEntryPlainText(uint32_t dataId, uint32_t recordId,
487     std::vector<std::shared_ptr<PasteDataEntry>> &entries, std::string &primaryText)
488 {
489     for (auto &entry : entries) {
490         if (primaryText.size() > MAX_RECOGNITION_LENGTH) {
491             return static_cast<int32_t>(PasteboardError::EXCEEDING_LIMIT_EXCEPTION);
492         }
493         int32_t result = static_cast<int32_t>(PasteboardError::E_OK);
494         if (entry->GetMimeType() == MIMETYPE_TEXT_PLAIN && !entry->HasContentByMimeType(MIMETYPE_TEXT_PLAIN)) {
495             result = GetRecordValueByType(dataId, recordId, *entry);
496         }
497         if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
498             continue;
499         }
500         std::shared_ptr<std::string> plainTextPtr = entry->ConvertToPlainText();
501         if (plainTextPtr != nullptr) {
502             primaryText += *plainTextPtr;
503         }
504     }
505     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetAllEntryPlainText finished");
506     return static_cast<int32_t>(PasteboardError::E_OK);
507 }
508 
GetAllPrimaryText(const PasteData & pasteData)509 std::string PasteboardService::GetAllPrimaryText(const PasteData &pasteData)
510 {
511     std::string primaryText = "";
512     std::vector<std::shared_ptr<PasteDataRecord>> records = pasteData.AllRecords();
513     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "size of records=%{public}zu", records.size());
514     for (const auto &record : records) {
515         if (primaryText.size() > MAX_RECOGNITION_LENGTH) {
516             primaryText = "";
517             break;
518         }
519         std::shared_ptr<std::string> plainTextPtr = record->GetPlainTextV0();
520         if (plainTextPtr != nullptr) {
521             primaryText += *plainTextPtr;
522             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "primaryText in record");
523             continue;
524         }
525         auto dataId = pasteData.GetDataId();
526         auto recordId = record->GetRecordId();
527         std::vector<std::shared_ptr<PasteDataEntry>> entries = record->GetEntries();
528         int32_t result = GetAllEntryPlainText(dataId, recordId, entries, primaryText);
529         if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
530             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "primaryText exceeded size, result=%{public}d", result);
531             primaryText = "";
532             break;
533         }
534     }
535     return primaryText;
536 }
537 
ExtractEntity(const std::string & entity,std::string & location)538 int32_t PasteboardService::ExtractEntity(const std::string &entity, std::string &location)
539 {
540     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!entity.empty(),
541         static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR), PASTEBOARD_MODULE_SERVICE,
542         "entity empty");
543     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(nlohmann::json::accept(entity),
544         static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR), PASTEBOARD_MODULE_SERVICE,
545         "entity invalid");
546     nlohmann::json entityJson = nlohmann::json::parse(entity);
547     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!entityJson.is_discarded(),
548         static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR), PASTEBOARD_MODULE_SERVICE,
549         "parse entity to json failed");
550     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(entityJson.contains("code") && entityJson["code"].is_number(),
551         static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR), PASTEBOARD_MODULE_SERVICE,
552         "entity find code failed");
553     int code = entityJson["code"].get<int>();
554     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(
555         code == 0, static_cast<int32_t>(code), PASTEBOARD_MODULE_SERVICE, "failed to get entity");
556     if (entityJson.contains("entity") && entityJson["entity"].contains("location") &&
557         entityJson["entity"]["location"].is_array()) {
558         nlohmann::json locationJson = entityJson["entity"]["location"].get<nlohmann::json>();
559         location = locationJson.dump();
560         PASTEBOARD_HILOGI(
561             PASTEBOARD_MODULE_SERVICE, "location dump finished, location size=%{public}zu", location.size());
562         return static_cast<int32_t>(PasteboardError::E_OK);
563     }
564     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PasteData did not contain entity");
565     return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
566 }
567 
OnRecognizePasteData(const std::string & primaryText)568 void PasteboardService::OnRecognizePasteData(const std::string &primaryText)
569 {
570     pthread_setname_np(pthread_self(), "PasteDataRecognize");
571     auto handle = dlopen(NLU_SO_PATH, RTLD_NOW);
572     PASTEBOARD_CHECK_AND_RETURN_LOGE(handle != nullptr, PASTEBOARD_MODULE_SERVICE, "Can not get AIEngine handle");
573     GetProcessorFunc GetProcessor = reinterpret_cast<GetProcessorFunc>(dlsym(handle, GET_PASTE_DATA_PROCESSOR));
574     if (GetProcessor == nullptr) {
575         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Can not get ProcessorFunc");
576         dlclose(handle);
577         return;
578     }
579     IPasteDataProcessor &processor = GetProcessor();
580     std::string entity = "";
581     int32_t result = processor.Process(primaryText, entity);
582     if (result != ERR_OK) {
583         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "AI Process failed, result=%{public}d", result);
584         dlclose(handle);
585         return;
586     }
587     std::string location = "";
588     int32_t ret = ExtractEntity(entity, location);
589     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
590         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ExtractEntity failed, ret=%{public}d", ret);
591         dlclose(handle);
592         return;
593     }
594     NotifyEntityObservers(location, EntityType::ADDRESS, static_cast<uint32_t>(primaryText.size()));
595     dlclose(handle);
596 }
597 
RecognizePasteData(PasteData & pasteData)598 void PasteboardService::RecognizePasteData(PasteData &pasteData)
599 {
600     if (pasteData.GetShareOption() == ShareOption::InApp) {
601         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "shareOption is InApp, recognition not allowed");
602         return;
603     }
604     std::string primaryText = GetAllPrimaryText(pasteData);
605     if (primaryText.empty()) {
606         return;
607     }
608     FFRTTask task = [this, primaryText]() {
609         std::thread thread([=]() {
610             PASTEBOARD_CHECK_AND_RETURN_LOGE(PasteboardService::state_ == ServiceRunningState::STATE_RUNNING,
611                 PASTEBOARD_MODULE_SERVICE, "PasteboardService is not running.");
612             OnRecognizePasteData(primaryText);
613         });
614         thread.detach();
615     };
616     FFRTUtils::SubmitTask(task);
617 }
618 
SubscribeEntityObserver(EntityType entityType,uint32_t expectedDataLength,const sptr<IEntityRecognitionObserver> & observer)619 int32_t PasteboardService::SubscribeEntityObserver(
620     EntityType entityType, uint32_t expectedDataLength, const sptr<IEntityRecognitionObserver> &observer)
621 {
622     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(static_cast<uint32_t>(entityType) < static_cast<uint32_t>(EntityType::MAX),
623         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
624         "Failed to read entityType data");
625     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(
626         observer != nullptr, static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
627         "Failed to read observer data");
628     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE,
629         "start, type=%{public}u, len=%{public}u", static_cast<uint32_t>(entityType), expectedDataLength);
630     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(expectedDataLength <= MAX_RECOGNITION_LENGTH,
631         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
632         "expected data length exceeds limitation");
633     auto tokenId = IPCSkeleton::GetCallingTokenID();
634     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(VerifyPermission(tokenId),
635         static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR), PASTEBOARD_MODULE_SERVICE,
636         "check permission failed");
637     auto callingPid = IPCSkeleton::GetCallingPid();
638     bool result = entityObserverMap_.ComputeIfPresent(
639         callingPid, [entityType, expectedDataLength, tokenId, &observer](auto, auto &observerList) {
640             auto it = std::find_if(observerList.begin(), observerList.end(),
641                 [entityType, expectedDataLength](const EntityObserverInfo &observer) {
642                     return observer.entityType == entityType && observer.expectedDataLength == expectedDataLength;
643                 });
644             if (it != observerList.end()) {
645                 it->tokenId = tokenId;
646                 it->observer = observer;
647                 return true;
648             }
649             observerList.emplace_back(entityType, expectedDataLength, tokenId, observer);
650             return true;
651         });
652     if (!result) {
653         std::vector<EntityObserverInfo> observerList;
654         observerList.emplace_back(entityType, expectedDataLength, tokenId, observer);
655         entityObserverMap_.Emplace(callingPid, observerList);
656     }
657     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "subscribe entityObserver finished");
658     return ERR_OK;
659 }
660 
UnsubscribeEntityObserver(EntityType entityType,uint32_t expectedDataLength,const sptr<IEntityRecognitionObserver> & observer)661 int32_t PasteboardService::UnsubscribeEntityObserver(
662     EntityType entityType, uint32_t expectedDataLength, const sptr<IEntityRecognitionObserver> &observer)
663 {
664     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(static_cast<uint32_t>(entityType) < static_cast<uint32_t>(EntityType::MAX),
665         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
666         "Failed to read entityType data");
667     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(
668         observer != nullptr, static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
669         "Failed to read observer data");
670     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(expectedDataLength <= MAX_RECOGNITION_LENGTH,
671         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
672         "expected data length exceeds limitation");
673     auto callingPid = IPCSkeleton::GetCallingPid();
674     auto result = entityObserverMap_.ComputeIfPresent(
675         callingPid, [entityType, expectedDataLength](auto, auto &observerList) {
676             auto it = std::find_if(observerList.begin(), observerList.end(),
677                 [entityType, expectedDataLength](const EntityObserverInfo &observer) {
678                     return observer.entityType == entityType && observer.expectedDataLength == expectedDataLength;
679                 });
680             if (it == observerList.end()) {
681                 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE,
682                     "Failed to unsubscribe, observer not found, type is %{public}u, length is %{public}u.",
683                     static_cast<uint32_t>(entityType), expectedDataLength);
684                 return true;
685             }
686             observerList.erase(it);
687             if (observerList.empty()) {
688                 return false;
689             }
690             return true;
691         });
692     return ERR_OK;
693 }
694 
UnsubscribeAllEntityObserver()695 void PasteboardService::UnsubscribeAllEntityObserver()
696 {
697     entityObserverMap_.Clear();
698 }
699 
GetRecordValueByType(uint32_t dataId,uint32_t recordId,int64_t & rawDataSize,std::vector<uint8_t> & buffer,int & fd)700 int32_t PasteboardService::GetRecordValueByType(uint32_t dataId, uint32_t recordId, int64_t &rawDataSize,
701     std::vector<uint8_t> &buffer, int &fd)
702 {
703     MessageParcelWarp messageReply;
704     if (rawDataSize <= 0 || rawDataSize > messageReply.GetRawDataSize()) {
705         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "invalid raw data size:%{public}" PRId64, rawDataSize);
706         return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
707     }
708     bool ret = false;
709     PasteDataEntry entryValue;
710     if (rawDataSize > MIN_ASHMEM_DATA_SIZE) {
711         auto actualSize = AshmemGetSize(fd);
712         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(actualSize >= 0 && rawDataSize <= actualSize,
713             static_cast<int32_t>(PasteboardError::INVALID_DATA_SIZE), PASTEBOARD_MODULE_SERVICE,
714             "rawDataSize invalid, actualSize=%{public}d, rawDataSize:%{public}" PRId64, actualSize, rawDataSize);
715         void *ptr = ::mmap(nullptr, rawDataSize, PROT_READ, MAP_SHARED, fd, 0);
716         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ptr != MAP_FAILED,
717             static_cast<int32_t>(PasteboardError::DESERIALIZATION_ERROR),
718             PASTEBOARD_MODULE_SERVICE, "mmap failed, fd:%{public}d size:%{public}" PRId64, fd, rawDataSize);
719         const uint8_t *rawData = reinterpret_cast<const uint8_t *>(ptr);
720         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(rawData != nullptr,
721             static_cast<int32_t>(PasteboardError::DESERIALIZATION_ERROR),
722             PASTEBOARD_MODULE_SERVICE, "Failed to get raw data, size=%{public}" PRId64, rawDataSize);
723         std::vector<uint8_t> pasteDataTlv(rawData, rawData + rawDataSize);
724         ret = entryValue.Decode(pasteDataTlv);
725         ::munmap(ptr, rawDataSize);
726     } else {
727         ret = entryValue.Decode(buffer);
728     }
729     if (!ret) {
730         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "fail to decode paste data entry");
731         return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
732     }
733     auto result = GetRecordValueByType(dataId, recordId, entryValue);
734     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(result == static_cast<int32_t>(PasteboardError::E_OK), result,
735         PASTEBOARD_MODULE_SERVICE, "get record value failed, type=%{public}s, ret=%{public}d",
736         entryValue.GetUtdId().c_str(), result);
737     rawDataSize = 0;
738     std::vector<uint8_t>().swap(buffer);
739     fd = -1;
740     return GetRecordValueByType(rawDataSize, buffer, fd, entryValue);
741 }
742 
GetRecordValueByType(int64_t & rawDataSize,std::vector<uint8_t> & buffer,int32_t & fd,const PasteDataEntry & entryValue)743 int32_t PasteboardService::GetRecordValueByType(int64_t &rawDataSize,
744     std::vector<uint8_t> &buffer, int32_t &fd, const PasteDataEntry &entryValue)
745 {
746     std::vector<uint8_t> entryValueTLV(0);
747     bool ret = entryValue.Encode(entryValueTLV);
748     if (!ret) {
749         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "fail encode entry value");
750         return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
751     }
752     rawDataSize = static_cast<int64_t>(entryValueTLV.size());
753     if (rawDataSize > MIN_ASHMEM_DATA_SIZE) {
754         if (!WriteRawData(entryValueTLV.data(), rawDataSize, fd)) {
755             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Failed to WriteRawData");
756             return static_cast<int32_t>(PasteboardError::SERIALIZATION_ERROR);
757         }
758         std::vector<uint8_t>().swap(entryValueTLV);
759     } else {
760         fd = AshmemCreate("PasteboardTmpAshmem", 1);
761         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(fd >= 0,
762             static_cast<int32_t>(PasteboardError::SERIALIZATION_ERROR),
763             PASTEBOARD_MODULE_SERVICE, "ashmem create failed");
764         buffer = std::move(entryValueTLV);
765     }
766 
767     return ERR_OK;
768 }
769 
GetRecordValueByType(uint32_t dataId,uint32_t recordId,PasteDataEntry & value)770 int32_t PasteboardService::GetRecordValueByType(uint32_t dataId, uint32_t recordId, PasteDataEntry &value)
771 {
772     auto tokenId = IPCSkeleton::GetCallingTokenID();
773     auto callPid = IPCSkeleton::GetCallingPid();
774     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((dataId == delayDataId_ && tokenId == delayTokenId_) ||
775         VerifyPermission(tokenId), static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR),
776         PASTEBOARD_MODULE_SERVICE, "check permission failed, calling pid is %{public}d", callPid);
777 
778     auto appInfo = GetAppInfo(tokenId);
779     auto [hasData, data] = clips_.Find(appInfo.userId);
780     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasData && data, static_cast<int32_t>(PasteboardError::NO_DATA_ERROR),
781         PASTEBOARD_MODULE_SERVICE, "data not find, userId=%{public}u", appInfo.userId);
782     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(dataId == data->GetDataId(),
783         static_cast<int32_t>(PasteboardError::INVALID_DATA_ID), PASTEBOARD_MODULE_SERVICE,
784         "dataId=%{public}u mismatch, local=%{public}u", dataId, data->GetDataId());
785 
786     auto record = data->GetRecordById(recordId);
787     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(record != nullptr, static_cast<int32_t>(PasteboardError::INVALID_RECORD_ID),
788         PASTEBOARD_MODULE_SERVICE, "recordId=%{public}u invalid, max=%{public}zu", recordId, data->GetRecordCount());
789 
790     std::string utdId = value.GetUtdId();
791     auto entry = record->GetEntry(utdId);
792     bool isRemoteData = data->IsRemote();
793     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(entry != nullptr, static_cast<int32_t>(PasteboardError::INVALID_MIMETYPE),
794         PASTEBOARD_MODULE_SERVICE, "entry is null, recordId=%{public}u, type=%{public}s", recordId, utdId.c_str());
795 
796     if (isRemoteData && !entry->HasContent(utdId)) {
797         int32_t ret = GetRemoteEntryValue(appInfo, *data, *record, value);
798         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
799             PASTEBOARD_MODULE_SERVICE, "get remote entry failed, type=%{public}s, ret=%{public}d", utdId.c_str(), ret);
800         return static_cast<int32_t>(PasteboardError::E_OK);
801     }
802 
803     int32_t ret = GetLocalEntryValue(appInfo.userId, *data, *record, value);
804     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
805         PASTEBOARD_MODULE_SERVICE, "get local entry failed, type=%{public}s, ret=%{public}d", utdId.c_str(), ret);
806 
807     std::string mimeType = value.GetMimeType();
808     if (mimeType == MIMETYPE_TEXT_HTML) {
809         return ProcessDelayHtmlEntry(*data, appInfo, value);
810     }
811     if (mimeType == MIMETYPE_TEXT_URI) {
812         std::vector<Uri> grantUris = CheckUriPermission(*data, std::make_pair(appInfo.bundleName, appInfo.appIndex));
813         return GrantUriPermission(grantUris, appInfo.bundleName, isRemoteData, appInfo.appIndex);
814     }
815     return static_cast<int32_t>(PasteboardError::E_OK);
816 }
817 
ProcessDelayHtmlEntry(PasteData & data,const AppInfo & targetAppInfo,PasteDataEntry & entry)818 int32_t PasteboardService::ProcessDelayHtmlEntry(PasteData &data, const AppInfo &targetAppInfo,
819     PasteDataEntry &entry)
820 {
821     const auto &targetBundle = targetAppInfo.bundleName;
822     const auto &appIndex = targetAppInfo.appIndex;
823     {
824         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
825         if (!PasteboardWebController::GetInstance().SplitWebviewPasteData(data)) {
826             return static_cast<int32_t>(PasteboardError::E_OK);
827         }
828     }
829 
830     PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
831     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
832 
833     PasteData tmp;
834     bool isRemoteData = data.IsRemote();
835     std::shared_ptr<std::string> html = entry.ConvertToHtml();
836     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(html != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
837         PASTEBOARD_MODULE_SERVICE, "convert to html failed");
838 
839     tmp.AddHtmlRecord(*html);
840     tmp.SetOriginAuthority(data.GetOriginAuthority());
841     tmp.SetTokenId(data.GetTokenId());
842     tmp.SetRemote(isRemoteData);
843     PasteboardWebController::GetInstance().SplitWebviewPasteData(tmp);
844     PasteboardWebController::GetInstance().SetWebviewPasteData(tmp, data.GetOriginAuthority());
845     PasteboardWebController::GetInstance().CheckAppUriPermission(tmp);
846 
847     std::vector<Uri> grantUris = CheckUriPermission(tmp, std::make_pair(targetBundle, appIndex));
848     int32_t ret = GrantUriPermission(grantUris, targetBundle, isRemoteData, appIndex);
849     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
850         PASTEBOARD_MODULE_SERVICE, "grant to %{public}s:%{public}d failed, ret=%{public}d", targetBundle.c_str(),
851         appIndex, ret);
852 
853     return PostProcessDelayHtmlEntry(tmp, targetAppInfo, entry);
854 }
855 
PostProcessDelayHtmlEntry(PasteData & data,const AppInfo & targetAppInfo,PasteDataEntry & entry)856 int32_t PasteboardService::PostProcessDelayHtmlEntry(PasteData &data, const AppInfo &targetAppInfo,
857     PasteDataEntry &entry)
858 {
859     PasteboardWebController::GetInstance().RetainUri(data);
860     PasteboardWebController::GetInstance().RebuildWebviewPasteData(data, targetAppInfo.bundleName,
861         targetAppInfo.appIndex);
862 
863     std::shared_ptr<std::string> html = data.GetPrimaryHtml();
864     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(html != nullptr, static_cast<int32_t>(PasteboardError::REBUILD_HTML_FAILED),
865         PASTEBOARD_MODULE_SERVICE, "rebuild html failed");
866 
867     auto entryValue = entry.GetValue();
868     if (std::holds_alternative<std::string>(entryValue)) {
869         entry.SetValue(*html);
870     } else if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
871         auto object = std::get<std::shared_ptr<Object>>(entryValue);
872         auto newObject = std::make_shared<Object>();
873         newObject->value_ = object->value_;
874         newObject->value_[UDMF::HTML_CONTENT] = *html;
875         entry.SetValue(newObject);
876     }
877     return static_cast<int32_t>(PasteboardError::E_OK);
878 }
879 
VerifyPermission(uint32_t tokenId)880 bool PasteboardService::VerifyPermission(uint32_t tokenId)
881 {
882     auto version = GetSdkVersion(tokenId);
883     auto callPid = IPCSkeleton::GetCallingPid();
884     if (version == INVALID_VERSION) {
885         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
886             "get hap version failed, callPid is %{public}d, tokenId is %{public}d", callPid, tokenId);
887         return false;
888     }
889     auto isReadGrant = PermissionUtils::IsPermissionGranted(READ_PASTEBOARD_PERMISSION, tokenId);
890     auto isSecureGrant = PermissionUtils::IsPermissionGranted(SECURE_PASTE_PERMISSION, tokenId);
891     AddPermissionRecord(tokenId, isReadGrant, isSecureGrant);
892     if (isSecureGrant || isReadGrant) {
893         return true;
894     }
895     auto tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
896     bool isAllowTokenAccess = (tokenType == ATokenTypeEnum::TOKEN_NATIVE || tokenType == ATokenTypeEnum::TOKEN_SHELL);
897     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE,
898         "isReadGrant is %{public}d, isSecureGrant is %{public}d, isAllowTokenAccess is %{public}d", isReadGrant,
899         isSecureGrant, isAllowTokenAccess);
900     bool isCtrlVAction = false;
901     if (inputEventCallback_ != nullptr) {
902         isCtrlVAction = inputEventCallback_->IsCtrlVProcess(callPid, IsFocusedApp(tokenId));
903         inputEventCallback_->Clear();
904     }
905     auto isGrant = isReadGrant || isSecureGrant || isAllowTokenAccess || isCtrlVAction;
906     if (!isGrant && version >= ADD_PERMISSION_CHECK_SDK_VERSION) {
907         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "no permission, callPid is %{public}d, version is %{public}d",
908             callPid, version);
909         return false;
910     }
911     return true;
912 }
913 
IsDataValid(PasteData & pasteData,uint32_t tokenId)914 int32_t PasteboardService::IsDataValid(PasteData &pasteData, uint32_t tokenId)
915 {
916     if (pasteData.IsDraggedData() || !pasteData.IsValid()) {
917         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is invalid");
918         return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
919     }
920     if (IsDataAged()) {
921         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is aged");
922         return static_cast<int32_t>(PasteboardError::DATA_EXPIRED_ERROR);
923     }
924     auto screenStatus = GetCurrentScreenStatus();
925     if (pasteData.GetScreenStatus() > screenStatus) {
926         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "current screen is %{public}d, set data screen is %{public}d.",
927             screenStatus, pasteData.GetScreenStatus());
928         return static_cast<int32_t>(PasteboardError::CROSS_BORDER_ERROR);
929     }
930     switch (pasteData.GetShareOption()) {
931         case ShareOption::InApp: {
932             if (pasteData.GetTokenId() != tokenId) {
933                 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "InApp check failed.");
934                 return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
935             }
936             break;
937         }
938         case ShareOption::LocalDevice: {
939             break;
940         }
941         case ShareOption::CrossDevice: {
942             break;
943         }
944         default: {
945             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "tokenId = 0x%{public}x, shareOption = %{public}d is error.",
946                 tokenId, pasteData.GetShareOption());
947             return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
948         }
949     }
950     return static_cast<int32_t>(PasteboardError::E_OK);
951 }
952 
GetSdkVersion(uint32_t tokenId)953 int32_t PasteboardService::GetSdkVersion(uint32_t tokenId)
954 {
955     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != ATokenTypeEnum::TOKEN_HAP) {
956         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "caller is not application");
957         return 0;
958     }
959     HapTokenInfo hapTokenInfo;
960     auto ret = AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
961     if (ret != 0) {
962         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetHapTokenInfo fail, tokenid is %{public}u, ret is %{public}d.",
963             tokenId, ret);
964         return INVALID_VERSION;
965     }
966     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "ver:%{public}d.", hapTokenInfo.apiVersion);
967     return hapTokenInfo.apiVersion;
968 }
969 
IsDataAged()970 bool PasteboardService::IsDataAged()
971 {
972     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "IsDataAged start");
973     auto userId = GetCurrentAccountId();
974     if (userId == ERROR_USERID) {
975         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
976         return true;
977     }
978     auto it = copyTime_.Find(userId);
979     if (!it.first) {
980         return true;
981     }
982     uint64_t copyTime = it.second;
983     auto curTime = static_cast<uint64_t>(PasteBoardTime::GetBootTimeMs());
984     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "copyTime = %{public}" PRIu64 ", curTime = %{public}" PRIu64,
985         copyTime, curTime);
986     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((curTime != 0 && copyTime != 0), false,
987         PASTEBOARD_MODULE_SERVICE, "Failed to get the time, data never aged."
988         "copyTime = %{public}" PRIu64 ", curtime = %{public}" PRIu64, copyTime, curTime);
989 
990     if (curTime > copyTime && curTime - copyTime > static_cast<uint64_t>(agedTime_)) {
991         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "data is out of the time");
992         auto data = clips_.Find(userId);
993         if (data.first) {
994             clips_.Erase(userId);
995             delayDataId_ = 0;
996             delayTokenId_ = 0;
997         }
998         copyTime_.Erase(userId);
999         RADAR_REPORT(DFX_CLEAR_PASTEBOARD, DFX_AUTO_CLEAR, DFX_SUCCESS);
1000         return true;
1001     }
1002     return false;
1003 }
1004 
GetAppInfo(uint32_t tokenId)1005 AppInfo PasteboardService::GetAppInfo(uint32_t tokenId)
1006 {
1007     AppInfo info;
1008     info.tokenId = tokenId;
1009     info.tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
1010     info.userId = GetCurrentAccountId();
1011     switch (info.tokenType) {
1012         case ATokenTypeEnum::TOKEN_HAP: {
1013             HapTokenInfo hapInfo;
1014             if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
1015                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get hap token info fail.");
1016                 info.userId = -1;
1017                 return info;
1018             }
1019             info.bundleName = hapInfo.bundleName;
1020             info.userId = hapInfo.userID;
1021             info.appIndex = hapInfo.instIndex;
1022             break;
1023         }
1024         case ATokenTypeEnum::TOKEN_NATIVE:
1025         case ATokenTypeEnum::TOKEN_SHELL: {
1026             NativeTokenInfo tokenInfo;
1027             if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
1028                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get native token info fail.");
1029                 return info;
1030             }
1031             info.bundleName = tokenInfo.processName;
1032             break;
1033         }
1034         default: {
1035             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "tokenType = %{public}d not match.", info.tokenType);
1036         }
1037     }
1038     return info;
1039 }
1040 
GetAppBundleName(const AppInfo & appInfo)1041 std::string PasteboardService::GetAppBundleName(const AppInfo &appInfo)
1042 {
1043     std::string bundleName;
1044     if (appInfo.userId != ERROR_USERID) {
1045         bundleName = appInfo.bundleName;
1046     } else {
1047         bundleName = "error";
1048         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetAppInfo error");
1049     }
1050     return bundleName;
1051 }
1052 
SetLocalPasteFlag(bool isCrossPaste,uint32_t tokenId,PasteData & pasteData)1053 void PasteboardService::SetLocalPasteFlag(bool isCrossPaste, uint32_t tokenId, PasteData &pasteData)
1054 {
1055     pasteData.SetLocalPasteFlag(!isCrossPaste && tokenId == pasteData.GetTokenId());
1056     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "isLocalPaste = %{public}d.", pasteData.IsLocalPaste());
1057 }
1058 
ShowProgress(const std::string & progressKey,const sptr<IRemoteObject> & observer)1059 int32_t PasteboardService::ShowProgress(const std::string &progressKey, const sptr<IRemoteObject> &observer)
1060 {
1061     if (!HasPasteData()) {
1062         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "not pastedata, no need to show progress.");
1063         return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
1064     }
1065     auto tokenId = IPCSkeleton::GetCallingTokenID();
1066     if (!IsFocusedApp(tokenId)) {
1067         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "not focused app, no need to show progress.");
1068         return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
1069     }
1070     PasteBoardDialog::ProgressMessageInfo message;
1071     std::string deviceName = "";
1072     bool isRemote = false;
1073     auto result = (GetRemoteDeviceName(deviceName, isRemote) == ERR_OK);
1074     if (result && isRemote) {
1075         message.promptText = "PromptText_PasteBoard_Remote";
1076         message.remoteDeviceName = deviceName;
1077     } else {
1078         message.promptText = "PromptText_PasteBoard_Local";
1079         message.remoteDeviceName = "";
1080     }
1081     message.isRemote = isRemote;
1082     message.progressKey = progressKey;
1083 
1084     FocusedAppInfo appInfo = GetFocusedAppInfo();
1085     message.windowId = appInfo.windowId;
1086     message.callerToken = appInfo.abilityToken;
1087     message.clientCallback = observer;
1088     PasteBoardDialog::GetInstance().ShowProgress(message);
1089     return ERR_OK;
1090 }
1091 
WriteRawData(const void * data,int64_t size,int & serFd)1092 bool PasteboardService::WriteRawData(const void *data, int64_t size, int &serFd)
1093 {
1094     MessageParcelWarp messageData;
1095     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(data != nullptr, false, PASTEBOARD_MODULE_SERVICE, "data is null");
1096     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(0 < size && size <= messageData.GetRawDataSize(), false,
1097         PASTEBOARD_MODULE_SERVICE, "size invalid, size:%{public}" PRId64, size);
1098 
1099     int fd = AshmemCreate("WriteRawData Ashmem", size);
1100     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(fd >= 0, false, PASTEBOARD_MODULE_SERVICE, "ashmem create failed");
1101 
1102     int32_t result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
1103     if (result < 0) {
1104         close(fd);
1105         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ashmem set prot failed");
1106         return false;
1107     }
1108     void *ptr = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
1109     if (ptr == MAP_FAILED) {
1110         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "mmap failed, fd:%{public}d", fd);
1111         close(fd);
1112         return false;
1113     }
1114     if (!messageData.MemcpyData(ptr, static_cast<size_t>(size), data, size)) {
1115         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "memcpy_s failed, fd:%{public}d", fd);
1116         ::munmap(ptr, size);
1117         close(fd);
1118         return false;
1119     }
1120     ::munmap(ptr, size);
1121     serFd = fd;
1122     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Write data end. fd:%{public}d size:%{public}" PRId64, serFd, size);
1123     return true;
1124 }
1125 
GetCommonState(int64_t dataSize)1126 CommonInfo PasteboardService::GetCommonState(int64_t dataSize)
1127 {
1128     CommonInfo commonInfo;
1129     commonInfo.currentAccountId = GetCurrentAccountId();
1130     commonInfo.deviceType = DMAdapter::GetInstance().GetLocalDeviceType();
1131     commonInfo.dataSize = dataSize;
1132     return commonInfo;
1133 }
1134 
SetRadarEvent(const AppInfo & appInfo,PasteData & data,bool isPeerOnline,RadarReportInfo & radarReportInfo,const std::string & peerNetId)1135 void PasteboardService::SetRadarEvent(const AppInfo &appInfo, PasteData &data, bool isPeerOnline,
1136     RadarReportInfo &radarReportInfo, const std::string &peerNetId)
1137 {
1138     DmDeviceInfo remoteDevice;
1139     auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(peerNetId, remoteDevice);
1140     if (ret == static_cast<int32_t>(PasteboardError::E_OK)) {
1141         DeviceManager::GetInstance().GetNetworkTypeByNetworkId(PASTEBOARD_SERVICE_SA_NAME, peerNetId,
1142             radarReportInfo.pasteInfo.networkType);
1143     }
1144     std::string peerUdid = DMAdapter::GetInstance().GetUdidByNetworkId(peerNetId);
1145     radarReportInfo.stageRes = DFX_SUCCESS;
1146     radarReportInfo.bundleName = appInfo.bundleName;
1147     radarReportInfo.description = data.GetReportDescription();
1148     radarReportInfo.pasteInfo.onlineDevNum = DMAdapter::GetInstance().GetNetworkIds().size();
1149     radarReportInfo.pasteInfo.peerNetId = PasteboardDfxUntil::GetAnonymousID(peerNetId);
1150     radarReportInfo.pasteInfo.peerUdid = PasteboardDfxUntil::GetAnonymousID(peerUdid);
1151     radarReportInfo.pasteInfo.peerBundleName = data.GetOriginAuthority().first;
1152     radarReportInfo.pasteInfo.isPeerOnline = isPeerOnline;
1153 }
1154 
SetUeEvent(const AppInfo & appInfo,PasteData & data,bool isPeerOnline,UeReportInfo & ueReportInfo,const std::string & peerNetId)1155 void PasteboardService::SetUeEvent(const AppInfo &appInfo, PasteData &data, bool isPeerOnline,
1156     UeReportInfo &ueReportInfo, const std::string &peerNetId)
1157 {
1158     DmDeviceInfo remoteDevice;
1159     auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(peerNetId, remoteDevice);
1160     if (ret == static_cast<int32_t>(PasteboardError::E_OK)) {
1161         DeviceManager::GetInstance().GetNetworkTypeByNetworkId(PASTEBOARD_SERVICE_SA_NAME, peerNetId,
1162             ueReportInfo.pasteInfo.networkType);
1163     }
1164     ueReportInfo.bundleName = appInfo.bundleName;
1165     ueReportInfo.pasteInfo.peerBundleName = data.GetOriginAuthority().first;
1166     ueReportInfo.pasteInfo.isDistributed = data.IsRemote();
1167     ueReportInfo.pasteInfo.isPeerOnline = isPeerOnline;
1168     ueReportInfo.pasteInfo.onlineDevNum = DMAdapter::GetInstance().GetNetworkIds().size();
1169     ueReportInfo.description = data.GetReportDescription();
1170 }
1171 
GetPasteData(int & fd,int64_t & size,std::vector<uint8_t> & rawData,const std::string & pasteId,int32_t & syncTime)1172 int32_t PasteboardService::GetPasteData(int &fd, int64_t &size, std::vector<uint8_t> &rawData,
1173     const std::string &pasteId, int32_t &syncTime)
1174 {
1175     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(PasteData::IsValidPasteId(pasteId),
1176         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
1177         "Parameter error. invalid pasteId=%{public}s", pasteId.c_str());
1178     UeReportInfo ueReportInfo;
1179     int32_t ret = GetPasteDataInner(fd, size, rawData, pasteId, syncTime, ueReportInfo);
1180     ueReportInfo.ret = (ret == static_cast<int32_t>(PasteboardError::E_OK) ? E_OK_OPERATION : ret);
1181     ueReportInfo.commonInfo = GetCommonState(size);
1182     UE_REPORT(UE_PASTE, ueReportInfo,
1183         "PEER_BUNDLE_NAME", ueReportInfo.pasteInfo.peerBundleName,
1184         "IS_DISTRIBUTED", ueReportInfo.pasteInfo.isDistributed,
1185         "IS_PEER_ONLINE", ueReportInfo.pasteInfo.isPeerOnline,
1186         "ONLINE_DEV_NUM", ueReportInfo.pasteInfo.onlineDevNum,
1187         "NETWORK_TYPE", ueReportInfo.pasteInfo.networkType);
1188     return ret;
1189 }
1190 
GetPasteDataInner(int & fd,int64_t & size,std::vector<uint8_t> & rawData,const std::string & pasteId,int32_t & syncTime,UeReportInfo & ueReportInfo)1191 int32_t PasteboardService::GetPasteDataInner(int &fd, int64_t &size, std::vector<uint8_t> &rawData,
1192     const std::string &pasteId, int32_t &syncTime, UeReportInfo &ueReportInfo)
1193 {
1194     PasteboardTrace tracer("PasteboardService GetPasteData");
1195     PasteData data{};
1196     data.SetPasteId(pasteId);
1197     auto tokenId = IPCSkeleton::GetCallingTokenID();
1198     auto callPid = IPCSkeleton::GetCallingPid();
1199     auto appInfo = GetAppInfo(tokenId);
1200     bool developerMode = OHOS::system::GetBoolParameter("const.security.developermode.state", false);
1201     bool isTestServerSetPasteData = developerMode && setPasteDataUId_ == TEST_SERVER_UID;
1202     if (!VerifyPermission(tokenId) && !isTestServerSetPasteData) {
1203         RADAR_REPORT(DFX_GET_PASTEBOARD, DFX_CHECK_GET_AUTHORITY, DFX_SUCCESS, GET_DATA_APP, appInfo.bundleName,
1204             RadarReporter::CONCURRENT_ID, data.GetPasteId());
1205         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "check permission failed, callingPid is %{public}d", callPid);
1206         HiViewAdapter::ReportUseBehaviour(data, HiViewAdapter::PASTE_STATE,
1207             static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR));
1208         return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
1209     }
1210     bool isPeerOnline = false;
1211     std::string peerNetId = "";
1212     std::string peerUdid = "";
1213     RadarReportInfo radarReportInfo;
1214     radarReportInfo.pasteInfo.pasteId = data.GetPasteId();
1215     auto ret = GetData(tokenId, data, syncTime, isPeerOnline, peerNetId, peerUdid);
1216     SetUeEvent(appInfo, data, isPeerOnline, ueReportInfo, peerNetId);
1217     SetRadarEvent(appInfo, data, isPeerOnline, radarReportInfo, peerNetId);
1218     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1219         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1220             "data is invalid, ret is %{public}d, callPid is %{public}d, tokenId is %{public}d", ret, callPid, tokenId);
1221         HiViewAdapter::ReportUseBehaviour(data, HiViewAdapter::PASTE_STATE, ret);
1222         radarReportInfo.commonInfo = GetCommonState(-1);
1223         PASTE_RADAR_REPORT(DFX_GET_PASTEBOARD, DFX_GET_DATA_INFO, radarReportInfo);
1224         return ret;
1225     }
1226     delayDataId_ = data.GetDataId();
1227     delayTokenId_ = tokenId;
1228 
1229     ret = DealData(fd, size, rawData, data);
1230     radarReportInfo.commonInfo = GetCommonState(size);
1231     PASTE_RADAR_REPORT(DFX_GET_PASTEBOARD, DFX_GET_DATA_INFO, radarReportInfo);
1232     return ret;
1233 }
1234 
DealData(int & fd,int64_t & size,std::vector<uint8_t> & rawData,PasteData & data)1235 int32_t PasteboardService::DealData(int &fd, int64_t &size, std::vector<uint8_t> &rawData, PasteData &data)
1236 {
1237     std::vector<uint8_t> pasteDataTlv(0);
1238     {
1239         std::shared_lock<std::shared_mutex> read(pasteDataMutex_);
1240         if (!data.Encode(pasteDataTlv)) {
1241             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Failed to encode pastedata in TLV");
1242             HiViewAdapter::ReportUseBehaviour(data, HiViewAdapter::PASTE_STATE, ERR_INVALID_VALUE);
1243             return static_cast<int32_t>(PasteboardError::SERIALIZATION_ERROR);
1244         }
1245     }
1246     int64_t tlvSize = static_cast<int64_t>(pasteDataTlv.size());
1247     int serviceFd = -1;
1248     if (tlvSize > MIN_ASHMEM_DATA_SIZE) {
1249         bool res = WriteRawData(pasteDataTlv.data(), tlvSize, serviceFd);
1250         if (!res) {
1251             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Failed to WriteRawData:%{public}" PRId64, tlvSize);
1252             return static_cast<int32_t>(PasteboardError::SERIALIZATION_ERROR);
1253         }
1254         pasteDataTlv.clear();
1255     } else {
1256         serviceFd = AshmemCreate("DealData Ashmem", 1);
1257         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(serviceFd >= 0,
1258             static_cast<int32_t>(PasteboardError::SERIALIZATION_ERROR),
1259             PASTEBOARD_MODULE_SERVICE, "create fd failed");
1260     }
1261     size = tlvSize;
1262     fd = serviceFd;
1263     rawData = std::move(pasteDataTlv);
1264     HiViewAdapter::ReportUseBehaviour(data, HiViewAdapter::PASTE_STATE, ERR_OK);
1265     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "DealData fd:%{public}d, size:%{public}" PRId64, fd, size);
1266     return ERR_OK;
1267 }
1268 
AddPermissionRecord(uint32_t tokenId,bool isReadGrant,bool isSecureGrant)1269 void PasteboardService::AddPermissionRecord(uint32_t tokenId, bool isReadGrant, bool isSecureGrant)
1270 {
1271     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) {
1272         return;
1273     }
1274     bool isGrant = isReadGrant || isSecureGrant;
1275     if (!isGrant) {
1276         return;
1277     }
1278     auto permUsedType = static_cast<PermissionUsedType>(AccessTokenKit::GetPermissionUsedType(
1279         tokenId, isSecureGrant ? SECURE_PASTE_PERMISSION : READ_PASTEBOARD_PERMISSION));
1280     AddPermParamInfo info;
1281     info.tokenId = tokenId;
1282     info.permissionName = READ_PASTEBOARD_PERMISSION;
1283     info.successCount = 1;
1284     info.failCount = 0;
1285     info.type = permUsedType;
1286     int32_t result = PrivacyKit::AddPermissionUsedRecord(info);
1287     if (result != RET_SUCCESS) {
1288         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "add record failed, result is %{public}d", result);
1289     }
1290     return;
1291 }
1292 
CheckAndGrantRemoteUri(PasteData & data,const AppInfo & appInfo,const std::string & pasteId,const std::string & deviceId,std::shared_ptr<BlockObject<int32_t>> pasteBlock)1293 int32_t PasteboardService::CheckAndGrantRemoteUri(PasteData &data, const AppInfo &appInfo,
1294     const std::string &pasteId, const std::string &deviceId, std::shared_ptr<BlockObject<int32_t>> pasteBlock)
1295 {
1296     int64_t fileSize = data.GetFileSize();
1297     bool isRemoteData = data.IsRemote();
1298     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "fileSize=%{public}" PRId64 ", isRemote=%{public}d", fileSize,
1299         static_cast<int>(isRemoteData));
1300     GetPasteDataDot(data, appInfo.bundleName);
1301     std::vector<Uri> grantUris = CheckUriPermission(data, std::make_pair(appInfo.bundleName, appInfo.appIndex));
1302     if (isRemoteData) {
1303         data.SetPasteId(pasteId);
1304         data.deviceId_ = deviceId;
1305         if (pasteBlock) {
1306             if (!grantUris.empty()) {
1307                 pasteBlock->GetValue();
1308                 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "wait P2PEstablish finish");
1309             } else {
1310                 PasteComplete(deviceId, pasteId);
1311             }
1312         }
1313     }
1314     ClearP2PEstablishTaskInfo();
1315     return GrantUriPermission(grantUris, appInfo.bundleName, isRemoteData, appInfo.appIndex);
1316 }
1317 
GetData(uint32_t tokenId,PasteData & data,int32_t & syncTime,bool & isPeerOnline,std::string & peerNetId,std::string & peerUdid)1318 int32_t PasteboardService::GetData(uint32_t tokenId, PasteData &data, int32_t &syncTime, bool &isPeerOnline,
1319     std::string &peerNetId, std::string &peerUdid)
1320 {
1321     CalculateTimeConsuming::SetBeginTime();
1322     auto appInfo = GetAppInfo(tokenId);
1323     int32_t result = static_cast<int32_t>(PasteboardError::E_OK);
1324     std::string pasteId = data.GetPasteId();
1325     std::shared_ptr<BlockObject<int32_t>> pasteBlock = nullptr;
1326     auto [distRet, distEvt] = GetValidDistributeEvent(appInfo.userId);
1327     pasteBlock = EstablishP2PLinkTask(pasteId, distEvt);
1328     if (distRet != static_cast<int32_t>(PasteboardError::E_OK) ||
1329         GetCurrentScreenStatus() != ScreenEvent::ScreenUnlocked) {
1330         result = GetLocalData(appInfo, data);
1331         if (distRet == static_cast<int32_t>(PasteboardError::GET_SAME_REMOTE_DATA)) {
1332             peerNetId = currentEvent_.deviceId;
1333             peerUdid = DMAdapter::GetInstance().GetUdidByNetworkId(peerNetId);
1334         }
1335     } else {
1336         result = GetRemoteData(appInfo.userId, distEvt, data, syncTime);
1337         peerNetId = distEvt.deviceId;
1338         peerUdid = DMAdapter::GetInstance().GetUdidByNetworkId(peerNetId);
1339     }
1340     if (observerEventMap_.size() != 0) {
1341         std::string targetBundleName = GetAppBundleName(appInfo);
1342         NotifyObservers(targetBundleName, appInfo.userId, PasteboardEventStatus::PASTEBOARD_READ);
1343     }
1344     if (!peerNetId.empty()) {
1345         auto peerNetIds = DMAdapter::GetInstance().GetNetworkIds();
1346         auto it = std::find(peerNetIds.begin(), peerNetIds.end(), peerNetId);
1347         isPeerOnline = (it != peerNetIds.end());
1348     }
1349 
1350     if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
1351         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get local or remote data err:%{public}d", result);
1352         if (pasteBlock) {
1353             PasteComplete(distEvt.deviceId, pasteId);
1354         }
1355         ClearP2PEstablishTaskInfo();
1356         return result;
1357     }
1358     return CheckAndGrantRemoteUri(data, appInfo, pasteId, distEvt.deviceId, pasteBlock);
1359 }
1360 
GetRemoteDataTask(const Event & event)1361 PasteboardService::RemoteDataTaskManager::DataTask PasteboardService::RemoteDataTaskManager::GetRemoteDataTask(
1362     const Event &event)
1363 {
1364     auto key = event.deviceId + std::to_string(event.seqId);
1365     std::lock_guard<std::mutex> lock(mutex_);
1366     auto it = dataTasks_.find(key);
1367     if (it == dataTasks_.end()) {
1368         it = dataTasks_.emplace(key, std::make_shared<TaskContext>()).first;
1369     }
1370 
1371     if (it == dataTasks_.end()) {
1372         return std::make_pair(nullptr, false);
1373     }
1374 
1375     return std::make_pair(it->second, it->second->pasting_.exchange(true));
1376 }
1377 
Notify(const Event & event,std::shared_ptr<PasteDateTime> data)1378 void PasteboardService::RemoteDataTaskManager::Notify(const Event &event, std::shared_ptr<PasteDateTime> data)
1379 {
1380     auto key = event.deviceId + std::to_string(event.seqId);
1381     std::lock_guard<std::mutex> lock(mutex_);
1382     auto it = dataTasks_.find(key);
1383     if (it == dataTasks_.end()) {
1384         return;
1385     }
1386     auto &task = it->second;
1387     task->data_ = data;
1388     task->getDataBlocks_.ForEach([](const auto &key, auto value) -> bool {
1389         value->SetValue(true);
1390         return false;
1391     });
1392 }
1393 
WaitRemoteData(const Event & event)1394 std::shared_ptr<PasteDateTime> PasteboardService::RemoteDataTaskManager::WaitRemoteData(const Event &event)
1395 {
1396     std::shared_ptr<PasteboardService::RemoteDataTaskManager::TaskContext> task;
1397     {
1398         auto key = event.deviceId + std::to_string(event.seqId);
1399         std::lock_guard<std::mutex> lock(mutex_);
1400         auto it = dataTasks_.find(key);
1401         if (it == dataTasks_.end()) {
1402             return nullptr;
1403         }
1404 
1405         task = it->second;
1406     }
1407 
1408     auto key = ++mapKey_;
1409     auto block = std::make_shared<BlockObject<bool>>(GET_REMOTE_DATA_WAIT_TIME);
1410     task->getDataBlocks_.InsertOrAssign(key, block);
1411     block->GetValue();
1412 
1413     task->getDataBlocks_.Erase(key);
1414     return task->data_;
1415 }
1416 
ClearRemoteDataTask(const Event & event)1417 void PasteboardService::RemoteDataTaskManager::ClearRemoteDataTask(const Event &event)
1418 {
1419     auto key = event.deviceId + std::to_string(event.seqId);
1420     std::lock_guard<std::mutex> lock(mutex_);
1421     dataTasks_.erase(key);
1422 }
1423 
GetRemoteData(int32_t userId,const Event & event,PasteData & data,int32_t & syncTime)1424 int32_t PasteboardService::GetRemoteData(int32_t userId, const Event &event, PasteData &data, int32_t &syncTime)
1425 {
1426     syncTime = -1;
1427     auto [task, isPasting] = taskMgr_.GetRemoteDataTask(event);
1428     if (task == nullptr) {
1429         return static_cast<int32_t>(PasteboardError::REMOTE_TASK_ERROR);
1430     }
1431 
1432     if (isPasting) {
1433         auto value = taskMgr_.WaitRemoteData(event);
1434         if (value != nullptr && value->data != nullptr) {
1435             syncTime = value->syncTime;
1436             data = *(value->data);
1437             return static_cast<int32_t>(PasteboardError::E_OK);
1438         }
1439         return static_cast<int32_t>(PasteboardError::TASK_PROCESSING);
1440     }
1441 
1442     auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1443     if (distRet != static_cast<int32_t>(PasteboardError::E_OK) || !(distEvt == event)) {
1444         int32_t ret = distRet == static_cast<int32_t>(PasteboardError::E_OK) ?
1445             static_cast<int32_t>(PasteboardError::INVALID_EVENT_ERROR) : distRet;
1446         auto it = clips_.Find(userId);
1447         if (it.first) {
1448             data = *it.second;
1449             ret = static_cast<int32_t>(PasteboardError::E_OK);
1450         }
1451         taskMgr_.ClearRemoteDataTask(event);
1452         return ret;
1453     }
1454 
1455     return GetRemotePasteData(userId, event, data, syncTime);
1456 }
1457 
GetRemotePasteData(int32_t userId,const Event & event,PasteData & data,int32_t & syncTime)1458 int32_t PasteboardService::GetRemotePasteData(int32_t userId, const Event &event, PasteData &data, int32_t &syncTime)
1459 {
1460     auto block = std::make_shared<BlockObject<std::shared_ptr<PasteDateTime>>>(GET_REMOTE_DATA_WAIT_TIME);
1461     std::thread thread([this, event, block, userId]() mutable {
1462         auto result = GetDistributedData(event, userId);
1463         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1464         std::shared_ptr<PasteDateTime> pasteDataTime = std::make_shared<PasteDateTime>();
1465         if (result.first != nullptr) {
1466             result.first->SetRemote(true);
1467             if (distEvt == event) {
1468                 clips_.InsertOrAssign(userId, result.first);
1469                 IncreaseChangeCount(userId);
1470                 auto curTime =
1471                     static_cast<uint64_t>(PasteBoardTime::GetBootTimeMs());
1472                 copyTime_.InsertOrAssign(userId, curTime);
1473             }
1474             pasteDataTime->syncTime = result.second.syncTime;
1475             pasteDataTime->data = result.first;
1476             pasteDataTime->errorCode = result.second.errorCode;
1477             taskMgr_.Notify(event, pasteDataTime);
1478         } else {
1479             pasteDataTime->data = nullptr;
1480             pasteDataTime->errorCode = result.second.errorCode;
1481             taskMgr_.Notify(event, pasteDataTime);
1482         }
1483         block->SetValue(pasteDataTime);
1484         taskMgr_.ClearRemoteDataTask(event);
1485     });
1486     thread.detach();
1487     auto value = block->GetValue();
1488     if (value != nullptr && value->data != nullptr) {
1489         syncTime = value->syncTime;
1490         data = std::move(*(value->data));
1491         return value->errorCode;
1492     } else if (value != nullptr && value->data == nullptr) {
1493         return value->errorCode;
1494     }
1495     return static_cast<int32_t>(PasteboardError::TIMEOUT_ERROR);
1496 }
1497 
GetLocalData(const AppInfo & appInfo,PasteData & data)1498 int32_t PasteboardService::GetLocalData(const AppInfo &appInfo, PasteData &data)
1499 {
1500     std::string pasteId = data.GetPasteId();
1501     auto it = clips_.Find(appInfo.userId);
1502     auto tempTime = copyTime_.Find(appInfo.userId);
1503     if (!it.first || !tempTime.first) {
1504         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "no data userId is %{public}d.", appInfo.userId);
1505         return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
1506     }
1507     auto ret = IsDataValid(*(it.second), appInfo.tokenId);
1508     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1509         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "paste data is invalid. ret = %{public}d "
1510             "appInfo.userId = %{public}d", ret, appInfo.userId);
1511         return ret;
1512     }
1513     data = *(it.second);
1514     auto originBundleName = it.second->GetBundleName();
1515     if (it.second->IsDelayData()) {
1516         GetDelayPasteData(appInfo.userId, data);
1517         RADAR_REPORT(DFX_GET_PASTEBOARD, DFX_CHECK_GET_DELAY_PASTE, DFX_SUCCESS, CONCURRENT_ID, pasteId);
1518     }
1519     if (it.second->IsDelayRecord()) {
1520         GetDelayPasteRecord(appInfo.userId, data);
1521     }
1522     data.SetBundleInfo(appInfo.bundleName, appInfo.appIndex);
1523     auto result = copyTime_.Find(appInfo.userId);
1524     if (!result.first) {
1525         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId not found userId is %{public}d", appInfo.userId);
1526         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
1527     }
1528     auto curTime = result.second;
1529     if (tempTime.second == curTime) {
1530         bool isNotify = false;
1531         clips_.ComputeIfPresent(appInfo.userId, [&data, &isNotify](auto &key, auto &value) {
1532             if (value->IsDelayData()) {
1533                 value = std::make_shared<PasteData>(data);
1534                 isNotify = true;
1535             }
1536             if (value->IsDelayRecord()) {
1537                 value = std::make_shared<PasteData>(data);
1538             }
1539             return true;
1540         });
1541         if (isNotify) {
1542             NotifyObservers(originBundleName, appInfo.userId, PasteboardEventStatus::PASTEBOARD_WRITE);
1543         }
1544     }
1545     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "GetPasteData success. appInfo.userId = %{public}d", appInfo.userId);
1546     SetLocalPasteFlag(data.IsRemote(), appInfo.tokenId, data);
1547     return static_cast<int32_t>(PasteboardError::E_OK);
1548 }
1549 
GetDelayPasteData(int32_t userId,PasteData & data)1550 void PasteboardService::GetDelayPasteData(int32_t userId, PasteData &data)
1551 {
1552     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "get delay data start");
1553     delayGetters_.ComputeIfPresent(userId, [this, &data](auto, auto &delayGetter) {
1554         PasteData delayData;
1555         if (delayGetter.first != nullptr) {
1556             delayGetter.first->GetPasteData("", delayData);
1557         }
1558         if (delayGetter.second != nullptr) {
1559             delayGetter.first->AsObject()->RemoveDeathRecipient(delayGetter.second);
1560         }
1561         delayData.SetDelayData(false);
1562         delayData.SetBundleInfo(data.GetBundleName(), data.GetAppIndex());
1563         delayData.SetOriginAuthority(data.GetOriginAuthority());
1564         delayData.SetTime(data.GetTime());
1565         delayData.SetTokenId(data.GetTokenId());
1566         PasteboardWebController::GetInstance().SplitWebviewPasteData(delayData);
1567         PasteboardWebController::GetInstance().SetWebviewPasteData(delayData, data.GetOriginAuthority());
1568         PasteboardWebController::GetInstance().CheckAppUriPermission(delayData);
1569         data = delayData;
1570         return false;
1571     });
1572 }
1573 
GetDelayPasteRecord(int32_t userId,PasteData & data)1574 int32_t PasteboardService::GetDelayPasteRecord(int32_t userId, PasteData &data)
1575 {
1576     auto [hasGetter, getter] = entryGetters_.Find(userId);
1577     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasGetter && getter.first,
1578         static_cast<int32_t>(PasteboardError::NO_DELAY_GETTER), PASTEBOARD_MODULE_SERVICE,
1579         "entry getter not find, userId=%{public}d, dataId=%{public}u", userId, data.GetDataId());
1580 
1581     for (auto record : data.AllRecords()) {
1582         if (!(record->HasEmptyEntry())) {
1583             PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "record do not has empty value.");
1584             continue;
1585         }
1586         if (!record->IsDelayRecord()) {
1587             PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "record is not DelayRecord.");
1588             continue;
1589         }
1590         auto entries = record->GetEntries();
1591         if (entries.empty()) {
1592             PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "record size is 0.");
1593             continue;
1594         }
1595         if (!std::holds_alternative<std::monostate>(entries[0]->GetValue())) {
1596             continue;
1597         }
1598         auto result = getter.first->GetRecordValueByType(record->GetRecordId(), *entries[0]);
1599         if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
1600             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1601                 "get record value fail, dataId is %{public}d, recordId is %{public}d", data.GetDataId(),
1602                 record->GetRecordId());
1603             continue;
1604         }
1605         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
1606         record->AddEntry(entries[0]->GetUtdId(), entries[0]);
1607     }
1608     {
1609         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
1610         PasteboardWebController::GetInstance().SplitWebviewPasteData(data);
1611     }
1612     PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
1613     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
1614     return static_cast<int32_t>(PasteboardError::E_OK);
1615 }
1616 
ClearP2PEstablishTaskInfo()1617 void PasteboardService::ClearP2PEstablishTaskInfo()
1618 {
1619     std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1620     p2pEstablishInfo_.networkId.clear();
1621     p2pEstablishInfo_.pasteBlock = nullptr;
1622 }
1623 
OpenP2PLink(const std::string & networkId)1624 void PasteboardService::OpenP2PLink(const std::string &networkId)
1625 {
1626     DmDeviceInfo remoteDevice;
1627     auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(networkId, remoteDevice);
1628     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1629         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist");
1630         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1631         p2pMap_.Erase(networkId);
1632         return;
1633     }
1634     auto plugin = GetClipPlugin();
1635     if (plugin == nullptr) {
1636         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "plugin is not exist");
1637         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1638         p2pMap_.Erase(networkId);
1639         return;
1640     }
1641     auto status = DistributedFileDaemonManager::GetInstance().OpenP2PConnection(remoteDevice);
1642     if (status != RESULT_OK) {
1643         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "open p2p error, status:%{public}d", status);
1644         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1645         p2pMap_.Erase(networkId);
1646         return;
1647     }
1648     status = plugin->PublishServiceState(networkId, ClipPlugin::ServiceStatus::CONNECT_SUCC);
1649     if (status != RESULT_OK) {
1650         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Publish state connect_succ error, status:%{public}d", status);
1651     }
1652 }
1653 
EstablishP2PLink(const std::string & networkId,const std::string & pasteId)1654 void PasteboardService::EstablishP2PLink(const std::string &networkId, const std::string &pasteId)
1655 {
1656 #ifdef PB_DEVICE_MANAGER_ENABLE
1657     auto callPid = IPCSkeleton::GetCallingPid();
1658     {
1659         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1660         p2pMap_.Compute(networkId, [pasteId, callPid](const auto &key, auto &value) {
1661             value.Compute(pasteId, [callPid](const auto &key, auto &value) {
1662                 value = callPid;
1663                 return true;
1664             });
1665             return true;
1666         });
1667     }
1668     if (ffrtTimer_) {
1669         FFRTTask task = [this, networkId, pasteId] {
1670             std::thread thread([=]() {
1671                 PasteComplete(networkId, pasteId);
1672             });
1673             thread.detach();
1674         };
1675         ffrtTimer_->SetTimer(pasteId, task, MIN_TRANMISSION_TIME);
1676     }
1677     OpenP2PLink(networkId);
1678 #endif
1679 }
1680 
CheckAndReuseP2PLink(const std::string & networkId,const std::string & pasteId)1681 std::shared_ptr<BlockObject<int32_t>> PasteboardService::CheckAndReuseP2PLink(
1682     const std::string &networkId, const std::string &pasteId)
1683 {
1684 #ifdef PB_DEVICE_MANAGER_ENABLE
1685     auto callPid = IPCSkeleton::GetCallingPid();
1686     std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1687     p2pMap_.Compute(networkId, [pasteId, callPid](const auto &key, auto &value) {
1688         value.Compute(pasteId, [callPid](const auto &key, auto &value) {
1689             value = callPid;
1690             return true;
1691         });
1692         return true;
1693     });
1694     if (ffrtTimer_) {
1695         FFRTTask task = [this, networkId, pasteId] {
1696             std::thread thread([=]() {
1697                 PasteComplete(networkId, pasteId);
1698             });
1699             thread.detach();
1700         };
1701         ffrtTimer_->SetTimer(pasteId, task, MIN_TRANMISSION_TIME);
1702     }
1703     auto p2pNetwork = p2pMap_.Find(networkId);
1704     if (p2pNetwork.first && p2pNetwork.second.Find(P2P_PRESYNC_ID).first) {
1705         if (ffrtTimer_) {
1706             std::string taskName = P2P_PRESYNC_ID + networkId;
1707             ffrtTimer_->CancelTimer(taskName);
1708         }
1709         p2pMap_.ComputeIfPresent(networkId, [this](const auto &key, auto &value) {
1710             value.ComputeIfPresent(P2P_PRESYNC_ID, [](const auto &key, auto &value) {
1711                 return false;
1712             });
1713             return true;
1714         });
1715         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "No Need P2pEstablish");
1716         std::shared_ptr<BlockObject<int32_t>> result = nullptr;
1717         auto p2pIter = preSyncP2pMap_.find(networkId);
1718         if (p2pIter != preSyncP2pMap_.end()) {
1719             result = p2pIter->second;
1720         }
1721         preSyncP2pMap_.erase(networkId);
1722         return result;
1723     }
1724     return nullptr;
1725 #else
1726     return nullptr;
1727 #endif
1728 }
1729 
IsContainUri(const std::vector<std::string> & dataType)1730 bool PasteboardService::IsContainUri(const std::vector<std::string> &dataType)
1731 {
1732     std::vector<std::string> keyVecs;
1733     keyVecs.push_back(MIMETYPE_TEXT_URI);
1734     keyVecs.push_back(MIMETYPE_TEXT_HTML);
1735     bool result = std::any_of(keyVecs.begin(), keyVecs.end(), [dataType](const std::string &key) {
1736         return std::find(dataType.begin(), dataType.end(), key) != dataType.end();
1737     });
1738     return result;
1739 }
1740 
OnEstablishP2PLinkTask(const std::string & networkId,std::shared_ptr<BlockObject<int32_t>> pasteBlock)1741 void PasteboardService::OnEstablishP2PLinkTask(const std::string &networkId,
1742     std::shared_ptr<BlockObject<int32_t>> pasteBlock)
1743 {
1744     PASTEBOARD_CHECK_AND_RETURN_LOGE(pasteBlock != nullptr, PASTEBOARD_MODULE_SERVICE, "block is nullptr");
1745     OpenP2PLink(networkId);
1746     pasteBlock->SetValue(SET_VALUE_SUCCESS);
1747     std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1748     auto findResult = p2pMap_.Find(networkId);
1749     if (!findResult.first || findResult.second.Empty()) {
1750         CloseP2PLink(networkId);
1751     }
1752     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "P2pEstablish Finish");
1753 }
1754 
EstablishP2PLinkTask(const std::string & pasteId,const ClipPlugin::GlobalEvent & event)1755 std::shared_ptr<BlockObject<int32_t>> PasteboardService::EstablishP2PLinkTask(
1756     const std::string &pasteId, const ClipPlugin::GlobalEvent &event)
1757 {
1758 #ifdef PB_DEVICE_MANAGER_ENABLE
1759     const std::string &networkId = event.deviceId;
1760     if (networkId.empty() || networkId == DMAdapter::GetInstance().GetLocalNetworkId()) {
1761         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "local device");
1762         return nullptr;
1763     }
1764     if (!IsContainUri(event.dataType)) {
1765         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "no MIMETYPE_TEXT_URI and no MIMETYPE_TEXT_HTML");
1766         return nullptr;
1767     }
1768     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "EstablishP2PLinkTask enter");
1769     std::shared_ptr<BlockObject<int32_t>> result = CheckAndReuseP2PLink(networkId, pasteId);
1770     if (result) {
1771         return result;
1772     }
1773     if (!ffrtTimer_) {
1774         return nullptr;
1775     }
1776     std::shared_ptr<BlockObject<int32_t>> pasteBlock = std::make_shared<BlockObject<int32_t>>(MIN_TRANMISSION_TIME, 0);
1777     if (!pasteBlock) {
1778         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "failed to alloc BlockObject");
1779         return nullptr;
1780     }
1781     {
1782         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1783         p2pEstablishInfo_.networkId = networkId;
1784         p2pEstablishInfo_.pasteBlock = pasteBlock;
1785     }
1786     FFRTTask p2pTask = [networkId, pasteBlock, this] {
1787         std::thread thread([=]() {
1788             OnEstablishP2PLinkTask(networkId, pasteBlock);
1789         });
1790         thread.detach();
1791     };
1792     std::string taskName = pasteId + P2P_ESTABLISH_STR;
1793     ffrtTimer_->SetTimer(taskName, p2pTask);
1794     return pasteBlock;
1795 #else
1796     return nullptr;
1797 #endif
1798 }
1799 
CloseP2PLink(const std::string & networkId)1800 void PasteboardService::CloseP2PLink(const std::string &networkId)
1801 {
1802 #ifdef PB_DEVICE_MANAGER_ENABLE
1803     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "CloseP2PLink enter");
1804     DmDeviceInfo remoteDevice;
1805     auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(networkId, remoteDevice);
1806     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1807         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist");
1808         return;
1809     }
1810     auto status = DistributedFileDaemonManager::GetInstance().CloseP2PConnection(remoteDevice);
1811     if (status != RESULT_OK) {
1812         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "close p2p error, status:%{public}d", status);
1813     }
1814     auto plugin = GetClipPlugin();
1815     PASTEBOARD_CHECK_AND_RETURN_LOGE(plugin != nullptr, PASTEBOARD_MODULE_SERVICE, "plugin is not exist");
1816     status = plugin->PublishServiceState(networkId, ClipPlugin::ServiceStatus::IDLE);
1817     if (status != RESULT_OK) {
1818         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Publish state idle error, status:%{public}d", status);
1819     }
1820 #endif
1821 }
1822 
PasteStart(const std::string & pasteId)1823 int32_t PasteboardService::PasteStart(const std::string &pasteId)
1824 {
1825     if (ffrtTimer_) {
1826         ffrtTimer_->CancelTimer(pasteId);
1827     }
1828     return ERR_OK;
1829 }
1830 
PasteComplete(const std::string & deviceId,const std::string & pasteId)1831 int32_t PasteboardService::PasteComplete(const std::string &deviceId, const std::string &pasteId)
1832 {
1833     if (deviceId.empty()) {
1834         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "deviceId is empty");
1835         return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
1836     }
1837     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "deviceId is %{public}.6s, taskId is %{public}s", deviceId.c_str(),
1838         pasteId.c_str());
1839     RADAR_REPORT(RadarReporter::DFX_GET_PASTEBOARD, RadarReporter::DFX_DISTRIBUTED_FILE_END, RadarReporter::DFX_SUCCESS,
1840         RadarReporter::BIZ_STATE, RadarReporter::DFX_END, RadarReporter::CONCURRENT_ID, pasteId);
1841     std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
1842     p2pMap_.ComputeIfPresent(deviceId, [pasteId, deviceId, this](const auto &key, auto &value) {
1843         value.ComputeIfPresent(pasteId, [deviceId](const auto &key, auto &value) {
1844             return false;
1845         });
1846         if (value.Empty()) {
1847             CloseP2PLink(deviceId);
1848             return false;
1849         }
1850         return true;
1851     });
1852     return ERR_OK;
1853 }
1854 
GetRemoteDeviceName(std::string & deviceName,bool & isRemote)1855 int32_t PasteboardService::GetRemoteDeviceName(std::string &deviceName, bool &isRemote)
1856 {
1857     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "enter");
1858     auto tokenId = IPCSkeleton::GetCallingTokenID();
1859     auto appInfo = GetAppInfo(tokenId);
1860     auto event = GetValidDistributeEvent(appInfo.userId);
1861     DmDeviceInfo remoteDevice;
1862     if (!event.second.deviceId.empty()) {
1863         auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(event.second.deviceId, remoteDevice);
1864         if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1865             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist");
1866             return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
1867         }
1868         deviceName = remoteDevice.deviceName;
1869         isRemote = true;
1870     } else {
1871         deviceName = "local";
1872         isRemote = false;
1873     }
1874     if (deviceName.empty()) {
1875         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Failed to get remote device name");
1876         return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
1877     }
1878     return ERR_OK;
1879 }
1880 
GrantUriPermission(const std::vector<Uri> & grantUris,const std::string & targetBundleName,bool isRemoteData,int32_t appIndex)1881 int32_t PasteboardService::GrantUriPermission(const std::vector<Uri> &grantUris, const std::string &targetBundleName,
1882     bool isRemoteData, int32_t appIndex)
1883 {
1884     PASTEBOARD_CHECK_AND_RETURN_RET_LOGD(!grantUris.empty(), static_cast<int32_t>(PasteboardError::E_OK),
1885         PASTEBOARD_MODULE_SERVICE, "no uri");
1886     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri size=%{public}zu, target=%{public}s, appIndex=%{public}d",
1887         grantUris.size(), targetBundleName.c_str(), appIndex);
1888     bool hasGranted = false;
1889     int32_t ret = 0;
1890     size_t offset = 0;
1891     size_t length = grantUris.size();
1892     size_t count = PasteData::URI_BATCH_SIZE;
1893     bool isNeedPersistance = OHOS::system::GetBoolParameter("const.pasteboard.uri_persistable_permission", false);
1894     auto permFlag = AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION;
1895     if (isNeedPersistance && !isRemoteData) {
1896         permFlag |= AAFwk::Want::FLAG_AUTH_WRITE_URI_PERMISSION | AAFwk::Want::FLAG_AUTH_PERSISTABLE_URI_PERMISSION;
1897     }
1898     while (length > offset) {
1899         if (length - offset < PasteData::URI_BATCH_SIZE) {
1900             count = length - offset;
1901         }
1902         auto sendValues = std::vector<Uri>(grantUris.begin() + offset, grantUris.begin() + offset + count);
1903         int32_t permissionCode = AAFwk::UriPermissionManagerClient::GetInstance().GrantUriPermissionPrivileged(
1904             sendValues, permFlag, targetBundleName, appIndex);
1905         hasGranted = hasGranted || (permissionCode == 0);
1906         ret = permissionCode == 0 ? ret : permissionCode;
1907         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "permissionCode is %{public}d", permissionCode);
1908         offset += count;
1909     }
1910     if (hasGranted) {
1911         std::lock_guard<std::mutex> lock(readBundleMutex_);
1912         if (readBundles_.count({ targetBundleName, appIndex }) == 0) {
1913             readBundles_.insert({ targetBundleName, appIndex });
1914         }
1915     }
1916     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "leave, ret=%{public}d", ret);
1917     return ret == 0 ? static_cast<int32_t>(PasteboardError::E_OK) : ret;
1918 }
1919 
CheckUriPermission(PasteData & data,const std::pair<std::string,int32_t> & targetBundleAndIndex)1920 std::vector<Uri> PasteboardService::CheckUriPermission(PasteData &data,
1921     const std::pair<std::string, int32_t> &targetBundleAndIndex)
1922 {
1923     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "enter");
1924     std::vector<Uri> grantUris;
1925     for (size_t i = 0; i < data.GetRecordCount(); i++) {
1926         auto item = data.GetRecordAt(i);
1927         if (item == nullptr || (!data.IsRemote() && targetBundleAndIndex == data.GetOriginAuthority())) {
1928             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "local dev & local app");
1929             continue;
1930         }
1931         std::shared_ptr<OHOS::Uri> uri = nullptr;
1932         if (!item->isConvertUriFromRemote && !item->GetConvertUri().empty()) {
1933             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "clear local disUri");
1934             item->SetConvertUri("");
1935         }
1936         if (item->isConvertUriFromRemote && !item->GetConvertUri().empty()) {
1937             PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "get remote disUri");
1938             uri = std::make_shared<OHOS::Uri>(item->GetConvertUri());
1939         } else if (!item->isConvertUriFromRemote && item->GetOriginUri() != nullptr) {
1940             uri = item->GetOriginUri();
1941         }
1942         if (uri == nullptr) {
1943             continue;
1944         }
1945         auto hasGrantUriPermission = item->HasGrantUriPermission();
1946         const std::string &bundleName = data.GetOriginAuthority().first;
1947         if (!IsBundleOwnUriPermission(bundleName, *uri) && !hasGrantUriPermission) {
1948             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri:%{private}s, bundleName:%{public}s, appIndex:%{public}d,"
1949                 " has grant:%{public}d", uri->ToString().c_str(), bundleName.c_str(), data.GetOriginAuthority().second,
1950                 hasGrantUriPermission);
1951             continue;
1952         }
1953         grantUris.emplace_back(*uri);
1954     }
1955     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "leave, grant:%{public}zu", grantUris.size());
1956     return grantUris;
1957 }
1958 
IsBundleOwnUriPermission(const std::string & bundleName,Uri & uri)1959 bool PasteboardService::IsBundleOwnUriPermission(const std::string &bundleName, Uri &uri)
1960 {
1961     return (bundleName.compare(uri.GetAuthority()) == 0);
1962 }
1963 
ShowHintToast(uint32_t tokenId,uint32_t pid)1964 void PasteboardService::ShowHintToast(uint32_t tokenId, uint32_t pid)
1965 {
1966     PasteBoardDialog::ToastMessageInfo message;
1967     message.appName = GetAppLabel(tokenId);
1968     PasteBoardDialog::GetInstance().ShowToast(message);
1969 }
1970 
HasPasteData(bool & funcResult)1971 int32_t PasteboardService::HasPasteData(bool &funcResult)
1972 {
1973     funcResult = HasPasteData();
1974     return ERR_OK;
1975 }
1976 
HasPasteData()1977 bool PasteboardService::HasPasteData()
1978 {
1979     auto userId = GetCurrentAccountId();
1980     if (userId == ERROR_USERID) {
1981         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
1982         return false;
1983     }
1984 
1985     if (GetCurrentScreenStatus() == ScreenEvent::ScreenUnlocked) {
1986         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
1987         if (distRet == static_cast<int32_t>(PasteboardError::E_OK)) {
1988             return true;
1989         }
1990     }
1991 
1992     auto it = clips_.Find(userId);
1993     if (it.first && (it.second != nullptr)) {
1994         auto tokenId = IPCSkeleton::GetCallingTokenID();
1995         auto ret = IsDataValid(*(it.second), tokenId);
1996         if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
1997             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
1998                 "pasteData is invalid, tokenId: %{public}d, userId: %{public}d,"
1999                 "ret is %{public}d", tokenId, userId, ret);
2000             return false;
2001         }
2002         return true;
2003     }
2004     return false;
2005 }
2006 
SaveData(PasteData & pasteData,int64_t dataSize,const sptr<IPasteboardDelayGetter> delayGetter,const sptr<IPasteboardEntryGetter> entryGetter)2007 int32_t PasteboardService::SaveData(PasteData &pasteData, int64_t dataSize,
2008     const sptr<IPasteboardDelayGetter> delayGetter, const sptr<IPasteboardEntryGetter> entryGetter)
2009 {
2010     PasteboardTrace tracer("PasteboardService, SetPasteData");
2011     auto tokenId = IPCSkeleton::GetCallingTokenID();
2012     if (!IsCopyable(tokenId)) {
2013         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_SET_AUTHORITY, DFX_SUCCESS);
2014         return static_cast<int32_t>(PasteboardError::PROHIBIT_COPY);
2015     }
2016     if (setting_.exchange(true)) {
2017         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "is setting.");
2018         return static_cast<int32_t>(PasteboardError::TASK_PROCESSING);
2019     }
2020     CalculateTimeConsuming::SetBeginTime();
2021     auto appInfo = GetAppInfo(tokenId);
2022     if (appInfo.userId == ERROR_USERID) {
2023         setting_.store(false);
2024         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
2025         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
2026     }
2027     setPasteDataUId_ = IPCSkeleton::GetCallingUid();
2028     RemovePasteData(appInfo);
2029     SetPasteDataInfo(pasteData, appInfo, tokenId);
2030     PasteboardWebController::GetInstance().SetWebviewPasteData(pasteData,
2031         std::make_pair(appInfo.bundleName, appInfo.appIndex));
2032     PasteboardWebController::GetInstance().CheckAppUriPermission(pasteData);
2033     clips_.InsertOrAssign(appInfo.userId, std::make_shared<PasteData>(pasteData));
2034     IncreaseChangeCount(appInfo.userId);
2035     RadarReportInfo radarReportInfo;
2036     radarReportInfo.stageRes = static_cast<int32_t>(pasteData.IsDelayData());
2037     radarReportInfo.bundleName = appInfo.bundleName;
2038     radarReportInfo.description = pasteData.GetReportDescription();
2039     radarReportInfo.commonInfo = GetCommonState(dataSize);
2040     COPY_RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_SET_DELAY_COPY, radarReportInfo);
2041     HandleDelayDataAndRecord(pasteData, delayGetter, entryGetter, appInfo);
2042     auto curTime = static_cast<uint64_t>(PasteBoardTime::GetBootTimeMs());
2043     copyTime_.InsertOrAssign(appInfo.userId, curTime);
2044     if (!(pasteData.IsDelayData())) {
2045         SetDistributedData(appInfo.userId, pasteData);
2046         NotifyObservers(appInfo.bundleName, appInfo.userId, PasteboardEventStatus::PASTEBOARD_WRITE);
2047     }
2048     SetPasteDataDot(pasteData);
2049     setting_.store(false);
2050     SubscribeKeyboardEvent();
2051     return static_cast<int32_t>(PasteboardError::E_OK);
2052 }
2053 
SetPasteDataInfo(PasteData & pasteData,const AppInfo & appInfo,uint32_t tokenId)2054 void PasteboardService::SetPasteDataInfo(PasteData &pasteData, const AppInfo &appInfo, uint32_t tokenId)
2055 {
2056     pasteData.SetBundleInfo(appInfo.bundleName, appInfo.appIndex);
2057     pasteData.SetOriginAuthority(std::make_pair(appInfo.bundleName, appInfo.appIndex));
2058     pasteData.SetTime(GetTime());
2059     pasteData.SetScreenStatus(GetCurrentScreenStatus());
2060     pasteData.SetTokenId(tokenId);
2061     auto dataId = ++dataId_;
2062     pasteData.SetDataId(dataId);
2063     for (auto &record : pasteData.AllRecords()) {
2064         record->SetDataId(dataId);
2065     }
2066 }
2067 
HandleDelayDataAndRecord(PasteData & pasteData,const sptr<IPasteboardDelayGetter> delayGetter,const sptr<IPasteboardEntryGetter> entryGetter,const AppInfo & appInfo)2068 void PasteboardService::HandleDelayDataAndRecord(PasteData &pasteData, const sptr<IPasteboardDelayGetter> delayGetter,
2069     const sptr<IPasteboardEntryGetter> entryGetter, const AppInfo &appInfo)
2070 {
2071     if (pasteData.IsDelayData() && delayGetter != nullptr) {
2072         sptr<DelayGetterDeathRecipient> deathRecipient = new (std::nothrow)
2073             DelayGetterDeathRecipient(appInfo.userId, *this);
2074         delayGetter->AsObject()->AddDeathRecipient(deathRecipient);
2075         delayGetters_.InsertOrAssign(appInfo.userId, std::make_pair(delayGetter, deathRecipient));
2076     }
2077     if (pasteData.IsDelayRecord() && entryGetter != nullptr) {
2078         sptr<EntryGetterDeathRecipient> deathRecipient = new (std::nothrow)
2079             EntryGetterDeathRecipient(appInfo.userId, *this);
2080         entryGetter->AsObject()->AddDeathRecipient(deathRecipient);
2081         entryGetters_.InsertOrAssign(appInfo.userId, std::make_pair(entryGetter, deathRecipient));
2082     }
2083 }
2084 
IsBasicType(const std::string & mimeType)2085 bool PasteboardService::IsBasicType(const std::string &mimeType)
2086 {
2087     if (mimeType == MIMETYPE_TEXT_HTML || mimeType == MIMETYPE_TEXT_PLAIN || mimeType == MIMETYPE_TEXT_URI) {
2088         return true;
2089     }
2090     return false;
2091 }
2092 
GetMimeTypes(std::vector<std::string> & funcResult)2093 int32_t PasteboardService::GetMimeTypes(std::vector<std::string> &funcResult)
2094 {
2095     if (GetCurrentScreenStatus() == ScreenEvent::ScreenUnlocked) {
2096         auto userId = GetCurrentAccountId();
2097         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
2098         if (distRet == static_cast<int32_t>(PasteboardError::E_OK)) {
2099             PasteData data;
2100             int32_t syncTime = 0;
2101             int32_t ret = GetRemoteData(userId, distEvt, data, syncTime);
2102             PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK),
2103                 static_cast<int32_t>(PasteboardError::GET_REMOTE_DATA_ERROR),
2104                 PASTEBOARD_MODULE_SERVICE, "get remote data failed, ret=%{public}d", ret);
2105         }
2106     }
2107     funcResult = GetLocalMimeTypes();
2108     return ERR_OK;
2109 }
2110 
HasDataType(const std::string & mimeType,bool & funcResult)2111 int32_t PasteboardService::HasDataType(const std::string &mimeType, bool &funcResult)
2112 {
2113     auto ret = PasteBoardCommon::IsValidMimeType(mimeType);
2114     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret, static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR),
2115         PASTEBOARD_MODULE_SERVICE, "Parameter error. MimeType size=%{public}zu.", mimeType.size());
2116     funcResult = HasDataType(mimeType);
2117     return ERR_OK;
2118 }
2119 
HasDataType(const std::string & mimeType)2120 bool PasteboardService::HasDataType(const std::string &mimeType)
2121 {
2122     if (GetCurrentScreenStatus() == ScreenEvent::ScreenUnlocked) {
2123         auto userId = GetCurrentAccountId();
2124         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
2125         if (distRet == static_cast<int32_t>(PasteboardError::E_OK)) {
2126             auto it = std::find(distEvt.dataType.begin(), distEvt.dataType.end(), mimeType);
2127             if (it != distEvt.dataType.end()) {
2128                 return true;
2129             }
2130             if (IsBasicType(mimeType)) {
2131                 return false;
2132             }
2133             PasteData data;
2134             int32_t syncTime = 0;
2135             if (GetRemoteData(userId, distEvt, data, syncTime) != static_cast<int32_t>(PasteboardError::E_OK)) {
2136                 return false;
2137             }
2138         }
2139     }
2140     return HasLocalDataType(mimeType);
2141 }
2142 
DetectPatterns(const std::vector<Pattern> & patternsToCheck,std::vector<Pattern> & funcResult)2143 int32_t PasteboardService::DetectPatterns(const std::vector<Pattern> &patternsToCheck,
2144     std::vector<Pattern> &funcResult)
2145 {
2146     bool hasPlain = HasLocalDataType(MIMETYPE_TEXT_PLAIN);
2147     bool hasHTML = HasLocalDataType(MIMETYPE_TEXT_HTML);
2148     if (!hasHTML && !hasPlain) {
2149         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "no text");
2150         std::vector<Pattern>().swap(funcResult);
2151         return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
2152     }
2153     int32_t userId = GetCurrentAccountId();
2154     auto it = clips_.Find(userId);
2155     if (!it.first) {
2156         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "error, no PasteData!");
2157         std::vector<Pattern>().swap(funcResult);
2158         return static_cast<int32_t>(PasteboardError::NO_DATA_ERROR);
2159     }
2160     std::shared_ptr<PasteData> pasteData = it.second;
2161     const std::set<Pattern> patterns(patternsToCheck.begin(), patternsToCheck.end());
2162     std::set<Pattern> result = {};
2163     result = OHOS::MiscServices::PatternDetection::Detect(patterns, *pasteData, hasHTML, hasPlain);
2164     funcResult.assign(result.begin(), result.end());
2165     return ERR_OK;
2166 }
2167 
GetValidDistributeEvent(int32_t user)2168 std::pair<int32_t, ClipPlugin::GlobalEvent> PasteboardService::GetValidDistributeEvent(int32_t user)
2169 {
2170     Event evt;
2171     auto plugin = GetClipPlugin();
2172     if (plugin == nullptr) {
2173         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "plugin is null");
2174         return std::make_pair(static_cast<int32_t>(PasteboardError::PLUGIN_IS_NULL), evt);
2175     }
2176     auto events = plugin->GetTopEvents(1, user);
2177     if (events.empty()) {
2178         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "plugin event is empty");
2179         return std::make_pair(static_cast<int32_t>(PasteboardError::PLUGIN_EVENT_EMPTY), evt);
2180     }
2181 
2182     evt = events[0];
2183     if (evt.deviceId == DMAdapter::GetInstance().GetLocalNetworkId() || evt.expiration < currentEvent_.expiration) {
2184         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get local data");
2185         return std::make_pair(static_cast<int32_t>(PasteboardError::GET_LOCAL_DATA), evt);
2186     }
2187     if (evt.account != AccountManager::GetInstance().GetCurrentAccount()) {
2188         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "account error");
2189         return std::make_pair(static_cast<int32_t>(PasteboardError::INVALID_EVENT_ACCOUNT), evt);
2190     }
2191     DmDeviceInfo remoteDevice;
2192     int32_t ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(evt.deviceId, remoteDevice);
2193     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
2194         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "deviceId: %{public}.6s is offline", evt.deviceId.c_str());
2195         return std::make_pair(ret, evt);
2196     }
2197 
2198     if (evt.deviceId == currentEvent_.deviceId && evt.seqId == currentEvent_.seqId &&
2199         evt.expiration == currentEvent_.expiration) {
2200         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get same remote data");
2201         return std::make_pair(static_cast<int32_t>(PasteboardError::GET_SAME_REMOTE_DATA), evt);
2202     }
2203 
2204     uint64_t curTime =
2205         static_cast<uint64_t>(PasteBoardTime::GetBootTimeMs());
2206     ret = evt.status == ClipPlugin::EVT_NORMAL ? ret : static_cast<int32_t>(PasteboardError::INVALID_EVENT_STATUS);
2207     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE((curTime != 0 && evt.expiration != EXPIRATION_INTERVAL),
2208         std::make_pair(static_cast<int32_t>(PasteboardError::GET_BOOTTIME_FAILED), evt),
2209         PASTEBOARD_MODULE_SERVICE, "Failed to get the time."
2210         "expiration = %{public}" PRIu64 ", curTime = %{public}" PRIu64, evt.expiration, curTime);
2211     ret = curTime < evt.expiration ? ret : static_cast<int32_t>(PasteboardError::DATA_EXPIRED_ERROR);
2212     return std::make_pair(ret, evt);
2213 }
2214 
GetLocalMimeTypes()2215 std::vector<std::string> PasteboardService::GetLocalMimeTypes()
2216 {
2217     auto userId = GetCurrentAccountId();
2218     auto it = clips_.Find(userId);
2219     if (!it.first) {
2220         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "can not find data. userId: %{public}d", userId);
2221         return {};
2222     }
2223     if (it.second == nullptr) {
2224         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is nullptr. userId: %{public}d", userId);
2225         return {};
2226     }
2227     auto tokenId = IPCSkeleton::GetCallingTokenID();
2228     auto ret = IsDataValid(*(it.second), tokenId);
2229     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
2230         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
2231             "pasteData is invalid, tokenId is %{public}d, userId: %{public}d, ret is %{public}d",
2232             tokenId, userId, ret);
2233         return {};
2234     }
2235     return it.second->GetMimeTypes();
2236 }
2237 
HasLocalDataType(const std::string & mimeType)2238 bool PasteboardService::HasLocalDataType(const std::string &mimeType)
2239 {
2240     auto userId = GetCurrentAccountId();
2241     auto it = clips_.Find(userId);
2242     if (!it.first) {
2243         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "can not find data. userId: %{public}d, mimeType: %{public}s",
2244             userId, mimeType.c_str());
2245         return false;
2246     }
2247     if (it.second == nullptr) {
2248         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is nullptr. userId: %{public}d, mimeType: %{public}s",
2249             userId, mimeType.c_str());
2250         return false;
2251     }
2252     auto tokenId = IPCSkeleton::GetCallingTokenID();
2253     auto ret = IsDataValid(*(it.second), tokenId);
2254     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
2255         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
2256             "pasteData is invalid, tokenId is %{public}d, userId: %{public}d,"
2257             "mimeType: %{public}s, ret is %{public}d",
2258             tokenId, userId, mimeType.c_str(), ret);
2259         return false;
2260     }
2261     auto screenStatus = GetCurrentScreenStatus();
2262     if (it.second->GetScreenStatus() > screenStatus) {
2263         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
2264             "current screen is %{public}d, set data screen is %{public}d."
2265             "userId: %{public}d, mimeType: %{public}s",
2266             screenStatus, it.second->GetScreenStatus(), userId, mimeType.c_str());
2267         return false;
2268     }
2269     std::vector<std::string> mimeTypes = it.second->GetMimeTypes();
2270     auto isExistType = std::find(mimeTypes.begin(), mimeTypes.end(), mimeType) != mimeTypes.end();
2271     return isExistType;
2272 }
2273 
IsRemoteData(bool & funcResult)2274 int32_t PasteboardService::IsRemoteData(bool &funcResult)
2275 {
2276     funcResult = IsRemoteData();
2277     return ERR_OK;
2278 }
2279 
IsRemoteData()2280 bool PasteboardService::IsRemoteData()
2281 {
2282     auto userId = GetCurrentAccountId();
2283     if (userId == ERROR_USERID) {
2284         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId is error.");
2285         return false;
2286     }
2287     auto it = clips_.Find(userId);
2288     if (!it.first) {
2289         auto [distRet, distEvt] = GetValidDistributeEvent(userId);
2290         return distRet == static_cast<int32_t>(PasteboardError::E_OK);
2291     }
2292     return it.second->IsRemote();
2293 }
2294 
GetDataSource(std::string & bundleName)2295 int32_t PasteboardService::GetDataSource(std::string &bundleName)
2296 {
2297     auto userId = GetCurrentAccountId();
2298     if (userId == ERROR_USERID) {
2299         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
2300     }
2301     auto it = clips_.Find(userId);
2302     if (!it.first) {
2303         return static_cast<int32_t>(PasteboardError::NO_USER_DATA_ERROR);
2304     }
2305     auto data = it.second;
2306     if (data->IsRemote()) {
2307         return static_cast<int32_t>(PasteboardError::REMOTE_EXCEPTION);
2308     }
2309     auto tokenId = data->GetTokenId();
2310     bundleName = GetAppLabel(tokenId);
2311     if (bundleName.empty() || bundleName.length() > MAX_BUNDLE_NAME_LENGTH) {
2312         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Failed to get bundleName");
2313         return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
2314     }
2315     return ERR_OK;
2316 }
2317 
CloseSharedMemFd(int fd)2318 void PasteboardService::CloseSharedMemFd(int fd)
2319 {
2320     if (fd >= 0) {
2321         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Close fd:%{public}d", fd);
2322         close(fd);
2323     }
2324 }
2325 
WritePasteData(int fd,int64_t rawDataSize,const std::vector<uint8_t> & buffer,PasteData & pasteData,bool & hasData)2326 int32_t PasteboardService::WritePasteData(
2327     int fd, int64_t rawDataSize, const std::vector<uint8_t> &buffer, PasteData &pasteData, bool &hasData)
2328 {
2329     if (rawDataSize > MIN_ASHMEM_DATA_SIZE) {
2330         auto actualSize = AshmemGetSize(fd);
2331         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(actualSize >= 0 && rawDataSize <= actualSize,
2332             static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
2333             "rawDataSize invalid, actualSize=%{public}d, rawDataSize:%{public}" PRId64, actualSize, rawDataSize);
2334         void *ptr = ::mmap(nullptr, rawDataSize, PROT_READ, MAP_SHARED, fd, 0);
2335         if (ptr == MAP_FAILED) {
2336             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "mmap failed, size:%{public}" PRId64, rawDataSize);
2337             CloseSharedMemFd(fd);
2338             return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
2339         }
2340         const uint8_t *rawData = reinterpret_cast<const uint8_t *>(ptr);
2341         if (rawData == nullptr) {
2342             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "rawData is nullptr, size:%{public}" PRId64, rawDataSize);
2343             ::munmap(ptr, rawDataSize);
2344             CloseSharedMemFd(fd);
2345             return static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR);
2346         }
2347         std::vector<uint8_t> pasteDataTlv(rawData, rawData + rawDataSize);
2348         hasData = pasteData.Decode(pasteDataTlv);
2349         ::munmap(ptr, rawDataSize);
2350     } else {
2351         hasData = pasteData.Decode(buffer);
2352     }
2353     CloseSharedMemFd(fd);
2354     return static_cast<int32_t>(PasteboardError::E_OK);
2355 }
2356 
SubscribeDisposableObserver(const sptr<IPasteboardDisposableObserver> & observer,const std::string & targetBundleName,DisposableType type,uint32_t maxLength)2357 int32_t PasteboardService::SubscribeDisposableObserver(const sptr<IPasteboardDisposableObserver> &observer,
2358     const std::string &targetBundleName, DisposableType type, uint32_t maxLength)
2359 {
2360     constexpr pid_t SELECTION_SERVICE_UID = 1080;
2361     pid_t uid = IPCSkeleton::GetCallingUid();
2362     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(uid == SELECTION_SERVICE_UID,
2363         static_cast<int32_t>(PasteboardError::NOT_SUPPORT), PASTEBOARD_MODULE_SERVICE, "not support");
2364 
2365     pid_t pid = IPCSkeleton::GetCallingPid();
2366     auto tokenId = IPCSkeleton::GetCallingTokenID();
2367     DisposableInfo info(pid, tokenId, targetBundleName, type, maxLength, observer);
2368     int32_t ret = DisposableManager::GetInstance().AddDisposableInfo(info);
2369     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2370         PASTEBOARD_MODULE_SERVICE, "add observer info failed, ret=%{public}d", ret);
2371     return ERR_OK;
2372 }
2373 
SetPasteData(int fd,int64_t rawDataSize,const std::vector<uint8_t> & buffer,const sptr<IPasteboardDelayGetter> & delayGetter,const sptr<IPasteboardEntryGetter> & entryGetter)2374 int32_t PasteboardService::SetPasteData(int fd, int64_t rawDataSize, const std::vector<uint8_t> &buffer,
2375     const sptr<IPasteboardDelayGetter> &delayGetter, const sptr<IPasteboardEntryGetter> &entryGetter)
2376 {
2377     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(
2378         fd >= 0, static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE, "fd invalid");
2379     MessageParcelWarp messageData;
2380     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "fd=%{public}d, agedTime_ = %{public}d,"
2381         "rawDataSize=%{public}" PRId64, fd, agedTime_, rawDataSize);
2382     SetCriticalTimer();
2383     if (rawDataSize <= 0 || rawDataSize > messageData.GetRawDataSize()) {
2384         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Invalid raw data size:%{public}" PRId64, rawDataSize);
2385         CloseSharedMemFd(fd);
2386         return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
2387     }
2388     PasteData pasteData{};
2389     bool result = false;
2390     auto ret = WritePasteData(fd, rawDataSize, buffer, pasteData, result);
2391     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK),
2392         static_cast<int32_t>(PasteboardError::INVALID_DATA_ERROR), PASTEBOARD_MODULE_SERVICE,
2393         "Failed to write paste data");
2394     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(result, static_cast<int32_t>(PasteboardError::NO_DATA_ERROR),
2395         PASTEBOARD_MODULE_SERVICE, "Failed to decode paste data in TLV");
2396 
2397     auto tokenId = IPCSkeleton::GetCallingTokenID();
2398     auto appInfo = GetAppInfo(tokenId);
2399     std::string bundleName = GetAppBundleName(appInfo);
2400     pasteData.SetTokenId(tokenId);
2401     UpdateShareOption(pasteData);
2402     if (DisposableManager::GetInstance().TryProcessDisposableData(bundleName, pasteData, delayGetter, entryGetter)) {
2403         return ERR_OK;
2404     }
2405     PasteboardWebController::GetInstance().SplitWebviewPasteData(pasteData);
2406     ret = SaveData(pasteData, rawDataSize, delayGetter, entryGetter);
2407     if (entityObserverMap_.Size() != 0 && pasteData.HasMimeType(MIMETYPE_TEXT_PLAIN)) {
2408         RecognizePasteData(pasteData);
2409     }
2410     ReportUeCopyEvent(pasteData, rawDataSize, ret);
2411     HiViewAdapter::ReportUseBehaviour(pasteData, HiViewAdapter::COPY_STATE, ret);
2412     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
2413         PASTEBOARD_MODULE_SERVICE, "Failed to save data, ret=%{public}d", ret);
2414     return ERR_OK;
2415 }
2416 
SetPasteDataDelayData(int fd,int64_t rawDataSize,const std::vector<uint8_t> & buffer,const sptr<IPasteboardDelayGetter> & delayGetter)2417 int32_t PasteboardService::SetPasteDataDelayData(int fd, int64_t rawDataSize, const std::vector<uint8_t> &buffer,
2418     const sptr<IPasteboardDelayGetter> &delayGetter)
2419 {
2420     return SetPasteData(fd, rawDataSize, buffer, delayGetter, nullptr);
2421 }
2422 
SetPasteDataEntryData(int fd,int64_t rawDataSize,const std::vector<uint8_t> & buffer,const sptr<IPasteboardEntryGetter> & entryGetter)2423 int32_t PasteboardService::SetPasteDataEntryData(int fd, int64_t rawDataSize, const std::vector<uint8_t> &buffer,
2424     const sptr<IPasteboardEntryGetter> &entryGetter)
2425 {
2426     return SetPasteData(fd, rawDataSize, buffer, nullptr, entryGetter);
2427 }
2428 
SetPasteDataOnly(int fd,int64_t rawDataSize,const std::vector<uint8_t> & buffer)2429 int32_t PasteboardService::SetPasteDataOnly(int fd, int64_t rawDataSize, const std::vector<uint8_t> &buffer)
2430 {
2431     return SetPasteData(fd, rawDataSize, buffer, nullptr, nullptr);
2432 }
2433 
RemovePasteData(const AppInfo & appInfo)2434 void PasteboardService::RemovePasteData(const AppInfo &appInfo)
2435 {
2436     delayGetters_.ComputeIfPresent(appInfo.userId, [](auto, auto &delayGetter) {
2437         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_SET_DELAY_COPY, DFX_SUCCESS, COVER_DELAY_DATA, DFX_SUCCESS);
2438         if (delayGetter.first != nullptr && delayGetter.second != nullptr) {
2439             delayGetter.first->AsObject()->RemoveDeathRecipient(delayGetter.second);
2440         }
2441         return false;
2442     });
2443     entryGetters_.ComputeIfPresent(appInfo.userId, [](auto, auto &entryGetter) {
2444         if (entryGetter.first != nullptr && entryGetter.second != nullptr) {
2445             entryGetter.first->AsObject()->RemoveDeathRecipient(entryGetter.second);
2446         }
2447         return false;
2448     });
2449 }
2450 
GetCurrentAccountId()2451 int32_t PasteboardService::GetCurrentAccountId()
2452 {
2453     if (currentUserId_ != ERROR_USERID) {
2454         return currentUserId_;
2455     }
2456     std::vector<int32_t> accountIds;
2457     auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(accountIds);
2458     if (ret != ERR_OK || accountIds.empty()) {
2459         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed errCode=%{public}d", ret);
2460         return ERROR_USERID;
2461     }
2462     currentUserId_ = accountIds.front();
2463     return currentUserId_;
2464 }
2465 
GetCurrentScreenStatus()2466 ScreenEvent PasteboardService::GetCurrentScreenStatus()
2467 {
2468     if (currentScreenStatus != ScreenEvent::Default) {
2469         return currentScreenStatus;
2470     }
2471 
2472     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query current screen status failed.");
2473     return ScreenEvent::Default;
2474 }
2475 
IsCopyable(uint32_t tokenId) const2476 bool PasteboardService::IsCopyable(uint32_t tokenId) const
2477 {
2478 #ifdef WITH_DLP
2479     bool copyable = false;
2480     auto ret = Security::DlpPermission::DlpPermissionKit::QueryDlpFileCopyableByTokenId(copyable, tokenId);
2481     if (ret != Security::DlpPermission::DLP_OK || !copyable) {
2482         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "tokenId = 0x%{public}x ret = %{public}d, copyable = %{public}d.",
2483             tokenId, ret, copyable);
2484         return false;
2485     }
2486 #endif
2487     return true;
2488 }
2489 
SetInputMethodPid(int32_t userId,pid_t callPid)2490 void PasteboardService::SetInputMethodPid(int32_t userId, pid_t callPid)
2491 {
2492     auto imc = InputMethodController::GetInstance();
2493     if (imc == nullptr) {
2494         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "InputMethodController is nullptr!");
2495         return;
2496     }
2497     auto isImePid = imc->IsCurrentImeByPid(callPid);
2498     if (isImePid) {
2499         imeMap_.InsertOrAssign(userId, callPid);
2500         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "set inputMethod userId = %{public}d, pid = %{public}d",
2501             userId, callPid);
2502     }
2503 }
2504 
ClearInputMethodPidByPid(int32_t userId,pid_t callPid)2505 void PasteboardService::ClearInputMethodPidByPid(int32_t userId, pid_t callPid)
2506 {
2507     auto [hasPid, pid] = imeMap_.Find(userId);
2508     if (hasPid && callPid == pid) {
2509         imeMap_.Erase(userId);
2510         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "clear inputMethod userId = %{public}d, pid = %{public}d",
2511             userId, callPid);
2512     }
2513 }
2514 
ClearInputMethodPid()2515 void PasteboardService::ClearInputMethodPid()
2516 {
2517     imeMap_.Clear();
2518     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clear inputMethod pid!");
2519 }
2520 
SubscribeObserver(PasteboardObserverType type,const sptr<IPasteboardChangedObserver> & observer)2521 int32_t PasteboardService::SubscribeObserver(PasteboardObserverType type,
2522     const sptr<IPasteboardChangedObserver> &observer)
2523 {
2524     auto callPid = IPCSkeleton::GetCallingPid();
2525     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
2526     bool isEventType = static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_EVENT);
2527     int32_t userId = isEventType ? COMMON_USERID : appInfo.userId;
2528     SetInputMethodPid(userId, callPid);
2529     if (userId == ERROR_USERID) {
2530         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
2531         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
2532     }
2533     bool addSucc = false;
2534     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_LOCAL)) {
2535         addSucc = AddObserver(userId, observer, observerLocalChangedMap_) || addSucc;
2536     }
2537 
2538     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_REMOTE)) {
2539         addSucc = AddObserver(userId, observer, observerRemoteChangedMap_) || addSucc;
2540     }
2541 
2542     if (isEventType && IsCallerUidValid()) {
2543         addSucc = AddObserver(userId, observer, observerEventMap_) || addSucc;
2544     }
2545     return addSucc ? ERR_OK : static_cast<int32_t>(PasteboardError::ADD_OBSERVER_FAILED);
2546 }
2547 
ResubscribeObserver(PasteboardObserverType type,const sptr<IPasteboardChangedObserver> & observer)2548 int32_t PasteboardService::ResubscribeObserver(
2549     PasteboardObserverType type, const sptr<IPasteboardChangedObserver> &observer)
2550 {
2551     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
2552     if (appInfo.tokenType == ATokenTypeEnum::TOKEN_HAP) {
2553         return SubscribeObserver(type, observer);
2554     }
2555     return ERR_OK;
2556 }
2557 
UnsubscribeObserver(PasteboardObserverType type,const sptr<IPasteboardChangedObserver> & observer)2558 int32_t PasteboardService::UnsubscribeObserver(
2559     PasteboardObserverType type, const sptr<IPasteboardChangedObserver> &observer)
2560 {
2561     auto callPid = IPCSkeleton::GetCallingPid();
2562     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
2563     bool isEventType = static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_EVENT);
2564     int32_t userId = isEventType ? COMMON_USERID : appInfo.userId;
2565     ClearInputMethodPidByPid(userId, callPid);
2566     if (userId == ERROR_USERID) {
2567         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
2568         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
2569     }
2570     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_LOCAL)) {
2571         RemoveSingleObserver(userId, observer, observerLocalChangedMap_);
2572     }
2573 
2574     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_REMOTE)) {
2575         RemoveSingleObserver(userId, observer, observerRemoteChangedMap_);
2576     }
2577 
2578     if (isEventType && IsCallerUidValid()) {
2579         RemoveSingleObserver(userId, observer, observerEventMap_);
2580     }
2581     return ERR_OK;
2582 }
2583 
UnsubscribeAllObserver(PasteboardObserverType type)2584 int32_t PasteboardService::UnsubscribeAllObserver(PasteboardObserverType type)
2585 {
2586     ClearInputMethodPid();
2587     bool isEventType = static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_EVENT);
2588     int32_t userId = isEventType ? COMMON_USERID : GetCurrentAccountId();
2589     if (userId == ERROR_USERID) {
2590         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
2591         return static_cast<int32_t>(PasteboardError::INVALID_USERID_ERROR);
2592     }
2593     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_LOCAL)) {
2594         RemoveAllObserver(userId, observerLocalChangedMap_);
2595     }
2596 
2597     if (static_cast<uint32_t>(type) & static_cast<uint32_t>(PasteboardObserverType::OBSERVER_REMOTE)) {
2598         RemoveAllObserver(userId, observerRemoteChangedMap_);
2599     }
2600 
2601     if (isEventType && IsCallerUidValid()) {
2602         RemoveAllObserver(userId, observerEventMap_);
2603     }
2604     return ERR_OK;
2605 }
2606 
GetAllObserversSize(int32_t userId,pid_t pid)2607 uint32_t PasteboardService::GetAllObserversSize(int32_t userId, pid_t pid)
2608 {
2609     auto localObserverSize = GetObserversSize(userId, pid, observerLocalChangedMap_);
2610     auto remoteObserverSize = GetObserversSize(userId, pid, observerRemoteChangedMap_);
2611     auto eventObserverSize = GetObserversSize(COMMON_USERID, pid, observerEventMap_);
2612     return localObserverSize + remoteObserverSize + eventObserverSize;
2613 }
2614 
GetObserversSize(int32_t userId,pid_t pid,ObserverMap & observerMap)2615 uint32_t PasteboardService::GetObserversSize(int32_t userId, pid_t pid, ObserverMap &observerMap)
2616 {
2617     auto countKey = std::make_pair(userId, pid);
2618     auto it = observerMap.find(countKey);
2619     if (it != observerMap.end()) {
2620         return it->second->size();
2621     }
2622     return 0;
2623 }
2624 
AddObserver(int32_t userId,const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)2625 bool PasteboardService::AddObserver(
2626     int32_t userId, const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
2627 {
2628     if (observer == nullptr) {
2629         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
2630         return false;
2631     }
2632     std::lock_guard<std::mutex> lock(observerMutex_);
2633     auto callPid = IPCSkeleton::GetCallingPid();
2634     auto callObserverKey = std::make_pair(userId, callPid);
2635     auto it = observerMap.find(callObserverKey);
2636     std::shared_ptr<std::set<sptr<IPasteboardChangedObserver>, classcomp>> observers;
2637     if (it != observerMap.end()) {
2638         observers = it->second;
2639     } else {
2640         observers = std::make_shared<std::set<sptr<IPasteboardChangedObserver>, classcomp>>();
2641         observerMap.insert(std::make_pair(callObserverKey, observers));
2642     }
2643     auto allObserverCount = GetAllObserversSize(userId, callPid);
2644     if (allObserverCount >= MAX_OBSERVER_COUNT) {
2645         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer count over limit. callPid:%{public}d", callPid);
2646         return false;
2647     }
2648     observers->insert(observer);
2649     RADAR_REPORT(DFX_OBSERVER, DFX_ADD_OBSERVER, DFX_SUCCESS);
2650     PASTEBOARD_HILOGI(
2651         PASTEBOARD_MODULE_SERVICE, "observers->size = %{public}u.", static_cast<unsigned int>(observers->size()));
2652     return true;
2653 }
2654 
RemoveSingleObserver(int32_t userId,const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)2655 void PasteboardService::RemoveSingleObserver(
2656     int32_t userId, const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
2657 {
2658     if (observer == nullptr) {
2659         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
2660         return;
2661     }
2662     std::lock_guard<std::mutex> lock(observerMutex_);
2663     auto callPid = IPCSkeleton::GetCallingPid();
2664     auto callObserverKey = std::make_pair(userId, callPid);
2665     auto it = observerMap.find(callObserverKey);
2666     if (it == observerMap.end()) {
2667         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "user id not found userId is %{public}d", userId);
2668         return;
2669     }
2670     auto observers = it->second;
2671     PASTEBOARD_HILOGD(
2672         PASTEBOARD_MODULE_SERVICE, "observers size: %{public}u.", static_cast<unsigned int>(observers->size()));
2673     auto eraseNum = observers->erase(observer);
2674     RADAR_REPORT(DFX_OBSERVER, DFX_REMOVE_SINGLE_OBSERVER, DFX_SUCCESS);
2675     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers size = %{public}u, eraseNum = %{public}zu",
2676         static_cast<unsigned int>(observers->size()), eraseNum);
2677 }
2678 
RemoveAllObserver(int32_t userId,ObserverMap & observerMap)2679 void PasteboardService::RemoveAllObserver(int32_t userId, ObserverMap &observerMap)
2680 {
2681     std::lock_guard<std::mutex> lock(observerMutex_);
2682     for (auto it = observerMap.begin(); it != observerMap.end();) {
2683         if (it->first.first == userId) {
2684             it = observerMap.erase(it);
2685         } else {
2686             ++it;
2687         }
2688     }
2689     RADAR_REPORT(DFX_OBSERVER, DFX_REMOVE_ALL_OBSERVER, DFX_SUCCESS);
2690 }
2691 
SetGlobalShareOption(const std::unordered_map<uint32_t,int32_t> & globalShareOptions)2692 int32_t PasteboardService::SetGlobalShareOption(const std::unordered_map<uint32_t, int32_t> &globalShareOptions)
2693 {
2694     if (!IsCallerUidValid()) {
2695         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No Permission");
2696         return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2697     }
2698     std::map<uint32_t, ShareOption> shareOptions;
2699     for (const auto& pair : globalShareOptions) {
2700         uint32_t key = pair.first;
2701         int32_t value = pair.second;
2702         if (value >= InApp && value <= CrossDevice) {
2703             shareOptions[key] = static_cast<ShareOption>(value);
2704         }
2705     }
2706     for (const auto &[tokenId, shareOption] : shareOptions) {
2707         GlobalShareOption option = {.source = MDM, .shareOption = shareOption};
2708         globalShareOptions_.InsertOrAssign(tokenId, option);
2709     }
2710     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Set %{public}zu global shareOption.", globalShareOptions.size());
2711     return ERR_OK;
2712 }
2713 
RemoveGlobalShareOption(const std::vector<uint32_t> & tokenIds)2714 int32_t PasteboardService::RemoveGlobalShareOption(const std::vector<uint32_t> &tokenIds)
2715 {
2716     if (!IsCallerUidValid()) {
2717         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No Permission");
2718         return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2719     }
2720     int32_t count = 0;
2721     for (const uint32_t &tokenId : tokenIds) {
2722         globalShareOptions_.ComputeIfPresent(tokenId, [&count](const uint32_t &key, GlobalShareOption &value) {
2723             count++;
2724             return false;
2725         });
2726     }
2727     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Remove %{public}d global shareOption.", count);
2728     return ERR_OK;
2729 }
2730 
GetGlobalShareOption(const std::vector<uint32_t> & tokenIds,std::unordered_map<uint32_t,int32_t> & funcResult)2731 int32_t PasteboardService::GetGlobalShareOption(const std::vector<uint32_t> &tokenIds,
2732     std::unordered_map<uint32_t, int32_t>& funcResult)
2733 {
2734     if (!IsCallerUidValid()) {
2735         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No Permission");
2736         funcResult = {};
2737         return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2738     }
2739     std::map<uint32_t, ShareOption> result;
2740     if (tokenIds.empty()) {
2741         globalShareOptions_.ForEach([&result](const uint32_t &key, GlobalShareOption &value) {
2742             result[key] = value.shareOption;
2743             return false;
2744         });
2745         for (const auto &pair : result) {
2746             funcResult[pair.first] = static_cast<int32_t>(pair.second);
2747         }
2748         return ERR_OK;
2749     }
2750     for (const uint32_t &tokenId : tokenIds) {
2751         globalShareOptions_.ComputeIfPresent(tokenId, [&result](const uint32_t &key, GlobalShareOption &value) {
2752             result[key] = value.shareOption;
2753             return true;
2754         });
2755     }
2756     for (const auto &pair : result) {
2757         funcResult[pair.first] = static_cast<int32_t>(pair.second);
2758     }
2759     return ERR_OK;
2760 }
2761 
IsSystemAppByFullTokenID(uint64_t tokenId)2762 bool PasteboardService::IsSystemAppByFullTokenID(uint64_t tokenId)
2763 {
2764     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "called token id: %{public}" PRIu64, tokenId);
2765     return (tokenId & SYSTEM_APP_MASK) == SYSTEM_APP_MASK;
2766 }
2767 
SetAppShareOptions(int32_t shareOptions)2768 int32_t PasteboardService::SetAppShareOptions(int32_t shareOptions)
2769 {
2770     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(PasteData::IsValidShareOption(shareOptions),
2771         static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR), PASTEBOARD_MODULE_SERVICE,
2772         "shareOptions invalid, shareOptions=%{public}d", shareOptions);
2773     auto fullTokenId = IPCSkeleton::GetCallingFullTokenID();
2774     auto tokenId = IPCSkeleton::GetCallingTokenID();
2775     if (!IsSystemAppByFullTokenID(fullTokenId)) {
2776         if (shareOptions != ShareOption::InApp) {
2777             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "param is invalid");
2778             return static_cast<int32_t>(PasteboardError::INVALID_PARAM_ERROR);
2779         }
2780         auto isManageGrant = PermissionUtils::IsPermissionGranted(MANAGE_PASTEBOARD_APP_SHARE_OPTION_PERMISSION,
2781             tokenId);
2782         if (!isManageGrant) {
2783             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No permission, token id: 0x%{public}x.", tokenId);
2784             return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2785         }
2786     }
2787     GlobalShareOption option = {.source = APP, .shareOption = static_cast<ShareOption>(shareOptions)};
2788     auto isAbsent = globalShareOptions_.ComputeIfAbsent(tokenId, [&option](const uint32_t &tokenId) {
2789         return option;
2790     });
2791     if (!isAbsent) {
2792         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Settings already exist, token id: 0x%{public}x.", tokenId);
2793         return static_cast<int32_t>(PasteboardError::INVALID_OPERATION_ERROR);
2794     }
2795     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Set token id: 0x%{public}x share options: %{public}d success.",
2796         tokenId, shareOptions);
2797     return 0;
2798 }
2799 
RemoveAppShareOptions()2800 int32_t PasteboardService::RemoveAppShareOptions()
2801 {
2802     auto fullTokenId = IPCSkeleton::GetCallingFullTokenID();
2803     auto tokenId = IPCSkeleton::GetCallingTokenID();
2804     if (!IsSystemAppByFullTokenID(fullTokenId)) {
2805         auto isManageGrant = PermissionUtils::IsPermissionGranted(MANAGE_PASTEBOARD_APP_SHARE_OPTION_PERMISSION,
2806             tokenId);
2807         if (!isManageGrant) {
2808             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "No permission, token id: 0x%{public}x.", tokenId);
2809             return static_cast<int32_t>(PasteboardError::PERMISSION_VERIFICATION_ERROR);
2810         }
2811     }
2812     std::map<uint32_t, GlobalShareOption> result;
2813     globalShareOptions_.ComputeIfPresent(tokenId, [&result](const uint32_t &key, GlobalShareOption &value) {
2814         result[key] = value;
2815         return true;
2816     });
2817     if (!result.empty()) {
2818         if (result[tokenId].source == APP) {
2819             globalShareOptions_.Erase(tokenId);
2820             PASTEBOARD_HILOGI(
2821                 PASTEBOARD_MODULE_SERVICE, "Remove token id: 0x%{public}x share options success.", tokenId);
2822             return 0;
2823         } else {
2824             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Can not remove token id: 0x%{public}x.", tokenId);
2825             return 0;
2826         }
2827     }
2828     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "This token id: 0x%{public}x not set.", tokenId);
2829     return 0;
2830 }
2831 
UpdateShareOption(PasteData & pasteData)2832 void PasteboardService::UpdateShareOption(PasteData &pasteData)
2833 {
2834     globalShareOptions_.ComputeIfPresent(
2835         pasteData.GetTokenId(), [&pasteData](const uint32_t &tokenId, GlobalShareOption &option) {
2836             pasteData.SetShareOption(option.shareOption);
2837             return true;
2838         });
2839 }
2840 
CheckMdmShareOption(PasteData & pasteData)2841 bool PasteboardService::CheckMdmShareOption(PasteData &pasteData)
2842 {
2843     bool result = false;
2844     globalShareOptions_.ComputeIfPresent(
2845         pasteData.GetTokenId(), [&result](const uint32_t &tokenId, GlobalShareOption &option) {
2846             if (option.source == MDM) {
2847                 result = true;
2848             }
2849             return true;
2850         });
2851     return result;
2852 }
2853 
IsCallerUidValid()2854 bool PasteboardService::IsCallerUidValid()
2855 {
2856     pid_t callingUid = IPCSkeleton::GetCallingUid();
2857     if (callingUid == EDM_UID || (uid_ != -1 && callingUid == uid_)) {
2858         return true;
2859     }
2860     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "callingUid error: %{public}d.", callingUid);
2861     return false;
2862 }
2863 
ThawInputMethod(pid_t imePid)2864 void PasteboardService::ThawInputMethod(pid_t imePid)
2865 {
2866     auto type = ResourceSchedule::ResType::RES_TYPE_SA_CONTROL_APP_EVENT;
2867     auto status = ResourceSchedule::ResType::SaControlAppStatus::SA_START_APP;
2868 
2869     std::unordered_map<std::string, std::string> payload = {
2870         { "saId", std::to_string(PASTEBOARD_SERVICE_ID) },
2871         { "saName", PASTEBOARD_SERVICE_SA_NAME },
2872         { "extensionType", std::to_string(static_cast<int32_t>(AppExecFwk::ExtensionAbilityType::INPUTMETHOD)) },
2873         { "pid", std::to_string(imePid) },
2874         { "isDelay", std::to_string(true) } };
2875     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "report RSS need thaw:pid = %{public}d", imePid);
2876     ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, status, payload);
2877 }
2878 
IsNeedThaw()2879 bool PasteboardService::IsNeedThaw()
2880 {
2881     auto imc = InputMethodController::GetInstance();
2882     if (imc == nullptr) {
2883         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "InputMethodController is nullptr!");
2884         return false;
2885     }
2886 
2887     std::shared_ptr<Property> property;
2888     int32_t ret = imc->GetDefaultInputMethod(property);
2889     if (ret != ErrorCode::NO_ERROR || property == nullptr) {
2890         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "default input method is nullptr!");
2891         return false;
2892     }
2893     return true;
2894 }
NotifyObservers(std::string bundleName,int32_t userId,PasteboardEventStatus status)2895 void PasteboardService::NotifyObservers(std::string bundleName, int32_t userId, PasteboardEventStatus status)
2896 {
2897     auto [hasPid, pid] = imeMap_.Find(userId);
2898     if (hasPid && IsNeedThaw()) {
2899         ThawInputMethod(pid);
2900     }
2901     std::thread thread([this, bundleName, userId, status]() {
2902         std::lock_guard<std::mutex> lock(observerMutex_);
2903         for (auto &observers : observerLocalChangedMap_) {
2904             for (const auto &observer : *(observers.second)) {
2905                 if (status != PasteboardEventStatus::PASTEBOARD_READ && userId == observers.first.first) {
2906                     observer->OnPasteboardChanged();
2907                 }
2908             }
2909         }
2910         for (auto &observers : observerEventMap_) {
2911             for (const auto &observer : *(observers.second)) {
2912                 observer->OnPasteboardEvent(bundleName, static_cast<int32_t>(status));
2913             }
2914         }
2915     });
2916     thread.detach();
2917 }
2918 
GetDataSize(PasteData & data) const2919 size_t PasteboardService::GetDataSize(PasteData &data) const
2920 {
2921     if (data.GetRecordCount() != 0) {
2922         size_t counts = data.GetRecordCount() - 1;
2923         std::shared_ptr<PasteDataRecord> records = data.GetRecordAt(counts);
2924         std::string text = records->ConvertToText();
2925         size_t textSize = text.size();
2926         return textSize;
2927     }
2928     return 0; // get wrong size
2929 }
2930 
SetPasteboardHistory(HistoryInfo & info)2931 bool PasteboardService::SetPasteboardHistory(HistoryInfo &info)
2932 {
2933     std::string history = std::move(info.time) + " " + std::move(info.bundleName) + " " + std::move(info.state) + " " +
2934                           " " + std::move(info.remote);
2935     constexpr const size_t DATA_HISTORY_SIZE = 10;
2936     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
2937     if (dataHistory_.size() == DATA_HISTORY_SIZE) {
2938         dataHistory_.erase(dataHistory_.begin());
2939     }
2940     dataHistory_.push_back(std::move(history));
2941     return true;
2942 }
2943 
Dump(int fd,const std::vector<std::u16string> & args)2944 int PasteboardService::Dump(int fd, const std::vector<std::u16string> &args)
2945 {
2946     int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
2947     const int maxUid = 10000;
2948     if (uid > maxUid) {
2949         return 0;
2950     }
2951 
2952     std::vector<std::string> argsStr;
2953     for (auto item : args) {
2954         argsStr.emplace_back(Str16ToStr8(item));
2955     }
2956 
2957     if (PasteboardDumpHelper::GetInstance().Dump(fd, argsStr)) {
2958         return 0;
2959     }
2960     return 0;
2961 }
2962 
GetTime()2963 std::string PasteboardService::GetTime()
2964 {
2965     constexpr int USEC_TO_MSEC = 1000;
2966     time_t timeSeconds = time(0);
2967     if (timeSeconds == -1) {
2968         return FAIL_TO_GET_TIME_STAMP;
2969     }
2970     struct tm nowTime;
2971     localtime_r(&timeSeconds, &nowTime);
2972 
2973     struct timeval timeVal = { 0, 0 };
2974     gettimeofday(&timeVal, nullptr);
2975 
2976     std::string targetTime = std::to_string(nowTime.tm_year + 1900) + "-" + std::to_string(nowTime.tm_mon + 1) + "-" +
2977                              std::to_string(nowTime.tm_mday) + " " + std::to_string(nowTime.tm_hour) + ":" +
2978                              std::to_string(nowTime.tm_min) + ":" + std::to_string(nowTime.tm_sec) + "." +
2979                              std::to_string(timeVal.tv_usec / USEC_TO_MSEC);
2980     return targetTime;
2981 }
2982 
DumpHistory() const2983 std::string PasteboardService::DumpHistory() const
2984 {
2985     std::string result;
2986     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
2987     if (!dataHistory_.empty()) {
2988         result.append("Access history last ten times: ").append("\n");
2989         for (auto iter = dataHistory_.rbegin(); iter != dataHistory_.rend(); ++iter) {
2990             result.append("          ").append(*iter).append("\n");
2991         }
2992     } else {
2993         result.append("Access history fail! dataHistory_ no data.").append("\n");
2994     }
2995     return result;
2996 }
2997 
DumpData()2998 std::string PasteboardService::DumpData()
2999 {
3000     auto userId = GetCurrentAccountId();
3001     if (userId == ERROR_USERID) {
3002         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed.");
3003         return "";
3004     }
3005     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "id = %{public}d", userId);
3006     auto it = clips_.Find(userId);
3007     std::string result;
3008     if (it.first && it.second != nullptr) {
3009         size_t recordCounts = it.second->GetRecordCount();
3010         auto property = it.second->GetProperty();
3011         std::string shareOption;
3012         PasteData::ShareOptionToString(property.shareOption, shareOption);
3013         std::string sourceDevice;
3014         if (property.isRemote) {
3015             sourceDevice = "remote";
3016         } else {
3017             sourceDevice = "local";
3018         }
3019         result.append("|Owner       :  ")
3020             .append(property.bundleName)
3021             .append("\n")
3022             .append("|Timestamp   :  ")
3023             .append(property.setTime)
3024             .append("\n")
3025             .append("|Share Option:  ")
3026             .append(shareOption)
3027             .append("\n")
3028             .append("|Record Count:  ")
3029             .append(std::to_string(recordCounts))
3030             .append("\n")
3031             .append("|Mime types  :  {");
3032         if (!property.mimeTypes.empty()) {
3033             for (size_t i = 0; i < property.mimeTypes.size(); ++i) {
3034                 result.append(property.mimeTypes[i]).append(",");
3035             }
3036         }
3037         result.append("}").append("\n").append("|source device:  ").append(sourceDevice);
3038     } else {
3039         result.append("No copy data.").append("\n");
3040     }
3041     return result;
3042 }
3043 
IsFocusedApp(uint32_t tokenId)3044 bool PasteboardService::IsFocusedApp(uint32_t tokenId)
3045 {
3046     if (AccessTokenKit::GetTokenTypeFlag(tokenId) != ATokenTypeEnum::TOKEN_HAP) {
3047         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "caller is not application");
3048         return true;
3049     }
3050     FocusChangeInfo info;
3051 #ifdef SCENE_BOARD_ENABLE
3052     WindowManagerLite::GetInstance().GetFocusWindowInfo(info);
3053 #else
3054     WindowManager::GetInstance().GetFocusWindowInfo(info);
3055 #endif
3056     auto callPid = IPCSkeleton::GetCallingPid();
3057     if (callPid == info.pid_) {
3058         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "pid is same, it is focused app");
3059         return true;
3060     }
3061     bool isFocused = false;
3062     auto ret = AAFwk::AbilityManagerClient::GetInstance()->CheckUIExtensionIsFocused(tokenId, isFocused);
3063     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "check result:%{public}d, isFocused:%{public}d", ret, isFocused);
3064     return ret == NO_ERROR && isFocused;
3065 }
3066 
DeletePreSyncP2pFromP2pMap(const std::string & networkId)3067 void PasteboardService::DeletePreSyncP2pFromP2pMap(const std::string &networkId)
3068 {
3069     std::string taskName = P2P_PRESYNC_ID + networkId;
3070     if (ffrtTimer_) {
3071         ffrtTimer_->CancelTimer(taskName);
3072     }
3073     std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
3074     p2pMap_.ComputeIfPresent(networkId, [this](const auto &key, auto &value) {
3075         value.ComputeIfPresent(P2P_PRESYNC_ID, [](const auto &key, auto &value) {
3076             return false;
3077         });
3078         return true;
3079     });
3080     DeletePreSyncP2pMap(networkId);
3081 }
3082 
DeletePreSyncP2pMap(const std::string & networkId)3083 void PasteboardService::DeletePreSyncP2pMap(const std::string &networkId)
3084 {
3085     auto p2pIter = preSyncP2pMap_.find(networkId);
3086     if (p2pIter != preSyncP2pMap_.end()) {
3087         if (p2pIter->second) {
3088             p2pIter->second->SetValue(SET_VALUE_SUCCESS);
3089         }
3090         preSyncP2pMap_.erase(networkId);
3091     }
3092 }
3093 
AddPreSyncP2pTimeoutTask(const std::string & networkId)3094 void PasteboardService::AddPreSyncP2pTimeoutTask(const std::string &networkId)
3095 {
3096     if (!ffrtTimer_) {
3097         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ffrtTimer_ is null");
3098         return;
3099     }
3100     std::string taskName = P2P_PRESYNC_ID + networkId;
3101     ffrtTimer_->CancelTimer(taskName);
3102     FFRTTask p2pTask = [this, networkId] {
3103         std::thread thread([=]() {
3104             PasteComplete(networkId, P2P_PRESYNC_ID);
3105             std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
3106             DeletePreSyncP2pMap(networkId);
3107         });
3108         thread.detach();
3109     };
3110     ffrtTimer_->SetTimer(taskName, p2pTask, PRE_ESTABLISH_P2P_LINK_TIME);
3111 }
3112 
RegisterPreSyncCallback(std::shared_ptr<ClipPlugin> clipPlugin)3113 void PasteboardService::RegisterPreSyncCallback(std::shared_ptr<ClipPlugin> clipPlugin)
3114 {
3115     if (!clipPlugin) {
3116         return;
3117     }
3118     clipPlugin->RegisterPreSyncCallback(std::bind(&PasteboardService::PreEstablishP2PLinkCallback,
3119         this, std::placeholders::_1, std::placeholders::_2));
3120     clipPlugin->RegisterPreSyncMonitorCallback(std::bind(&PasteboardService::PreSyncSwitchMonitorCallback, this));
3121 }
3122 
OpenP2PLinkForPreEstablish(const std::string & networkId,ClipPlugin * clipPlugin)3123 bool PasteboardService::OpenP2PLinkForPreEstablish(const std::string &networkId, ClipPlugin *clipPlugin)
3124 {
3125 #ifdef PB_DEVICE_MANAGER_ENABLE
3126     DmDeviceInfo remoteDevice;
3127     auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(networkId, remoteDevice);
3128     if (ret != static_cast<int32_t>(PasteboardError::E_OK)) {
3129         DeletePreSyncP2pFromP2pMap(networkId);
3130         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist, ret:%{public}d", ret);
3131         return false;
3132     }
3133     auto status = DistributedFileDaemonManager::GetInstance().OpenP2PConnection(remoteDevice);
3134     if (status != RESULT_OK) {
3135         DeletePreSyncP2pFromP2pMap(networkId);
3136         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "open p2p error, status:%{public}d", status);
3137         return false;
3138     }
3139     if (clipPlugin) {
3140         status = clipPlugin->PublishServiceState(networkId, ClipPlugin::ServiceStatus::CONNECT_SUCC);
3141         if (status != RESULT_OK) {
3142             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Publish state connect_succ error, status:%{public}d", status);
3143         }
3144     }
3145     AddPreSyncP2pTimeoutTask(networkId);
3146     return true;
3147 #else
3148     return false;
3149 #endif
3150 }
3151 
PreEstablishP2PLink(const std::string & networkId,ClipPlugin * clipPlugin)3152 void PasteboardService::PreEstablishP2PLink(const std::string &networkId, ClipPlugin *clipPlugin)
3153 {
3154 #ifdef PB_DEVICE_MANAGER_ENABLE
3155     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PreEstablishP2PLink enter");
3156     std::shared_ptr<BlockObject<int32_t>> pasteBlock = nullptr;
3157     {
3158         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
3159         if (p2pEstablishInfo_.pasteBlock && p2pEstablishInfo_.networkId == networkId) {
3160             return;
3161         }
3162         auto p2pNetwork = p2pMap_.Find(networkId);
3163         if (p2pNetwork.first && p2pNetwork.second.Find(P2P_PRESYNC_ID).first) {
3164             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Pre P2pEstablish exist");
3165             AddPreSyncP2pTimeoutTask(networkId);
3166             return;
3167         }
3168         pasteBlock = std::make_shared<BlockObject<int32_t>>(MIN_TRANMISSION_TIME, 0);
3169         if (!pasteBlock) {
3170             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "failed to alloc BlockObject");
3171             return;
3172         }
3173         p2pMap_.Compute(networkId, [this](const auto &key, auto &value) {
3174             value.Compute(P2P_PRESYNC_ID, [](const auto &key, auto &value) {
3175                 value = 0;
3176                 return true;
3177             });
3178             return true;
3179         });
3180         preSyncP2pMap_.emplace(networkId, pasteBlock);
3181     }
3182     if (OpenP2PLinkForPreEstablish(networkId, clipPlugin)) {
3183         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PreEstablishP2PLink Finish");
3184     } else {
3185         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "PreEstablishP2PLink failed");
3186     }
3187     pasteBlock->SetValue(SET_VALUE_SUCCESS);
3188 #endif
3189 }
3190 
PreEstablishP2PLinkCallback(const std::string & networkId,ClipPlugin * clipPlugin)3191 void PasteboardService::PreEstablishP2PLinkCallback(const std::string &networkId, ClipPlugin *clipPlugin)
3192 {
3193     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PreEstablishP2PLinkCallback enter");
3194     if (networkId.empty()) {
3195         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "PreEstablishP2PLinkCallback failed, networkId is null");
3196         return;
3197     }
3198     if (!clipPlugin) {
3199         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin is null");
3200         return;
3201     }
3202     if (!ffrtTimer_) {
3203         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ffrtTimer_ is null");
3204         return;
3205     }
3206 #ifdef PB_DEVICE_MANAGER_ENABLE
3207     FFRTTask p2pTask = [this, networkId, clipPlugin] {
3208         std::thread thread([=]() {
3209             PreEstablishP2PLink(networkId, clipPlugin);
3210         });
3211         thread.detach();
3212     };
3213     std::string taskName = "PreEstablishP2PLink_";
3214     taskName += networkId;
3215     ffrtTimer_->SetTimer(taskName, p2pTask);
3216 #endif
3217 }
3218 
PreSyncRemotePasteboardData()3219 void PasteboardService::PreSyncRemotePasteboardData()
3220 {
3221     auto clipPlugin = GetClipPlugin();
3222     if (!clipPlugin) {
3223         return;
3224     }
3225     if (!clipPlugin->NeedSyncTopEvent()) {
3226         return;
3227     }
3228     const int32_t DEFAULT_USER_ID = 0;
3229     clipPlugin->SendPreSyncEvent(DEFAULT_USER_ID);
3230 }
3231 
PreSyncSwitchMonitorCallback()3232 void PasteboardService::PreSyncSwitchMonitorCallback()
3233 {
3234     if (!ffrtTimer_) {
3235         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ffrtTimer_ is null");
3236         return;
3237     }
3238     FFRTTask monitorTask = [this] {
3239         std::thread thread([=]() {
3240             RegisterPreSyncMonitor();
3241         });
3242         thread.detach();
3243     };
3244     ffrtTimer_->SetTimer(REGISTER_PRESYNC_MONITOR, monitorTask);
3245 }
3246 
RegisterPreSyncMonitor()3247 void PasteboardService::RegisterPreSyncMonitor()
3248 {
3249     if (!ffrtTimer_) {
3250         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "ffrtTimer_ is null");
3251         return;
3252     }
3253     if (!MMI::InputManager::GetInstance()) {
3254         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "MMI::InputManager is null");
3255         return;
3256     }
3257     FFRTTask monitorTask = [this] {
3258         std::thread thread([=]() {
3259             UnRegisterPreSyncMonitor();
3260         });
3261         thread.detach();
3262     };
3263     if (subscribeActiveId_ != INVALID_SUBSCRIBE_ID) {
3264         ffrtTimer_->SetTimer(UNREGISTER_PRESYNC_MONITOR, monitorTask, PRESYNC_MONITOR_TIME);
3265         return;
3266     }
3267     std::shared_ptr<InputEventCallback> preSyncMonitor =
3268         std::make_shared<InputEventCallback>(InputEventCallback::INPUTTYPE_PRESYNC, this);
3269     if (!preSyncMonitor) {
3270         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "failed to alloc InputEventCallback");
3271         return;
3272     }
3273     subscribeActiveId_ = MMI::InputManager::GetInstance()->SubscribeInputActive(
3274         std::static_pointer_cast<MMI::IInputEventConsumer>(preSyncMonitor), PRESYNC_MONITOR_INTERVAL_MILLISECONDS);
3275     if (subscribeActiveId_ < 0) {
3276         subscribeActiveId_ = INVALID_SUBSCRIBE_ID;
3277         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "SubscribeInputActive failed");
3278         return;
3279     }
3280     ffrtTimer_->SetTimer(UNREGISTER_PRESYNC_MONITOR, monitorTask, PRESYNC_MONITOR_TIME);
3281 }
3282 
UnRegisterPreSyncMonitor()3283 void PasteboardService::UnRegisterPreSyncMonitor()
3284 {
3285     if (!MMI::InputManager::GetInstance()) {
3286         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "MMI::InputManager is null");
3287         return;
3288     }
3289     if (subscribeActiveId_ != INVALID_SUBSCRIBE_ID) {
3290         MMI::InputManager::GetInstance()->UnsubscribeInputActive(subscribeActiveId_);
3291         subscribeActiveId_ = INVALID_SUBSCRIBE_ID;
3292     }
3293 }
3294 
GetFocusedAppInfo(void) const3295 FocusedAppInfo PasteboardService::GetFocusedAppInfo(void) const
3296 {
3297     FocusedAppInfo appInfo = { 0 };
3298     FocusChangeInfo info;
3299 #ifdef SCENE_BOARD_ENABLE
3300     WindowManagerLite::GetInstance().GetFocusWindowInfo(info);
3301 #else
3302     WindowManager::GetInstance().GetFocusWindowInfo(info);
3303 #endif
3304     appInfo.windowId = info.windowId_;
3305     appInfo.abilityToken = info.abilityToken_;
3306     return appInfo;
3307 }
3308 
SetPasteDataDot(PasteData & pasteData)3309 void PasteboardService::SetPasteDataDot(PasteData &pasteData)
3310 {
3311     auto bundleName = pasteData.GetBundleName();
3312     HistoryInfo info{ pasteData.GetTime(), bundleName, "set", "" };
3313     SetPasteboardHistory(info);
3314 
3315     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData Report!");
3316     Reporter::GetInstance().PasteboardBehaviour().Report(
3317         { static_cast<int>(BehaviourPasteboardState::BPS_COPY_STATE), bundleName });
3318 
3319     int state = static_cast<int>(StatisticPasteboardState::SPS_COPY_STATE);
3320     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData GetDataSize!");
3321     size_t dataSize = GetDataSize(pasteData);
3322     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData timeC!");
3323     CalculateTimeConsuming timeC(dataSize, state);
3324 }
3325 
GetPasteDataDot(PasteData & pasteData,const std::string & bundleName)3326 void PasteboardService::GetPasteDataDot(PasteData &pasteData, const std::string &bundleName)
3327 {
3328     std::string remote;
3329     if (pasteData.IsRemote()) {
3330         remote = "remote";
3331     }
3332     std::string time = GetTime();
3333     HistoryInfo info{ time, bundleName, "get", remote };
3334     SetPasteboardHistory(info);
3335     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData Report!");
3336     int pState = StatisticPasteboardState::SPS_INVALID_STATE;
3337     int bState = BehaviourPasteboardState::BPS_INVALID_STATE;
3338     if (pasteData.IsRemote()) {
3339         pState = static_cast<int>(StatisticPasteboardState::SPS_REMOTE_PASTE_STATE);
3340         bState = static_cast<int>(BehaviourPasteboardState::BPS_REMOTE_PASTE_STATE);
3341     } else {
3342         pState = static_cast<int>(StatisticPasteboardState::SPS_PASTE_STATE);
3343         bState = static_cast<int>(BehaviourPasteboardState::BPS_PASTE_STATE);
3344     };
3345 
3346     Reporter::GetInstance().PasteboardBehaviour().Report({ bState, bundleName });
3347     size_t dataSize = GetDataSize(pasteData);
3348     CalculateTimeConsuming timeC(dataSize, pState);
3349 }
3350 
GetDistributedData(const Event & event,int32_t user)3351 std::pair<std::shared_ptr<PasteData>, PasteDateResult> PasteboardService::GetDistributedData(
3352     const Event &event, int32_t user)
3353 {
3354     auto clipPlugin = GetClipPlugin();
3355     PasteDateResult pasteDateResult;
3356     if (clipPlugin == nullptr) {
3357         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
3358         pasteDateResult.syncTime = -1;
3359         pasteDateResult.errorCode = static_cast<int32_t>(PasteboardError::REMOTE_TASK_ERROR);
3360         return std::make_pair(nullptr, pasteDateResult);
3361     }
3362     std::vector<uint8_t> rawData;
3363     auto result = clipPlugin->GetPasteData(event, rawData);
3364     if (result.first != 0) {
3365         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get data failed");
3366         Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
3367         pasteDateResult.syncTime = -1;
3368         pasteDateResult.errorCode = result.first;
3369         return std::make_pair(nullptr, pasteDateResult);
3370     }
3371 
3372     currentEvent_ = std::move(event);
3373     std::shared_ptr<PasteData> pasteData = std::make_shared<PasteData>();
3374     pasteData->Decode(rawData);
3375     pasteData->SetOriginAuthority(std::make_pair(pasteData->GetBundleName(), pasteData->GetAppIndex()));
3376     for (size_t i = 0; i < pasteData->GetRecordCount(); i++) {
3377         auto item = pasteData->GetRecordAt(i);
3378         if (item == nullptr || item->GetConvertUri().empty()) {
3379             continue;
3380         }
3381         if (item->GetOriginUri() == nullptr) {
3382             item->SetConvertUri("");
3383             continue;
3384         }
3385         item->isConvertUriFromRemote = true;
3386     }
3387     pasteDateResult.syncTime = result.second;
3388     pasteDateResult.errorCode = static_cast<int32_t>(PasteboardError::E_OK);
3389     return std::make_pair(pasteData, pasteDateResult);
3390 }
3391 
IsAllowSendData()3392 bool PasteboardService::IsAllowSendData()
3393 {
3394     auto controlType =
3395         system::GetIntParameter(TRANSMIT_CONTROL_PROP_KEY, CONTROL_TYPE_ALLOW_SEND_RECEIVE, INT_MIN, INT_MAX);
3396     if (controlType != CONTROL_TYPE_ALLOW_SEND_RECEIVE) {
3397         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "control type is: %{public}d.", controlType);
3398         return false;
3399     }
3400     return true;
3401 }
3402 
IsDisallowDistributed()3403 bool PasteboardService::IsDisallowDistributed()
3404 {
3405     pid_t uid = IPCSkeleton::GetCallingUid();
3406     if (uid == DEVICE_COLLABORATION_UID) {
3407         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uid from device collaboration");
3408         return true;
3409     }
3410     return false;
3411 }
3412 
SetDistributedData(int32_t user,PasteData & data)3413 bool PasteboardService::SetDistributedData(int32_t user, PasteData &data)
3414 {
3415     auto networkId = DMAdapter::GetInstance().GetLocalNetworkId();
3416     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(!networkId.empty(), false, PASTEBOARD_MODULE_SERVICE, "networkId is empty.");
3417     Event event;
3418     event.user = user;
3419     event.seqId = ++sequenceId_;
3420     auto expiration = PasteBoardTime::GetBootTimeMs() + EXPIRATION_INTERVAL;
3421     event.expiration = static_cast<uint64_t>(expiration);
3422     event.deviceId = networkId;
3423     event.account = AccountManager::GetInstance().GetCurrentAccount();
3424     event.status = ClipPlugin::EVT_NORMAL;
3425     event.dataType = data.GetMimeTypes();
3426     event.isDelay = data.IsDelayRecord();
3427     event.dataId = data.GetDataId();
3428     currentEvent_ = event;
3429 
3430     if (!IsAllowSendData() || IsDisallowDistributed()) {
3431         return false;
3432     }
3433     auto clipPlugin = GetClipPlugin();
3434     if (clipPlugin == nullptr) {
3435         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_ONLINE_DEVICE, DFX_SUCCESS);
3436         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clip plugin is null, dataId:%{public}u", data.GetDataId());
3437         return false;
3438     }
3439     ShareOption shareOpt = data.GetShareOption();
3440     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(shareOpt != ShareOption::InApp, false, PASTEBOARD_MODULE_SERVICE,
3441         "data share option is in app, dataId:%{public}u", data.GetDataId());
3442     if (CheckMdmShareOption(data)) {
3443         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(shareOpt != ShareOption::LocalDevice, false, PASTEBOARD_MODULE_SERVICE,
3444             "data share option is local device, dataId:%{public}u", data.GetDataId());
3445     }
3446     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "dataId:%{public}u, seqId:%{public}hu, isDelay:%{public}d,"
3447         "expiration:%{public}" PRIu64, event.dataId, event.seqId, event.isDelay, event.expiration);
3448     return SetCurrentDistributedData(data, event);
3449 }
3450 
SetCurrentDistributedData(PasteData & data,Event event)3451 bool PasteboardService::SetCurrentDistributedData(PasteData &data, Event event)
3452 {
3453     std::thread thread([this, data, event]() mutable {
3454         {
3455             std::lock_guard<std::mutex> lock(setDistributedMemory_.mutex);
3456             setDistributedMemory_.event = event;
3457             setDistributedMemory_.data = std::make_shared<PasteData>(data);
3458             if (setDistributedMemory_.isRunning) {
3459                 return;
3460             }
3461             setDistributedMemory_.isRunning = true;
3462         }
3463         bool isNeedCheck = false;
3464         while (true) {
3465             auto block = std::make_shared<BlockObject<bool>>(SET_DISTRIBUTED_DATA_INTERVAL, false);
3466             {
3467                 std::lock_guard<std::mutex> lock(setDistributedMemory_.mutex);
3468                 if ((event.seqId == setDistributedMemory_.event.seqId && isNeedCheck) ||
3469                     setDistributedMemory_.data == nullptr) {
3470                     setDistributedMemory_.data = nullptr;
3471                     setDistributedMemory_.isRunning = false;
3472                     break;
3473                 }
3474                 if (!isNeedCheck) {
3475                     isNeedCheck = true;
3476                 }
3477                 std::thread thread([this, event, block]() mutable {
3478                     PasteData data;
3479                     {
3480                         std::lock_guard<std::mutex> lock(setDistributedMemory_.mutex);
3481                         if (setDistributedMemory_.data == nullptr) {
3482                             block->SetValue(true);
3483                             return;
3484                         }
3485                         event = setDistributedMemory_.event;
3486                         data = *setDistributedMemory_.data;
3487                     }
3488                     auto result = SetCurrentData(event, data);
3489                     block->SetValue(true);
3490                 });
3491                 thread.detach();
3492             }
3493             bool ret = block->GetValue();
3494             if (!ret) {
3495                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "SetCurrentData timeout,seqId:%{public}hu", event.seqId);
3496             }
3497         }
3498     });
3499     thread.detach();
3500     return true;
3501 }
3502 
SetCurrentData(Event event,PasteData & data)3503 bool PasteboardService::SetCurrentData(Event event, PasteData &data)
3504 {
3505     auto clipPlugin = GetClipPlugin();
3506     if (clipPlugin == nullptr) {
3507         RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_CHECK_ONLINE_DEVICE, DFX_SUCCESS);
3508         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clip plugin is null, dataId:%{public}u", data.GetDataId());
3509         return false;
3510     }
3511     RADAR_REPORT(DFX_SET_PASTEBOARD, DFX_LOAD_DISTRIBUTED_PLUGIN, DFX_SUCCESS);
3512     bool needFull = data.IsDelayRecord() &&
3513         moduleConfig_.GetRemoteDeviceMinVersion() == DistributedModuleConfig::FIRST_VERSION;
3514     if (needFull) {
3515         GetFullDelayPasteData(event.user, data);
3516         event.isDelay = false;
3517         {
3518             std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3519             PasteboardWebController::GetInstance().SplitWebviewPasteData(data);
3520         }
3521         PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
3522         PasteboardWebController::GetInstance().CheckAppUriPermission(data);
3523     }
3524     GenerateDistributedUri(data);
3525     std::vector<uint8_t> rawData;
3526     auto remoteVersionMin = moduleConfig_.GetRemoteDeviceMinVersion();
3527     {
3528         std::shared_lock<std::shared_mutex> read(pasteDataMutex_);
3529         if (!data.Encode(rawData, remoteVersionMin <= DistributedModuleConfig::SECOND_VERSION)) {
3530             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
3531                 "distributed data encode failed, dataId:%{public}u, seqId:%{public}hu", event.dataId, event.seqId);
3532             return false;
3533         }
3534     }
3535     if (data.IsDelayRecord() && !needFull) {
3536         clipPlugin->RegisterDelayCallback(
3537             std::bind(&PasteboardService::GetDistributedDelayData, this, std::placeholders::_1,
3538                 std::placeholders::_2, std::placeholders::_3),
3539             std::bind(&PasteboardService::GetDistributedDelayEntry, this, std::placeholders::_1,
3540                 std::placeholders::_2, std::placeholders::_3, std::placeholders::_4));
3541     }
3542     clipPlugin->SetPasteData(event, rawData);
3543     return true;
3544 }
3545 
GetDistributedDelayEntry(const Event & evt,uint32_t recordId,const std::string & utdId,std::vector<uint8_t> & rawData)3546 int32_t PasteboardService::GetDistributedDelayEntry(const Event &evt, uint32_t recordId, const std::string &utdId,
3547     std::vector<uint8_t> &rawData)
3548 {
3549     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "dataId:%{public}u, seqId:%{public}hu, expiration:%{public}" PRIu64
3550         ", recordId:%{public}u, type:%{public}s", evt.dataId, evt.seqId, evt.expiration, recordId, utdId.c_str());
3551     auto [hasData, data] = clips_.Find(evt.user);
3552     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasData && data, static_cast<int32_t>(PasteboardError::NO_DATA_ERROR),
3553         PASTEBOARD_MODULE_SERVICE, "data not find, userId=%{public}u", evt.user);
3554     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(evt.dataId == data->GetDataId(),
3555         static_cast<int32_t>(PasteboardError::INVALID_DATA_ID), PASTEBOARD_MODULE_SERVICE,
3556         "dataId=%{public}u mismatch, local=%{public}u", evt.dataId, data->GetDataId());
3557 
3558     auto record = data->GetRecordById(recordId);
3559     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(record != nullptr, static_cast<int32_t>(PasteboardError::INVALID_RECORD_ID),
3560         PASTEBOARD_MODULE_SERVICE, "recordId=%{public}u invalid, max=%{public}zu", recordId, data->GetRecordCount());
3561 
3562     PasteDataEntry entry;
3563     entry.SetUtdId(utdId);
3564     int32_t ret = GetLocalEntryValue(evt.user, *data, *record, entry);
3565     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3566         PASTEBOARD_MODULE_SERVICE, "get local entry failed, seqId=%{public}hu, dataId=%{public}u, recordId=%{public}u"
3567         ", type=%{public}s, ret=%{public}d", evt.seqId, evt.dataId, recordId, utdId.c_str(), ret);
3568 
3569     std::string mimeType = entry.GetMimeType();
3570     if (mimeType == MIMETYPE_TEXT_URI) {
3571         ret = ProcessDistributedDelayUri(evt.user, *data, entry, rawData);
3572     } else if (mimeType == MIMETYPE_TEXT_HTML) {
3573         ret = ProcessDistributedDelayHtml(*data, entry, rawData);
3574     } else {
3575         ret = ProcessDistributedDelayEntry(entry, rawData);
3576     }
3577     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3578         PASTEBOARD_MODULE_SERVICE, "process distributed entry failed, seqId=%{public}hu, dataId=%{public}u, "
3579         "recordId=%{public}u, type=%{public}s, ret=%{public}d", evt.seqId, evt.dataId, recordId, utdId.c_str(), ret);
3580 
3581     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "type=%{public}s, size=%{public}zu", utdId.c_str(), rawData.size());
3582     return static_cast<int32_t>(PasteboardError::E_OK);
3583 }
3584 
ProcessDistributedDelayUri(int32_t userId,PasteData & data,PasteDataEntry & entry,std::vector<uint8_t> & rawData)3585 int32_t PasteboardService::ProcessDistributedDelayUri(int32_t userId, PasteData &data, PasteDataEntry &entry,
3586     std::vector<uint8_t> &rawData)
3587 {
3588     auto uri = entry.ConvertToUri();
3589     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(uri != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
3590         PASTEBOARD_MODULE_SERVICE, "convert entry to uri failed");
3591 
3592     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
3593     std::string localUri = uri->ToString();
3594     HmdfsUriInfo dfsUri;
3595     int32_t ret = RemoteFileShare::GetDfsUriFromLocal(localUri, userId, dfsUri);
3596     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == 0, ret, PASTEBOARD_MODULE_SERVICE,
3597         "generate distributed uri failed, uri=%{private}s", localUri.c_str());
3598 
3599     std::string distributedUri = dfsUri.uriStr;
3600     size_t fileSize = dfsUri.fileSize;
3601     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri: %{private}s -> %{private}s, fileSize=%{public}zu",
3602         localUri.c_str(), distributedUri.c_str(), fileSize);
3603 
3604     auto entryValue = entry.GetValue();
3605     if (std::holds_alternative<std::string>(entryValue)) {
3606         entry.SetValue(distributedUri);
3607     } else if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
3608         auto object = std::get<std::shared_ptr<Object>>(entryValue);
3609         auto newObject = std::make_shared<Object>();
3610         newObject->value_ = object->value_;
3611         newObject->value_[UDMF::FILE_URI_PARAM] = distributedUri;
3612         entry.SetValue(newObject);
3613         entry.SetFileSize(static_cast<int64_t>(fileSize));
3614     }
3615 
3616     bool encodeSucc = entry.Encode(rawData, true);
3617     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
3618         PASTEBOARD_MODULE_SERVICE, "encode uri failed");
3619     return static_cast<int32_t>(PasteboardError::E_OK);
3620 }
3621 
ProcessDistributedDelayHtml(PasteData & data,PasteDataEntry & entry,std::vector<uint8_t> & rawData)3622 int32_t PasteboardService::ProcessDistributedDelayHtml(PasteData &data, PasteDataEntry &entry,
3623     std::vector<uint8_t> &rawData)
3624 {
3625     {
3626         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3627         if (PasteboardWebController::GetInstance().SplitWebviewPasteData(data)) {
3628             PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
3629             PasteboardWebController::GetInstance().CheckAppUriPermission(data);
3630         }
3631     }
3632 
3633     PasteData tmp;
3634     std::shared_ptr<std::string> html = entry.ConvertToHtml();
3635     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(html != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
3636         PASTEBOARD_MODULE_SERVICE, "convert to html failed");
3637 
3638     tmp.AddHtmlRecord(*html);
3639     tmp.SetBundleInfo(data.GetBundleName(), data.GetAppIndex());
3640     tmp.SetOriginAuthority(data.GetOriginAuthority());
3641     tmp.SetTokenId(data.GetTokenId());
3642     if (PasteboardWebController::GetInstance().SplitWebviewPasteData(tmp)) {
3643         PasteboardWebController::GetInstance().SetWebviewPasteData(tmp, data.GetOriginAuthority());
3644         PasteboardWebController::GetInstance().CheckAppUriPermission(tmp);
3645         GenerateDistributedUri(tmp);
3646     }
3647 
3648     auto remoteVersionMin = moduleConfig_.GetRemoteDeviceMinVersion();
3649     bool encodeSucc = tmp.Encode(rawData, remoteVersionMin <= DistributedModuleConfig::SECOND_VERSION);
3650     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
3651         PASTEBOARD_MODULE_SERVICE, "encode html failed");
3652     return static_cast<int32_t>(PasteboardError::E_OK);
3653 }
3654 
ProcessDistributedDelayEntry(PasteDataEntry & entry,std::vector<uint8_t> & rawData)3655 int32_t PasteboardService::ProcessDistributedDelayEntry(PasteDataEntry &entry, std::vector<uint8_t> &rawData)
3656 {
3657     bool encodeSucc = entry.Encode(rawData, true);
3658     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
3659         PASTEBOARD_MODULE_SERVICE, "encode entry failed, type=%{public}s", entry.GetUtdId().c_str());
3660     return static_cast<int32_t>(PasteboardError::E_OK);
3661 }
3662 
GetDistributedDelayData(const Event & evt,uint8_t version,std::vector<uint8_t> & rawData)3663 int32_t PasteboardService::GetDistributedDelayData(const Event &evt, uint8_t version, std::vector<uint8_t> &rawData)
3664 {
3665     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "dataId:%{public}u, seqId:%{public}hu, expiration:%{public}" PRIu64,
3666         evt.dataId, evt.seqId, evt.expiration);
3667     auto [hasData, data] = clips_.Find(evt.user);
3668     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasData && data, static_cast<int32_t>(PasteboardError::NO_DATA_ERROR),
3669         PASTEBOARD_MODULE_SERVICE, "data not find, userId=%{public}u", evt.user);
3670     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(evt.dataId == data->GetDataId(),
3671         static_cast<int32_t>(PasteboardError::INVALID_DATA_ID), PASTEBOARD_MODULE_SERVICE,
3672         "dataId=%{public}u mismatch, local=%{public}u", evt.dataId, data->GetDataId());
3673 
3674     int32_t ret = static_cast<int32_t>(PasteboardError::E_OK);
3675     if (version == 0) {
3676         ret = GetFullDelayPasteData(evt.user, *data);
3677     } else if (version == 1) {
3678         ret = GetDelayPasteRecord(evt.user, *data);
3679     }
3680     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3681         PASTEBOARD_MODULE_SERVICE, "get delay data failed, version=%{public}hhu", version);
3682 
3683     auto authorityInfo = data->GetOriginAuthority();
3684     data->SetBundleInfo(authorityInfo.first, authorityInfo.second);
3685     {
3686         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3687         PasteboardWebController::GetInstance().SplitWebviewPasteData(*data);
3688     }
3689     PasteboardWebController::GetInstance().SetWebviewPasteData(*data, authorityInfo);
3690     PasteboardWebController::GetInstance().CheckAppUriPermission(*data);
3691     GenerateDistributedUri(*data);
3692 
3693     auto remoteVersionMin = moduleConfig_.GetRemoteDeviceMinVersion();
3694     std::shared_lock<std::shared_mutex> read(pasteDataMutex_);
3695     bool encodeSucc = data->Encode(rawData, remoteVersionMin <= DistributedModuleConfig::SECOND_VERSION);
3696     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(encodeSucc, static_cast<int32_t>(PasteboardError::DATA_ENCODE_ERROR),
3697         PASTEBOARD_MODULE_SERVICE, "encode data failed, dataId:%{public}u, seqId:%{public}hu", evt.dataId, evt.seqId);
3698 
3699     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "size=%{public}zu", rawData.size());
3700     return static_cast<int32_t>(PasteboardError::E_OK);
3701 }
3702 
GetLocalEntryValue(int32_t userId,PasteData & data,PasteDataRecord & record,PasteDataEntry & value)3703 int32_t PasteboardService::GetLocalEntryValue(int32_t userId, PasteData &data, PasteDataRecord &record,
3704     PasteDataEntry &value)
3705 {
3706     std::string utdId = value.GetUtdId();
3707     auto entry = record.GetEntry(utdId);
3708     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(entry != nullptr, static_cast<int32_t>(PasteboardError::INVALID_MIMETYPE),
3709         PASTEBOARD_MODULE_SERVICE, "entry is null, recordId=%{public}u, type=%{public}s", record.GetRecordId(),
3710         utdId.c_str());
3711 
3712     std::string mimeType = entry->GetMimeType();
3713     value.SetMimeType(mimeType);
3714     if (entry->HasContent(utdId)) {
3715         value.SetValue(entry->GetValue());
3716         return static_cast<int32_t>(PasteboardError::E_OK);
3717     }
3718 
3719     auto [hasGetter, getter] = entryGetters_.Find(userId);
3720     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasGetter && getter.first,
3721         static_cast<int32_t>(PasteboardError::NO_DELAY_GETTER), PASTEBOARD_MODULE_SERVICE,
3722         "entry getter not find, userId=%{public}d, dataId=%{public}u", userId, data.GetDataId());
3723 
3724     int32_t ret = getter.first->GetRecordValueByType(record.GetRecordId(), value);
3725     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3726         PASTEBOARD_MODULE_SERVICE, "get local entry failed, type=%{public}s, ret=%{public}d", utdId.c_str(), ret);
3727 
3728     {
3729         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3730         record.AddEntry(utdId, std::make_shared<PasteDataEntry>(value));
3731     }
3732     return static_cast<int32_t>(PasteboardError::E_OK);
3733 }
3734 
GetRemoteEntryValue(const AppInfo & appInfo,PasteData & data,PasteDataRecord & record,PasteDataEntry & entry)3735 int32_t PasteboardService::GetRemoteEntryValue(const AppInfo &appInfo, PasteData &data, PasteDataRecord &record,
3736     PasteDataEntry &entry)
3737 {
3738     auto clipPlugin = GetClipPlugin();
3739     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(clipPlugin != nullptr, static_cast<int32_t>(PasteboardError::PLUGIN_IS_NULL),
3740         PASTEBOARD_MODULE_SERVICE, "plugin is null");
3741 
3742     auto [distRet, distEvt] = GetValidDistributeEvent(appInfo.userId);
3743     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(distRet == static_cast<int32_t>(PasteboardError::E_OK) ||
3744         distRet == static_cast<int32_t>(PasteboardError::GET_SAME_REMOTE_DATA), distRet,
3745         PASTEBOARD_MODULE_SERVICE, "get distribute event failed, ret=%{public}d", distRet);
3746 
3747     std::vector<uint8_t> rawData;
3748     std::string utdId = entry.GetUtdId();
3749     int32_t ret = clipPlugin->GetPasteDataEntry(distEvt, record.GetRecordId(), utdId, rawData);
3750     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == 0, ret, PASTEBOARD_MODULE_SERVICE, "get remote raw data failed");
3751 
3752     std::string mimeType = entry.GetMimeType();
3753     if (mimeType == MIMETYPE_TEXT_HTML) {
3754         ret = ProcessRemoteDelayHtml(distEvt.deviceId, appInfo, rawData, data, record, entry);
3755         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3756             PASTEBOARD_MODULE_SERVICE, "process remote delay html failed");
3757         return static_cast<int32_t>(PasteboardError::E_OK);
3758     }
3759 
3760     PasteDataEntry tmpEntry;
3761     tmpEntry.Decode(rawData);
3762     entry.SetValue(tmpEntry.GetValue());
3763     {
3764         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3765         record.AddEntry(utdId, std::make_shared<PasteDataEntry>(entry));
3766     }
3767 
3768     if (mimeType != MIMETYPE_TEXT_URI) {
3769         return static_cast<int32_t>(PasteboardError::E_OK);
3770     }
3771 
3772     return ProcessRemoteDelayUri(distEvt.deviceId, appInfo, data, record, entry);
3773 }
3774 
ProcessRemoteDelayUri(const std::string & deviceId,const AppInfo & appInfo,PasteData & data,PasteDataRecord & record,PasteDataEntry & entry)3775 int32_t PasteboardService::ProcessRemoteDelayUri(const std::string &deviceId, const AppInfo &appInfo,
3776     PasteData &data, PasteDataRecord &record, PasteDataEntry &entry)
3777 {
3778     auto uri = entry.ConvertToUri();
3779     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(uri != nullptr, static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED),
3780         PASTEBOARD_MODULE_SERVICE, "convert entry to uri failed");
3781     std::string distributedUri = uri->ToString();
3782     record.SetConvertUri(distributedUri);
3783     record.isConvertUriFromRemote = true;
3784     record.SetGrantUriPermission(true);
3785 
3786     int64_t uriFileSize = entry.GetFileSize();
3787     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "uri=%{private}s, fileSize=%{public}" PRId64,
3788         distributedUri.c_str(), uriFileSize);
3789     if (uriFileSize > 0) {
3790         int64_t dataFileSize = data.GetFileSize();
3791         int64_t fileSize = (uriFileSize > INT64_MAX - dataFileSize) ? INT64_MAX : uriFileSize + dataFileSize;
3792         data.SetFileSize(fileSize);
3793     }
3794     std::vector<Uri> grantUris = CheckUriPermission(data, std::make_pair(appInfo.bundleName, appInfo.appIndex));
3795     if (!grantUris.empty()) {
3796         EstablishP2PLink(deviceId, data.GetPasteId());
3797         int32_t ret = GrantUriPermission(grantUris, appInfo.bundleName, data.IsRemote(), appInfo.appIndex);
3798         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3799             PASTEBOARD_MODULE_SERVICE, "grant remote uri failed, uri=%{private}s, ret=%{public}d",
3800             distributedUri.c_str(), ret);
3801     }
3802     return static_cast<int32_t>(PasteboardError::E_OK);
3803 }
3804 
ProcessRemoteDelayHtml(const std::string & remoteDeviceId,const AppInfo & appInfo,const std::vector<uint8_t> & rawData,PasteData & data,PasteDataRecord & record,PasteDataEntry & entry)3805 int32_t PasteboardService::ProcessRemoteDelayHtml(const std::string &remoteDeviceId, const AppInfo &appInfo,
3806     const std::vector<uint8_t> &rawData, PasteData &data, PasteDataRecord &record, PasteDataEntry &entry)
3807 {
3808     PasteData tmpData;
3809     tmpData.Decode(rawData);
3810     auto htmlRecord = tmpData.GetRecordById(1);
3811     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(htmlRecord != nullptr,
3812         static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED), PASTEBOARD_MODULE_SERVICE, "record is null");
3813     auto htmlEntry = htmlRecord->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
3814     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(htmlEntry != nullptr,
3815         static_cast<int32_t>(PasteboardError::GET_ENTRY_VALUE_FAILED), PASTEBOARD_MODULE_SERVICE, "htmlEntry is null");
3816     entry.SetValue(htmlEntry->GetValue());
3817     {
3818         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3819         record.AddEntry(entry.GetUtdId(), std::make_shared<PasteDataEntry>(entry));
3820     }
3821 
3822     PASTEBOARD_CHECK_AND_RETURN_RET_LOGD(htmlRecord->GetFrom() != 0, static_cast<int32_t>(PasteboardError::E_OK),
3823         PASTEBOARD_MODULE_SERVICE, "no uri");
3824 
3825     data.SetTag(PasteData::WEBVIEW_PASTEDATA_TAG);
3826     uint32_t htmlRecordId = record.GetRecordId();
3827     record.SetFrom(htmlRecordId);
3828     for (auto &recordItem : tmpData.AllRecords()) {
3829         if (recordItem == nullptr) {
3830             continue;
3831         }
3832         if (!recordItem->GetConvertUri().empty()) {
3833             recordItem->isConvertUriFromRemote = true;
3834         }
3835         if (recordItem->GetFrom() > 0 && recordItem->GetRecordId() != recordItem->GetFrom()) {
3836             recordItem->SetFrom(htmlRecordId);
3837             data.AddRecord(*recordItem);
3838         }
3839     }
3840 
3841     return ProcessRemoteDelayHtmlInner(remoteDeviceId, appInfo, tmpData, data, entry);
3842 }
3843 
ProcessRemoteDelayHtmlInner(const std::string & remoteDeviceId,const AppInfo & appInfo,PasteData & tmpData,PasteData & data,PasteDataEntry & entry)3844 int32_t PasteboardService::ProcessRemoteDelayHtmlInner(const std::string &remoteDeviceId, const AppInfo &appInfo,
3845     PasteData &tmpData, PasteData &data, PasteDataEntry &entry)
3846 {
3847     int64_t htmlFileSize = tmpData.GetFileSize();
3848     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "htmlFileSize=%{public}" PRId64, htmlFileSize);
3849     if (htmlFileSize > 0) {
3850         int64_t dataFileSize = data.GetFileSize();
3851         int64_t fileSize = (htmlFileSize > INT64_MAX - dataFileSize) ? INT64_MAX : htmlFileSize + dataFileSize;
3852         data.SetFileSize(fileSize);
3853     }
3854 
3855     std::vector<Uri> grantUris = CheckUriPermission(data, std::make_pair(appInfo.bundleName, appInfo.appIndex));
3856     if (!grantUris.empty()) {
3857         EstablishP2PLink(remoteDeviceId, data.GetPasteId());
3858         int32_t ret = GrantUriPermission(grantUris, appInfo.bundleName, data.IsRemote(), appInfo.appIndex);
3859         PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3860             PASTEBOARD_MODULE_SERVICE, "grant to %{public}s failed, ret=%{public}d", appInfo.bundleName.c_str(), ret);
3861     }
3862 
3863     tmpData.SetOriginAuthority(data.GetOriginAuthority());
3864     tmpData.SetTokenId(data.GetTokenId());
3865     tmpData.SetRemote(data.IsRemote());
3866     int32_t ret = PostProcessDelayHtmlEntry(tmpData, appInfo, entry);
3867     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(ret == static_cast<int32_t>(PasteboardError::E_OK), ret,
3868         PASTEBOARD_MODULE_SERVICE, "post process remote html failed, ret=%{public}d", ret);
3869     return static_cast<int32_t>(PasteboardError::E_OK);
3870 }
3871 
GetFullDelayPasteData(int32_t userId,PasteData & data)3872 int32_t PasteboardService::GetFullDelayPasteData(int32_t userId, PasteData &data)
3873 {
3874     auto [hasGetter, getter] = entryGetters_.Find(userId);
3875     PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(hasGetter && getter.first,
3876         static_cast<int32_t>(PasteboardError::NO_DELAY_GETTER), PASTEBOARD_MODULE_SERVICE,
3877         "entry getter not find, userId=%{public}d, dataId=%{public}u", userId, data.GetDataId());
3878 
3879     for (auto record : data.AllRecords()) {
3880         if (!record->IsDelayRecord()) {
3881             continue;
3882         }
3883         auto recordId = record->GetRecordId();
3884         auto mimeType = record->GetMimeType();
3885         for (auto entry : record->GetEntries()) {
3886             if (!std::holds_alternative<std::monostate>(entry->GetValue())) {
3887                 continue;
3888             }
3889             auto result = getter.first->GetRecordValueByType(recordId, *entry);
3890             if (result != static_cast<int32_t>(PasteboardError::E_OK)) {
3891                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
3892                     "get record value fail, dataId is %{public}d, recordId is %{public}d, mimeType is %{public}s",
3893                     data.GetDataId(), record->GetRecordId(), entry->GetMimeType().c_str());
3894                 continue;
3895             }
3896             if (entry->GetMimeType() == mimeType) {
3897                 std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3898                 record->AddEntry(entry->GetUtdId(), std::make_shared<PasteDataEntry>(*entry));
3899             }
3900         }
3901     }
3902     {
3903         std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3904         PasteboardWebController::GetInstance().SplitWebviewPasteData(data);
3905     }
3906     PasteboardWebController::GetInstance().SetWebviewPasteData(data, data.GetOriginAuthority());
3907     PasteboardWebController::GetInstance().CheckAppUriPermission(data);
3908     clips_.ComputeIfPresent(userId, [&data](auto, auto &value) {
3909         if (data.GetDataId() != value->GetDataId()) {
3910             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE,
3911                 "set data fail, data is out time, pre dataId is %{public}d, cur dataId is %{public}d",
3912                 data.GetDataId(), value->GetDataId());
3913             return true;
3914         }
3915         value = std::make_shared<PasteData>(data);
3916         return true;
3917     });
3918     return static_cast<int32_t>(PasteboardError::E_OK);
3919 }
3920 
GenerateDistributedUri(PasteData & data)3921 void PasteboardService::GenerateDistributedUri(PasteData &data)
3922 {
3923     std::vector<std::string> uris;
3924     std::vector<size_t> indexes;
3925     auto userId = GetCurrentAccountId();
3926     PASTEBOARD_CHECK_AND_RETURN_LOGE(userId != ERROR_USERID, PASTEBOARD_MODULE_SERVICE, "invalid userId");
3927     std::unique_lock<std::shared_mutex> write(pasteDataMutex_);
3928     for (size_t i = 0; i < data.GetRecordCount(); i++) {
3929         auto item = data.GetRecordAt(i);
3930         if (item == nullptr) {
3931             continue;
3932         }
3933         item->SetConvertUri("");
3934         const auto &uri = item->GetOriginUri();
3935         if (uri == nullptr) {
3936             continue;
3937         }
3938         auto hasGrantUriPermission = item->HasGrantUriPermission();
3939         const std::string &bundleName = data.GetOriginAuthority().first;
3940         if (!IsBundleOwnUriPermission(bundleName, *uri) && !hasGrantUriPermission) {
3941             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "uri:%{private}s, bundleName:%{public}s, appIndex:%{public}d,"
3942                 " has grant:%{public}d", uri->ToString().c_str(), bundleName.c_str(), data.GetOriginAuthority().second,
3943                 hasGrantUriPermission);
3944             continue;
3945         }
3946         uris.emplace_back(uri->ToString());
3947         indexes.emplace_back(i);
3948     }
3949     size_t fileSize = 0;
3950     std::unordered_map<std::string, HmdfsUriInfo> dfsUris;
3951     if (!uris.empty()) {
3952         int ret = Storage::DistributedFile::FileMountManager::GetDfsUrisDirFromLocal(uris, userId, dfsUris);
3953         PASTEBOARD_CHECK_AND_RETURN_LOGE((ret == 0 && !dfsUris.empty()), PASTEBOARD_MODULE_SERVICE,
3954             "Get remoteUri failed, ret:%{public}d, userId:%{public}d, uri size:%{public}zu.", ret, userId, uris.size());
3955         for (size_t i = 0; i < indexes.size(); i++) {
3956             auto item = data.GetRecordAt(indexes[i]);
3957             if (item == nullptr || item->GetOriginUri() == nullptr) {
3958                 continue;
3959             }
3960             auto it = dfsUris.find(item->GetOriginUri()->ToString());
3961             if (it != dfsUris.end()) {
3962                 item->SetConvertUri(it->second.uriStr);
3963                 fileSize += it->second.fileSize;
3964             }
3965         }
3966     }
3967     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "file size: %{public}zu", fileSize);
3968     data.SetFileSize(static_cast<int64_t>(fileSize));
3969 }
3970 
GetClipPlugin()3971 std::shared_ptr<ClipPlugin> PasteboardService::GetClipPlugin()
3972 {
3973     auto isOn = moduleConfig_.IsOn();
3974     if (isOn) {
3975         auto securityLevel = securityLevel_.GetDeviceSecurityLevel();
3976         if (securityLevel < DATA_SEC_LEVEL3) {
3977             return nullptr;
3978         }
3979     }
3980     std::lock_guard<decltype(mutex)> lockGuard(mutex);
3981     if (!isOn || clipPlugin_ != nullptr) {
3982         return clipPlugin_;
3983     }
3984     Loader loader;
3985     loader.LoadComponents();
3986     auto release = [this](ClipPlugin *plugin) {
3987         ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
3988     };
3989 
3990     clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
3991     RegisterPreSyncCallback(clipPlugin_);
3992     return clipPlugin_;
3993 }
3994 
CleanDistributedData(int32_t user)3995 void PasteboardService::CleanDistributedData(int32_t user)
3996 {
3997     auto clipPlugin = GetClipPlugin();
3998     if (clipPlugin == nullptr) {
3999         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
4000         return;
4001     }
4002     clipPlugin->Clear(user);
4003 }
4004 
CloseDistributedStore(int32_t user,bool isNeedClear)4005 void PasteboardService::CloseDistributedStore(int32_t user, bool isNeedClear)
4006 {
4007     auto clipPlugin = GetClipPlugin();
4008     if (clipPlugin == nullptr) {
4009         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
4010         return;
4011     }
4012     if (isNeedClear) {
4013         clipPlugin->Clear(user);
4014     }
4015     clipPlugin->Close(user);
4016 }
4017 
OnConfigChange(bool isOn)4018 void PasteboardService::OnConfigChange(bool isOn)
4019 {
4020     std::thread thread([=]() {
4021         OnConfigChangeInner(isOn);
4022     });
4023     thread.detach();
4024 }
4025 
OnConfigChangeInner(bool isOn)4026 void PasteboardService::OnConfigChangeInner(bool isOn)
4027 {
4028     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "ConfigChange isOn: %{public}d.", isOn);
4029     {
4030         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
4031         p2pMap_.Clear();
4032     }
4033     std::lock_guard<decltype(mutex)> lockGuard(mutex);
4034     if (!isOn) {
4035         PASTEBOARD_CHECK_AND_RETURN_LOGE(clipPlugin_ != nullptr, PASTEBOARD_MODULE_SERVICE, "clipPlugin is null");
4036         int32_t userId = GetCurrentAccountId();
4037         clipPlugin_->Close(userId);
4038         clipPlugin_ = nullptr;
4039         return;
4040     }
4041     SetCriticalTimer();
4042     auto securityLevel = securityLevel_.GetDeviceSecurityLevel();
4043     if (securityLevel < DATA_SEC_LEVEL3) {
4044         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "device sec level is %{public}u less than 3.", securityLevel);
4045         return;
4046     }
4047     if (clipPlugin_ != nullptr) {
4048         return;
4049     }
4050     SubscribeKeyboardEvent();
4051     Loader loader;
4052     loader.LoadComponents();
4053     auto release = [this](ClipPlugin *plugin) {
4054         ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
4055     };
4056 
4057     clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
4058     RegisterPreSyncCallback(clipPlugin_);
4059 }
4060 
GetAppLabel(uint32_t tokenId)4061 std::string PasteboardService::GetAppLabel(uint32_t tokenId)
4062 {
4063     auto iBundleMgr = GetAppBundleManager();
4064     if (iBundleMgr == nullptr) {
4065         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to cast bundle mgr service.");
4066         return PasteBoardDialog::DEFAULT_LABEL;
4067     }
4068     AppInfo info = GetAppInfo(tokenId);
4069     AppExecFwk::ApplicationInfo appInfo;
4070     auto result = iBundleMgr->GetApplicationInfo(info.bundleName, 0, info.userId, appInfo);
4071     if (!result) {
4072         return PasteBoardDialog::DEFAULT_LABEL;
4073     }
4074     auto &resource = appInfo.labelResource;
4075     auto label = iBundleMgr->GetStringById(resource.bundleName, resource.moduleName, resource.id, info.userId);
4076     return label.empty() ? PasteBoardDialog::DEFAULT_LABEL : label;
4077 }
4078 
GetAppBundleManager()4079 sptr<AppExecFwk::IBundleMgr> PasteboardService::GetAppBundleManager()
4080 {
4081     auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
4082     if (systemAbilityManager == nullptr) {
4083         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get SystemAbilityManager.");
4084         return nullptr;
4085     }
4086     auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
4087     if (remoteObject == nullptr) {
4088         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get bundle mgr service.");
4089         return nullptr;
4090     }
4091     return OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
4092 }
4093 
ChangeStoreStatus(int32_t userId)4094 void PasteboardService::ChangeStoreStatus(int32_t userId)
4095 {
4096     PasteboardService::currentUserId_ = userId;
4097     auto clipPlugin = GetClipPlugin();
4098     if (clipPlugin == nullptr) {
4099         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
4100         return;
4101     }
4102     clipPlugin->ChangeStoreStatus(userId);
4103 }
4104 
OnReceiveEvent(const EventFwk::CommonEventData & data)4105 void PasteBoardCommonEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData &data)
4106 {
4107     auto want = data.GetWant();
4108     std::string action = want.GetAction();
4109     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
4110         std::lock_guard<std::mutex> lock(mutex_);
4111         int32_t userId = data.GetCode();
4112         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "user id switched: %{public}d", userId);
4113         if (pasteboardService_ != nullptr) {
4114             pasteboardService_->ChangeStoreStatus(userId);
4115             auto accountId = pasteboardService_->GetCurrentAccountId();
4116             pasteboardService_->switch_.DeInit();
4117             pasteboardService_->switch_.Init(accountId);
4118             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "SetSwitch end");
4119         }
4120     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_STOPPING) {
4121         std::lock_guard<std::mutex> lock(mutex_);
4122         int32_t userId = data.GetCode();
4123         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "user id is stopping: %{public}d", userId);
4124         if (pasteboardService_ != nullptr) {
4125             pasteboardService_->Clear();
4126         }
4127     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED) {
4128         std::lock_guard<std::mutex> lock(mutex_);
4129         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "screen is locked");
4130         PasteboardService::currentScreenStatus = ScreenEvent::ScreenLocked;
4131     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
4132         std::lock_guard<std::mutex> lock(mutex_);
4133         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "screen is unlocked");
4134         PasteboardService::currentScreenStatus = ScreenEvent::ScreenUnlocked;
4135     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED) {
4136         auto tokenId = want.GetIntParam("accessTokenId", -1);
4137         if (pasteboardService_ != nullptr) {
4138             pasteboardService_->RevokeUriOnUninstall(tokenId);
4139         }
4140     }
4141 }
4142 
RevokeUriOnUninstall(int32_t tokenId)4143 void PasteboardService::RevokeUriOnUninstall(int32_t tokenId)
4144 {
4145     PASTEBOARD_CHECK_AND_RETURN_LOGE(tokenId >= 0, PASTEBOARD_MODULE_SERVICE, "tokenId is invalids");
4146     auto userId = GetCurrentAccountId();
4147     clips_.ComputeIfPresent(userId, [this, tokenId, userId](auto, auto &pasteData) {
4148         if (pasteData == nullptr) {
4149             return true;
4150         }
4151         if (pasteData->GetTokenId() != static_cast<uint32_t>(tokenId)) {
4152             return true;
4153         }
4154         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "revoke and clear uri tokenId: %{public}d", tokenId);
4155         RevokeAndClearUri(pasteData);
4156         delayGetters_.ComputeIfPresent(userId, [](auto, auto &delayGetter) {
4157             if (delayGetter.first != nullptr && delayGetter.second != nullptr) {
4158                 delayGetter.first->AsObject()->RemoveDeathRecipient(delayGetter.second);
4159             }
4160             return false;
4161         });
4162         entryGetters_.ComputeIfPresent(userId, [](auto, auto &entryGetter) {
4163             if (entryGetter.first != nullptr && entryGetter.second != nullptr) {
4164                 entryGetter.first->AsObject()->RemoveDeathRecipient(entryGetter.second);
4165             }
4166             return false;
4167         });
4168         return true;
4169     });
4170 }
4171 
RevokeAndClearUri(std::shared_ptr<PasteData> pasteData)4172 void PasteboardService::RevokeAndClearUri(std::shared_ptr<PasteData> pasteData)
4173 {
4174     std::set<std::pair<std::string, int32_t>> bundles;
4175     {
4176         std::lock_guard<std::mutex> lock(readBundleMutex_);
4177         bundles = std::move(readBundles_);
4178     }
4179     PASTEBOARD_CHECK_AND_RETURN_LOGE(pasteData != nullptr, PASTEBOARD_MODULE_SERVICE, "pasteData is null");
4180     std::thread thread([pasteData, bundles, this]() {
4181         auto &permissionClient = AAFwk::UriPermissionManagerClient::GetInstance();
4182         std::unique_lock<std::shared_mutex> threadWriteLock(this->pasteDataMutex_);
4183         for (size_t i = 0; i < pasteData->GetRecordCount(); i++) {
4184             auto item = pasteData->GetRecordAt(i);
4185             if (item == nullptr || item->GetOriginUri() == nullptr) {
4186                 continue;
4187             }
4188             Uri uri = *(item->GetOriginUri());
4189             for (std::set<std::pair<std::string, int32_t>>::iterator it = bundles.begin(); it != bundles.end(); it++) {
4190                 auto permissionCode = permissionClient.RevokeUriPermissionManually(uri, it->first, it->second);
4191                 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "permissionCode is %{public}d", permissionCode);
4192             }
4193             auto emptyUri = std::make_shared<OHOS::Uri>("");
4194             item->SetUri(emptyUri);
4195         }
4196     });
4197     thread.detach();
4198 }
4199 
OnStateChanged(const AccountSA::OsAccountStateData & data)4200 void PasteBoardAccountStateSubscriber::OnStateChanged(const AccountSA::OsAccountStateData &data)
4201 {
4202     std::thread thread([=]() {
4203         OnStateChangedInner(data);
4204     });
4205     thread.detach();
4206 }
4207 
OnStateChangedInner(const AccountSA::OsAccountStateData & data)4208 void PasteBoardAccountStateSubscriber::OnStateChangedInner(const AccountSA::OsAccountStateData &data)
4209 {
4210     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "state: %{public}d, fromId: %{public}d, toId: %{public}d,"
4211         "callback is nullptr: %{public}d", data.state, data.fromId, data.toId, data.callback == nullptr);
4212     if (data.state == AccountSA::OsAccountState::STOPPING && pasteboardService_ != nullptr) {
4213         std::lock_guard<std::mutex> lock(mutex_);
4214         pasteboardService_->CloseDistributedStore(data.fromId, true);
4215     }
4216     if (data.callback != nullptr) {
4217         data.callback->OnComplete();
4218     }
4219 }
4220 
SubscribeKeyboardEvent()4221 bool PasteboardService::SubscribeKeyboardEvent()
4222 {
4223     std::lock_guard<std::mutex> lock(eventMutex_);
4224     if (inputEventCallback_ != nullptr) {
4225         return true;
4226     }
4227     inputEventCallback_ = std::make_shared<InputEventCallback>();
4228     int32_t monitorId = MMI::InputManager::GetInstance()->AddMonitor(
4229         std::static_pointer_cast<MMI::IInputEventConsumer>(inputEventCallback_), MMI::HANDLE_EVENT_TYPE_KEY);
4230     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "add monitor ret is: %{public}d", monitorId);
4231     return monitorId >= 0;
4232 }
4233 
PasteboardEventSubscriber()4234 void PasteboardService::PasteboardEventSubscriber()
4235 {
4236     EventCenter::GetInstance().Subscribe(PasteboardEvent::DISCONNECT, [this](const OHOS::MiscServices::Event &event) {
4237         auto &evt = static_cast<const PasteboardEvent &>(event);
4238         auto networkId = evt.GetNetworkId();
4239         if (networkId.empty()) {
4240             PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "networkId is empty.");
4241             return;
4242         }
4243         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
4244         p2pMap_.EraseIf([networkId, this](auto &key, auto &value) {
4245             if (key == networkId) {
4246                 CloseP2PLink(networkId);
4247                 return true;
4248             }
4249             return false;
4250         });
4251     });
4252 }
4253 
CommonEventSubscriber()4254 void PasteboardService::CommonEventSubscriber()
4255 {
4256     if (commonEventSubscriber_ != nullptr) {
4257         return;
4258     }
4259     EventFwk::MatchingSkills matchingSkills;
4260     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
4261     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_STOPPING);
4262     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_LOCKED);
4263     matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
4264     EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills);
4265     commonEventSubscriber_ = std::make_shared<PasteBoardCommonEventSubscriber>(subscribeInfo, this);
4266     EventFwk::CommonEventManager::SubscribeCommonEvent(commonEventSubscriber_);
4267 }
4268 
AccountStateSubscriber()4269 void PasteboardService::AccountStateSubscriber()
4270 {
4271     if (accountStateSubscriber_ != nullptr) {
4272         return;
4273     }
4274     std::set<AccountSA::OsAccountState> states = { AccountSA::OsAccountState::STOPPING,
4275         AccountSA::OsAccountState::CREATED, AccountSA::OsAccountState::SWITCHING,
4276         AccountSA::OsAccountState::SWITCHED, AccountSA::OsAccountState::UNLOCKED,
4277         AccountSA::OsAccountState::STOPPED, AccountSA::OsAccountState::REMOVED };
4278     AccountSA::OsAccountSubscribeInfo subscribeInfo(states, true);
4279     accountStateSubscriber_ = std::make_shared<PasteBoardAccountStateSubscriber>(subscribeInfo, this);
4280     AccountSA::OsAccountManager::SubscribeOsAccount(accountStateSubscriber_);
4281 }
4282 
RemoveObserverByPid(int32_t userId,pid_t pid,ObserverMap & observerMap)4283 void PasteboardService::RemoveObserverByPid(int32_t userId, pid_t pid, ObserverMap &observerMap)
4284 {
4285     std::lock_guard<std::mutex> lock(observerMutex_);
4286     auto callObserverKey = std::make_pair(userId, pid);
4287     auto it = observerMap.find(callObserverKey);
4288     if (it == observerMap.end()) {
4289         return;
4290     }
4291     observerMap.erase(callObserverKey);
4292 }
4293 
AppExit(pid_t pid)4294 int32_t PasteboardService::AppExit(pid_t pid)
4295 {
4296     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "pid %{public}d exit.", pid);
4297     int32_t userId = GetCurrentAccountId();
4298     RemoveObserverByPid(userId, pid, observerLocalChangedMap_);
4299     RemoveObserverByPid(userId, pid, observerRemoteChangedMap_);
4300     RemoveObserverByPid(COMMON_USERID, pid, observerEventMap_);
4301     entityObserverMap_.Erase(pid);
4302     ClearInputMethodPidByPid(userId, pid);
4303     DisposableManager::GetInstance().RemoveDisposableInfo(pid, false);
4304     std::vector<std::string> networkIds;
4305     {
4306         std::lock_guard<std::mutex> tmpMutex(p2pMapMutex_);
4307         p2pMap_.EraseIf([pid, &networkIds, this](auto &networkId, auto &pidMap) {
4308             pidMap.EraseIf([pid, this](const auto &key, const auto &value) {
4309                 if (value == pid) {
4310                     PasteStart(key);
4311                     return true;
4312                 }
4313                 return false;
4314             });
4315             if (pidMap.Empty()) {
4316                 networkIds.emplace_back(networkId);
4317                 return true;
4318             }
4319             return false;
4320         });
4321     }
4322     for (const auto &id : networkIds) {
4323         CloseP2PLink(id);
4324     }
4325     clients_.Erase(pid);
4326     return ERR_OK;
4327 }
4328 
OnRemoteDied(const wptr<IRemoteObject> & remote)4329 void PasteboardService::PasteboardDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
4330 {
4331     (void)remote;
4332     service_.AppExit(pid_);
4333 }
4334 
PasteboardDeathRecipient(PasteboardService & service,sptr<IRemoteObject> observer,pid_t pid)4335 PasteboardService::PasteboardDeathRecipient::PasteboardDeathRecipient(
4336     PasteboardService &service, sptr<IRemoteObject> observer, pid_t pid)
4337     : service_(service), observer_(observer), pid_(pid)
4338 {
4339     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Construct Pasteboard Client Death Recipient, pid: %{public}d", pid);
4340 }
4341 
RegisterClientDeathObserver(const sptr<IRemoteObject> & observer)4342 int32_t PasteboardService::RegisterClientDeathObserver(const sptr<IRemoteObject> &observer)
4343 {
4344     pid_t pid = IPCSkeleton::GetCallingPid();
4345     sptr<PasteboardDeathRecipient> deathRecipient = new (std::nothrow) PasteboardDeathRecipient(*this, observer, pid);
4346     observer->AddDeathRecipient(deathRecipient);
4347     clients_.InsertOrAssign(pid, std::move(deathRecipient));
4348     return ERR_OK;
4349 }
4350 
RemotePasteboardChange()4351 std::function<void(const OHOS::MiscServices::Event &)> PasteboardService::RemotePasteboardChange()
4352 {
4353     return [this](const OHOS::MiscServices::Event &event) {
4354         (void)event;
4355         std::lock_guard<std::mutex> lock(observerMutex_);
4356         for (auto &observers : observerRemoteChangedMap_) {
4357             for (const auto &observer : *(observers.second)) {
4358                 observer->OnPasteboardChanged();
4359             }
4360         }
4361     };
4362 }
4363 
CallbackEnter(uint32_t code)4364 int32_t PasteboardService::CallbackEnter(uint32_t code)
4365 {
4366     if (!IPCSkeleton::IsLocalCalling()) {
4367         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "invalid request, only support local, cmd:%{public}u", code);
4368         return ERR_TRANSACTION_FAILED;
4369     }
4370     if (code == static_cast<uint32_t>(IPasteboardServiceIpcCode::COMMAND_HAS_PASTE_DATA)) {
4371         return ERR_NONE;
4372     }
4373     pid_t pid = IPCSkeleton::GetCallingPid();
4374     pid_t uid = IPCSkeleton::GetCallingUid();
4375     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "pid:%{public}d, uid:%{public}d, cmd:%{public}u", pid, uid, code);
4376     return ERR_NONE;
4377 }
4378 
CallbackExit(uint32_t code,int32_t result)4379 int32_t PasteboardService::CallbackExit(uint32_t code, int32_t result)
4380 {
4381     if (code == static_cast<uint32_t>(IPasteboardServiceIpcCode::COMMAND_HAS_PASTE_DATA)) {
4382         return ERR_NONE;
4383     }
4384     pid_t pid = IPCSkeleton::GetCallingPid();
4385     pid_t uid = IPCSkeleton::GetCallingUid();
4386     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "pid:%{public}d, uid:%{public}d, cmd:%{public}u, ret:%{public}d",
4387         pid, uid, code, result);
4388     return ERR_NONE;
4389 }
4390 
OnKeyInputEventForPaste(std::shared_ptr<MMI::KeyEvent> keyEvent) const4391 void InputEventCallback::OnKeyInputEventForPaste(std::shared_ptr<MMI::KeyEvent> keyEvent) const
4392 {
4393     auto keyItems = keyEvent->GetKeyItems();
4394     if (keyItems.size() != CTRLV_EVENT_SIZE) {
4395         return;
4396     }
4397     if ((keyEvent->GetKeyAction() == MMI::KeyEvent::KEY_ACTION_DOWN) &&
4398         ((keyItems[0].GetKeyCode() == MMI::KeyEvent::KEYCODE_CTRL_LEFT) ||
4399         (keyItems[0].GetKeyCode() == MMI::KeyEvent::KEYCODE_CTRL_RIGHT)) &&
4400         keyItems[1].GetKeyCode() == MMI::KeyEvent::KEYCODE_V) {
4401         int32_t windowId = keyEvent->GetTargetWindowId();
4402         std::unique_lock<std::shared_mutex> lock(inputEventMutex_);
4403         windowPid_ = MMI::InputManager::GetInstance()->GetWindowPid(windowId);
4404         actionTime_ =
4405             static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
4406         std::shared_ptr<BlockObject<int32_t>> block = nullptr;
4407         {
4408             std::unique_lock<std::shared_mutex> blockMapLock(blockMapMutex_);
4409             auto it = blockMap_.find(windowPid_);
4410             if (it != blockMap_.end()) {
4411                 block = it->second;
4412             } else {
4413                 block = std::make_shared<BlockObject<int32_t>>(WAIT_TIME_OUT, 0);
4414                 blockMap_.insert(std::make_pair(windowPid_, block));
4415             }
4416         }
4417         if (block != nullptr) {
4418             block->SetValue(SET_VALUE_SUCCESS);
4419         }
4420     }
4421 }
4422 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const4423 void InputEventCallback::OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const
4424 {
4425     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "keyEvent, inputType_ = %{public}d", inputType_);
4426     if (inputType_ == INPUTTYPE_PASTE) {
4427         OnKeyInputEventForPaste(keyEvent);
4428     } else if (inputType_ == INPUTTYPE_PRESYNC) {
4429         if (pasteboardService_) {
4430             pasteboardService_->PreSyncRemotePasteboardData();
4431         }
4432     } else {
4433         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "invalid inputType_ = %{public}d", inputType_);
4434     }
4435 }
4436 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const4437 void InputEventCallback::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
4438 {
4439     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "pointerEvent, inputType_ = %{public}d", inputType_);
4440     if (inputType_ == INPUTTYPE_PRESYNC) {
4441         if (pasteboardService_) {
4442             pasteboardService_->PreSyncRemotePasteboardData();
4443         }
4444     }
4445 }
4446 
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const4447 void InputEventCallback::OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const {}
4448 
IsCtrlVProcess(uint32_t callingPid,bool isFocused)4449 bool InputEventCallback::IsCtrlVProcess(uint32_t callingPid, bool isFocused)
4450 {
4451     std::shared_ptr<BlockObject<int32_t>> block = nullptr;
4452     {
4453         std::unique_lock<std::shared_mutex> blockMapLock(blockMapMutex_);
4454         auto it = blockMap_.find(callingPid);
4455         if (it != blockMap_.end()) {
4456             block = it->second;
4457         } else {
4458             block = std::make_shared<BlockObject<int32_t>>(WAIT_TIME_OUT, 0);
4459             blockMap_.insert(std::make_pair(callingPid, block));
4460         }
4461     }
4462     if (block != nullptr) {
4463         block->GetValue();
4464     }
4465     std::shared_lock<std::shared_mutex> lock(inputEventMutex_);
4466     auto curTime = static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
4467     auto ret = (callingPid == static_cast<uint32_t>(windowPid_) || isFocused) && curTime >= actionTime_ &&
4468         curTime - actionTime_ < EVENT_TIME_OUT;
4469     if (!ret) {
4470         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "windowPid is: %{public}d, callingPid is: %{public}d,"
4471             "curTime is: %{public}" PRIu64 ", actionTime is: %{public}" PRIu64 ", isFocused is: %{public}d",
4472             windowPid_, callingPid, curTime, actionTime_, isFocused);
4473     }
4474     return ret;
4475 }
4476 
Clear()4477 void InputEventCallback::Clear()
4478 {
4479     std::unique_lock<std::shared_mutex> lock(inputEventMutex_);
4480     actionTime_ = 0;
4481     windowPid_ = 0;
4482     std::unique_lock<std::shared_mutex> blockMapLock(blockMapMutex_);
4483     blockMap_.clear();
4484 }
4485 } // namespace MiscServices
4486 } // namespace OHOS
4487