1 /*
2 * Copyright (C) 2023-2025 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 "pasteboard_web_controller.h"
17
18 #include <regex>
19
20 #include "file_uri.h"
21 #include "pasteboard_common.h"
22 #include "uri_permission_manager_client.h"
23 #include "pasteboard_hilog.h"
24
25 namespace {
26 constexpr const char *IMG_TAG_PATTERN = "<img.*?>";
27 constexpr const char *IMG_TAG_SRC_PATTERN = "src=(['\"])(.*?)\\1";
28 constexpr const char *IMG_TAG_SRC_HEAD = "src=\"";
29 constexpr const char *IMG_LOCAL_URI = "file:///";
30 constexpr const char *IMG_LOCAL_PATH = "://";
31 constexpr const char *FILE_SCHEME_PREFIX = "file://";
32
33 constexpr uint32_t FOUR_BYTES = 4;
34 constexpr uint32_t EIGHT_BIT = 8;
35 constexpr int32_t DOCS_LOCAL_PATH_SUBSTR_START_INDEX = 1;
36
37 struct Cmp {
operator ()__anon98d63e070111::Cmp38 bool operator()(const uint32_t &lhs, const uint32_t &rhs) const
39 {
40 return lhs > rhs;
41 }
42 };
43 } // namespace
44
45 namespace OHOS {
46 namespace MiscServices {
47
48 // static
GetInstance()49 PasteboardWebController &PasteboardWebController::GetInstance()
50 {
51 static PasteboardWebController instance;
52 return instance;
53 }
54
SplitWebviewPasteData(PasteData & pasteData)55 bool PasteboardWebController::SplitWebviewPasteData(PasteData &pasteData)
56 {
57 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "start");
58 auto hasExtraRecord = false;
59 for (const auto &record : pasteData.AllRecords()) {
60 if (record->GetRecordId() == record->GetFrom()) {
61 continue;
62 }
63 auto htmlEntry = record->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
64 if (htmlEntry == nullptr) {
65 continue;
66 }
67 std::shared_ptr<std::string> html = htmlEntry->ConvertToHtml();
68 if (html == nullptr || html->empty()) {
69 continue;
70 }
71 std::vector<std::shared_ptr<PasteDataRecord>> extraUriRecords = SplitHtml2Records(html, record->GetRecordId());
72 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "split html, recordId=%{public}u, uri count=%{public}zu",
73 record->GetRecordId(), extraUriRecords.size());
74 if (extraUriRecords.empty()) {
75 continue;
76 }
77 hasExtraRecord = true;
78 for (const auto &item : extraUriRecords) {
79 pasteData.AddRecord(item);
80 }
81 record->SetFrom(record->GetRecordId());
82 }
83 if (hasExtraRecord) {
84 pasteData.SetTag(PasteData::WEBVIEW_PASTEDATA_TAG);
85 }
86 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "end");
87 return hasExtraRecord;
88 }
89
SetWebviewPasteData(PasteData & pasteData,const std::pair<std::string,int32_t> & bundleIndex)90 void PasteboardWebController::SetWebviewPasteData(PasteData &pasteData,
91 const std::pair<std::string, int32_t> &bundleIndex)
92 {
93 if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG) {
94 return;
95 }
96 for (auto &item : pasteData.AllRecords()) {
97 if (item->GetUriV0() == nullptr || item->GetFrom() == 0 || item->GetRecordId() == item->GetFrom()) {
98 continue;
99 }
100 std::shared_ptr<Uri> uri = item->GetUriV0();
101 std::string puri = uri->ToString();
102 if (puri.substr(0, strlen(IMG_LOCAL_URI)) == PasteData::IMG_LOCAL_URI &&
103 puri.find(std::string(FILE_SCHEME_PREFIX) + PasteData::PATH_SHARE) == std::string::npos) {
104 std::string path = uri->GetPath();
105 std::string newUriStr = "";
106 if (path.substr(0, std::string(PasteData::DOCS_LOCAL_TAG).size()) == PasteData::DOCS_LOCAL_TAG) {
107 newUriStr = FILE_SCHEME_PREFIX;
108 newUriStr += path.substr(DOCS_LOCAL_PATH_SUBSTR_START_INDEX);
109 } else {
110 newUriStr = FILE_SCHEME_PREFIX;
111 std::string bundleIndexName;
112 PasteBoardCommon::GetDirByBundleNameAndAppIndex(bundleIndex.first,
113 bundleIndex.second, bundleIndexName);
114 newUriStr += bundleIndexName + path;
115 }
116 item->SetUri(std::make_shared<OHOS::Uri>(newUriStr));
117 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "uri: %{private}s -> %{private}s", puri.c_str(),
118 newUriStr.c_str());
119 }
120 }
121 }
122
CheckAppUriPermission(PasteData & pasteData)123 void PasteboardWebController::CheckAppUriPermission(PasteData &pasteData)
124 {
125 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "enter");
126 std::vector<std::string> uris;
127 std::vector<size_t> indexs;
128 std::vector<bool> checkResults;
129 for (size_t i = 0; i < pasteData.GetRecordCount(); i++) {
130 auto item = pasteData.GetRecordAt(i);
131 if (item == nullptr || item->GetOriginUri() == nullptr) {
132 continue;
133 }
134 auto uri = item->GetOriginUri()->ToString();
135 uris.emplace_back(uri);
136 indexs.emplace_back(i);
137 }
138 if (uris.empty()) {
139 return;
140 }
141 size_t offset = 0;
142 size_t length = uris.size();
143 size_t count = PasteData::URI_BATCH_SIZE;
144 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "loop for CheckUriAuthorization, uri count=%{public}zu", uris.size());
145 while (length > offset) {
146 if (length - offset < PasteData::URI_BATCH_SIZE) {
147 count = length - offset;
148 }
149 auto sendValues = std::vector<std::string>(uris.begin() + offset, uris.begin() + offset + count);
150 std::vector<bool> ret = AAFwk::UriPermissionManagerClient::GetInstance().CheckUriAuthorization(
151 sendValues, AAFwk::Want::FLAG_AUTH_READ_URI_PERMISSION, pasteData.GetTokenId());
152 checkResults.insert(checkResults.end(), ret.begin(), ret.end());
153 offset += count;
154 }
155 if (checkResults.size() != indexs.size()) {
156 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "check uri authorization fail");
157 return;
158 }
159 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "loop for SetGrantUriPermission");
160 for (size_t i = 0; i < indexs.size(); i++) {
161 auto item = pasteData.GetRecordAt(indexs[i]);
162 if (item == nullptr || item->GetOriginUri() == nullptr) {
163 continue;
164 }
165 item->SetGrantUriPermission(checkResults[i]);
166 }
167 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "leave");
168 }
169
RefreshUri(std::shared_ptr<PasteDataRecord> & record,const std::string & targetBundle,int32_t appIndex)170 void PasteboardWebController::RefreshUri(std::shared_ptr<PasteDataRecord> &record, const std::string &targetBundle,
171 int32_t appIndex)
172 {
173 std::string bundleIndex;
174 PasteBoardCommon::GetDirByBundleNameAndAppIndex(targetBundle, appIndex, bundleIndex);
175 PASTEBOARD_CHECK_AND_RETURN_LOGD(record->GetUriV0() != nullptr, PASTEBOARD_MODULE_COMMON,
176 "id=%{public}u, uri is null", record->GetRecordId());
177 PASTEBOARD_CHECK_AND_RETURN_LOGD(record->GetFrom() != 0 && record->GetFrom() != record->GetRecordId(),
178 PASTEBOARD_MODULE_COMMON, "id=%{public}u, from=%{public}u", record->GetRecordId(), record->GetFrom());
179
180 std::shared_ptr<Uri> uri = record->GetUriV0();
181 std::string puri = uri->ToString();
182 std::string realUri = puri;
183 if (puri.substr(0, strlen(FILE_SCHEME_PREFIX)) == FILE_SCHEME_PREFIX) {
184 AppFileService::ModuleFileUri::FileUri fileUri(puri);
185 std::string realPath = PasteBoardCommon::IsPasteboardService() ? fileUri.GetRealPathBySA(bundleIndex) :
186 fileUri.GetRealPath();
187 PASTEBOARD_CHECK_AND_RETURN_LOGE(!realPath.empty(), PASTEBOARD_MODULE_COMMON,
188 "file not exist, id=%{public}u, uri=%{public}s", record->GetRecordId(), puri.c_str());
189 realUri = FILE_SCHEME_PREFIX;
190 realUri += realPath;
191 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "uri: %{private}s -> %{private}s", puri.c_str(), realUri.c_str());
192 }
193 if (realUri.find(PasteData::DISTRIBUTEDFILES_TAG) != std::string::npos) {
194 record->SetConvertUri(realUri);
195 } else {
196 record->SetUri(std::make_shared<OHOS::Uri>(realUri));
197 }
198 }
199
RetainUri(PasteData & pasteData)200 void PasteboardWebController::RetainUri(PasteData &pasteData)
201 {
202 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "start");
203 if (!pasteData.IsLocalPaste()) {
204 return;
205 }
206 // clear convert uri
207 for (size_t i = 0; i < pasteData.GetRecordCount(); ++i) {
208 auto record = pasteData.GetRecordAt(i);
209 if (record != nullptr) {
210 record->SetConvertUri("");
211 }
212 }
213 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "end");
214 }
215
RebuildWebviewPasteData(PasteData & pasteData,const std::string & targetBundle,int32_t appIndex)216 void PasteboardWebController::RebuildWebviewPasteData(PasteData &pasteData, const std::string &targetBundle,
217 int32_t appIndex)
218 {
219 if (pasteData.GetTag() != PasteData::WEBVIEW_PASTEDATA_TAG) {
220 return;
221 }
222 PASTEBOARD_HILOGI(PASTEBOARD_MODULE_COMMON, "rebuild start, record count=%{public}zu", pasteData.GetRecordCount());
223 auto justSplitHtml = false;
224 for (auto &item : pasteData.AllRecords()) {
225 justSplitHtml = justSplitHtml || item->GetFrom() > 0;
226 RefreshUri(item, targetBundle, appIndex);
227 }
228 if (justSplitHtml) {
229 MergeExtraUris2Html(pasteData);
230 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Rebuild webview PasteData end, merged uris into html.");
231 return;
232 }
233 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Rebuild end, record count=%{public}zu", pasteData.GetRecordCount());
234 }
235
SplitHtml2Records(const std::shared_ptr<std::string> & html,uint32_t recordId)236 std::vector<std::shared_ptr<PasteDataRecord>> PasteboardWebController::SplitHtml2Records(
237 const std::shared_ptr<std::string> &html, uint32_t recordId) noexcept
238 {
239 std::vector<std::pair<std::string, uint32_t>> matchVec = SplitHtmlWithImgLabel(html);
240 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "matchVec size: %{public}zu", matchVec.size());
241 if (matchVec.empty()) {
242 return {};
243 }
244 std::map<std::string, std::vector<uint8_t>> imgSrcMap = SplitHtmlWithImgSrcLabel(matchVec);
245 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "imgSrcMap size: %{public}zu", imgSrcMap.size());
246 return BuildPasteDataRecords(imgSrcMap, recordId);
247 }
248
MergeExtraUris2Html(PasteData & data)249 void PasteboardWebController::MergeExtraUris2Html(PasteData &data)
250 {
251 auto recordGroups = GroupRecordWithFrom(data);
252 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "recordGroups size: %{public}zu", recordGroups.size());
253 for (auto &recordGroup : recordGroups) {
254 ReplaceHtmlRecordContentByExtraUris(recordGroup.second);
255 }
256 RemoveExtraUris(data);
257 }
258
RebuildHtml(std::shared_ptr<PasteData> pasteData)259 std::shared_ptr<std::string> PasteboardWebController::RebuildHtml(std::shared_ptr<PasteData> pasteData) noexcept
260 {
261 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(pasteData != nullptr, nullptr, PASTEBOARD_MODULE_COMMON, "pasteData is null");
262 std::vector<std::shared_ptr<PasteDataRecord>> pasteDataRecords = pasteData->AllRecords();
263 std::shared_ptr<std::string> htmlData;
264 std::map<uint32_t, std::pair<std::string, std::string>, Cmp> replaceUris;
265
266 for (const auto &item : pasteDataRecords) {
267 PASTEBOARD_CHECK_AND_RETURN_RET_LOGE(item != nullptr, nullptr,
268 PASTEBOARD_MODULE_COMMON, "item is null");
269 std::shared_ptr<std::string> html = item->GetHtmlTextV0();
270 if (html != nullptr) {
271 htmlData = html;
272 }
273 std::shared_ptr<OHOS::Uri> uri = item->GetUriV0();
274 std::shared_ptr<MiscServices::MineCustomData> customData = item->GetCustomData();
275 if (uri == nullptr || customData == nullptr) {
276 continue;
277 }
278 std::map<std::string, std::vector<uint8_t>> customItemData = customData->GetItemData();
279 for (const auto &itemData : customItemData) {
280 for (uint32_t i = 0; i < itemData.second.size(); i += FOUR_BYTES) {
281 uint32_t offset = static_cast<uint32_t>(itemData.second[i]) |
282 static_cast<uint32_t>(itemData.second[i + 1] << 8) |
283 static_cast<uint32_t>(itemData.second[i + 2] << 16) |
284 static_cast<uint32_t>(itemData.second[i + 3] << 24);
285 replaceUris[offset] = std::make_pair(uri->ToString(), itemData.first);
286 }
287 }
288 }
289
290 RemoveAllRecord(pasteData);
291 for (auto &replaceUri : replaceUris) {
292 htmlData->replace(replaceUri.first, replaceUri.second.second.size(), replaceUri.second.first);
293 }
294 pasteData->AddHtmlRecord(*htmlData);
295 return htmlData;
296 }
297
SplitHtmlWithImgLabel(const std::shared_ptr<std::string> html)298 std::vector<std::pair<std::string, uint32_t>> PasteboardWebController::SplitHtmlWithImgLabel(
299 const std::shared_ptr<std::string> html) noexcept
300 {
301 std::smatch results;
302 std::string pattern(IMG_TAG_PATTERN);
303 std::regex reg(pattern);
304 std::string::const_iterator iterStart = html->begin();
305 std::string::const_iterator iterEnd = html->end();
306 std::vector<std::pair<std::string, uint32_t>> matchVec;
307
308 while (std::regex_search(iterStart, iterEnd, results, reg)) {
309 std::string tmp = results[0];
310 iterStart = results[0].second;
311 uint32_t offset = static_cast<uint32_t>(results[0].first - html->begin());
312 matchVec.emplace_back(tmp, offset);
313 }
314 return matchVec;
315 }
316
SplitHtmlWithImgSrcLabel(const std::vector<std::pair<std::string,uint32_t>> & matchVec)317 std::map<std::string, std::vector<uint8_t>> PasteboardWebController::SplitHtmlWithImgSrcLabel(
318 const std::vector<std::pair<std::string, uint32_t>> &matchVec) noexcept
319 {
320 std::map<std::string, std::vector<uint8_t>> res;
321 std::smatch match;
322 std::regex re(IMG_TAG_SRC_PATTERN);
323 for (const auto &node : matchVec) {
324 std::string::const_iterator iterStart = node.first.begin();
325 std::string::const_iterator iterEnd = node.first.end();
326
327 while (std::regex_search(iterStart, iterEnd, match, re)) {
328 std::string tmp = match[0];
329 iterStart = match[0].second;
330 uint32_t offset = static_cast<uint32_t>(match[0].first - node.first.begin());
331 tmp = tmp.substr(strlen(IMG_TAG_SRC_HEAD));
332 tmp.pop_back();
333 if (!IsLocalURI(tmp)) {
334 continue;
335 }
336 offset += strlen(IMG_TAG_SRC_HEAD) + node.second;
337 for (uint32_t i = 0; i < FOUR_BYTES; i++) {
338 res[tmp].emplace_back((offset >> (EIGHT_BIT * i)) & 0xff);
339 }
340 }
341 }
342 return res;
343 }
344
BuildPasteDataRecords(const std::map<std::string,std::vector<uint8_t>> & imgSrcMap,uint32_t recordId)345 std::vector<std::shared_ptr<PasteDataRecord>> PasteboardWebController::BuildPasteDataRecords(
346 const std::map<std::string, std::vector<uint8_t>> &imgSrcMap, uint32_t recordId) noexcept
347 {
348 std::vector<std::shared_ptr<PasteDataRecord>> records;
349 for (const auto &item : imgSrcMap) {
350 PasteDataRecord::Builder builder(MiscServices::MIMETYPE_TEXT_URI);
351 auto uri = std::make_shared<OHOS::Uri>(item.first);
352 builder.SetUri(uri);
353 auto customData = std::make_shared<MiscServices::MineCustomData>();
354 customData->AddItemData(item.first, item.second);
355 builder.SetCustomData(customData);
356 auto record = builder.Build();
357 record->SetFrom(recordId);
358 records.push_back(record);
359 }
360 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Build extra records size: %{public}zu", records.size());
361 return records;
362 }
363
RemoveRecordById(PasteData & pasteData,uint32_t recordId)364 void PasteboardWebController::RemoveRecordById(PasteData &pasteData, uint32_t recordId) noexcept
365 {
366 for (uint32_t i = 0; i < pasteData.GetRecordCount(); i++) {
367 if (pasteData.GetRecordAt(i)->GetRecordId() == recordId) {
368 if (pasteData.RemoveRecordAt(i)) {
369 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON,
370 "WebClipboardController RemoveRecord success, i=%{public}u", i);
371 return;
372 }
373 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_COMMON,
374 "WebClipboardController RemoveRecord failed, i=%{public}u", i);
375 }
376 }
377 }
378
RemoveAllRecord(std::shared_ptr<PasteData> pasteData)379 void PasteboardWebController::RemoveAllRecord(std::shared_ptr<PasteData> pasteData) noexcept
380 {
381 PASTEBOARD_CHECK_AND_RETURN_LOGE(pasteData != nullptr, PASTEBOARD_MODULE_COMMON, "pasteData is null");
382 std::size_t recordCount = pasteData->GetRecordCount();
383 for (uint32_t i = 0; i < recordCount; i++) {
384 if (!pasteData->RemoveRecordAt(0)) {
385 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "WebClipboardController RemoveRecord failed, i=%{public}u", i);
386 }
387 }
388 }
389
IsLocalURI(std::string & uri)390 bool PasteboardWebController::IsLocalURI(std::string &uri) noexcept
391 {
392 return uri.substr(0, strlen(IMG_LOCAL_URI)) == std::string(IMG_LOCAL_URI) ||
393 uri.find(IMG_LOCAL_PATH) == std::string::npos;
394 }
395
UpdateHtmlRecord(std::shared_ptr<PasteDataRecord> & htmlRecord,std::shared_ptr<std::string> & htmlData)396 void PasteboardWebController::UpdateHtmlRecord(
397 std::shared_ptr<PasteDataRecord> &htmlRecord, std::shared_ptr<std::string> &htmlData)
398 {
399 if (htmlRecord == nullptr || htmlData == nullptr) {
400 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "htmlRecord or htmlData is nullptr");
401 return;
402 }
403 auto entry = htmlRecord->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
404 if (entry == nullptr) {
405 PASTEBOARD_HILOGE(PASTEBOARD_MODULE_COMMON, "entry is nullptr");
406 return;
407 }
408 auto entryValue = entry->GetValue();
409 if (std::holds_alternative<std::string>(entryValue)) {
410 entry->SetValue(*htmlData);
411 } else if (std::holds_alternative<std::shared_ptr<Object>>(entryValue)) {
412 auto object = std::get<std::shared_ptr<Object>>(entryValue);
413 auto newObject = std::make_shared<Object>();
414 newObject->value_ = object->value_;
415 newObject->value_[UDMF::HTML_CONTENT] = *htmlData;
416 entry->SetValue(newObject);
417 }
418 htmlRecord->AddEntryByMimeType(MIMETYPE_TEXT_HTML, entry);
419 htmlRecord->SetFrom(0);
420 }
421
ReplaceHtmlRecordContentByExtraUris(std::vector<std::shared_ptr<PasteDataRecord>> & records)422 void PasteboardWebController::ReplaceHtmlRecordContentByExtraUris(
423 std::vector<std::shared_ptr<PasteDataRecord>> &records)
424 {
425 std::shared_ptr<PasteDataRecord> htmlRecord = nullptr;
426 std::shared_ptr<std::string> htmlData;
427 std::map<uint32_t, std::pair<std::string, std::string>, Cmp> replaceUris;
428 for (const auto &item : records) {
429 auto htmlEntry = item->GetEntryByMimeType(MIMETYPE_TEXT_HTML);
430 if (htmlEntry != nullptr) {
431 auto html = htmlEntry->ConvertToHtml();
432 if (html != nullptr && !html->empty()) {
433 htmlData = html;
434 htmlRecord = item;
435 continue;
436 }
437 }
438 std::shared_ptr<OHOS::Uri> uri = item->GetUriV0();
439 std::shared_ptr<MiscServices::MineCustomData> customData = item->GetCustomData();
440 if (!uri || !customData) {
441 continue;
442 }
443 std::map<std::string, std::vector<uint8_t>> customItemData = customData->GetItemData();
444 for (auto &itemData : customItemData) {
445 for (uint32_t i = 0; i < itemData.second.size(); i += FOUR_BYTES) {
446 uint32_t offset = static_cast<uint32_t>(itemData.second[i]) |
447 static_cast<uint32_t>(itemData.second[i + 1] << 8) |
448 static_cast<uint32_t>(itemData.second[i + 2] << 16) |
449 static_cast<uint32_t>(itemData.second[i + 3] << 24);
450 replaceUris[offset] = std::make_pair(uri->ToString(), itemData.first);
451 }
452 }
453 }
454 if (htmlData == nullptr) {
455 PASTEBOARD_HILOGW(PASTEBOARD_MODULE_COMMON, "htmlData is nullptr");
456 return;
457 }
458
459 for (const auto &replaceUri : replaceUris) {
460 htmlData->replace(replaceUri.first, replaceUri.second.second.size(), replaceUri.second.first);
461 }
462 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "replace uri count: %{public}zu", replaceUris.size());
463 if (htmlRecord != nullptr) {
464 UpdateHtmlRecord(htmlRecord, htmlData);
465 }
466 }
467
GroupRecordWithFrom(PasteData & data)468 std::map<std::uint32_t, std::vector<std::shared_ptr<PasteDataRecord>>> PasteboardWebController::GroupRecordWithFrom(
469 PasteData &data)
470 {
471 std::map<std::uint32_t, std::vector<std::shared_ptr<PasteDataRecord>>> groupMap;
472 for (const auto &record : data.AllRecords()) {
473 if (record->GetFrom() == 0) {
474 continue;
475 }
476 auto item = groupMap.find(record->GetFrom());
477 auto value = item != groupMap.end() ? item->second : std::vector<std::shared_ptr<PasteDataRecord>>();
478 value.emplace_back(record);
479 groupMap.insert_or_assign(record->GetFrom(), value);
480 }
481 return groupMap;
482 }
483
RemoveExtraUris(PasteData & data)484 void PasteboardWebController::RemoveExtraUris(PasteData &data)
485 {
486 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "Before remove record count: %{public}zu", data.AllRecords().size());
487 for (const auto &record : data.AllRecords()) {
488 if (record->GetFrom() > 0 && record->GetMimeType() == MIMETYPE_TEXT_URI) {
489 RemoveRecordById(data, record->GetRecordId());
490 }
491 }
492 PASTEBOARD_HILOGD(PASTEBOARD_MODULE_COMMON, "After remove record count: %{public}zu", data.AllRecords().size());
493 }
494 } // namespace MiscServices
495 } // namespace OHOS
496