• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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