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