• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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_module_config.h"
30 #include "hiview_adapter.h"
31 #include "input_method_controller.h"
32 #include "iservice_registry.h"
33 #include "loader.h"
34 #include "native_token_info.h"
35 #include "os_account_manager.h"
36 #include "para_handle.h"
37 #include "pasteboard_error.h"
38 #include "pasteboard_dialog.h"
39 #include "pasteboard_trace.h"
40 #include "reporter.h"
41 #ifdef WITH_DLP
42 #include "dlp_permission_kit.h"
43 #endif // WITH_DLP
44 
45 namespace OHOS {
46 namespace MiscServices {
47 using namespace std::chrono;
48 namespace {
49 constexpr const int GET_WRONG_SIZE = 0;
50 const std::int32_t INIT_INTERVAL = 10000L;
51 const std::string PASTEBOARD_SERVICE_NAME = "PasteboardService";
52 const std::string FAIL_TO_GET_TIME_STAMP = "FAIL_TO_GET_TIME_STAMP";
53 const bool G_REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(new PasteboardService());
54 } // namespace
55 using namespace Security::AccessToken;
56 std::mutex PasteboardService::historyMutex_;
57 std::vector<std::string> PasteboardService::dataHistory_;
58 std::shared_ptr<Command> PasteboardService::copyHistory;
59 std::shared_ptr<Command> PasteboardService::copyData;
60 
PasteboardService()61 PasteboardService::PasteboardService()
62     : SystemAbility(PASTEBOARD_SERVICE_ID, true), state_(ServiceRunningState::STATE_NOT_START)
63 {
64     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "PasteboardService Start.");
65     ServiceListenerFunc_[static_cast<int32_t>(DISTRIBUTED_HARDWARE_DEVICEMANAGER_SA_ID)] =
66         &PasteboardService::DevManagerInit;
67     ServiceListenerFunc_[static_cast<int32_t>(DISTRIBUTED_DEVICE_PROFILE_SA_ID)] = &PasteboardService::DevProfileInit;
68 }
69 
~PasteboardService()70 PasteboardService::~PasteboardService()
71 {
72 }
73 
Init()74 int32_t PasteboardService::Init()
75 {
76     if (!Publish(this)) {
77         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStart register to system ability manager failed.");
78         auto userId = GetUserIdByToken(IPCSkeleton::GetCallingTokenID());
79         Reporter::GetInstance().PasteboardFault().Report({ userId, "ERR_INVALID_OPTION" });
80         return static_cast<int32_t>(PasteboardError::E_INVALID_OPTION);
81     }
82     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Init Success.");
83     state_ = ServiceRunningState::STATE_RUNNING;
84     return ERR_OK;
85 }
86 
OnStart()87 void PasteboardService::OnStart()
88 {
89     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "PasteboardService OnStart.");
90     if (state_ == ServiceRunningState::STATE_RUNNING) {
91         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "PasteboardService is already running.");
92         return;
93     }
94 
95     InitServiceHandler();
96     auto appInfo = GetAppInfo(IPCSkeleton::GetCallingTokenID());
97     Loader loader;
98     loader.LoadComponents();
99     DMAdapter::GetInstance().Initialize(appInfo.bundleName);
100     DistributedModuleConfig::Watch(std::bind(&PasteboardService::OnConfigChange, this, std::placeholders::_1));
101 
102     AddSysAbilityListener();
103 
104     if (Init() != ERR_OK) {
105         auto callback = [this]() { Init(); };
106         serviceHandler_->PostTask(callback, INIT_INTERVAL);
107         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Init failed. Try again 10s later.");
108         return;
109     }
110 
111     copyHistory = std::make_shared<Command>(std::vector<std::string>{ "--copy-history" },
112         "Dump access history last ten times.",
113         [this](const std::vector<std::string> &input, std::string &output) -> bool {
114             output = DumpHistory();
115             return true;
116         });
117 
118     copyData = std::make_shared<Command>(std::vector<std::string>{ "--data" }, "Show copy data details.",
119         [this](const std::vector<std::string> &input, std::string &output) -> bool {
120             output = DumpData();
121             return true;
122         });
123 
124     PasteboardDumpHelper::GetInstance().RegisterCommand(copyHistory);
125     PasteboardDumpHelper::GetInstance().RegisterCommand(copyData);
126 
127     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "Start PasteboardService success.");
128     HiViewAdapter::StartTimerThread();
129     return;
130 }
131 
OnStop()132 void PasteboardService::OnStop()
133 {
134     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop Started.");
135     if (state_ != ServiceRunningState::STATE_RUNNING) {
136         return;
137     }
138     serviceHandler_ = nullptr;
139     state_ = ServiceRunningState::STATE_NOT_START;
140 
141     ParaHandle::GetInstance().WatchEnabledStatus(nullptr);
142     DevManager::GetInstance().UnregisterDevCallback();
143 
144     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "OnStop End.");
145 }
146 
AddSysAbilityListener()147 void PasteboardService::AddSysAbilityListener()
148 {
149     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "begin.");
150     for (uint32_t i = 0; i < sizeof(LISTENING_SERVICE) / sizeof(LISTENING_SERVICE[0]); i++) {
151         auto ret = AddSystemAbilityListener(LISTENING_SERVICE[i]);
152         PASTEBOARD_HILOGD(
153             PASTEBOARD_MODULE_SERVICE, "ret = %{public}d, serviceId = %{public}d.", ret, LISTENING_SERVICE[i]);
154     }
155 }
156 
OnAddSystemAbility(int32_t systemAbilityId,const std::string & deviceId)157 void PasteboardService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId)
158 {
159     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "systemAbilityId = %{public}d added!", systemAbilityId);
160     auto itFunc = ServiceListenerFunc_.find(systemAbilityId);
161     if (itFunc != ServiceListenerFunc_.end()) {
162         auto ServiceListenerFunc = itFunc->second;
163         if (ServiceListenerFunc != nullptr) {
164             (this->*ServiceListenerFunc)();
165         }
166     }
167 }
168 
DevManagerInit()169 void PasteboardService::DevManagerInit()
170 {
171     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "begin.");
172     DevManager::GetInstance().Init();
173 }
174 
DevProfileInit()175 void PasteboardService::DevProfileInit()
176 {
177     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "begin.");
178     ParaHandle::GetInstance().Init();
179     DevProfile::GetInstance().Init();
180 }
181 
InitServiceHandler()182 void PasteboardService::InitServiceHandler()
183 {
184     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler started.");
185     if (serviceHandler_ != nullptr) {
186         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "Already init.");
187         return;
188     }
189     std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(PASTEBOARD_SERVICE_NAME);
190     serviceHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
191 
192     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "InitServiceHandler Succeeded.");
193 }
194 
Clear()195 void PasteboardService::Clear()
196 {
197     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
198     auto tokenId = IPCSkeleton::GetCallingTokenID();
199     auto userId = GetUserIdByToken(tokenId);
200     if (userId == ERROR_USERID) {
201         return;
202     }
203     std::lock_guard<std::mutex> lock(clipMutex_);
204     auto it = clips_.find(userId);
205     if (it != clips_.end()) {
206         clips_.erase(it);
207         std::string bundleName = GetAppBundleName(tokenId);
208         NotifyObservers(bundleName, PasteboardEventStatus::PASTEBOARD_CLEAR);
209     }
210     CleanDistributedData(userId);
211 }
212 
IsDefaultIME(const AppInfo & appInfo)213 bool PasteboardService::IsDefaultIME(const AppInfo &appInfo)
214 {
215     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "start.");
216     if (appInfo.tokenType != ATokenTypeEnum::TOKEN_HAP) {
217         return true;
218     }
219     std::shared_ptr<Property> property = InputMethodController::GetInstance()->GetCurrentInputMethod();
220     return property != nullptr && property->name == appInfo.bundleName;
221 }
222 
IsFocusedApp(int32_t tokenId)223 bool PasteboardService::IsFocusedApp(int32_t tokenId)
224 {
225     using namespace OHOS::AAFwk;
226     AppInfo appInfo = GetAppInfo(tokenId);
227     if (appInfo.bundleName.empty()) {
228         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get bundle name by token failed");
229         return false;
230     }
231     auto elementName = AbilityManagerClient::GetInstance()->GetTopAbility();
232     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, " Top app:%{public}s, caller app:%{public}s",
233         elementName.GetBundleName().c_str(), appInfo.bundleName.c_str());
234     return elementName.GetBundleName() == appInfo.bundleName;
235 }
236 
HasPastePermission(uint32_t tokenId,bool isFocusedApp,const std::shared_ptr<PasteData> & pasteData)237 bool PasteboardService::HasPastePermission(uint32_t tokenId, bool isFocusedApp,
238     const std::shared_ptr<PasteData> &pasteData)
239 {
240     if (pasteData == nullptr) {
241         return false;
242     }
243 
244     if (!pasteData->IsDraggedData() && (!isFocusedApp && !IsDefaultIME(GetAppInfo(tokenId)))) {
245         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "token:0x%{public}x", tokenId);
246         return false;
247     }
248     switch (pasteData->GetShareOption()) {
249         case ShareOption::InApp: {
250             if (pasteData->GetTokenId() != tokenId) {
251                 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "InApp check failed.");
252                 return false;
253             }
254             break;
255         }
256         case ShareOption::LocalDevice: {
257             break;
258         }
259         case ShareOption::CrossDevice: {
260             break;
261         }
262         default: {
263             PASTEBOARD_HILOGE(
264                 PASTEBOARD_MODULE_SERVICE, "shareOption = %{public}d is error.", pasteData->GetShareOption());
265             return false;
266         }
267     }
268     return true;
269 }
270 
GetAppInfo(uint32_t tokenId)271 AppInfo PasteboardService::GetAppInfo(uint32_t tokenId)
272 {
273     AppInfo info;
274     info.tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
275     switch (info.tokenType) {
276         case ATokenTypeEnum::TOKEN_HAP: {
277             HapTokenInfo hapInfo;
278             if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
279                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get hap token info fail.");
280                 return info;
281             }
282             info.bundleName = hapInfo.bundleName;
283             info.userId = hapInfo.userID;
284             break;
285         }
286         case ATokenTypeEnum::TOKEN_NATIVE:
287         case ATokenTypeEnum::TOKEN_SHELL: {
288             NativeTokenInfo tokenInfo;
289             if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
290                 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "get native token info fail.");
291                 return info;
292             }
293             info.bundleName = tokenInfo.processName;
294             info.userId = 0;
295             break;
296         }
297         default: {
298             PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "tokenType = %{public}d not match.", info.tokenType);
299         }
300     }
301     return info;
302 }
303 
GetAppBundleName(uint32_t tokenId)304 std::string PasteboardService::GetAppBundleName(uint32_t tokenId)
305 {
306     auto appInfo = GetAppInfo(tokenId);
307     std::string bundleName;
308     if (appInfo.userId != ERROR_USERID) {
309         bundleName = appInfo.bundleName;
310     } else {
311         bundleName = "error";
312         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "GetAppInfo error");
313     }
314     return bundleName;
315 }
316 
SetLocalPasteFlag(bool isCrossPaste,uint32_t tokenId,PasteData & pasteData)317 void PasteboardService::SetLocalPasteFlag(bool isCrossPaste, uint32_t tokenId, PasteData &pasteData)
318 {
319     pasteData.SetLocalPasteFlag(!isCrossPaste && tokenId == pasteData.GetTokenId());
320     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "isLocalPaste = %{public}d.", pasteData.IsLocalPaste());
321 }
322 
GetPasteData(PasteData & data)323 int32_t PasteboardService::GetPasteData(PasteData &data)
324 {
325     auto tokenId = IPCSkeleton::GetCallingTokenID();
326     if (pasting_.exchange(true)) {
327         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "is passing.");
328         return static_cast<int32_t>(PasteboardError::E_IS_BEGING_PROCESSED);
329     }
330 
331     CalculateTimeConsuming::SetBeginTime();
332 
333     SetDeviceName();
334     PasteboardTrace tracer("PasteboardService GetPasteData");
335 
336     bool isFocusedApp = IsFocusedApp(tokenId);
337     auto block =  std::make_shared<BlockObject<std::shared_ptr<PasteData>>>(PasteBoardDialog::POPUP_INTERVAL);
338     std::thread thread([this, block, tokenId, isFocusedApp]() mutable {
339         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData Begin");
340         std::shared_ptr<PasteData> pasteData = std::make_shared<PasteData>();
341         auto success = GetPasteData(*pasteData, tokenId, isFocusedApp);
342         if (!success) {
343             pasteData->SetInvalid();
344         }
345         block->SetValue(pasteData);
346         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData End");
347     });
348     thread.detach();
349     auto value = block->GetValue();
350     std::string pop;
351     if (value == nullptr) {
352         PasteBoardDialog::MessageInfo message;
353         message.appName = GetAppLabel(tokenId);
354         message.deviceType = GetDeviceName();
355         PasteBoardDialog::GetInstance().ShowDialog(message, [block] { block->SetValue(nullptr); });
356         pop = "pop";
357         block->SetInterval(PasteBoardDialog::MAX_LIFE_TIME);
358         value = block->GetValue();
359         PasteBoardDialog::GetInstance().CancelDialog();
360     }
361     bool result = false;
362     if (value != nullptr) {
363         result = value->IsValid();
364         data = std::move(*value);
365     }
366     std::string bundleName = GetAppBundleName(tokenId);
367     NotifyObservers(bundleName, PasteboardEventStatus::PASTEBOARD_READ);
368     GetPasteDataDot(data, pop, tokenId);
369     pasting_.store(false);
370     return result ? static_cast<int32_t>(PasteboardError::E_OK) : static_cast<int32_t>(PasteboardError::E_ERROR);
371 }
372 
GetPasteData(PasteData & data,uint32_t tokenId,bool isFocusedApp)373 bool PasteboardService::GetPasteData(PasteData &data, uint32_t tokenId, bool isFocusedApp)
374 {
375     PasteboardTrace tracer("GetPasteData inner");
376     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start inner.");
377     auto userId = GetUserIdByToken(tokenId);
378     if (userId == ERROR_USERID) {
379         PasteData::sharePath = "";
380         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId error.");
381         return false;
382     }
383     PasteData::sharePath = PasteData::SHARE_PATH_PREFIX + std::to_string(userId) + PasteData::SHARE_PATH_PREFIX_ACCOUNT;
384     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Clips length %{public}d.", static_cast<uint32_t>(clips_.size()));
385     bool isRemote = false;
386     std::lock_guard<std::mutex> lock(clipMutex_);
387     auto pastData = GetDistributedData(userId);
388     if (pastData != nullptr) {
389         isRemote = true;
390         pastData->SetRemote(isRemote);
391         clips_.insert_or_assign(userId, pastData);
392     }
393     auto it = clips_.find(userId);
394     if (it == clips_.end()) {
395         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "no data.");
396         return false;
397     }
398 
399     auto ret = HasPastePermission(tokenId, isFocusedApp, it->second);
400     if (!ret) {
401         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "don't have paste permission.");
402         return false;
403     }
404     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "GetPasteData success.");
405 
406     data = *(it->second);
407     data.SetRemote(isRemote);
408 
409     SetLocalPasteFlag(isRemote, tokenId, data);
410     return true;
411 }
412 
HasPasteData()413 bool PasteboardService::HasPasteData()
414 {
415     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
416     auto tokenId = IPCSkeleton::GetCallingTokenID();
417     auto userId = GetUserIdByToken(tokenId);
418     if (userId == ERROR_USERID) {
419         return false;
420     }
421     std::lock_guard<std::mutex> lock(clipMutex_);
422     auto it = clips_.find(userId);
423     if (it == clips_.end()) {
424         return HasDistributedData(userId);
425     }
426 
427     return HasPastePermission(tokenId, IsFocusedApp(tokenId), it->second);
428 }
429 
SetPasteData(PasteData & pasteData)430 int32_t PasteboardService::SetPasteData(PasteData &pasteData)
431 {
432     PasteboardTrace tracer("PasteboardService, SetPasteData");
433     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
434     auto tokenId = IPCSkeleton::GetCallingTokenID();
435     if (!IsCopyable(tokenId)) {
436         return static_cast<int32_t>(PasteboardError::E_COPY_FORBIDDEN);
437     }
438     if (setting_.exchange(true)) {
439         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "is setting.");
440         return static_cast<int32_t>(PasteboardError::E_IS_BEGING_PROCESSED);
441     }
442     CalculateTimeConsuming::SetBeginTime();
443     auto appInfo = GetAppInfo(tokenId);
444     if (appInfo.userId == ERROR_USERID) {
445         return static_cast<int32_t>(PasteboardError::E_ERROR);
446     }
447     pasteData.SetBundleName(appInfo.bundleName);
448     std::string time = GetTime();
449     pasteData.SetTime(time);
450     pasteData.SetTokenId(tokenId);
451 
452     std::lock_guard<std::mutex> lock(clipMutex_);
453     auto it = clips_.find(appInfo.userId);
454     if (it != clips_.end()) {
455         clips_.erase(it);
456     }
457     clips_.insert_or_assign(appInfo.userId, std::make_shared<PasteData>(pasteData));
458     SetDistributedData(appInfo.userId, pasteData);
459     NotifyObservers(appInfo.bundleName, PasteboardEventStatus::PASTEBOARD_WRITE);
460     SetPasteDataDot(pasteData);
461     setting_.store(false);
462     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "Clips length %{public}d.", static_cast<uint32_t>(clips_.size()));
463     return static_cast<int32_t>(PasteboardError::E_OK);
464 }
465 
GetUserIdByToken(uint32_t tokenId)466 int32_t PasteboardService::GetUserIdByToken(uint32_t tokenId)
467 {
468     auto appInfo = GetAppInfo(tokenId);
469     PASTEBOARD_HILOGD(
470         PASTEBOARD_MODULE_SERVICE, "tokenId = 0x%{public}x, userId = %{public}d.", tokenId, appInfo.userId);
471     return appInfo.userId;
472 }
473 
IsCopyable(uint32_t tokenId) const474 bool PasteboardService::IsCopyable(uint32_t tokenId) const
475 {
476 #ifdef WITH_DLP
477     bool copyable = false;
478     auto ret = Security::DlpPermission::DlpPermissionKit::QueryDlpFileCopyableByTokenId(copyable, tokenId);
479     if (ret != 0 || !copyable) {
480         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "tokenId = 0x%{public}x ret = %{public}d, copyable = %{public}d.",
481             tokenId, ret, copyable);
482         return false;
483     }
484 #endif
485     return true;
486 }
487 
AddPasteboardChangedObserver(const sptr<IPasteboardChangedObserver> & observer)488 void PasteboardService::AddPasteboardChangedObserver(const sptr<IPasteboardChangedObserver> &observer)
489 {
490     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
491     AddObserver(observer, observerChangedMap_);
492 }
493 
RemovePasteboardChangedObserver(const sptr<IPasteboardChangedObserver> & observer)494 void PasteboardService::RemovePasteboardChangedObserver(const sptr<IPasteboardChangedObserver> &observer)
495 {
496     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
497     RemoveSingleObserver(observer, observerChangedMap_);
498 }
499 
RemoveAllChangedObserver()500 void PasteboardService::RemoveAllChangedObserver()
501 {
502     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
503     RemoveAllObserver(observerChangedMap_);
504 }
505 
AddPasteboardEventObserver(const sptr<IPasteboardChangedObserver> & observer)506 void PasteboardService::AddPasteboardEventObserver(const sptr<IPasteboardChangedObserver> &observer)
507 {
508     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
509     if (!IsCallerUidValid()) {
510         return;
511     }
512     AddObserver(observer, observerEventMap_);
513 }
514 
RemovePasteboardEventObserver(const sptr<IPasteboardChangedObserver> & observer)515 void PasteboardService::RemovePasteboardEventObserver(const sptr<IPasteboardChangedObserver> &observer)
516 {
517     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
518     if (!IsCallerUidValid()) {
519         return;
520     }
521     RemoveSingleObserver(observer, observerEventMap_);
522 }
523 
RemoveAllEventObserver()524 void PasteboardService::RemoveAllEventObserver()
525 {
526     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
527     if (!IsCallerUidValid()) {
528         return;
529     }
530     RemoveAllObserver(observerEventMap_);
531 }
532 
AddObserver(const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)533 void PasteboardService::AddObserver(const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
534 {
535     if (observer == nullptr) {
536         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
537         return;
538     }
539     auto userId = GetUserIdByToken(IPCSkeleton::GetCallingTokenID());
540     if (userId == ERROR_USERID) {
541         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
542         return;
543     }
544     std::lock_guard<std::mutex> lock(observerMutex_);
545     auto it = observerMap.find(userId);
546     std::shared_ptr<std::set<sptr<IPasteboardChangedObserver>, classcomp>> observers;
547     if (it != observerMap.end()) {
548         observers = it->second;
549     } else {
550         observers = std::make_shared<std::set<sptr<IPasteboardChangedObserver>, classcomp>>();
551         observerMap.insert(std::make_pair(userId, observers));
552     }
553     observers->insert(observer);
554     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, " observers->size = %{public}u.",
555         static_cast<unsigned int>(observers->size()));
556 }
557 
RemoveSingleObserver(const sptr<IPasteboardChangedObserver> & observer,ObserverMap & observerMap)558 void PasteboardService::RemoveSingleObserver(const sptr<IPasteboardChangedObserver> &observer, ObserverMap &observerMap)
559 {
560     if (observer == nullptr) {
561         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "observer null.");
562         return;
563     }
564     auto userId = GetUserIdByToken(IPCSkeleton::GetCallingTokenID());
565     if (userId == ERROR_USERID) {
566         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
567         return;
568     }
569     std::lock_guard<std::mutex> lock(observerMutex_);
570     auto it = observerMap.find(userId);
571     if (it == observerMap.end()) {
572         return;
573     }
574     auto observers = it->second;
575     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers->size: %{public}u.",
576         static_cast<unsigned int>(observers->size()));
577     auto eraseNum = observers->erase(observer);
578     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "listeners.size = %{public}u, eraseNum = %{public}zu",
579         static_cast<unsigned int>(observers->size()), eraseNum);
580 }
581 
RemoveAllObserver(ObserverMap & observerMap)582 void PasteboardService::RemoveAllObserver(ObserverMap &observerMap)
583 {
584     auto userId = GetUserIdByToken(IPCSkeleton::GetCallingTokenID());
585     if (userId == ERROR_USERID) {
586         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "userId invalid.");
587         return;
588     }
589     std::lock_guard<std::mutex> lock(observerMutex_);
590     auto it = observerMap.find(userId);
591     if (it == observerMap.end()) {
592         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_SERVICE, "observer empty.");
593         return;
594     }
595     auto observers = it->second;
596     auto eraseNum = observerMap.erase(userId);
597     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "listeners.size = %{public}u, eraseNum = %{public}zu",
598         static_cast<unsigned int>(observers->size()), eraseNum);
599 }
600 
IsCallerUidValid()601 inline bool PasteboardService::IsCallerUidValid()
602 {
603     pid_t callingUid = IPCSkeleton::GetCallingUid();
604     if (callingUid == EDM_UID || callingUid == ROOT_UID) {
605         return true;
606     }
607     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "callingUid error: %{public}d.", callingUid);
608     return false;
609 }
610 
NotifyObservers(std::string bundleName,PasteboardEventStatus status)611 void PasteboardService::NotifyObservers(std::string bundleName, PasteboardEventStatus status)
612 {
613     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
614     std::lock_guard<std::mutex> lock(observerMutex_);
615     for (auto &observers : observerChangedMap_) {
616         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "notify uid : %{public}d, changed observers size: %{public}u",
617             observers.first, static_cast<unsigned int>(observers.second->size()));
618         for (const auto &observer : *(observers.second)) {
619             if (status != PasteboardEventStatus::PASTEBOARD_READ) {
620                 observer->OnPasteboardChanged();
621             }
622         }
623     }
624     for (auto &observers : observerEventMap_) {
625         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "notify uid : %{public}d, event observers size: %{public}u",
626             observers.first, static_cast<unsigned int>(observers.second->size()));
627         for (const auto &observer : *(observers.second)) {
628             observer->OnPasteboardEvent(bundleName, static_cast<int32_t>(status));
629         }
630     }
631 }
632 
GetDataSize(PasteData & data) const633 size_t PasteboardService::GetDataSize(PasteData &data) const
634 {
635     if (data.GetRecordCount() != 0) {
636         size_t counts = data.GetRecordCount() - 1;
637         std::shared_ptr<PasteDataRecord> records = data.GetRecordAt(counts);
638         std::string text = records->ConvertToText();
639         size_t textSize = text.size();
640         return textSize;
641     }
642     return GET_WRONG_SIZE;
643 }
644 
SetPasteboardHistory(HistoryInfo & info)645 bool PasteboardService::SetPasteboardHistory(HistoryInfo &info)
646 {
647     std::string history = std::move(info.time) + " " + std::move(info.bundleName) + " " + std::move(info.state) + " "
648                           + " " + std::move(info.pop) + " " + std::move(info.remote);
649     constexpr const size_t DATA_HISTORY_SIZE = 10;
650     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
651     if (dataHistory_.size() == DATA_HISTORY_SIZE) {
652         dataHistory_.erase(dataHistory_.begin());
653     }
654     dataHistory_.push_back(std::move(history));
655     return true;
656 }
657 
Dump(int fd,const std::vector<std::u16string> & args)658 int PasteboardService::Dump(int fd, const std::vector<std::u16string> &args)
659 {
660     int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
661     const int maxUid = 10000;
662     if (uid > maxUid) {
663         return 0;
664     }
665 
666     std::vector<std::string> argsStr;
667     for (auto item : args) {
668         argsStr.emplace_back(Str16ToStr8(item));
669     }
670 
671     if (PasteboardDumpHelper::GetInstance().Dump(fd, argsStr)) {
672         return 0;
673     }
674     return 0;
675 }
676 
GetTime()677 std::string PasteboardService::GetTime()
678 {
679     constexpr int USEC_TO_MSEC = 1000;
680     time_t timeSeconds = time(0);
681     if (timeSeconds == -1) {
682         return FAIL_TO_GET_TIME_STAMP;
683     }
684     struct tm nowTime;
685     localtime_r(&timeSeconds, &nowTime);
686 
687     struct timeval timeVal = { 0, 0 };
688     gettimeofday(&timeVal, nullptr);
689 
690     std::string targetTime = std::to_string(nowTime.tm_year + 1900) + "-" + std::to_string(nowTime.tm_mon + 1) + "-" +
691                              std::to_string(nowTime.tm_mday) + " " + std::to_string(nowTime.tm_hour) + ":" +
692                              std::to_string(nowTime.tm_min) + ":" + std::to_string(nowTime.tm_sec) + "." +
693                              std::to_string(timeVal.tv_usec / USEC_TO_MSEC);
694     return targetTime;
695 }
696 
DumpHistory() const697 std::string PasteboardService::DumpHistory() const
698 {
699     std::string result;
700     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
701     if (!dataHistory_.empty()) {
702         result.append("Access history last ten times: ").append("\n");
703         for (auto iter = dataHistory_.rbegin(); iter != dataHistory_.rend(); ++iter) {
704             result.append("          ").append(*iter).append("\n");
705         }
706     } else {
707         result.append("Access history fail! dataHistory_ no data.").append("\n");
708     }
709     return result;
710 }
711 
ShareOptionToString(ShareOption shareOption,std::string & out)712 void PasteboardService::ShareOptionToString(ShareOption shareOption, std::string &out)
713 {
714     if (shareOption == ShareOption::InApp) {
715         out = "InAPP";
716     } else if (shareOption == ShareOption::LocalDevice) {
717         out = "LocalDevice";
718     } else {
719         out = "CrossDevice";
720     }
721 }
722 
DumpData()723 std::string PasteboardService::DumpData()
724 {
725     std::vector<int32_t> ids;
726     auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
727     if (ret != ERR_OK || ids.empty()) {
728         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed errCode=%{public}d", ret);
729         return "";
730     }
731     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "id = %{public}d", ids[0]);
732     std::lock_guard<std::mutex> lock(clipMutex_);
733     auto it = clips_.find(ids[0]);
734     std::string result;
735     if (it != clips_.end() && it->second != nullptr) {
736         size_t recordCounts = it->second->GetRecordCount();
737         auto property = it->second->GetProperty();
738         std::string shareOption;
739         ShareOptionToString(property.shareOption, shareOption);
740         std::string sourceDevice;
741         if (property.isRemote) {
742             sourceDevice = "remote";
743         } else {
744             sourceDevice = "local";
745         }
746         result.append("|Owner       :  ")
747             .append(property.bundleName)
748             .append("\n")
749             .append("|Timestamp   :  ")
750             .append(property.setTime)
751             .append("\n")
752             .append("|Share Option:  ")
753             .append(shareOption)
754             .append("\n")
755             .append("|Record Count:  ")
756             .append(std::to_string(recordCounts))
757             .append("\n")
758             .append("|Mime types  :  {");
759         if (!property.mimeTypes.empty()) {
760             for (size_t i = 0; i < property.mimeTypes.size(); ++i) {
761                 result.append(property.mimeTypes[i]).append(",");
762             }
763         }
764         result.append("}")
765             .append("\n")
766             .append("|source device:  ")
767             .append(sourceDevice);
768     } else {
769         result.append("No copy data.").append("\n");
770     }
771     return result;
772 }
773 
SetPasteDataDot(PasteData & pasteData)774 void PasteboardService::SetPasteDataDot(PasteData &pasteData)
775 {
776     auto property = pasteData.GetProperty();
777     HistoryInfo info{ property.setTime, property.bundleName, "set", "", "" };
778     SetPasteboardHistory(info);
779 
780     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData Report!");
781     Reporter::GetInstance().PasteboardBehaviour().Report(
782         { static_cast<int>(BehaviourPasteboardState::BPS_COPY_STATE), property.bundleName });
783 
784     int state = static_cast<int>(StatisticPasteboardState::SPS_COPY_STATE);
785     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData GetDataSize!");
786     size_t dataSize = GetDataSize(pasteData);
787     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData timeC!");
788     CalculateTimeConsuming timeC(dataSize, state);
789 }
790 
GetPasteDataDot(PasteData & pasteData,const std::string & pop,uint32_t tokenId)791 void PasteboardService::GetPasteDataDot(PasteData &pasteData, const std::string &pop, uint32_t tokenId)
792 {
793     auto property = pasteData.GetProperty();
794     std::string remote;
795     if (property.isRemote) {
796         remote = "remote";
797     }
798     std::string time = GetTime();
799     auto appInfo = GetAppInfo(tokenId);
800     HistoryInfo info{ time, appInfo.bundleName, "get", pop, remote };
801     SetPasteboardHistory(info);
802 
803     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData Report!");
804     int pState = StatisticPasteboardState::SPS_INVALID_STATE;
805     int bState = BehaviourPasteboardState::BPS_INVALID_STATE;
806     if (property.isRemote) {
807         pState = static_cast<int>(StatisticPasteboardState::SPS_REMOTE_PASTE_STATE);
808         bState = static_cast<int>(BehaviourPasteboardState::BPS_REMOTE_PASTE_STATE);
809     } else {
810         pState = static_cast<int>(StatisticPasteboardState::SPS_PASTE_STATE);
811         bState = static_cast<int>(BehaviourPasteboardState::BPS_PASTE_STATE);
812     };
813 
814     Reporter::GetInstance().PasteboardBehaviour().Report({ bState, appInfo.bundleName });
815 
816     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData GetDataSize");
817     size_t dataSize = GetDataSize(pasteData);
818     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData timeC");
819     CalculateTimeConsuming timeC(dataSize, pState);
820 }
821 
GetDistributedData(int32_t user)822 std::shared_ptr<PasteData> PasteboardService::GetDistributedData(int32_t user)
823 {
824     auto clipPlugin = GetClipPlugin();
825     if (clipPlugin == nullptr) {
826         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
827         return nullptr;
828     }
829     ClipPlugin::GlobalEvent event;
830     auto isEffective = GetDistributedEvent(clipPlugin, user, event);
831     if (event.status == ClipPlugin::EVT_UNKNOWN) {
832         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "EVT_UNKNOWN.");
833         return nullptr;
834     }
835     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "same device:%{public}d, evt seq:%{public}u current seq:%{public}u.",
836         event.deviceId == currentEvent_.deviceId, event.seqId, currentEvent_.seqId);
837     std::vector<uint8_t> rawData = std::move(event.addition);
838     SetDeviceName(event.deviceId);
839     if (!isEffective) {
840         currentEvent_.status = ClipPlugin::EVT_INVALID;
841         currentEvent_ = std::move(event);
842         Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
843         return nullptr;
844     }
845 
846     if (event.frameNum > 0 && (clipPlugin->GetPasteData(event, rawData) != 0)) {
847         Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
848         return nullptr;
849     }
850 
851     currentEvent_ = std::move(event);
852     std::shared_ptr<PasteData> pasteData = std::make_shared<PasteData>();
853     pasteData->Decode(rawData);
854     pasteData->ReplaceShareUri(user);
855     return pasteData;
856 }
857 
SetDistributedData(int32_t user,PasteData & data)858 bool PasteboardService::SetDistributedData(int32_t user, PasteData &data)
859 {
860     std::vector<uint8_t> rawData;
861     auto clipPlugin = GetClipPlugin();
862     if (clipPlugin == nullptr) {
863         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
864         return false;
865     }
866 
867     if (data.GetShareOption() == CrossDevice && !data.Encode(rawData)) {
868         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "encode failed.");
869         return false;
870     }
871 
872     uint64_t expiration =
873         duration_cast<milliseconds>((system_clock::now() + minutes(EXPIRATION_INTERVAL)).time_since_epoch()).count();
874     Event event;
875     event.user = user;
876     event.seqId = ++sequenceId_;
877     event.expiration = expiration;
878     event.deviceId = DMAdapter::GetInstance().GetLocalDevice();
879     event.account = AccountManager::GetInstance().GetCurrentAccount();
880     event.status = (data.GetShareOption() == CrossDevice) ? ClipPlugin::EVT_NORMAL : ClipPlugin::EVT_INVALID;
881     currentEvent_ = event;
882     clipPlugin->SetPasteData(event, rawData);
883     return true;
884 }
885 
HasDistributedData(int32_t user)886 bool PasteboardService::HasDistributedData(int32_t user)
887 {
888     auto clipPlugin = GetClipPlugin();
889     if (clipPlugin == nullptr) {
890         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
891         return false;
892     }
893     Event event;
894     auto has = GetDistributedEvent(clipPlugin, user, event);
895     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "same device:%{public}d, evt seq:%{public}u current seq:%{public}u.",
896         event.deviceId == currentEvent_.deviceId, event.seqId, currentEvent_.seqId);
897     return has;
898 }
899 
GetClipPlugin()900 std::shared_ptr<ClipPlugin> PasteboardService::GetClipPlugin()
901 {
902     auto isOn = DistributedModuleConfig::IsOn();
903     std::lock_guard<decltype(mutex)> lockGuard(mutex);
904     if (!isOn || clipPlugin_ != nullptr) {
905         return clipPlugin_;
906     }
907 
908     auto release = [this](ClipPlugin *plugin) {
909         std::lock_guard<decltype(mutex)> lockGuard(mutex);
910         ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
911     };
912 
913     clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
914     return clipPlugin_;
915 }
916 
CleanDistributedData(int32_t user)917 bool PasteboardService::CleanDistributedData(int32_t user)
918 {
919     auto clipPlugin = GetClipPlugin();
920     if (clipPlugin == nullptr) {
921         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
922         return true;
923     }
924     clipPlugin->Clear(user);
925     return true;
926 }
927 
OnConfigChange(bool isOn)928 void PasteboardService::OnConfigChange(bool isOn)
929 {
930     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "ConfigChange isOn: %{public}d.", isOn);
931     if (isOn) {
932         return;
933     }
934     std::lock_guard<decltype(mutex)> lockGuard(mutex);
935     clipPlugin_ = nullptr;
936 }
937 
GetDistributedEvent(std::shared_ptr<ClipPlugin> plugin,int32_t user,Event & event)938 bool PasteboardService::GetDistributedEvent(std::shared_ptr<ClipPlugin> plugin, int32_t user, Event &event)
939 {
940     auto events = plugin->GetTopEvents(1, user);
941     if (events.empty()) {
942         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "events empty.");
943         return false;
944     }
945 
946     auto &tmpEvent = events[0];
947     if (tmpEvent.deviceId == DMAdapter::GetInstance().GetLocalDevice()) {
948         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get local data.");
949         return false;
950     }
951     if (tmpEvent.account != AccountManager::GetInstance().GetCurrentAccount()) {
952         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "account error.");
953         return false;
954     }
955     if (tmpEvent.deviceId == currentEvent_.deviceId && tmpEvent.seqId == currentEvent_.seqId) {
956         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get same remote data.");
957         return false;
958     }
959 
960     event = std::move(tmpEvent);
961     uint64_t curTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
962     return ((curTime < event.expiration) && (event.status == ClipPlugin::EVT_NORMAL));
963 }
964 
GetAppLabel(uint32_t tokenId)965 std::string PasteboardService::GetAppLabel(uint32_t tokenId)
966 {
967     auto iBundleMgr = GetAppBundleManager();
968     if (iBundleMgr == nullptr) {
969         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to cast bundle mgr service.");
970         return PasteBoardDialog::DEFAULT_LABEL;
971     }
972     AppInfo info = GetAppInfo(tokenId);
973     AppExecFwk::ApplicationInfo appInfo;
974     auto result = iBundleMgr->GetApplicationInfo(info.bundleName, 0, info.userId, appInfo);
975     if (!result) {
976         return PasteBoardDialog::DEFAULT_LABEL;
977     }
978     auto &resource = appInfo.labelResource;
979     auto label = iBundleMgr->GetStringById(resource.bundleName, resource.moduleName, resource.id, info.userId);
980     return label.empty() ? PasteBoardDialog::DEFAULT_LABEL : label;
981 }
982 
GetAppBundleManager()983 sptr<AppExecFwk::IBundleMgr> PasteboardService::GetAppBundleManager()
984 {
985     auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
986     if (systemAbilityManager == nullptr) {
987         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get SystemAbilityManager.");
988         return nullptr;
989     }
990     auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
991     if (remoteObject == nullptr) {
992         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get bundle mgr service.");
993         return nullptr;
994     }
995     return OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
996 }
997 
GetDeviceName()998 std::string PasteboardService::GetDeviceName()
999 {
1000     std::lock_guard<decltype(deviceMutex_)> lockGuard(deviceMutex_);
1001     return fromDevice_;
1002 }
1003 
SetDeviceName(const std::string & device)1004 void PasteboardService::SetDeviceName(const std::string &device)
1005 {
1006     std::lock_guard<decltype(deviceMutex_)> lockGuard(deviceMutex_);
1007     if (device.empty() || device == DMAdapter::GetInstance().GetLocalDevice()) {
1008         fromDevice_ = "local";
1009         return;
1010     }
1011     fromDevice_ = DMAdapter::GetInstance().GetDeviceName(device);
1012 }
1013 } // namespace MiscServices
1014 } // namespace OHOS
1015