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_client.h"
16
17 #include <if_system_ability_manager.h>
18 #include <ipc_skeleton.h>
19 #include <iservice_registry.h>
20
21 #include "hitrace_meter.h"
22
23 #include "pasteboard_observer.h"
24 #include "string_ex.h"
25 #include "system_ability_definition.h"
26 #include "pasteboard_observer.h"
27 #include "pasteboard_error.h"
28 #include "pasteboard_client.h"
29
30 using namespace OHOS::Media;
31
32 namespace OHOS {
33 namespace MiscServices {
34 constexpr const int32_t HITRACE_GETPASTEDATA = 0;
35 sptr<IPasteboardService> PasteboardClient::pasteboardServiceProxy_;
36 PasteboardClient::StaticDestoryMonitor PasteboardClient::staticDestoryMonitor_;
37 std::mutex PasteboardClient::instanceLock_;
PasteboardClient()38 PasteboardClient::PasteboardClient(){};
~PasteboardClient()39 PasteboardClient::~PasteboardClient()
40 {
41 if (pasteboardServiceProxy_ != nullptr && !staticDestoryMonitor_.IsDestoryed()) {
42 auto remoteObject = pasteboardServiceProxy_->AsObject();
43 if (remoteObject != nullptr) {
44 remoteObject->RemoveDeathRecipient(deathRecipient_);
45 }
46 }
47 }
48
CreateHtmlTextRecord(const std::string & htmlText)49 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateHtmlTextRecord(const std::string &htmlText)
50 {
51 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New text record");
52 return PasteDataRecord::NewHtmlRecord(htmlText);
53 }
54
CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)55 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateWantRecord(std::shared_ptr<OHOS::AAFwk::Want> want)
56 {
57 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New want record");
58 return PasteDataRecord::NewWantRecord(std::move(want));
59 }
60
CreatePlainTextRecord(const std::string & text)61 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePlainTextRecord(const std::string &text)
62 {
63 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New text record");
64 return PasteDataRecord::NewPlaintTextRecord(text);
65 }
66
CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)67 std::shared_ptr<PasteDataRecord> PasteboardClient::CreatePixelMapRecord(std::shared_ptr<PixelMap> pixelMap)
68 {
69 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New pixelMap record");
70 return PasteDataRecord::NewPixelMapRecord(std::move(pixelMap));
71 }
72
CreateUriRecord(const OHOS::Uri & uri)73 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateUriRecord(const OHOS::Uri &uri)
74 {
75 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New uri record");
76 return PasteDataRecord::NewUriRecord(uri);
77 }
78
CreateKvRecord(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)79 std::shared_ptr<PasteDataRecord> PasteboardClient::CreateKvRecord(
80 const std::string &mimeType, const std::vector<uint8_t>& arrayBuffer)
81 {
82 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New kv record");
83 return PasteDataRecord::NewKvRecord(mimeType, arrayBuffer);
84 }
85
CreateHtmlData(const std::string & htmlText)86 std::shared_ptr<PasteData> PasteboardClient::CreateHtmlData(const std::string &htmlText)
87 {
88 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New htmlText data");
89 auto pasteData = std::make_shared<PasteData>();
90 pasteData->AddHtmlRecord(htmlText);
91 return pasteData;
92 }
93
CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)94 std::shared_ptr<PasteData> PasteboardClient::CreateWantData(std::shared_ptr<OHOS::AAFwk::Want> want)
95 {
96 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New want data");
97 auto pasteData = std::make_shared<PasteData>();
98 pasteData->AddWantRecord(std::move(want));
99 return pasteData;
100 }
101
CreatePlainTextData(const std::string & text)102 std::shared_ptr<PasteData> PasteboardClient::CreatePlainTextData(const std::string &text)
103 {
104 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New plain data");
105 auto pasteData = std::make_shared<PasteData>();
106 pasteData->AddTextRecord(text);
107 return pasteData;
108 }
109
CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)110 std::shared_ptr<PasteData> PasteboardClient::CreatePixelMapData(std::shared_ptr<PixelMap> pixelMap)
111 {
112 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New pixelMap data");
113 auto pasteData = std::make_shared<PasteData>();
114 pasteData->AddPixelMapRecord(std::move(pixelMap));
115 return pasteData;
116 }
117
CreateUriData(const OHOS::Uri & uri)118 std::shared_ptr<PasteData> PasteboardClient::CreateUriData(const OHOS::Uri &uri)
119 {
120 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New uri data");
121 auto pasteData = std::make_shared<PasteData>();
122 pasteData->AddUriRecord(uri);
123 return pasteData;
124 }
125
CreateKvData(const std::string & mimeType,const std::vector<uint8_t> & arrayBuffer)126 std::shared_ptr<PasteData> PasteboardClient::CreateKvData(
127 const std::string &mimeType, const std::vector<uint8_t> &arrayBuffer)
128 {
129 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "New Kv data");
130 auto pasteData = std::make_shared<PasteData>();
131 pasteData->AddKvRecord(mimeType, arrayBuffer);
132 return pasteData;
133 }
134
Clear()135 void PasteboardClient::Clear()
136 {
137 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
138 if (pasteboardServiceProxy_ == nullptr) {
139 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
140 ConnectService();
141 }
142
143 if (pasteboardServiceProxy_ == nullptr) {
144 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "GetPasteData quit.");
145 return;
146 }
147 pasteboardServiceProxy_->Clear();
148 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "end.");
149 return;
150 }
151
GetPasteData(PasteData & pasteData)152 int32_t PasteboardClient::GetPasteData(PasteData& pasteData)
153 {
154 StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
155 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
156 if (pasteboardServiceProxy_ == nullptr) {
157 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
158 ConnectService();
159 }
160
161 if (pasteboardServiceProxy_ == nullptr) {
162 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "GetPasteData quit.");
163 return static_cast<int32_t>(PasteboardError::E_SA_DIED);
164 }
165 int32_t ret = pasteboardServiceProxy_->GetPasteData(pasteData);
166 RetainUri(pasteData);
167 FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
168 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "end.");
169 return ret;
170 }
RetainUri(PasteData & pasteData)171 void PasteboardClient::RetainUri(PasteData &pasteData)
172 {
173 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start");
174 if (!pasteData.IsLocalPaste()) {
175 return;
176 }
177 // clear convert uri
178 for (size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
179 auto record = pasteData.GetRecordAt(0);
180 if (record != nullptr) {
181 record->SetConvertUri("");
182 }
183 }
184 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "end");
185 }
186
HasPasteData()187 bool PasteboardClient::HasPasteData()
188 {
189 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
190 if (pasteboardServiceProxy_ == nullptr) {
191 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
192 ConnectService();
193 }
194
195 if (pasteboardServiceProxy_ == nullptr) {
196 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "HasPasteData quit");
197 return false;
198 }
199 return pasteboardServiceProxy_->HasPasteData();
200 }
201
SetPasteData(PasteData & pasteData)202 int32_t PasteboardClient::SetPasteData(PasteData &pasteData)
203 {
204 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
205 if (pasteboardServiceProxy_ == nullptr) {
206 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
207 ConnectService();
208 }
209
210 if (pasteboardServiceProxy_ == nullptr) {
211 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "SetPasteData quit.");
212 return static_cast<int32_t>(PasteboardError::E_SA_DIED);
213 }
214 return pasteboardServiceProxy_->SetPasteData(pasteData);
215 }
216
AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)217 void PasteboardClient::AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)
218 {
219 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
220 if (callback == nullptr) {
221 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "input nullptr.");
222 return;
223 }
224 if (pasteboardServiceProxy_ == nullptr) {
225 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
226 ConnectService();
227 }
228
229 if (pasteboardServiceProxy_ == nullptr) {
230 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "AddPasteboardChangedObserver quit.");
231 return;
232 }
233
234 pasteboardServiceProxy_->AddPasteboardChangedObserver(callback);
235 return;
236 }
237
AddPasteboardEventObserver(sptr<PasteboardObserver> callback)238 void PasteboardClient::AddPasteboardEventObserver(sptr<PasteboardObserver> callback)
239 {
240 this->AddPasteboardChangedObserver(callback);
241 }
242
RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)243 void PasteboardClient::RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)
244 {
245 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
246 if (pasteboardServiceProxy_ == nullptr) {
247 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
248 ConnectService();
249 }
250
251 if (pasteboardServiceProxy_ == nullptr) {
252 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "quit.");
253 return;
254 }
255 if (callback == nullptr) {
256 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "remove all.");
257 pasteboardServiceProxy_->RemoveAllChangedObserver();
258 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "end.");
259 return;
260 }
261 pasteboardServiceProxy_->RemovePasteboardChangedObserver(callback);
262 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "end.");
263 return;
264 }
265
RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)266 void PasteboardClient::RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)
267 {
268 this->RemovePasteboardChangedObserver(callback);
269 }
270
ConnectService()271 void PasteboardClient::ConnectService()
272 {
273 std::lock_guard<std::mutex> lock(instanceLock_);
274 if (pasteboardServiceProxy_ != nullptr) {
275 return ;
276 }
277 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
278 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
279 if (sam == nullptr) {
280 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Getting SystemAbilityManager failed.");
281 pasteboardServiceProxy_ = nullptr;
282 return;
283 }
284 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(PASTEBOARD_SERVICE_ID);
285 if (remoteObject == nullptr) {
286 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "GetSystemAbility failed!");
287 return;
288 }
289
290 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
291 if (deathRecipient_ == nullptr) {
292 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Getting deathRecipient_ failed.");
293 return;
294 }
295 if ((remoteObject->IsProxyObject()) && (!remoteObject->AddDeathRecipient(deathRecipient_))) {
296 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Add death recipient to paste service failed.");
297 return;
298 }
299
300 pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
301 if (pasteboardServiceProxy_ == nullptr) {
302 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Get PasteboardServiceProxy from SA failed.");
303 return ;
304 }
305 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Getting PasteboardServiceProxy succeeded.");
306 }
307
OnRemoteSaDied(const wptr<IRemoteObject> & remote)308 void PasteboardClient::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
309 {
310 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
311 ConnectService();
312 }
313
PasteboardSaDeathRecipient()314 PasteboardSaDeathRecipient::PasteboardSaDeathRecipient()
315 {
316 }
317
OnRemoteDied(const wptr<IRemoteObject> & object)318 void PasteboardSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
319 {
320 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "PasteboardSaDeathRecipient on remote systemAbility died.");
321 PasteboardClient::GetInstance()->OnRemoteSaDied(object);
322 }
323 } // MiscServices
324 } // OHOS
325