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