1 /*
2 * Copyright (C) 2024 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 "convert_utils.h"
16 
17 #include "pasteboard_hilog.h"
18 #include "unified_meta.h"
19 namespace OHOS {
20 namespace MiscServices {
21 using UnifiedRecord = UDMF::UnifiedRecord;
22 using UnifiedData = UDMF::UnifiedData;
23 using UnifiedDataProperties = UDMF::UnifiedDataProperties;
24 using UDType = UDMF::UDType;
25 using ShareOptions = UDMF::ShareOptions;
26 
Convert(const UnifiedData & unifiedData)27 std::shared_ptr<PasteData> ConvertUtils::Convert(const UnifiedData& unifiedData)
28 {
29     auto pasteData = std::make_shared<PasteData>(Convert(unifiedData.GetRecords()));
30     pasteData->SetProperty(ConvertProperty(unifiedData.GetProperties(), unifiedData));
31     return pasteData;
32 }
33 
Convert(const PasteData & pasteData)34 std::shared_ptr<UnifiedData> ConvertUtils::Convert(const PasteData& pasteData)
35 {
36     auto unifiedData = std::make_shared<UnifiedData>();
37     unifiedData->SetRecords(Convert(pasteData.AllRecords()));
38     unifiedData->SetProperties(ConvertProperty(pasteData.GetProperty()));
39     unifiedData->SetDataId(pasteData.GetDataId());
40     return unifiedData;
41 }
42 
Convert(const std::vector<std::shared_ptr<PasteDataRecord>> & records)43 std::vector<std::shared_ptr<UnifiedRecord>> ConvertUtils::Convert(
44     const std::vector<std::shared_ptr<PasteDataRecord>>& records)
45 {
46     std::vector<std::shared_ptr<UnifiedRecord>> unifiedRecords;
47     for (auto const& record : records) {
48         unifiedRecords.emplace_back(Convert(record));
49     }
50     return unifiedRecords;
51 }
52 
Convert(const std::vector<std::shared_ptr<UnifiedRecord>> & records)53 std::vector<std::shared_ptr<PasteDataRecord>> ConvertUtils::Convert(
54     const std::vector<std::shared_ptr<UnifiedRecord>>& records)
55 {
56     std::vector<std::shared_ptr<PasteDataRecord>> pasteboardRecords;
57     for (auto const& record : records) {
58         pasteboardRecords.emplace_back(Convert(record));
59     }
60     return pasteboardRecords;
61 }
62 
Convert(std::shared_ptr<PasteDataRecord> record)63 std::shared_ptr<UnifiedRecord> ConvertUtils::Convert(std::shared_ptr<PasteDataRecord> record)
64 {
65     if (record == nullptr) {
66         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "paste record is nullptr");
67         return nullptr;
68     }
69     std::shared_ptr<UnifiedRecord> udmfRecord = std::make_shared<UnifiedRecord>();
70     auto entries = Convert(record->GetEntries(), record);
71     if (entries->empty()) {
72         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "entries is nullptr");
73         auto udmfValue = record->GetUDMFValue();
74         if (udmfValue) {
75             auto utdId = CommonUtils::Convert2UtdId(record->GetUDType(), record->GetMimeType());
76             udmfRecord->AddEntry(utdId, std::move(*udmfValue));
77         }
78         return udmfRecord;
79     }
80     for (auto &udmfEntry : *entries) {
81         udmfRecord->AddEntry(udmfEntry.first, std::move(udmfEntry.second));
82     }
83     udmfRecord->SetChannelName(CHANNEL_NAME);
84     udmfRecord->SetDataId(record->GetDataId());
85     udmfRecord->SetRecordId(record->GetRecordId());
86     return udmfRecord;
87 }
88 
Convert(std::shared_ptr<UnifiedRecord> record)89 std::shared_ptr<PasteDataRecord> ConvertUtils::Convert(std::shared_ptr<UnifiedRecord> record)
90 {
91     if (record == nullptr) {
92         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "udmfRecord is nullptr");
93         return nullptr;
94     }
95     std::shared_ptr<PasteDataRecord> pbRecord = std::make_shared<PasteDataRecord>();
96     auto utdId = record->GetUtdId();
97     pbRecord->AddEntry(utdId, std::make_shared<PasteDataEntry>(utdId, record->GetOriginValue()));
98     for (auto const& entry : Convert(record->GetEntries())) {
99         if (entry == nullptr) {
100             PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "entry is empty");
101             continue;
102         }
103         if (utdId == entry->GetUtdId()) {
104             continue;
105         }
106         pbRecord->AddEntry(entry->GetUtdId(), entry);
107     }
108     pbRecord->SetDataId(record->GetDataId());
109     pbRecord->SetRecordId(record->GetRecordId());
110     if (record->GetEntryGetter() != nullptr) {
111         pbRecord->SetDelayRecordFlag(true);
112     }
113     return pbRecord;
114 }
115 
Convert(const std::shared_ptr<std::map<std::string,UDMF::ValueType>> & entries)116 std::vector<std::shared_ptr<PasteDataEntry>> ConvertUtils::Convert(
117     const std::shared_ptr<std::map<std::string, UDMF::ValueType>>& entries)
118 {
119     std::vector<std::shared_ptr<PasteDataEntry>> pbEntries;
120     if (entries == nullptr) {
121         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "pbEntries is empty");
122         return pbEntries;
123     }
124     for (auto const& [utdId, value] : *entries) {
125         pbEntries.emplace_back(std::make_shared<PasteDataEntry>(utdId, value));
126     }
127     return pbEntries;
128 }
129 
Convert(const std::shared_ptr<PasteDataEntry> & entry,const std::shared_ptr<PasteDataRecord> & record)130 UDMF::ValueType ConvertUtils::Convert(const std::shared_ptr<PasteDataEntry>& entry,
131     const std::shared_ptr<PasteDataRecord> &record)
132 {
133     if (entry == nullptr) {
134         PASTEBOARD_HILOGE(PASTEBOARD_MODULE_CLIENT, "entry is null, convert failed.");
135         return nullptr;
136     }
137     auto utdId = entry->GetUtdId();
138     auto value = entry->GetValue();
139     if (std::holds_alternative<std::monostate>(value) || std::holds_alternative<std::shared_ptr<Object>>(value)) {
140         if (std::holds_alternative<std::shared_ptr<Object>>(value) && CommonUtils::IsFileUri(utdId) &&
141             record->GetUri() != nullptr) {
142             auto object = std::get<std::shared_ptr<Object>>(value);
143             object->value_[UDMF::FILE_URI_PARAM] = record->GetUri()->ToString();
144         }
145         return value;
146     }
147     auto mimeType = entry->GetMimeType();
148     auto object = std::make_shared<UDMF::Object>();
149     if (mimeType == MIMETYPE_TEXT_PLAIN) {
150         object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
151         if (std::holds_alternative<std::string>(value)) {
152             object->value_[UDMF::CONTENT] = std::get<std::string>(value);
153         }
154     } else if (mimeType == MIMETYPE_TEXT_HTML) {
155         object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
156         if (std::holds_alternative<std::string>(value)) {
157             object->value_[UDMF::HTML_CONTENT] = std::get<std::string>(value);
158         }
159     } else if (mimeType == MIMETYPE_TEXT_URI) {
160         object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
161         if (record->GetUri() != nullptr) {
162             object->value_[UDMF::FILE_URI_PARAM] = record->GetUri()->ToString();
163         } else if (std::holds_alternative<std::string>(value)) {
164             object->value_[UDMF::FILE_URI_PARAM] = std::get<std::string>(value);
165         }
166     } else if (mimeType == MIMETYPE_PIXELMAP) {
167         object->value_[UDMF::UNIFORM_DATA_TYPE] = utdId;
168         if (std::holds_alternative<std::shared_ptr<OHOS::Media::PixelMap>>(value)) {
169             object->value_[UDMF::PIXEL_MAP] = std::get<std::shared_ptr<OHOS::Media::PixelMap>>(value);
170         }
171     } else if (mimeType == MIMETYPE_TEXT_WANT) {
172         PASTEBOARD_HILOGW(PASTEBOARD_MODULE_CLIENT, "mimeType is want, udmf not support");
173     } else {
174         return value;
175     }
176     return object;
177 }
178 
Convert(const std::vector<std::shared_ptr<PasteDataEntry>> & entries,const std::shared_ptr<PasteDataRecord> & record)179 std::shared_ptr<std::vector<std::pair<std::string, UDMF::ValueType>>> ConvertUtils::Convert(
180     const std::vector<std::shared_ptr<PasteDataEntry>> &entries, const std::shared_ptr<PasteDataRecord> &record)
181 {
182     std::map<std::string, UDMF::ValueType> udmfEntryMap;
183     std::vector<std::pair<std::string, UDMF::ValueType>> udmfEntries;
184     std::vector<std::string> entryUtdIds;
185     for (auto const &entry : entries) {
186         if (entry == nullptr) {
187             continue;
188         }
189         if (udmfEntryMap.find(entry->GetUtdId()) == udmfEntryMap.end()) {
190             entryUtdIds.emplace_back(entry->GetUtdId());
191         }
192         udmfEntryMap.insert_or_assign(entry->GetUtdId(), Convert(entry, record));
193     }
194     for (auto const &utdId : entryUtdIds) {
195         auto item = udmfEntryMap.find(utdId);
196         if (item != udmfEntryMap.end()) {
197             udmfEntries.emplace_back(std::pair<std::string, UDMF::ValueType>(item->first, item->second));
198         }
199     }
200     return std::make_shared<std::vector<std::pair<std::string, UDMF::ValueType>>>(udmfEntries);
201 }
202 
UdmfOptions2PbOption(ShareOptions udmfOptions)203 ShareOption ConvertUtils::UdmfOptions2PbOption(ShareOptions udmfOptions)
204 {
205     ShareOption pbOption = CrossDevice;
206     switch (udmfOptions) {
207         case UDMF::IN_APP:
208             pbOption = InApp;
209             break;
210         case UDMF::CROSS_APP:
211             pbOption = LocalDevice;
212             break;
213         case UDMF::CROSS_DEVICE:
214             pbOption = CrossDevice;
215             break;
216         default:
217             break;
218     }
219     return pbOption;
220 }
221 
PbOption2UdmfOptions(ShareOption pbOption)222 ShareOptions ConvertUtils::PbOption2UdmfOptions(ShareOption pbOption)
223 {
224     ShareOptions udmfOptions = UDMF::CROSS_DEVICE;
225     switch (pbOption) {
226         case InApp:
227             udmfOptions = UDMF::IN_APP;
228             break;
229         case LocalDevice:
230             udmfOptions = UDMF::CROSS_APP;
231             break;
232         case CrossDevice:
233             udmfOptions = UDMF::CROSS_DEVICE;
234             break;
235         default:
236             break;
237     }
238     return udmfOptions;
239 }
240 
ConvertProperty(const std::shared_ptr<UnifiedDataProperties> & properties,const UnifiedData & unifiedData)241 PasteDataProperty ConvertUtils::ConvertProperty(const std::shared_ptr<UnifiedDataProperties>& properties,
242     const UnifiedData& unifiedData)
243 {
244     if (!properties) {
245         return {};
246     }
247     PasteDataProperty pasteDataProperty;
248     pasteDataProperty.shareOption = UdmfOptions2PbOption(properties->shareOptions);
249     pasteDataProperty.additions = properties->extras;
250     pasteDataProperty.timestamp = properties->timestamp;
251     pasteDataProperty.tag = properties->tag;
252     auto utdIds = unifiedData.GetTypesLabels();
253     pasteDataProperty.mimeTypes = Convert(utdIds);
254     pasteDataProperty.isRemote = properties->isRemote;
255     return PasteDataProperty(pasteDataProperty);
256 }
257 
ConvertProperty(const PasteDataProperty & properties)258 std::shared_ptr<UnifiedDataProperties> ConvertUtils::ConvertProperty(const PasteDataProperty& properties)
259 {
260     auto unifiedDataProperties = std::make_shared<UnifiedDataProperties>();
261     unifiedDataProperties->shareOptions = PbOption2UdmfOptions(properties.shareOption);
262     unifiedDataProperties->extras = properties.additions;
263     unifiedDataProperties->timestamp = properties.timestamp;
264     unifiedDataProperties->tag = properties.tag;
265     unifiedDataProperties->isRemote = properties.isRemote;
266     return unifiedDataProperties;
267 }
268 
Convert(const std::vector<std::string> & utdIds)269 std::vector<std::string> ConvertUtils::Convert(const std::vector<std::string>& utdIds)
270 {
271     std::vector<std::string> types;
272     for (const auto& utdId : utdIds) {
273         types.push_back(CommonUtils::Convert2MimeType(utdId));
274     }
275     return types;
276 }
277 } // namespace MiscServices
278 } // namespace OHOS