• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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