• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <if_system_ability_manager.h>
17 #include <ipc_skeleton.h>
18 #include <iservice_registry.h>
19 #include <chrono>
20 
21 #include "hiview_adapter.h"
22 #include "hitrace_meter.h"
23 #include "pasteboard_client.h"
24 #include "pasteboard_error.h"
25 #include "pasteboard_load_callback.h"
26 #include "pasteboard_observer.h"
27 #include "string_ex.h"
28 #include "system_ability_definition.h"
29 #include "pasteboard_web_controller.h"
30 
31 using namespace OHOS::Media;
32 
33 namespace OHOS {
34 namespace MiscServices {
35 constexpr const int32_t HITRACE_GETPASTEDATA = 0;
36 constexpr int32_t LOADSA_TIMEOUT_MS = 10000;
37 sptr<IPasteboardService> PasteboardClient::pasteboardServiceProxy_;
38 PasteboardClient::StaticDestoryMonitor PasteboardClient::staticDestoryMonitor_;
39 std::mutex PasteboardClient::instanceLock_;
40 std::condition_variable PasteboardClient::proxyConVar_;
PasteboardClient()41 PasteboardClient::PasteboardClient(){};
~PasteboardClient()42 PasteboardClient::~PasteboardClient()
43 {
44     if (pasteboardServiceProxy_ != nullptr && !staticDestoryMonitor_.IsDestoryed()) {
45         auto remoteObject = pasteboardServiceProxy_->AsObject();
46         if (remoteObject != nullptr) {
47             remoteObject->RemoveDeathRecipient(deathRecipient_);
48         }
49     }
50 }
51 
CreateHtmlTextRecord(const std::string & htmlText)52 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateHtmlTextRecord(const std::string &htmlText)
53 {
54     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New text record");
55     return PasteDataRecord::NewHtmlRecord(htmlText);
56 }
57 
CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)58 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
59 {
60     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New want record");
61     return PasteDataRecord::NewWantRecord(std::move(want));
62 }
63 
CreatePlainTextRecord(const std::string & text)64 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePlainTextRecord(const std::string &text)
65 {
66     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New text record");
67     return PasteDataRecord::NewPlaintTextRecord(text);
68 }
69 
CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)70 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
71 {
72     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New pixelMap record");
73     return PasteDataRecord::NewPixelMapRecord(std::move(pixelMap));
74 }
75 
CreateUriRecord(const OHOS::Uri & uri)76 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateUriRecord(const OHOS::Uri &uri)
77 {
78     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New uri record");
79     return PasteDataRecord::NewUriRecord(uri);
80 }
81 
CreateKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)82 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateKvRecord(
83     const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
84 {
85     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New kv record");
86     return PasteDataRecord::NewKvRecord(mimeType, arrayBuffer);
87 }
88 
CreateHtmlData(const std::string & htmlText)89 std::shared_ptr<PasteData> PasteboardClient::CreateHtmlData(const std::string &htmlText)
90 {
91     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New htmlText data");
92     auto pasteData = std::make_shared<PasteData>();
93     pasteData->AddHtmlRecord(htmlText);
94     return pasteData;
95 }
96 
CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)97 std::shared_ptr<PasteData> PasteboardClient::CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)
98 {
99     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New want data");
100     auto pasteData = std::make_shared<PasteData>();
101     pasteData->AddWantRecord(std::move(want));
102     return pasteData;
103 }
104 
CreatePlainTextData(const std::string & text)105 std::shared_ptr<PasteData> PasteboardClient::CreatePlainTextData(const std::string &text)
106 {
107     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New plain data");
108     auto pasteData = std::make_shared<PasteData>();
109     pasteData->AddTextRecord(text);
110     return pasteData;
111 }
112 
CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)113 std::shared_ptr<PasteData> PasteboardClient::CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)
114 {
115     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New pixelMap data");
116     auto pasteData = std::make_shared<PasteData>();
117     pasteData->AddPixelMapRecord(std::move(pixelMap));
118     return pasteData;
119 }
120 
CreateUriData(const OHOS::Uri & uri)121 std::shared_ptr<PasteData> PasteboardClient::CreateUriData(const OHOS::Uri &uri)
122 {
123     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New uri data");
124     auto pasteData = std::make_shared<PasteData>();
125     pasteData->AddUriRecord(uri);
126     return pasteData;
127 }
128 
CreateKvData(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)129 std::shared_ptr<PasteData> PasteboardClient::CreateKvData(
130     const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
131 {
132     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "New Kv data");
133     auto pasteData = std::make_shared<PasteData>();
134     pasteData->AddKvRecord(mimeType, arrayBuffer);
135     return pasteData;
136 }
137 
Clear()138 void PasteboardClient::Clear()
139 {
140     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Clear start.");
141     if (!IsServiceAvailable()) {
142         return;
143     }
144     pasteboardServiceProxy_->Clear();
145     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Clear end.");
146     return;
147 }
148 
GetPasteData(PasteData & pasteData)149 int32_t PasteboardClient::GetPasteData(PasteData &pasteData)
150 {
151     StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
152     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetPasteData start.");
153     if (!IsServiceAvailable()) {
154         return static_cast<int32_t>(PasteboardError::E_SA_DIED);
155     }
156     int32_t ret = pasteboardServiceProxy_->GetPasteData(pasteData);
157     RebuildWebviewPasteData(pasteData);
158     RetainUri(pasteData);
159     FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
160     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "GetPasteData end.");
161     return ret;
162 }
163 
RebuildWebviewPasteData(PasteData & pasteData)164 void PasteboardClient::RebuildWebviewPasteData(PasteData &pasteData)
165 {
166     if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG || pasteData.GetPrimaryHtml() == nullptr) {
167         return;
168     }
169     auto PasteboardWebController = PasteboardWebController::GetInstance();
170     PasteboardWebController.RebuildHtml(std::make_shared<PasteData>(pasteData));
171 }
172 
RetainUri(PasteData & pasteData)173 void PasteboardClient::RetainUri(PasteData &pasteData)
174 {
175     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start");
176     if (!pasteData.IsLocalPaste()) {
177         return;
178     }
179     // clear convert uri
180     for (size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
181         auto record = pasteData.GetRecordAt(0);
182         if (record != nullptr) {
183             record->SetConvertUri("");
184         }
185     }
186     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end");
187 }
188 
HasPasteData()189 bool PasteboardClient::HasPasteData()
190 {
191     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "HasPasteData start.");
192     if (!IsServiceAvailable()) {
193         return false;
194     }
195     return pasteboardServiceProxy_->HasPasteData();
196 }
197 
SetPasteData(PasteData & pasteData)198 int32_t PasteboardClient::SetPasteData(PasteData &pasteData)
199 {
200     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SetPasteData start.");
201     if (!IsServiceAvailable()) {
202         return static_cast<int32_t>(PasteboardError::E_SA_DIED);
203     }
204     std::shared_ptr<std::string> html = pasteData.GetPrimaryHtml();
205     if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG || html == nullptr) {
206         return pasteboardServiceProxy_->SetPasteData(pasteData);
207     }
208     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "SetPasteData from webview start.");
209     std::shared_ptr<std::string> primaryText = pasteData.GetRecordAt(0)->GetPlainText();
210     auto PasteboardWebController = PasteboardWebController::GetInstance();
211     std::shared_ptr<PasteData> webPasteData = PasteboardWebController.SplitHtml(html);
212     webPasteData->RemoveRecordAt(webPasteData->GetRecordCount() - 1);
213     std::string mimeType = MIMETYPE_TEXT_PLAIN;
214     PasteDataRecord::Builder builder(MIMETYPE_TEXT_HTML);
215     std::shared_ptr<PasteDataRecord> pasteDataRecord =
216         builder.SetMimeType(mimeType).SetPlainText(primaryText).SetHtmlText(html).Build();
217     webPasteData->AddRecord(pasteDataRecord);
218     webPasteData->SetTag(PasteData::WEBVIEW_PASTEDATA_TAG);
219     return pasteboardServiceProxy_->SetPasteData(*webPasteData);
220 }
221 
AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)222 void PasteboardClient::AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)
223 {
224     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
225     if (callback == nullptr) {
226         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "input nullptr.");
227         return;
228     }
229     if (!IsServiceAvailable()) {
230         return;
231     }
232     pasteboardServiceProxy_->AddPasteboardChangedObserver(callback);
233     return;
234 }
235 
AddPasteboardEventObserver(sptr<PasteboardObserver> callback)236 void PasteboardClient::AddPasteboardEventObserver(sptr<PasteboardObserver> callback)
237 {
238     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
239     if (callback == nullptr) {
240         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "input nullptr.");
241         return;
242     }
243     if (!IsServiceAvailable()) {
244         return;
245     }
246     pasteboardServiceProxy_->AddPasteboardEventObserver(callback);
247 }
248 
RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)249 void PasteboardClient::RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)
250 {
251     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
252     if (!IsServiceAvailable()) {
253         return;
254     }
255     if (callback == nullptr) {
256         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "remove all.");
257         pasteboardServiceProxy_->RemoveAllChangedObserver();
258         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
259         return;
260     }
261     pasteboardServiceProxy_->RemovePasteboardChangedObserver(callback);
262     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
263     return;
264 }
265 
RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)266 void PasteboardClient::RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)
267 {
268     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
269     if (!IsServiceAvailable()) {
270         return;
271     }
272     if (callback == nullptr) {
273         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "remove all.");
274         pasteboardServiceProxy_->RemoveAllEventObserver();
275         PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
276         return;
277     }
278     pasteboardServiceProxy_->RemovePasteboardEventObserver(callback);
279     PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
280 }
281 
IsServiceAvailable()282 inline bool PasteboardClient::IsServiceAvailable()
283 {
284     if (pasteboardServiceProxy_ == nullptr) {
285         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
286         ConnectService();
287     }
288 
289     if (pasteboardServiceProxy_ == nullptr) {
290         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Service proxy null.");
291         return false;
292     }
293     return true;
294 }
295 
ConnectService()296 void PasteboardClient::ConnectService()
297 {
298     std::unique_lock<std::mutex> lock(instanceLock_);
299     if (pasteboardServiceProxy_ != nullptr) {
300         return;
301     }
302     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "ConnectService start.");
303     sptr<ISystemAbilityManager> samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
304     if (samgrProxy == nullptr) {
305         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Get SystemAbilityManager failed.");
306         pasteboardServiceProxy_ = nullptr;
307         return;
308     }
309     sptr<IRemoteObject> remoteObject = samgrProxy->CheckSystemAbility(PASTEBOARD_SERVICE_ID);
310     if (remoteObject != nullptr) {
311         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Get PasteboardServiceProxy succeed.");
312         if (deathRecipient_ == nullptr) {
313             deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
314         }
315         remoteObject->AddDeathRecipient(deathRecipient_);
316         pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
317         return;
318     }
319     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "remoteObject is null.");
320     sptr<PasteboardLoadCallback> loadCallback = new PasteboardLoadCallback();
321     if (loadCallback == nullptr) {
322         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "loadCallback is nullptr.");
323         return;
324     }
325     int32_t ret = samgrProxy->LoadSystemAbility(PASTEBOARD_SERVICE_ID, loadCallback);
326     if (ret != ERR_OK) {
327         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Failed to load systemAbility.");
328         return;
329     }
330     auto waitStatus = proxyConVar_.wait_for(lock, std::chrono::milliseconds(LOADSA_TIMEOUT_MS),
331         [this]() { return pasteboardServiceProxy_ != nullptr; });
332     if (!waitStatus) {
333         PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "Load systemAbility timeout.");
334         return;
335     }
336     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Getting PasteboardServiceProxy succeeded.");
337 }
338 
LoadSystemAbilitySuccess(const sptr<IRemoteObject> & remoteObject)339 void PasteboardClient::LoadSystemAbilitySuccess(const sptr<IRemoteObject> &remoteObject)
340 {
341     std::lock_guard<std::mutex> lock(instanceLock_);
342     if (deathRecipient_ == nullptr) {
343         deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
344     }
345     if (remoteObject != nullptr) {
346         remoteObject->AddDeathRecipient(deathRecipient_);
347         pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
348     }
349     proxyConVar_.notify_one();
350 }
351 
LoadSystemAbilityFail()352 void PasteboardClient::LoadSystemAbilityFail()
353 {
354     std::lock_guard<std::mutex> lock(instanceLock_);
355     pasteboardServiceProxy_ = nullptr;
356     proxyConVar_.notify_one();
357 }
358 
OnRemoteSaDied(const wptr<IRemoteObject> & remote)359 void PasteboardClient::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
360 {
361     PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "OnRemoteSaDied start.");
362     pasteboardServiceProxy_ = nullptr;
363     ConnectService();
364 }
365 
PasteboardSaDeathRecipient()366 PasteboardSaDeathRecipient::PasteboardSaDeathRecipient()
367 {
368 }
369 
OnRemoteDied(const wptr<IRemoteObject> & object)370 void PasteboardSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
371 {
372     PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "PasteboardSaDeathRecipient on remote systemAbility died.");
373     PasteboardClient::GetInstance()->OnRemoteSaDied(object);
374 }
375 } // namespace MiscServices
376 } // namespace OHOS
377