1 /*
2 * Copyright (C) 2021-2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "pasteboard_service.h"
16
17 #include <unistd.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/block_object.h"
24 #include "dev_manager.h"
25 #include "dev_profile.h"
26 #include "device/dm_adapter.h"
27 #include "dfx_code_constant.h"
28 #include "dfx_types.h"
29 #include "distributed_file_daemon_manager.h"
30 #include "distributed_module_config.h"
31 #include "hiview_adapter.h"
32 #include "input_method_controller.h"
33 #include "iservice_registry.h"
34 #include "loader.h"
35 #include "int_wrapper.h"
36 #include "native_token_info.h"
37 #include "os_account_manager.h"
38 #include "para_handle.h"
39 #include "pasteboard_dialog.h"
40 #include "pasteboard_error.h"
41 #include "pasteboard_trace.h"
42 #include "remote_file_share.h"
43 #include "reporter.h"
44 #include "uri_permission_manager_client.h"
45 #ifdef WITH_DLP
46 #include "dlp_permission_kit.h"
47 #endif // WITH_DLP
48
49 namespace OHOS {
50 namespace MiscServices {
51 using namespace std::chrono;
52 using namespace Storage::DistributedFile;
53 namespace {
54 constexpr const int GET_WRONG_SIZE = 0;
55 const std::int32_t INIT_INTERVAL = 10000L;
56 const std::string PASTEBOARD_SERVICE_NAME = "PasteboardService";
57 const std::string FAIL_TO_GET_TIME_STAMP = "FAIL_TO_GET_TIME_STAMP";
58 const std::string PASTEBOARD_PROXY_AUTHOR_URI = "ohos.permission.PROXY_AUTHORIZATION_URI";
59 const std::int32_t ANCO_CALL_UID = 5528;
60 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(new PasteboardService());
61 } // namespace
62 using namespace Security::AccessToken;
63 using namespace OHOS::AppFileService::ModuleRemoteFileShare;
64 std::mutex PasteboardService::historyMutex_;
65 std::vector<std::string> PasteboardService::dataHistory_;
66 std::shared_ptr<Command> PasteboardService::copyHistory;
67 std::shared_ptr<Command> PasteboardService::copyData;
68
PasteboardService()69 PasteboardService::PasteboardService()
70 : SystemAbility(PASTEBOARD_SERVICE_ID, true), state_(ServiceRunningState::STATE_NOT_START)
71 {
72 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PasteboardService Start.");
73 ServiceListenerFunc_[static_cast<int32_t>(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID)] =
74 &PasteboardService::DevManagerInit;
75 ServiceListenerFunc_[static_cast<int32_t>(DISTRIBUTED_DEVICE_PROFILE_SA_ID)] = &PasteboardService::DevProfileInit;
76 }
77
~PasteboardService()78 PasteboardService::~PasteboardService()
79 {
80 }
81
Init()82 int32_t PasteboardService::Init()
83 {
84 if (!Publish(this)) {
85 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStart register to system ability manager failed.");
86 auto userId = GetCurrentAccountId();
87 Reporter::GetInstance().PasteboardFault().Report({ userId, "ERR_INVALID_OPTION" });
88 return static_cast<int32_t>(PasteboardError::E_INVALID_OPTION);
89 }
90 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Init Success.");
91 state_ = ServiceRunningState::STATE_RUNNING;
92 return ERR_OK;
93 }
94
OnStart()95 void PasteboardService::OnStart()
96 {
97 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PasteboardService OnStart.");
98 if (state_ == ServiceRunningState::STATE_RUNNING) {
99 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "PasteboardService is already running.");
100 return;
101 }
102
103 InitServiceHandler();
104 auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
105 Loader loader;
106 loader.LoadComponents();
107 DMAdapter::GetInstance().Initialize(appInfo.bundleName);
108 DistributedModuleConfig::Watch(std::bind(&PasteboardService::OnConfigChange, this, std::placeholders::_1));
109
110 AddSysAbilityListener();
111
112 if (Init() != ERR_OK) {
113 auto callback = [this]() { Init(); };
114 serviceHandler_->PostTask(callback, INIT_INTERVAL);
115 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Init failed. Try again 10s later.");
116 return;
117 }
118
119 copyHistory = std::make_shared<Command>(std::vector<std::string>{ "--copy-history" },
120 "Dump access history last ten times.",
121 [this](const std::vector<std::string> &input, std::string &output) -> bool {
122 output = DumpHistory();
123 return true;
124 });
125
126 copyData = std::make_shared<Command>(std::vector<std::string>{ "--data" }, "Show copy data details.",
127 [this](const std::vector<std::string> &input, std::string &output) -> bool {
128 output = DumpData();
129 return true;
130 });
131
132 PasteboardDumpHelper::GetInstance().RegisterCommand(copyHistory);
133 PasteboardDumpHelper::GetInstance().RegisterCommand(copyData);
134
135 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Start PasteboardService success.");
136 HiViewAdapter::StartTimerThread();
137 return;
138 }
139
OnStop()140 void PasteboardService::OnStop()
141 {
142 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop Started.");
143 if (state_ != ServiceRunningState::STATE_RUNNING) {
144 return;
145 }
146 serviceHandler_ = nullptr;
147 state_ = ServiceRunningState::STATE_NOT_START;
148
149 ParaHandle::GetInstance().WatchEnabledStatus(nullptr);
150 DevManager::GetInstance().UnregisterDevCallback();
151
152 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop End.");
153 }
154
AddSysAbilityListener()155 void PasteboardService::AddSysAbilityListener()
156 {
157 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "begin.");
158 for (uint32_t i = 0; i < sizeof(LISTENING_SERVICE) / sizeof(LISTENING_SERVICE[0]); i++) {
159 auto ret = AddSystemAbilityListener(LISTENING_SERVICE[i]);
160 PASTEBOARD_HILOGD(
161 PASTEBOARD_MODULE_SERVICE, "ret = %{public}d, serviceId = %{public}d.", ret, LISTENING_SERVICE[i]);
162 }
163 }
164
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)165 void PasteboardService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
166 {
167 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "systemAbilityId = %{public}d added!", systemAbilityId);
168 auto itFunc = ServiceListenerFunc_.find(systemAbilityId);
169 if (itFunc != ServiceListenerFunc_.end()) {
170 auto ServiceListenerFunc = itFunc->second;
171 if (ServiceListenerFunc != nullptr) {
172 (this->*ServiceListenerFunc)();
173 }
174 }
175 }
176
DevManagerInit()177 void PasteboardService::DevManagerInit()
178 {
179 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "begin.");
180 DevManager::GetInstance().Init();
181 }
182
DevProfileInit()183 void PasteboardService::DevProfileInit()
184 {
185 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "begin.");
186 ParaHandle::GetInstance().Init();
187 DevProfile::GetInstance().Init();
188 }
189
InitServiceHandler()190 void PasteboardService::InitServiceHandler()
191 {
192 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler started.");
193 if (serviceHandler_ != nullptr) {
194 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Already init.");
195 return;
196 }
197 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(PASTEBOARD_SERVICE_NAME);
198 serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
199
200 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler Succeeded.");
201 }
202
Clear()203 void PasteboardService::Clear()
204 {
205 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
206 auto userId = GetCurrentAccountId();
207 if (userId == ERROR_USERID) {
208 return;
209 }
210 std::lock_guard<std::recursive_mutex> lock(clipMutex_);
211 auto it = clips_.find(userId);
212 if (it != clips_.end()) {
213 RevokeUriPermission(*(it->second));
214 clips_.erase(it);
215 auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
216 std::string bundleName = GetAppBundleName(appInfo);
217 NotifyObservers(bundleName, PasteboardEventStatus::PASTEBOARD_CLEAR);
218 }
219 auto hintItem = hints_.find(userId);
220 if (hintItem != hints_.end()) {
221 hints_.erase(hintItem);
222 }
223 CleanDistributedData(userId);
224 }
225
IsDefaultIME(const AppInfo & appInfo)226 bool PasteboardService::IsDefaultIME(const AppInfo &appInfo)
227 {
228 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "start.");
229 if (appInfo.tokenType != ATokenTypeEnum::TOKEN_HAP) {
230 return true;
231 }
232 std::shared_ptr<Property> property = InputMethodController::GetInstance()->GetCurrentInputMethod();
233 return property != nullptr && property->name == appInfo.bundleName;
234 }
235
IsFocusedApp(const std::string & bundleName)236 bool PasteboardService::IsFocusedApp(const std::string &bundleName)
237 {
238 if (bundleName.empty()) {
239 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get bundle name by token failed");
240 return false;
241 }
242 auto elementName = OHOS::AAFwk::AbilityManagerClient::GetInstance()->GetTopAbility();
243 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, " Top app:%{public}s, caller app:%{public}s",
244 elementName.GetBundleName().c_str(), bundleName.c_str());
245 return elementName.GetBundleName() == bundleName;
246 }
247
HasPastePermission(uint32_t tokenId,bool isFocusedApp,const std::shared_ptr<PasteData> & pasteData)248 bool PasteboardService::HasPastePermission(
249 uint32_t tokenId, bool isFocusedApp, const std::shared_ptr<PasteData> &pasteData)
250 {
251 if (pasteData == nullptr) {
252 return false;
253 }
254
255 if (!pasteData->IsDraggedData() && (!isFocusedApp && !IsDefaultIME(GetAppInfo(tokenId)))) {
256 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "token:0x%{public}x", tokenId);
257 return false;
258 }
259 switch (pasteData->GetShareOption()) {
260 case ShareOption::InApp: {
261 if (pasteData->GetTokenId() != tokenId) {
262 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "InApp check failed.");
263 return false;
264 }
265 break;
266 }
267 case ShareOption::LocalDevice: {
268 break;
269 }
270 case ShareOption::CrossDevice: {
271 break;
272 }
273 default: {
274 PASTEBOARD_HILOGE(
275 PASTEBOARD_MODULE_SERVICE, "shareOption = %{public}d is error.", pasteData->GetShareOption());
276 return false;
277 }
278 }
279 return true;
280 }
281
GetAppInfo(uint32_t tokenId)282 AppInfo PasteboardService::GetAppInfo(uint32_t tokenId)
283 {
284 AppInfo info;
285 info.tokenId = tokenId;
286 info.tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
287 switch (info.tokenType) {
288 case ATokenTypeEnum::TOKEN_HAP: {
289 HapTokenInfo hapInfo;
290 if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
291 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get hap token info fail.");
292 return info;
293 }
294 info.bundleName = hapInfo.bundleName;
295 info.userId = GetCurrentAccountId();
296 break;
297 }
298 case ATokenTypeEnum::TOKEN_NATIVE:
299 case ATokenTypeEnum::TOKEN_SHELL: {
300 NativeTokenInfo tokenInfo;
301 if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
302 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get native token info fail.");
303 return info;
304 }
305 info.bundleName = tokenInfo.processName;
306 info.userId = GetCurrentAccountId();
307 break;
308 }
309 default: {
310 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "tokenType = %{public}d not match.", info.tokenType);
311 }
312 }
313 return info;
314 }
315
GetAppBundleName(const AppInfo & appInfo)316 std::string PasteboardService::GetAppBundleName(const AppInfo &appInfo)
317 {
318 std::string bundleName;
319 if (appInfo.userId != ERROR_USERID) {
320 bundleName = appInfo.bundleName;
321 } else {
322 bundleName = "error";
323 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetAppInfo error");
324 }
325 return bundleName;
326 }
327
SetLocalPasteFlag(bool isCrossPaste,uint32_t tokenId,PasteData & pasteData)328 void PasteboardService::SetLocalPasteFlag(bool isCrossPaste, uint32_t tokenId, PasteData &pasteData)
329 {
330 pasteData.SetLocalPasteFlag(!isCrossPaste && tokenId == pasteData.GetTokenId());
331 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "isLocalPaste = %{public}d.", pasteData.IsLocalPaste());
332 }
333
GetPasteData(PasteData & data)334 int32_t PasteboardService::GetPasteData(PasteData &data)
335 {
336 CalculateTimeConsuming::SetBeginTime();
337
338 PasteboardTrace tracer("PasteboardService GetPasteData");
339
340 auto tokenId = IPCSkeleton::GetCallingTokenID();
341 auto appInfo = GetAppInfo(tokenId);
342 bool isFocusedApp = IsFocusedApp(appInfo.bundleName);
343 bool result = false;
344 std::string pop;
345 auto clipPlugin = GetClipPlugin();
346 if (clipPlugin == nullptr) {
347 result = CheckPasteData(appInfo, data, isFocusedApp);
348 } else {
349 std::lock_guard<std::mutex> lock(remoteMutex_);
350 result = GetRemoteData(appInfo, data, pop, isFocusedApp, tokenId);
351 }
352 if (observerEventMap_.size() != 0) {
353 std::string targetBundleName = GetAppBundleName(appInfo);
354 NotifyObservers(targetBundleName, PasteboardEventStatus::PASTEBOARD_READ);
355 }
356 GetPasteDataDot(data, pop, appInfo.bundleName);
357 GrantUriPermission(data, appInfo.bundleName);
358 return result ? static_cast<int32_t>(PasteboardError::E_OK) : static_cast<int32_t>(PasteboardError::E_ERROR);
359 }
360
GetRemoteData(AppInfo & appInfo,PasteData & data,std::string & pop,bool isFocusedApp,uint32_t tokenId)361 bool PasteboardService::GetRemoteData(
362 AppInfo &appInfo, PasteData &data, std::string &pop, bool isFocusedApp, uint32_t tokenId)
363 {
364 auto block = std::make_shared<BlockObject<std::shared_ptr<PasteData>>>(PasteBoardDialog::POPUP_INTERVAL);
365 std::thread thread([this, block, isFocusedApp, &appInfo]() mutable {
366 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData Begin");
367 std::shared_ptr<PasteData> pasteData = std::make_shared<PasteData>();
368 auto success = GetPasteData(appInfo, *pasteData, isFocusedApp);
369 if (!success) {
370 pasteData->SetInvalid();
371 }
372 block->SetValue(pasteData);
373 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData End");
374 });
375 thread.detach();
376 auto value = block->GetValue();
377 if (value == nullptr) {
378 if (IsDefaultIME(appInfo)) {
379 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "not need show dialog");
380 block->SetInterval(PasteBoardDialog::MAX_LIFE_TIME);
381 value = block->GetValue();
382 } else {
383 PasteBoardDialog::MessageInfo message;
384 message.appName = GetAppLabel(tokenId);
385 message.deviceType = GetDeviceName();
386 PasteBoardDialog::GetInstance().ShowDialog(message, [block] { block->SetValue(nullptr); });
387 pop = "pop";
388 block->SetInterval(PasteBoardDialog::MAX_LIFE_TIME);
389 value = block->GetValue();
390 PasteBoardDialog::GetInstance().CancelDialog();
391 SetDeviceName();
392 }
393 }
394 if (value != nullptr) {
395 auto ret = value->IsValid();
396 data = std::move(*value);
397 return ret;
398 }
399 return false;
400 }
401
GetPasteData(AppInfo & appInfo,PasteData & data,bool isFocusedApp)402 bool PasteboardService::GetPasteData(AppInfo &appInfo, PasteData &data, bool isFocusedApp)
403 {
404 PasteboardTrace tracer("GetPasteData inner");
405 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start inner.");
406 if (appInfo.userId == ERROR_USERID) {
407 PasteData::sharePath = "";
408 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId error.");
409 return false;
410 }
411 PasteData::sharePath = PasteData::SHARE_PATH_PREFIX + std::to_string(appInfo.userId)
412 + PasteData::SHARE_PATH_PREFIX_ACCOUNT;
413 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Clips length %{public}d.", static_cast<uint32_t>(clips_.size()));
414 bool isRemote = false;
415 std::lock_guard<std::recursive_mutex> lock(clipMutex_);
416 auto pastData = GetDistributedData(appInfo.userId);
417 if (pastData != nullptr) {
418 isRemote = true;
419 pastData->SetRemote(isRemote);
420 clips_.insert_or_assign(appInfo.userId, pastData);
421 }
422 data.SetRemote(isRemote);
423 return CheckPasteData(appInfo, data, isFocusedApp);
424 }
425
CheckPasteData(AppInfo & appInfo,PasteData & data,bool isFocusedApp)426 bool PasteboardService::CheckPasteData(AppInfo &appInfo, PasteData &data, bool isFocusedApp)
427 {
428 {
429 std::lock_guard<std::recursive_mutex> lock(clipMutex_);
430 auto it = clips_.find(appInfo.userId);
431 if (it == clips_.end()) {
432 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "no data.");
433 return false;
434 }
435 auto ret = HasPastePermission(appInfo.tokenId, isFocusedApp, it->second);
436 if (!ret) {
437 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "don't have paste permission.");
438 return false;
439 }
440 it->second->SetBundleName(appInfo.bundleName);
441 data = PasteData(*(it->second));
442 }
443 auto fileSize = data.GetProperty().additions.GetIntParam(PasteData::REMOTE_FILE_SIZE, -1);
444 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "get remote fileSize %{public}d", fileSize);
445 if (data.IsRemote() && fileSize > 0) {
446 EstablishP2PLink(fileSize);
447 std::this_thread::sleep_for(std::chrono::seconds(OPEN_P2P_SLEEP_TIME));
448 }
449 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "GetPasteData success.");
450 SetLocalPasteFlag(data.IsRemote(), appInfo.tokenId, data);
451 return true;
452 }
453
EstablishP2PLink(int fileSize)454 void PasteboardService::EstablishP2PLink(int fileSize)
455 {
456 auto keepLinkTime = (fileSize / TRANMISSION_BASELINE) * 3 + MIN_TRANMISSION_TIME;
457 DmDeviceInfo remoteDevice;
458 auto ret = DMAdapter::GetInstance().GetRemoteDeviceInfo(currentEvent_.deviceId, remoteDevice);
459 if (ret != RESULT_OK) {
460 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "remote device is not exist");
461 return;
462 }
463 std::thread thread([this, remoteDevice, keepLinkTime]() mutable {
464 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "EstablishP2PLink");
465 DistributedFileDaemonManager::GetInstance().OpenP2PConnection(remoteDevice);
466 std::this_thread::sleep_for(std::chrono::seconds(keepLinkTime));
467 DistributedFileDaemonManager::GetInstance().CloseP2PConnection(remoteDevice);
468 });
469 thread.detach();
470 }
471
GrantUriPermission(PasteData & data,const std::string & targetBundleName)472 void PasteboardService::GrantUriPermission(PasteData &data, const std::string &targetBundleName)
473 {
474 for (size_t i = 0; i < data.GetRecordCount(); i++) {
475 auto item = data.GetRecordAt(i);
476 if (item == nullptr || (!data.IsRemote()
477 && targetBundleName.compare(data.GetOrginAuthority()) == 0)) {
478 continue;
479 }
480 std::shared_ptr<OHOS::Uri> uri = nullptr;
481 if (!item->isConvertUriFromRemote && !item->GetConvertUri().empty()) {
482 item->SetConvertUri("");
483 }
484 if (item->isConvertUriFromRemote && !item->GetConvertUri().empty()) {
485 uri = std::make_shared<OHOS::Uri>(item->GetConvertUri());
486 } else if (!item->isConvertUriFromRemote && item->GetOrginUri() != nullptr) {
487 uri = item->GetOrginUri();
488 }
489 if (uri == nullptr || (!isBundleOwnUriPermission(data.GetOrginAuthority(), *uri)
490 && !item->HasGrantUriPermission())) {
491 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "do not grant permission: %{public}d.",
492 item->HasGrantUriPermission());
493 continue;
494 }
495 auto& permissionClient = AAFwk::UriPermissionManagerClient::GetInstance();
496 auto permissionCode = permissionClient.GrantUriPermission(*uri, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION,
497 targetBundleName, 1);
498 if (permissionCode == 0 && readBundles_.count(targetBundleName) == 0) {
499 readBundles_.insert(targetBundleName);
500 }
501 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "permissionCode is %{public}d, targetBundleName is %{public}s",
502 permissionCode, targetBundleName.c_str());
503 }
504 }
505
RevokeUriPermission(PasteData & lastData)506 void PasteboardService::RevokeUriPermission(PasteData &lastData)
507 {
508 if (readBundles_.size() == 0) {
509 return;
510 }
511 auto& permissionClient = AAFwk::UriPermissionManagerClient::GetInstance();
512 for (size_t i = 0; i < lastData.GetRecordCount(); i++) {
513 auto item = lastData.GetRecordAt(i);
514 if (item == nullptr || item->GetOrginUri() == nullptr) {
515 continue;
516 }
517 Uri uri = *(item->GetOrginUri());
518 for (std::set<std::string>::iterator it = readBundles_.begin(); it != readBundles_.end(); it++) {
519 auto permissionCode = permissionClient.RevokeUriPermissionManually(uri, *it);
520 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "permissionCode is %{public}d", permissionCode);
521 }
522 }
523 readBundles_.clear();
524 }
525
isBundleOwnUriPermission(const std::string & bundleName,Uri & uri)526 bool PasteboardService::isBundleOwnUriPermission(const std::string &bundleName, Uri &uri)
527 {
528 auto authority = uri.GetAuthority();
529 if (bundleName.compare(authority) != 0) {
530 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "grant error, uri:%{public}s, orgin:%{public}s",
531 authority.c_str(), bundleName.c_str());
532 return false;
533 }
534 return true;
535 }
536
CheckAppUriPermission(PasteData & data)537 void PasteboardService::CheckAppUriPermission(PasteData &data)
538 {
539 for (size_t i = 0; i < data.GetRecordCount(); i++) {
540 auto item = data.GetRecordAt(i);
541 if (item == nullptr || item->GetOrginUri() == nullptr) {
542 continue;
543 }
544 auto uri = item->GetOrginUri();
545 int32_t ret = Security::AccessToken::AccessTokenKit::VerifyAccessToken(data.GetTokenId(),
546 PASTEBOARD_PROXY_AUTHOR_URI);
547 if (ret != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
548 continue;
549 }
550 item->SetGrantUriPermission(true);
551 }
552 }
553
ShowHintToast(bool isValid,uint32_t tokenId,const std::shared_ptr<PasteData> & pasteData)554 void PasteboardService::ShowHintToast(bool isValid, uint32_t tokenId, const std::shared_ptr<PasteData> &pasteData)
555 {
556 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "show hint toast start");
557 if (!isValid || pasteData == nullptr || pasteData->IsDraggedData()) {
558 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "data is invalid");
559 return;
560 }
561 auto dataTokenId = pasteData->GetTokenId();
562 if (IsDefaultIME(GetAppInfo(tokenId)) || dataTokenId == tokenId || pasteData->IsRemote()) {
563 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "not need show hint toast");
564 return;
565 }
566 auto userId = GetCurrentAccountId();
567 auto hintItem = hints_.find(userId);
568 if (hintItem != hints_.end()) {
569 auto hintTokenId = std::find(hintItem->second.begin(), hintItem->second.end(), tokenId);
570 if (hintTokenId != hintItem->second.end()) {
571 return;
572 }
573 }
574 hints_[userId].emplace_back(tokenId);
575
576 PasteBoardDialog::ToastMessageInfo message;
577 message.fromAppName = GetAppLabel(dataTokenId);
578 message.toAppName = GetAppLabel(tokenId);
579 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "toast should show, fromName=%{public}s, toName = %{public}s",
580 message.fromAppName.c_str(), message.toAppName.c_str());
581 std::thread thread([this, message]() mutable {
582 PasteBoardDialog::GetInstance().ShowToast(message);
583 std::this_thread::sleep_for(std::chrono::milliseconds(PasteBoardDialog::SHOW_TOAST_TIME));
584 PasteBoardDialog::GetInstance().CancelToast();
585 });
586 thread.detach();
587 }
588
HasPasteData()589 bool PasteboardService::HasPasteData()
590 {
591 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
592 auto userId = GetCurrentAccountId();
593 if (userId == ERROR_USERID) {
594 return false;
595 }
596 std::lock_guard<std::recursive_mutex> lock(clipMutex_);
597 auto it = clips_.find(userId);
598 if (it == clips_.end()) {
599 return HasDistributedData(userId);
600 }
601
602 auto tokenId = IPCSkeleton::GetCallingTokenID();
603 AppInfo appInfo = GetAppInfo(tokenId);
604 return HasPastePermission(tokenId, IsFocusedApp(appInfo.bundleName), it->second);
605 }
606
SetPasteData(PasteData & pasteData)607 int32_t PasteboardService::SetPasteData(PasteData &pasteData)
608 {
609 auto data = std::make_shared<PasteData>(pasteData);
610 return SavePasteData(data);
611 }
612
SavePasteData(std::shared_ptr<PasteData> & pasteData)613 int32_t PasteboardService::SavePasteData(std::shared_ptr<PasteData> &pasteData)
614 {
615 PasteboardTrace tracer("PasteboardService, SetPasteData");
616 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
617 auto tokenId = IPCSkeleton::GetCallingTokenID();
618 if (!IsCopyable(tokenId)) {
619 return static_cast<int32_t>(PasteboardError::E_COPY_FORBIDDEN);
620 }
621 if (setting_.exchange(true)) {
622 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "is setting.");
623 return static_cast<int32_t>(PasteboardError::E_IS_BEGING_PROCESSED);
624 }
625 CalculateTimeConsuming::SetBeginTime();
626 auto appInfo = GetAppInfo(tokenId);
627 if (appInfo.userId == ERROR_USERID) {
628 setting_.store(false);
629 return static_cast<int32_t>(PasteboardError::E_ERROR);
630 }
631 std::lock_guard<std::recursive_mutex> lock(clipMutex_);
632 auto it = clips_.find(appInfo.userId);
633 if (it != clips_.end()) {
634 RevokeUriPermission(*(it->second));
635 clips_.erase(it);
636 }
637 pasteData->SetBundleName(appInfo.bundleName);
638 pasteData->SetOrginAuthority(appInfo.bundleName);
639 std::string time = GetTime();
640 pasteData->SetTime(time);
641 pasteData->SetTokenId(tokenId);
642 CheckAppUriPermission(*pasteData);
643 SetWebViewPasteData(*pasteData, appInfo.bundleName);
644 clips_.insert_or_assign(appInfo.userId, pasteData);
645 SetDistributedData(appInfo.userId, *pasteData);
646 NotifyObservers(appInfo.bundleName, PasteboardEventStatus::PASTEBOARD_WRITE);
647 SetPasteDataDot(*pasteData);
648 auto hintItem = hints_.find(appInfo.userId);
649 if (hintItem != hints_.end()) {
650 hints_.erase(hintItem);
651 }
652 setting_.store(false);
653 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Clips length %{public}d.", static_cast<uint32_t>(clips_.size()));
654 return static_cast<int32_t>(PasteboardError::E_OK);
655 }
656
SetWebViewPasteData(PasteData & pasteData,const std::string & bundleName)657 void PasteboardService::SetWebViewPasteData(PasteData &pasteData, const std::string &bundleName)
658 {
659 if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG) {
660 return;
661 }
662 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PasteboardService for webview.");
663 for (auto& item : pasteData.AllRecords()) {
664 if (item->GetUri() == nullptr) {
665 continue;
666 }
667 std::shared_ptr<Uri> uri = item->GetUri();
668 std::string puri = uri->ToString();
669 if (puri.substr(0, PasteData::IMG_LOCAL_URI.size()) == PasteData::IMG_LOCAL_URI &&
670 puri.find(PasteData::FILE_SCHEME_PREFIX + PasteData::PATH_SHARE) == std::string::npos) {
671 std::string path = uri->GetPath();
672 std::string newUriStr = PasteData::FILE_SCHEME_PREFIX + bundleName + path;
673 item->SetUri(std::make_shared<OHOS::Uri>(newUriStr));
674 }
675 }
676 }
677
GetCurrentAccountId()678 int32_t PasteboardService::GetCurrentAccountId()
679 {
680 std::vector<int32_t> accountIds;
681 auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(accountIds);
682 if (ret != ERR_OK || accountIds.empty()) {
683 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed errCode=%{public}d", ret);
684 return ERROR_USERID;
685 }
686 return accountIds.front();
687 }
688
IsCopyable(uint32_t tokenId) const689 bool PasteboardService::IsCopyable(uint32_t tokenId) const
690 {
691 #ifdef WITH_DLP
692 bool copyable = false;
693 auto ret = Security::DlpPermission::DlpPermissionKit::QueryDlpFileCopyableByTokenId(copyable, tokenId);
694 if (ret != 0 || !copyable) {
695 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "tokenId = 0x%{public}x ret = %{public}d, copyable = %{public}d.",
696 tokenId, ret, copyable);
697 return false;
698 }
699 #endif
700 return true;
701 }
702
AddPasteboardChangedObserver(const sptr<IPasteboardChangedObserver> & observer)703 void PasteboardService::AddPasteboardChangedObserver(const sptr<IPasteboardChangedObserver> &observer)
704 {
705 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
706 AddObserver(observer, observerChangedMap_);
707 }
708
RemovePasteboardChangedObserver(const sptr<IPasteboardChangedObserver> & observer)709 void PasteboardService::RemovePasteboardChangedObserver(const sptr<IPasteboardChangedObserver> &observer)
710 {
711 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
712 RemoveSingleObserver(observer, observerChangedMap_);
713 }
714
RemoveAllChangedObserver()715 void PasteboardService::RemoveAllChangedObserver()
716 {
717 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
718 RemoveAllObserver(observerChangedMap_);
719 }
720
AddPasteboardEventObserver(const sptr<IPasteboardChangedObserver> & observer)721 void PasteboardService::AddPasteboardEventObserver(const sptr<IPasteboardChangedObserver> &observer)
722 {
723 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
724 if (!IsCallerUidValid()) {
725 return;
726 }
727 AddObserver(observer, observerEventMap_);
728 }
729
RemovePasteboardEventObserver(const sptr<IPasteboardChangedObserver> & observer)730 void PasteboardService::RemovePasteboardEventObserver(const sptr<IPasteboardChangedObserver> &observer)
731 {
732 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
733 if (!IsCallerUidValid()) {
734 return;
735 }
736 RemoveSingleObserver(observer, observerEventMap_);
737 }
738
RemoveAllEventObserver()739 void PasteboardService::RemoveAllEventObserver()
740 {
741 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
742 if (!IsCallerUidValid()) {
743 return;
744 }
745 RemoveAllObserver(observerEventMap_);
746 }
747
AddObserver(const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)748 void PasteboardService::AddObserver(const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
749 {
750 if (observer == nullptr) {
751 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
752 return;
753 }
754 auto userId = GetCurrentAccountId();
755 if (userId == ERROR_USERID) {
756 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
757 return;
758 }
759 std::lock_guard<std::mutex> lock(observerMutex_);
760 auto it = observerMap.find(userId);
761 std::shared_ptr<std::set<sptr<IPasteboardChangedObserver>, classcomp>> observers;
762 if (it != observerMap.end()) {
763 observers = it->second;
764 } else {
765 observers = std::make_shared<std::set<sptr<IPasteboardChangedObserver>, classcomp>>();
766 observerMap.insert(std::make_pair(userId, observers));
767 }
768 observers->insert(observer);
769 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, " observers->size = %{public}u.",
770 static_cast<unsigned int>(observers->size()));
771 }
772
RemoveSingleObserver(const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)773 void PasteboardService::RemoveSingleObserver(const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
774 {
775 if (observer == nullptr) {
776 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
777 return;
778 }
779 auto userId = GetCurrentAccountId();
780 if (userId == ERROR_USERID) {
781 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
782 return;
783 }
784 std::lock_guard<std::mutex> lock(observerMutex_);
785 auto it = observerMap.find(userId);
786 if (it == observerMap.end()) {
787 return;
788 }
789 auto observers = it->second;
790 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers->size: %{public}u.",
791 static_cast<unsigned int>(observers->size()));
792 auto eraseNum = observers->erase(observer);
793 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "listeners.size = %{public}u, eraseNum = %{public}zu",
794 static_cast<unsigned int>(observers->size()), eraseNum);
795 }
796
RemoveAllObserver(ObserverMap & observerMap)797 void PasteboardService::RemoveAllObserver(ObserverMap &observerMap)
798 {
799 auto userId = GetCurrentAccountId();
800 if (userId == ERROR_USERID) {
801 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
802 return;
803 }
804 std::lock_guard<std::mutex> lock(observerMutex_);
805 auto it = observerMap.find(userId);
806 if (it == observerMap.end()) {
807 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "observer empty.");
808 return;
809 }
810 auto observers = it->second;
811 auto eraseNum = observerMap.erase(userId);
812 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "listeners.size = %{public}u, eraseNum = %{public}zu",
813 static_cast<unsigned int>(observers->size()), eraseNum);
814 }
815
IsCallerUidValid()816 inline bool PasteboardService::IsCallerUidValid()
817 {
818 pid_t callingUid = IPCSkeleton::GetCallingUid();
819 if (callingUid == EDM_UID || callingUid == ROOT_UID || callingUid == ANCO_CALL_UID) {
820 return true;
821 }
822 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "callingUid error: %{public}d.", callingUid);
823 return false;
824 }
825
NotifyObservers(std::string bundleName,PasteboardEventStatus status)826 void PasteboardService::NotifyObservers(std::string bundleName, PasteboardEventStatus status)
827 {
828 std::thread thread([this, bundleName, status] () {
829 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
830 std::lock_guard<std::mutex> lock(observerMutex_);
831 for (auto &observers : observerChangedMap_) {
832 for (const auto &observer : *(observers.second)) {
833 if (status != PasteboardEventStatus::PASTEBOARD_READ) {
834 observer->OnPasteboardChanged();
835 }
836 }
837 }
838 for (auto &observers : observerEventMap_) {
839 for (const auto &observer : *(observers.second)) {
840 observer->OnPasteboardEvent(bundleName, static_cast<int32_t>(status));
841 }
842 }
843 });
844 thread.detach();
845 }
846
GetDataSize(PasteData & data) const847 size_t PasteboardService::GetDataSize(PasteData &data) const
848 {
849 if (data.GetRecordCount() != 0) {
850 size_t counts = data.GetRecordCount() - 1;
851 std::shared_ptr<PasteDataRecord> records = data.GetRecordAt(counts);
852 std::string text = records->ConvertToText();
853 size_t textSize = text.size();
854 return textSize;
855 }
856 return GET_WRONG_SIZE;
857 }
858
SetPasteboardHistory(HistoryInfo & info)859 bool PasteboardService::SetPasteboardHistory(HistoryInfo &info)
860 {
861 std::string history = std::move(info.time) + " " + std::move(info.bundleName) + " " + std::move(info.state) + " " +
862 " " + std::move(info.pop) + " " + std::move(info.remote);
863 constexpr const size_t DATA_HISTORY_SIZE = 10;
864 std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
865 if (dataHistory_.size() == DATA_HISTORY_SIZE) {
866 dataHistory_.erase(dataHistory_.begin());
867 }
868 dataHistory_.push_back(std::move(history));
869 return true;
870 }
871
Dump(int fd,const std::vector<std::u16string> & args)872 int PasteboardService::Dump(int fd, const std::vector<std::u16string> &args)
873 {
874 int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
875 const int maxUid = 10000;
876 if (uid > maxUid) {
877 return 0;
878 }
879
880 std::vector<std::string> argsStr;
881 for (auto item : args) {
882 argsStr.emplace_back(Str16ToStr8(item));
883 }
884
885 if (PasteboardDumpHelper::GetInstance().Dump(fd, argsStr)) {
886 return 0;
887 }
888 return 0;
889 }
890
GetTime()891 std::string PasteboardService::GetTime()
892 {
893 constexpr int USEC_TO_MSEC = 1000;
894 time_t timeSeconds = time(0);
895 if (timeSeconds == -1) {
896 return FAIL_TO_GET_TIME_STAMP;
897 }
898 struct tm nowTime;
899 localtime_r(&timeSeconds, &nowTime);
900
901 struct timeval timeVal = { 0, 0 };
902 gettimeofday(&timeVal, nullptr);
903
904 std::string targetTime = std::to_string(nowTime.tm_year + 1900) + "-" + std::to_string(nowTime.tm_mon + 1) + "-" +
905 std::to_string(nowTime.tm_mday) + " " + std::to_string(nowTime.tm_hour) + ":" +
906 std::to_string(nowTime.tm_min) + ":" + std::to_string(nowTime.tm_sec) + "." +
907 std::to_string(timeVal.tv_usec / USEC_TO_MSEC);
908 return targetTime;
909 }
910
DumpHistory() const911 std::string PasteboardService::DumpHistory() const
912 {
913 std::string result;
914 std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
915 if (!dataHistory_.empty()) {
916 result.append("Access history last ten times: ").append("\n");
917 for (auto iter = dataHistory_.rbegin(); iter != dataHistory_.rend(); ++iter) {
918 result.append(" ").append(*iter).append("\n");
919 }
920 } else {
921 result.append("Access history fail! dataHistory_ no data.").append("\n");
922 }
923 return result;
924 }
925
DumpData()926 std::string PasteboardService::DumpData()
927 {
928 auto userId = GetCurrentAccountId();
929 if (userId == ERROR_USERID) {
930 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed.");
931 return "";
932 }
933 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "id = %{public}d", userId);
934 std::lock_guard<std::recursive_mutex> lock(clipMutex_);
935 auto it = clips_.find(userId);
936 std::string result;
937 if (it != clips_.end() && it->second != nullptr) {
938 size_t recordCounts = it->second->GetRecordCount();
939 auto property = it->second->GetProperty();
940 std::string shareOption;
941 PasteData::ShareOptionToString(property.shareOption, shareOption);
942 std::string sourceDevice;
943 if (property.isRemote) {
944 sourceDevice = "remote";
945 } else {
946 sourceDevice = "local";
947 }
948 result.append("|Owner : ")
949 .append(property.bundleName)
950 .append("\n")
951 .append("|Timestamp : ")
952 .append(property.setTime)
953 .append("\n")
954 .append("|Share Option: ")
955 .append(shareOption)
956 .append("\n")
957 .append("|Record Count: ")
958 .append(std::to_string(recordCounts))
959 .append("\n")
960 .append("|Mime types : {");
961 if (!property.mimeTypes.empty()) {
962 for (size_t i = 0; i < property.mimeTypes.size(); ++i) {
963 result.append(property.mimeTypes[i]).append(",");
964 }
965 }
966 result.append("}").append("\n").append("|source device: ").append(sourceDevice);
967 } else {
968 result.append("No copy data.").append("\n");
969 }
970 return result;
971 }
972
SetPasteDataDot(PasteData & pasteData)973 void PasteboardService::SetPasteDataDot(PasteData &pasteData)
974 {
975 auto bundleName = pasteData.GetBundleName();
976 HistoryInfo info{ pasteData.GetTime(), bundleName, "set", "", "" };
977 SetPasteboardHistory(info);
978
979 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData Report!");
980 Reporter::GetInstance().PasteboardBehaviour().Report(
981 { static_cast<int>(BehaviourPasteboardState::BPS_COPY_STATE), bundleName });
982
983 int state = static_cast<int>(StatisticPasteboardState::SPS_COPY_STATE);
984 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData GetDataSize!");
985 size_t dataSize = GetDataSize(pasteData);
986 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData timeC!");
987 CalculateTimeConsuming timeC(dataSize, state);
988 }
989
GetPasteDataDot(PasteData & pasteData,const std::string & pop,const std::string & bundleName)990 void PasteboardService::GetPasteDataDot(PasteData &pasteData, const std::string &pop, const std::string &bundleName)
991 {
992 std::string remote;
993 if (pasteData.IsRemote()) {
994 remote = "remote";
995 }
996 std::string time = GetTime();
997 HistoryInfo info{ time, bundleName, "get", pop, remote };
998 SetPasteboardHistory(info);
999 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData Report!");
1000 int pState = StatisticPasteboardState::SPS_INVALID_STATE;
1001 int bState = BehaviourPasteboardState::BPS_INVALID_STATE;
1002 if (pasteData.IsRemote()) {
1003 pState = static_cast<int>(StatisticPasteboardState::SPS_REMOTE_PASTE_STATE);
1004 bState = static_cast<int>(BehaviourPasteboardState::BPS_REMOTE_PASTE_STATE);
1005 } else {
1006 pState = static_cast<int>(StatisticPasteboardState::SPS_PASTE_STATE);
1007 bState = static_cast<int>(BehaviourPasteboardState::BPS_PASTE_STATE);
1008 };
1009
1010 Reporter::GetInstance().PasteboardBehaviour().Report({ bState, bundleName });
1011
1012 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData GetDataSize");
1013 size_t dataSize = GetDataSize(pasteData);
1014 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData timeC");
1015 CalculateTimeConsuming timeC(dataSize, pState);
1016 }
1017
GetDistributedData(int32_t user)1018 std::shared_ptr<PasteData> PasteboardService::GetDistributedData(int32_t user)
1019 {
1020 auto clipPlugin = GetClipPlugin();
1021 if (clipPlugin == nullptr) {
1022 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
1023 return nullptr;
1024 }
1025 ClipPlugin::GlobalEvent event;
1026 auto isEffective = GetDistributedEvent(clipPlugin, user, event);
1027 if (event.status == ClipPlugin::EVT_UNKNOWN) {
1028 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "EVT_UNKNOWN.");
1029 return nullptr;
1030 }
1031 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "same device:%{public}d, evt seq:%{public}u current seq:%{public}u.",
1032 event.deviceId == currentEvent_.deviceId, event.seqId, currentEvent_.seqId);
1033 std::vector<uint8_t> rawData = std::move(event.addition);
1034 if (!isEffective) {
1035 currentEvent_.status = ClipPlugin::EVT_INVALID;
1036 currentEvent_ = std::move(event);
1037 Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
1038 return nullptr;
1039 }
1040
1041 if (event.frameNum > 0 && (clipPlugin->GetPasteData(event, rawData) != 0)) {
1042 Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
1043 return nullptr;
1044 }
1045
1046 currentEvent_ = std::move(event);
1047 std::shared_ptr<PasteData> pasteData = std::make_shared<PasteData>();
1048 pasteData->Decode(rawData);
1049 pasteData->ReplaceShareUri(user);
1050 pasteData->SetOrginAuthority(pasteData->GetBundleName());
1051 int fileSize = pasteData->GetProperty().additions.GetIntParam(PasteData::REMOTE_FILE_SIZE, -1);
1052 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "remote bundle: %{public}s", pasteData->GetBundleName().c_str());
1053 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "remote file size: %{public}d", fileSize);
1054 for (size_t i = 0; i < pasteData->GetRecordCount(); i++) {
1055 auto item = pasteData->GetRecordAt(i);
1056 if (item == nullptr || item->GetConvertUri().empty()) {
1057 continue;
1058 }
1059 item->isConvertUriFromRemote = true;
1060 }
1061 return pasteData;
1062 }
1063
SetDistributedData(int32_t user,PasteData & data)1064 bool PasteboardService::SetDistributedData(int32_t user, PasteData &data)
1065 {
1066 std::vector<uint8_t> rawData;
1067 auto clipPlugin = GetClipPlugin();
1068 if (clipPlugin == nullptr) {
1069 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
1070 return false;
1071 }
1072 GenerateDistributedUri(data);
1073 if (data.GetShareOption() == CrossDevice && !data.Encode(rawData)) {
1074 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "encode failed.");
1075 return false;
1076 }
1077
1078 auto networkId = DMAdapter::GetInstance().GetLocalNetworkId();
1079 if (networkId.empty()) {
1080 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "networkId is empty.");
1081 return false;
1082 }
1083
1084 uint64_t expiration =
1085 duration_cast<milliseconds>((system_clock::now() + minutes(EXPIRATION_INTERVAL)).time_since_epoch()).count();
1086 Event event;
1087 event.user = user;
1088 event.seqId = ++sequenceId_;
1089 event.expiration = expiration;
1090 event.deviceId = networkId;
1091 event.account = AccountManager::GetInstance().GetCurrentAccount();
1092 event.status = (data.GetShareOption() == CrossDevice) ? ClipPlugin::EVT_NORMAL : ClipPlugin::EVT_INVALID;
1093 currentEvent_ = event;
1094 clipPlugin->SetPasteData(event, rawData);
1095 return true;
1096 }
1097
GenerateDistributedUri(PasteData & data)1098 void PasteboardService::GenerateDistributedUri(PasteData &data)
1099 {
1100 auto userId = GetCurrentAccountId();
1101 if (userId == ERROR_USERID) {
1102 return;
1103 }
1104 size_t fileSize = 0;
1105 for (size_t i = 0; i < data.GetRecordCount(); i++) {
1106 auto item = data.GetRecordAt(i);
1107 if (item == nullptr || item->GetOrginUri() == nullptr) {
1108 continue;
1109 }
1110 Uri uri = *(item->GetOrginUri());
1111 if (!isBundleOwnUriPermission(data.GetOrginAuthority(), uri) && !item->HasGrantUriPermission()) {
1112 continue;
1113 }
1114 HmdfsUriInfo hui;
1115 auto ret = RemoteFileShare::GetDfsUriFromLocal(uri.ToString(), userId, hui);
1116 if (ret != 0) {
1117 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "creat uri failed: %{public}d", ret);
1118 continue;
1119 }
1120 item->SetConvertUri(hui.uriStr);
1121 fileSize += hui.fileSize;
1122 }
1123 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "file size: %{public}zu", fileSize);
1124 data.SetAddition(PasteData::REMOTE_FILE_SIZE, AAFwk::Integer::Box(fileSize));
1125 }
1126
HasDistributedData(int32_t user)1127 bool PasteboardService::HasDistributedData(int32_t user)
1128 {
1129 auto clipPlugin = GetClipPlugin();
1130 if (clipPlugin == nullptr) {
1131 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
1132 return false;
1133 }
1134 Event event;
1135 auto has = GetDistributedEvent(clipPlugin, user, event);
1136 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "same device:%{public}d, evt seq:%{public}u current seq:%{public}u.",
1137 event.deviceId == currentEvent_.deviceId, event.seqId, currentEvent_.seqId);
1138 return has;
1139 }
1140
GetClipPlugin()1141 std::shared_ptr<ClipPlugin> PasteboardService::GetClipPlugin()
1142 {
1143 auto isOn = DistributedModuleConfig::IsOn();
1144 std::lock_guard<decltype(mutex)> lockGuard(mutex);
1145 if (!isOn || clipPlugin_ != nullptr) {
1146 return clipPlugin_;
1147 }
1148
1149 auto release = [this](ClipPlugin *plugin) {
1150 std::lock_guard<decltype(mutex)> lockGuard(mutex);
1151 ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
1152 };
1153
1154 clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
1155 return clipPlugin_;
1156 }
1157
CleanDistributedData(int32_t user)1158 bool PasteboardService::CleanDistributedData(int32_t user)
1159 {
1160 auto clipPlugin = GetClipPlugin();
1161 if (clipPlugin == nullptr) {
1162 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
1163 return true;
1164 }
1165 clipPlugin->Clear(user);
1166 return true;
1167 }
1168
OnConfigChange(bool isOn)1169 void PasteboardService::OnConfigChange(bool isOn)
1170 {
1171 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "ConfigChange isOn: %{public}d.", isOn);
1172 std::lock_guard<decltype(mutex)> lockGuard(mutex);
1173 if (!isOn) {
1174 clipPlugin_ = nullptr;
1175 return;
1176 }
1177 auto release = [this](ClipPlugin *plugin) {
1178 std::lock_guard<decltype(mutex)> lockGuard(mutex);
1179 ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
1180 };
1181
1182 clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
1183 }
1184
GetDistributedEvent(std::shared_ptr<ClipPlugin> plugin,int32_t user,Event & event)1185 bool PasteboardService::GetDistributedEvent(std::shared_ptr<ClipPlugin> plugin, int32_t user, Event &event)
1186 {
1187 auto events = plugin->GetTopEvents(1, user);
1188 if (events.empty()) {
1189 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "events empty.");
1190 return false;
1191 }
1192
1193 auto &tmpEvent = events[0];
1194 if (tmpEvent.deviceId == DMAdapter::GetInstance().GetLocalNetworkId()) {
1195 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get local data.");
1196 return false;
1197 }
1198 if (tmpEvent.account != AccountManager::GetInstance().GetCurrentAccount()) {
1199 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "account error.");
1200 return false;
1201 }
1202 SetDeviceName(tmpEvent.deviceId);
1203 if (tmpEvent.deviceId == currentEvent_.deviceId && tmpEvent.seqId == currentEvent_.seqId) {
1204 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get same remote data.");
1205 return false;
1206 }
1207
1208 event = std::move(tmpEvent);
1209 uint64_t curTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
1210 return ((curTime < event.expiration) && (event.status == ClipPlugin::EVT_NORMAL));
1211 }
1212
GetAppLabel(uint32_t tokenId)1213 std::string PasteboardService::GetAppLabel(uint32_t tokenId)
1214 {
1215 auto iBundleMgr = GetAppBundleManager();
1216 if (iBundleMgr == nullptr) {
1217 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to cast bundle mgr service.");
1218 return PasteBoardDialog::DEFAULT_LABEL;
1219 }
1220 AppInfo info = GetAppInfo(tokenId);
1221 AppExecFwk::ApplicationInfo appInfo;
1222 auto result = iBundleMgr->GetApplicationInfo(info.bundleName, 0, info.userId, appInfo);
1223 if (!result) {
1224 return PasteBoardDialog::DEFAULT_LABEL;
1225 }
1226 auto &resource = appInfo.labelResource;
1227 auto label = iBundleMgr->GetStringById(resource.bundleName, resource.moduleName, resource.id, info.userId);
1228 return label.empty() ? PasteBoardDialog::DEFAULT_LABEL : label;
1229 }
1230
GetAppBundleManager()1231 sptr<AppExecFwk::IBundleMgr> PasteboardService::GetAppBundleManager()
1232 {
1233 auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1234 if (systemAbilityManager == nullptr) {
1235 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get SystemAbilityManager.");
1236 return nullptr;
1237 }
1238 auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
1239 if (remoteObject == nullptr) {
1240 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get bundle mgr service.");
1241 return nullptr;
1242 }
1243 return OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
1244 }
1245
GetDeviceName()1246 std::string PasteboardService::GetDeviceName()
1247 {
1248 std::lock_guard<decltype(deviceMutex_)> lockGuard(deviceMutex_);
1249 return fromDevice_;
1250 }
1251
SetDeviceName(const std::string & device)1252 void PasteboardService::SetDeviceName(const std::string &device)
1253 {
1254 std::lock_guard<decltype(deviceMutex_)> lockGuard(deviceMutex_);
1255 if (device.empty() || device == DMAdapter::GetInstance().GetLocalNetworkId()) {
1256 fromDevice_ = "local";
1257 return;
1258 }
1259 fromDevice_ = DMAdapter::GetInstance().GetDeviceName(device);
1260 }
1261 } // namespace MiscServices
1262 } // namespace OHOS
1263