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