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