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, "Clear start.");
138 if (!IsServiceAvailable()) {
139 return;
140 }
141 pasteboardServiceProxy_->Clear();
142 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "end.");
143 return;
144 }
145
GetPasteData(PasteData & pasteData)146 int32_t PasteboardClient::GetPasteData(PasteData& pasteData)
147 {
148 StartAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
149 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "GetPasteData start.");
150 if (!IsServiceAvailable()) {
151 return static_cast<int32_t>(PasteboardError::E_SA_DIED);
152 }
153 int32_t ret = pasteboardServiceProxy_->GetPasteData(pasteData);
154 RetainUri(pasteData);
155 FinishAsyncTrace(HITRACE_TAG_MISC, "PasteboardClient::GetPasteData", HITRACE_GETPASTEDATA);
156 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "end.");
157 return ret;
158 }
RetainUri(PasteData & pasteData)159 void PasteboardClient::RetainUri(PasteData &pasteData)
160 {
161 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start");
162 if (!pasteData.IsLocalPaste()) {
163 return;
164 }
165 // clear convert uri
166 for (size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
167 auto record = pasteData.GetRecordAt(0);
168 if (record != nullptr) {
169 record->SetConvertUri("");
170 }
171 }
172 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "end");
173 }
174
HasPasteData()175 bool PasteboardClient::HasPasteData()
176 {
177 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "HasPasteData start.");
178 if (!IsServiceAvailable()) {
179 return false;
180 }
181 return pasteboardServiceProxy_->HasPasteData();
182 }
183
SetPasteData(PasteData & pasteData)184 int32_t PasteboardClient::SetPasteData(PasteData &pasteData)
185 {
186 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "SetPasteData start.");
187 if (!IsServiceAvailable()) {
188 return static_cast<int32_t>(PasteboardError::E_SA_DIED);
189 }
190 return pasteboardServiceProxy_->SetPasteData(pasteData);
191 }
192
AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)193 void PasteboardClient::AddPasteboardChangedObserver(sptr<PasteboardObserver> callback)
194 {
195 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
196 if (callback == nullptr) {
197 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "input nullptr.");
198 return;
199 }
200 if (!IsServiceAvailable()) {
201 return;
202 }
203 pasteboardServiceProxy_->AddPasteboardChangedObserver(callback);
204 return;
205 }
206
AddPasteboardEventObserver(sptr<PasteboardObserver> callback)207 void PasteboardClient::AddPasteboardEventObserver(sptr<PasteboardObserver> callback)
208 {
209 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
210 if (callback == nullptr) {
211 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "input nullptr.");
212 return;
213 }
214 if (!IsServiceAvailable()) {
215 return;
216 }
217 pasteboardServiceProxy_->AddPasteboardEventObserver(callback);
218 }
219
RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)220 void PasteboardClient::RemovePasteboardChangedObserver(sptr<PasteboardObserver> callback)
221 {
222 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
223 if (!IsServiceAvailable()) {
224 return;
225 }
226 if (callback == nullptr) {
227 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "remove all.");
228 pasteboardServiceProxy_->RemoveAllChangedObserver();
229 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
230 return;
231 }
232 pasteboardServiceProxy_->RemovePasteboardChangedObserver(callback);
233 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
234 return;
235 }
236
RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)237 void PasteboardClient::RemovePasteboardEventObserver(sptr<PasteboardObserver> callback)
238 {
239 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "start.");
240 if (!IsServiceAvailable()) {
241 return;
242 }
243 if (callback == nullptr) {
244 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "remove all.");
245 pasteboardServiceProxy_->RemoveAllEventObserver();
246 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
247 return;
248 }
249 pasteboardServiceProxy_->RemovePasteboardEventObserver(callback);
250 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "end.");
251 }
252
IsServiceAvailable()253 inline bool PasteboardClient::IsServiceAvailable() {
254 if (pasteboardServiceProxy_ == nullptr) {
255 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "Redo ConnectService");
256 ConnectService();
257 }
258
259 if (pasteboardServiceProxy_ == nullptr) {
260 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Service proxy null.");
261 return false;
262 }
263 return true;
264 }
265
ConnectService()266 void PasteboardClient::ConnectService()
267 {
268 std::lock_guard<std::mutex> lock(instanceLock_);
269 if (pasteboardServiceProxy_ != nullptr) {
270 return ;
271 }
272 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
273 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
274 if (sam == nullptr) {
275 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Getting SystemAbilityManager failed.");
276 pasteboardServiceProxy_ = nullptr;
277 return;
278 }
279 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(PASTEBOARD_SERVICE_ID);
280 if (remoteObject == nullptr) {
281 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "GetSystemAbility failed!");
282 return;
283 }
284
285 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new PasteboardSaDeathRecipient());
286 if (deathRecipient_ == nullptr) {
287 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Getting deathRecipient_ failed.");
288 return;
289 }
290 if ((remoteObject->IsProxyObject()) && (!remoteObject->AddDeathRecipient(deathRecipient_))) {
291 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Add death recipient to paste service failed.");
292 return;
293 }
294
295 pasteboardServiceProxy_ = iface_cast<IPasteboardService>(remoteObject);
296 if (pasteboardServiceProxy_ == nullptr) {
297 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "Get PasteboardServiceProxy from SA failed.");
298 return ;
299 }
300 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_CLIENT, "Getting PasteboardServiceProxy succeeded.");
301 }
302
OnRemoteSaDied(const wptr<IRemoteObject> & remote)303 void PasteboardClient::OnRemoteSaDied(const wptr<IRemoteObject> &remote)
304 {
305 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_CLIENT, "start.");
306 ConnectService();
307 }
308
PasteboardSaDeathRecipient()309 PasteboardSaDeathRecipient::PasteboardSaDeathRecipient()
310 {
311 }
312
OnRemoteDied(const wptr<IRemoteObject> & object)313 void PasteboardSaDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
314 {
315 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "PasteboardSaDeathRecipient on remote systemAbility died.");
316 PasteboardClient::GetInstance()->OnRemoteSaDied(object);
317 }
318 } // MiscServices
319 } // OHOS
320