• 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     if (observer == nullptr) {
492         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "nullptr.");
493         return;
494     }
495     auto userId = GetUserIdByToken(IPCSkeleton::GetCallingTokenID());
496     if (userId == ERROR_USERID) {
497         return;
498     }
499     std::lock_guard<std::mutex> lock(observerMutex_);
500     auto it = observerMap_.find(userId);
501     std::shared_ptr<std::set<sptr<IPasteboardChangedObserver>, classcomp>> observers;
502     if (it != observerMap_.end()) {
503         observers = it->second;
504     } else {
505         observers = std::make_shared<std::set<sptr<IPasteboardChangedObserver>, classcomp>>();
506         observerMap_.insert(std::make_pair(userId, observers));
507     }
508     observers->insert(observer);
509     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, " observers->size = %{public}d,",
510         static_cast<unsigned int>(observerMap_.size()));
511 }
RemovePasteboardChangedObserver(const sptr<IPasteboardChangedObserver> & observer)512 void PasteboardService::RemovePasteboardChangedObserver(const sptr<IPasteboardChangedObserver> &observer)
513 {
514     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
515     if (observer == nullptr) {
516         return;
517     }
518     auto userId = GetUserIdByToken(IPCSkeleton::GetCallingTokenID());
519     if (userId == ERROR_USERID) {
520         return;
521     }
522     std::lock_guard<std::mutex> lock(observerMutex_);
523     auto it = observerMap_.find(userId);
524     if (it == observerMap_.end()) {
525         return;
526     }
527     auto observers = it->second;
528     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "observers->size: %{public}d.",
529         static_cast<unsigned int>(observers->size()));
530     auto eraseNum = observers->erase(observer);
531     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE,
532         " listeners.size = %{public}d, eraseNum = %{public}zu", static_cast<unsigned int>(observers->size()), eraseNum);
533 }
534 
RemoveAllChangedObserver()535 void PasteboardService::RemoveAllChangedObserver()
536 {
537     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
538     auto userId = GetUserIdByToken(IPCSkeleton::GetCallingTokenID());
539     if (userId == ERROR_USERID) {
540         return;
541     }
542     std::lock_guard<std::mutex> lock(observerMutex_);
543     auto it = observerMap_.find(userId);
544     if (it == observerMap_.end()) {
545         return;
546     }
547     observerMap_.erase(userId);
548     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "end.");
549 }
550 
NotifyObservers(std::string bundleName,PasteboardEventStatus status)551 void PasteboardService::NotifyObservers(std::string bundleName, PasteboardEventStatus status)
552 {
553     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "start.");
554     std::lock_guard<std::mutex> lock(observerMutex_);
555     for (auto &observers : observerMap_) {
556         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "notify uid : %{public}d.", observers.first);
557         for (const auto &observer : *(observers.second)) {
558             if (status != PasteboardEventStatus::PASTEBOARD_READ) {
559                 observer->OnPasteboardChanged();
560             }
561             observer->OnPasteboardEvent(bundleName, static_cast<int32_t>(status));
562         }
563     }
564 }
565 
GetDataSize(PasteData & data) const566 size_t PasteboardService::GetDataSize(PasteData &data) const
567 {
568     if (data.GetRecordCount() != 0) {
569         size_t counts = data.GetRecordCount() - 1;
570         std::shared_ptr<PasteDataRecord> records = data.GetRecordAt(counts);
571         std::string text = records->ConvertToText();
572         size_t textSize = text.size();
573         return textSize;
574     }
575     return GET_WRONG_SIZE;
576 }
577 
SetPasteboardHistory(HistoryInfo & info)578 bool PasteboardService::SetPasteboardHistory(HistoryInfo &info)
579 {
580     std::string history = std::move(info.time) + " " + std::move(info.bundleName) + " " + std::move(info.state) + " "
581                           + " " + std::move(info.pop) + " " + std::move(info.remote);
582     constexpr const size_t DATA_HISTORY_SIZE = 10;
583     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
584     if (dataHistory_.size() == DATA_HISTORY_SIZE) {
585         dataHistory_.erase(dataHistory_.begin());
586     }
587     dataHistory_.push_back(std::move(history));
588     return true;
589 }
590 
Dump(int fd,const std::vector<std::u16string> & args)591 int PasteboardService::Dump(int fd, const std::vector<std::u16string> &args)
592 {
593     int uid = static_cast<int>(IPCSkeleton::GetCallingUid());
594     const int maxUid = 10000;
595     if (uid > maxUid) {
596         return 0;
597     }
598 
599     std::vector<std::string> argsStr;
600     for (auto item : args) {
601         argsStr.emplace_back(Str16ToStr8(item));
602     }
603 
604     if (PasteboardDumpHelper::GetInstance().Dump(fd, argsStr)) {
605         return 0;
606     }
607     return 0;
608 }
609 
GetTime()610 std::string PasteboardService::GetTime()
611 {
612     constexpr int USEC_TO_MSEC = 1000;
613     time_t timeSeconds = time(0);
614     if (timeSeconds == -1) {
615         return FAIL_TO_GET_TIME_STAMP;
616     }
617     struct tm nowTime;
618     localtime_r(&timeSeconds, &nowTime);
619 
620     struct timeval timeVal = { 0, 0 };
621     gettimeofday(&timeVal, nullptr);
622 
623     std::string targetTime = std::to_string(nowTime.tm_year + 1900) + "-" + std::to_string(nowTime.tm_mon + 1) + "-" +
624                              std::to_string(nowTime.tm_mday) + " " + std::to_string(nowTime.tm_hour) + ":" +
625                              std::to_string(nowTime.tm_min) + ":" + std::to_string(nowTime.tm_sec) + "." +
626                              std::to_string(timeVal.tv_usec / USEC_TO_MSEC);
627     return targetTime;
628 }
629 
DumpHistory() const630 std::string PasteboardService::DumpHistory() const
631 {
632     std::string result;
633     std::lock_guard<decltype(historyMutex_)> lg(historyMutex_);
634     if (!dataHistory_.empty()) {
635         result.append("Access history last ten times: ").append("\n");
636         for (auto iter = dataHistory_.rbegin(); iter != dataHistory_.rend(); ++iter) {
637             result.append("          ").append(*iter).append("\n");
638         }
639     } else {
640         result.append("Access history fail! dataHistory_ no data.").append("\n");
641     }
642     return result;
643 }
644 
ShareOptionToString(ShareOption shareOption,std::string & out)645 void PasteboardService::ShareOptionToString(ShareOption shareOption, std::string &out)
646 {
647     if (shareOption == ShareOption::InApp) {
648         out = "InAPP";
649     } else if (shareOption == ShareOption::LocalDevice) {
650         out = "LocalDevice";
651     } else {
652         out = "CrossDevice";
653     }
654 }
655 
DumpData()656 std::string PasteboardService::DumpData()
657 {
658     std::vector<int32_t> ids;
659     auto ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
660     if (ret != ERR_OK || ids.empty()) {
661         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "query active user failed errCode=%{public}d", ret);
662         return "";
663     }
664     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "id = %{public}d", ids[0]);
665     std::lock_guard<std::mutex> lock(clipMutex_);
666     auto it = clips_.find(ids[0]);
667     std::string result;
668     if (it != clips_.end() && it->second != nullptr) {
669         size_t recordCounts = it->second->GetRecordCount();
670         auto property = it->second->GetProperty();
671         std::string shareOption;
672         ShareOptionToString(property.shareOption, shareOption);
673         std::string sourceDevice;
674         if (property.isRemote) {
675             sourceDevice = "remote";
676         } else {
677             sourceDevice = "local";
678         }
679         result.append("|Owner       :  ")
680             .append(property.bundleName)
681             .append("\n")
682             .append("|Timestamp   :  ")
683             .append(property.setTime)
684             .append("\n")
685             .append("|Share Option:  ")
686             .append(shareOption)
687             .append("\n")
688             .append("|Record Count:  ")
689             .append(std::to_string(recordCounts))
690             .append("\n")
691             .append("|Mime types  :  {");
692         if (!property.mimeTypes.empty()) {
693             for (size_t i = 0; i < property.mimeTypes.size(); ++i) {
694                 result.append(property.mimeTypes[i]).append(",");
695             }
696         }
697         result.append("}")
698             .append("\n")
699             .append("|source device:  ")
700             .append(sourceDevice);
701     } else {
702         result.append("No copy data.").append("\n");
703     }
704     return result;
705 }
706 
SetPasteDataDot(PasteData & pasteData)707 void PasteboardService::SetPasteDataDot(PasteData &pasteData)
708 {
709     auto property = pasteData.GetProperty();
710     HistoryInfo info{ property.setTime, property.bundleName, "set", "", "" };
711     SetPasteboardHistory(info);
712 
713     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData Report!");
714     Reporter::GetInstance().PasteboardBehaviour().Report(
715         { static_cast<int>(BehaviourPasteboardState::BPS_COPY_STATE), property.bundleName });
716 
717     int state = static_cast<int>(StatisticPasteboardState::SPS_COPY_STATE);
718     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData GetDataSize!");
719     size_t dataSize = GetDataSize(pasteData);
720     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "SetPasteData timeC!");
721     CalculateTimeConsuming timeC(dataSize, state);
722 }
723 
GetPasteDataDot(PasteData & pasteData,const std::string & pop,uint32_t tokenId)724 void PasteboardService::GetPasteDataDot(PasteData &pasteData, const std::string &pop, uint32_t tokenId)
725 {
726     auto property = pasteData.GetProperty();
727     std::string remote;
728     if (property.isRemote) {
729         remote = "remote";
730     }
731     std::string time = GetTime();
732     auto appInfo = GetAppInfo(tokenId);
733     HistoryInfo info{ time, appInfo.bundleName, "get", pop, remote };
734     SetPasteboardHistory(info);
735 
736     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData Report!");
737     int pState = StatisticPasteboardState::SPS_INVALID_STATE;
738     int bState = BehaviourPasteboardState::BPS_INVALID_STATE;
739     if (property.isRemote) {
740         pState = static_cast<int>(StatisticPasteboardState::SPS_REMOTE_PASTE_STATE);
741         bState = static_cast<int>(BehaviourPasteboardState::BPS_REMOTE_PASTE_STATE);
742     } else {
743         pState = static_cast<int>(StatisticPasteboardState::SPS_PASTE_STATE);
744         bState = static_cast<int>(BehaviourPasteboardState::BPS_PASTE_STATE);
745     };
746 
747     Reporter::GetInstance().PasteboardBehaviour().Report({ bState, appInfo.bundleName });
748 
749     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData GetDataSize");
750     size_t dataSize = GetDataSize(pasteData);
751     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_SERVICE, "GetPasteData timeC");
752     CalculateTimeConsuming timeC(dataSize, pState);
753 }
754 
GetDistributedData(int32_t user)755 std::shared_ptr<PasteData> PasteboardService::GetDistributedData(int32_t user)
756 {
757     auto clipPlugin = GetClipPlugin();
758     if (clipPlugin == nullptr) {
759         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
760         return nullptr;
761     }
762     ClipPlugin::GlobalEvent event;
763     auto isEffective = GetDistributedEvent(clipPlugin, user, event);
764     if (event.status == ClipPlugin::EVT_UNKNOWN) {
765         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "EVT_UNKNOWN.");
766         return nullptr;
767     }
768     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "same device:%{public}d, evt seq:%{public}u current seq:%{public}u.",
769         event.deviceId == currentEvent_.deviceId, event.seqId, currentEvent_.seqId);
770     std::vector<uint8_t> rawData = std::move(event.addition);
771     SetDeviceName(event.deviceId);
772     if (!isEffective) {
773         currentEvent_.status = ClipPlugin::EVT_INVALID;
774         currentEvent_ = std::move(event);
775         Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
776         return nullptr;
777     }
778 
779     if (event.frameNum > 0 && (clipPlugin->GetPasteData(event, rawData) != 0)) {
780         Reporter::GetInstance().PasteboardFault().Report({ user, "GET_REMOTE_DATA_FAILED" });
781         return nullptr;
782     }
783 
784     currentEvent_ = std::move(event);
785     std::shared_ptr<PasteData> pasteData = std::make_shared<PasteData>();
786     pasteData->Decode(rawData);
787     pasteData->ReplaceShareUri(user);
788     return pasteData;
789 }
790 
SetDistributedData(int32_t user,PasteData & data)791 bool PasteboardService::SetDistributedData(int32_t user, PasteData &data)
792 {
793     std::vector<uint8_t> rawData;
794     auto clipPlugin = GetClipPlugin();
795     if (clipPlugin == nullptr) {
796         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
797         return false;
798     }
799 
800     if (data.GetShareOption() == CrossDevice && !data.Encode(rawData)) {
801         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "encode failed.");
802         return false;
803     }
804 
805     uint64_t expiration =
806         duration_cast<milliseconds>((system_clock::now() + minutes(EXPIRATION_INTERVAL)).time_since_epoch()).count();
807     Event event;
808     event.user = user;
809     event.seqId = ++sequenceId_;
810     event.expiration = expiration;
811     event.deviceId = DMAdapter::GetInstance().GetLocalDevice();
812     event.account = AccountManager::GetInstance().GetCurrentAccount();
813     event.status = (data.GetShareOption() == CrossDevice) ? ClipPlugin::EVT_NORMAL : ClipPlugin::EVT_INVALID;
814     currentEvent_ = event;
815     clipPlugin->SetPasteData(event, rawData);
816     return true;
817 }
818 
HasDistributedData(int32_t user)819 bool PasteboardService::HasDistributedData(int32_t user)
820 {
821     auto clipPlugin = GetClipPlugin();
822     if (clipPlugin == nullptr) {
823         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
824         return false;
825     }
826     Event event;
827     auto has = GetDistributedEvent(clipPlugin, user, event);
828     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "same device:%{public}d, evt seq:%{public}u current seq:%{public}u.",
829         event.deviceId == currentEvent_.deviceId, event.seqId, currentEvent_.seqId);
830     return has;
831 }
832 
GetClipPlugin()833 std::shared_ptr<ClipPlugin> PasteboardService::GetClipPlugin()
834 {
835     auto isOn = DistributedModuleConfig::IsOn();
836     std::lock_guard<decltype(mutex)> lockGuard(mutex);
837     if (!isOn || clipPlugin_ != nullptr) {
838         return clipPlugin_;
839     }
840 
841     auto release = [this](ClipPlugin *plugin) {
842         std::lock_guard<decltype(mutex)> lockGuard(mutex);
843         ClipPlugin::DestroyPlugin(PLUGIN_NAME, plugin);
844     };
845 
846     clipPlugin_ = std::shared_ptr<ClipPlugin>(ClipPlugin::CreatePlugin(PLUGIN_NAME), release);
847     return clipPlugin_;
848 }
849 
CleanDistributedData(int32_t user)850 bool PasteboardService::CleanDistributedData(int32_t user)
851 {
852     auto clipPlugin = GetClipPlugin();
853     if (clipPlugin == nullptr) {
854         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, "clipPlugin null.");
855         return true;
856     }
857     clipPlugin->Clear(user);
858     return true;
859 }
860 
OnConfigChange(bool isOn)861 void PasteboardService::OnConfigChange(bool isOn)
862 {
863     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "ConfigChange isOn: %{public}d.", isOn);
864     if (isOn) {
865         return;
866     }
867     std::lock_guard<decltype(mutex)> lockGuard(mutex);
868     clipPlugin_ = nullptr;
869 }
870 
GetDistributedEvent(std::shared_ptr<ClipPlugin> plugin,int32_t user,Event & event)871 bool PasteboardService::GetDistributedEvent(std::shared_ptr<ClipPlugin> plugin, int32_t user, Event &event)
872 {
873     auto events = plugin->GetTopEvents(1, user);
874     if (events.empty()) {
875         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "events empty.");
876         return false;
877     }
878 
879     auto &tmpEvent = events[0];
880     if (tmpEvent.deviceId == DMAdapter::GetInstance().GetLocalDevice()) {
881         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get local data.");
882         return false;
883     }
884     if (tmpEvent.account != AccountManager::GetInstance().GetCurrentAccount()) {
885         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "account error.");
886         return false;
887     }
888     if (tmpEvent.deviceId == currentEvent_.deviceId && tmpEvent.seqId == currentEvent_.seqId) {
889         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_SERVICE, "get same remote data.");
890         return false;
891     }
892 
893     event = std::move(tmpEvent);
894     uint64_t curTime = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
895     return ((curTime < event.expiration) && (event.status == ClipPlugin::EVT_NORMAL));
896 }
897 
GetAppLabel(uint32_t tokenId)898 std::string PasteboardService::GetAppLabel(uint32_t tokenId)
899 {
900     auto iBundleMgr = GetAppBundleManager();
901     if (iBundleMgr == nullptr) {
902         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to cast bundle mgr service.");
903         return PasteBoardDialog::DEFAULT_LABEL;
904     }
905     AppInfo info = GetAppInfo(tokenId);
906     AppExecFwk::ApplicationInfo appInfo;
907     auto result = iBundleMgr->GetApplicationInfo(info.bundleName, 0, info.userId, appInfo);
908     if (!result) {
909         return PasteBoardDialog::DEFAULT_LABEL;
910     }
911     auto &resource = appInfo.labelResource;
912     auto label = iBundleMgr->GetStringById(resource.bundleName, resource.moduleName, resource.id, info.userId);
913     return label.empty() ? PasteBoardDialog::DEFAULT_LABEL : label;
914 }
915 
GetAppBundleManager()916 sptr<AppExecFwk::IBundleMgr> PasteboardService::GetAppBundleManager()
917 {
918     auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
919     if (systemAbilityManager == nullptr) {
920         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get SystemAbilityManager.");
921         return nullptr;
922     }
923     auto remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
924     if (remoteObject == nullptr) {
925         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_SERVICE, " Failed to get bundle mgr service.");
926         return nullptr;
927     }
928     return OHOS::iface_cast<AppExecFwk::IBundleMgr>(remoteObject);
929 }
930 
GetDeviceName()931 std::string PasteboardService::GetDeviceName()
932 {
933     std::lock_guard<decltype(deviceMutex_)> lockGuard(deviceMutex_);
934     return fromDevice_;
935 }
936 
SetDeviceName(const std::string & device)937 void PasteboardService::SetDeviceName(const std::string &device)
938 {
939     std::lock_guard<decltype(deviceMutex_)> lockGuard(deviceMutex_);
940     if (device.empty() || device == DMAdapter::GetInstance().GetLocalDevice()) {
941         fromDevice_ = "local";
942         return;
943     }
944     fromDevice_ = DMAdapter::GetInstance().GetDeviceName(device);
945 }
946 } // namespace MiscServices
947 } // namespace OHOS
948