1 /*
2 * Copyright (C) 2022 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 #define MLOG_TAG "MtpDataUtils"
16 #include <map>
17 #include <filesystem>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include "medialibrary_errno.h"
21 #include "medialibrary_db_const.h"
22 #include "media_file_utils.h"
23 #include "media_log.h"
24 #include "media_mtp_utils.h"
25 #include "mtp_data_utils.h"
26 #include "mtp_constants.h"
27 #include "mtp_packet_tools.h"
28 #include "payload_data/get_object_props_supported_data.h"
29 #include "payload_data.h"
30 #include "rdb_errno.h"
31 #include "playback_formats.h"
32 #include "moving_photo_file_utils.h"
33
34 using namespace std;
35 namespace OHOS {
36 namespace Media {
37 struct NormalProperty {
38 int32_t intValue;
39 string strValue;
40 };
41 static constexpr int32_t INTTYPE16 = 16;
42 static constexpr int32_t INTTYPE128 = 128;
43 static constexpr int32_t STRINGTYPE = -1;
44 static const string MEDIA_DATA_DB_FORMAT = "format";
45 static const string MEDIA_DATA_DB_COMPOSER = "composer";
46 static constexpr int32_t EDITED_PHOTO_TYPE = 2;
47 static constexpr int32_t MOVING_PHOTO_TYPE = 3;
48 static constexpr int32_t EDITED_MOVING_TYPE = 4;
49 static constexpr int64_t MILLI_TO_SECOND = 1000;
50 static const string PARENT = "parent";
51 constexpr int32_t PARENT_ROOT_ID = 0;
52
53 static const map<uint16_t, string> FormatMap = {
54 { 0, MTP_FORMAT_ALL},
55 { MTP_FORMAT_UNDEFINED_CODE, MTP_FORMAT_UNDEFINED },
56 { MTP_FORMAT_ASSOCIATION_CODE, MTP_FORMAT_ASSOCIATION },
57 { MTP_FORMAT_SCRIPT_CODE, MTP_FORMAT_SCRIPT },
58 { MTP_FORMAT_EXECUTABLE_CODE, MTP_FORMAT_EXECUTABLE },
59 { MTP_FORMAT_TEXT_CODE, MTP_FORMAT_TEXT },
60 { MTP_FORMAT_DPOF_CODE, MTP_FORMAT_DPOF },
61 { MTP_FORMAT_AIFF_CODE, MTP_FORMAT_AIFF },
62 { MTP_FORMAT_WAV_CODE, MTP_FORMAT_WAV },
63 { MTP_FORMAT_HTML_CODE, MTP_FORMAT_HTML },
64 { MTP_FORMAT_MP3_CODE, MTP_FORMAT_MP3 },
65 { MTP_FORMAT_AVI_CODE, MTP_FORMAT_AVI },
66 { MTP_FORMAT_MPEG_CODE, MTP_FORMAT_MPEG },
67 // image files...
68 { MTP_FORMAT_DEFINED_CODE, MTP_FORMAT_DEFINED },
69 { MTP_FORMAT_EXIF_JPEG_CODE, MTP_FORMAT_EXIF_JPEG },
70 { MTP_FORMAT_FLASHPIX_CODE, MTP_FORMAT_FLASHPIX },
71 { MTP_FORMAT_BMP_CODE, MTP_FORMAT_BMP },
72 { MTP_FORMAT_CIFF_CODE, MTP_FORMAT_CIFF },
73 { MTP_FORMAT_GIF_CODE, MTP_FORMAT_GIF },
74 { MTP_FORMAT_JFIF_CODE, MTP_FORMAT_JFIF },
75 { MTP_FORMAT_CD_CODE, MTP_FORMAT_CD },
76 { MTP_FORMAT_PICT_CODE, MTP_FORMAT_PICT },
77 { MTP_FORMAT_PNG_CODE, MTP_FORMAT_PNG },
78 { MTP_FORMAT_TIFF_CODE, MTP_FORMAT_TIFF },
79 { MTP_FORMAT_JP2_CODE, MTP_FORMAT_JP2 },
80 { MTP_FORMAT_JPX_CODE, MTP_FORMAT_JPX },
81 // firmware files
82 { MTP_FORMAT_UNDEFINED_FIRMWARE_CODE, MTP_FORMAT_UNDEFINED_FIRMWARE },
83 // Windows image files
84 { MTP_FORMAT_WINDOWS_IMAGE_FORMAT_CODE, MTP_FORMAT_WINDOWS_IMAGE_FORMAT },
85 // audio files
86 { MTP_FORMAT_UNDEFINED_AUDIO_CODE, MTP_FORMAT_UNDEFINED_AUDIO },
87 { MTP_FORMAT_WMA_CODE, MTP_FORMAT_WMA },
88 { MTP_FORMAT_OGG_CODE, MTP_FORMAT_OGG },
89 { MTP_FORMAT_AAC_CODE, MTP_FORMAT_AAC },
90 { MTP_FORMAT_AUDIBLE_CODE, MTP_FORMAT_AUDIBLE },
91 { MTP_FORMAT_FLAC_CODE, MTP_FORMAT_FLAC },
92 // video files
93 { MTP_FORMAT_UNDEFINED_VIDEO_CODE, MTP_FORMAT_UNDEFINED_VIDEO },
94 { MTP_FORMAT_WMV_CODE, MTP_FORMAT_WMV },
95 { MTP_FORMAT_MP4_CONTAINER_CODE, MTP_FORMAT_MP4_CONTAINER },
96 { MTP_FORMAT_MP2_CODE, MTP_FORMAT_MP2 },
97 { MTP_FORMAT_3GP_CONTAINER_CODE, MTP_FORMAT_3GP_CONTAINER },
98 // unknown
99 { MTP_FORMAT_UNDEFINED_COLLECTION_CODE, MTP_FORMAT_UNDEFINED_COLLECTION },
100 { MTP_FORMAT_ABSTRACT_MULTIMEDIA_ALBUM_CODE, MTP_FORMAT_ABSTRACT_MULTIMEDIA_ALBUM },
101 { MTP_FORMAT_ABSTRACT_IMAGE_ALBUM_CODE, MTP_FORMAT_ABSTRACT_IMAGE_ALBUM },
102 { MTP_FORMAT_ABSTRACT_AUDIO_ALBUM_CODE, MTP_FORMAT_ABSTRACT_AUDIO_ALBUM },
103 { MTP_FORMAT_ABSTRACT_VIDEO_ALBUM_CODE, MTP_FORMAT_ABSTRACT_VIDEO_ALBUM },
104 { MTP_FORMAT_ABSTRACT_AUDIO_VIDEO_PLAYLIST_CODE, MTP_FORMAT_ABSTRACT_AUDIO_VIDEO_PLAYLIST },
105 { MTP_FORMAT_ABSTRACT_CONTACT_GROUP_CODE, MTP_FORMAT_ABSTRACT_CONTACT_GROUP },
106 { MTP_FORMAT_ABSTRACT_MESSAGE_FOLDER_CODE, MTP_FORMAT_ABSTRACT_MESSAGE_FOLDER },
107 { MTP_FORMAT_ABSTRACT_CHAPTERED_PRODUCTION_CODE, MTP_FORMAT_ABSTRACT_CHAPTERED_PRODUCTION },
108 { MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST_CODE, MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST },
109 { MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST_CODE, MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST },
110 { MTP_FORMAT_ABSTRACT_MEDIACAST_CODE, MTP_FORMAT_ABSTRACT_MEDIACAST },
111 { MTP_FORMAT_WPL_PLAYLIST_CODE, MTP_FORMAT_WPL_PLAYLIST },
112 { MTP_FORMAT_M3U_PLAYLIST_CODE, MTP_FORMAT_M3U_PLAYLIST },
113 { MTP_FORMAT_MPL_PLAYLIST_CODE, MTP_FORMAT_MPL_PLAYLIST },
114 { MTP_FORMAT_ASX_PLAYLIST_CODE, MTP_FORMAT_ASX_PLAYLIST },
115 { MTP_FORMAT_PLS_PLAYLIST_CODE, MTP_FORMAT_PLS_PLAYLIST },
116 { MTP_FORMAT_UNDEFINED_DOCUMENT_CODE, MTP_FORMAT_UNDEFINED_DOCUMENT },
117 { MTP_FORMAT_XML_DOCUMENT_CODE, MTP_FORMAT_XML_DOCUMENT },
118 { MTP_FORMAT_ABSTRACT_DOCUMENT_CODE, MTP_FORMAT_ABSTRACT_DOCUMENT },
119 { MTP_FORMAT_MICROSOFT_WORD_DOCUMENT_CODE, MTP_FORMAT_MICROSOFT_WORD_DOCUMENT },
120 { MTP_FORMAT_MHT_COMPILED_HTML_DOCUMENT_CODE, MTP_FORMAT_MHT_COMPILED_HTML_DOCUMENT },
121 { MTP_FORMAT_MICROSOFT_EXCEL_SPREADSHEET_CODE, MTP_FORMAT_MICROSOFT_EXCEL_SPREADSHEET },
122 { MTP_FORMAT_UNDEFINED_MESSAGE_CODE, MTP_FORMAT_UNDEFINED_MESSAGE },
123 { MTP_FORMAT_ABSTRACT_MESSAGE_CODE, MTP_FORMAT_ABSTRACT_MESSAGE },
124 { MTP_FORMAT_UNDEFINED_CONTACT_CODE, MTP_FORMAT_UNDEFINED_CONTACT },
125 { MTP_FORMAT_ABSTRACT_CONTACT_CODE, MTP_FORMAT_ABSTRACT_CONTACT },
126 { MTP_FORMAT_MICROSOFT_POWERPOINT_PRESENTATION_CODE, MTP_FORMAT_MICROSOFT_POWERPOINT_PRESENTATION },
127 { MTP_FORMAT_VCARD_2_CODE, MTP_FORMAT_VCARD_2 }
128 };
129
130 static const set<std::string> UndefinedImageFormatSet = {
131 MTP_FORMAT_HEIC,
132 MTP_FORMAT_HEICS,
133 MTP_FORMAT_HEIFS,
134 MTP_FORMAT_BM,
135 MTP_FORMAT_HEIF,
136 MTP_FORMAT_HIF,
137 MTP_FORMAT_AVIF,
138 MTP_FORMAT_CUR,
139 MTP_FORMAT_WEBP,
140 MTP_FORMAT_DNG,
141 MTP_FORMAT_RAF,
142 MTP_FORMAT_ICO,
143 MTP_FORMAT_NRW,
144 MTP_FORMAT_RW2,
145 MTP_FORMAT_PEF,
146 MTP_FORMAT_SRW,
147 MTP_FORMAT_ARW,
148 MTP_FORMAT_SVG,
149 MTP_FORMAT_RAW,
150 MTP_FORMAT_IEF,
151 MTP_FORMAT_JP2,
152 MTP_FORMAT_JPG2,
153 MTP_FORMAT_JPM,
154 MTP_FORMAT_JPX,
155 MTP_FORMAT_JPF,
156 MTP_FORMAT_PCX,
157 MTP_FORMAT_SVGZ,
158 MTP_FORMAT_TIFF_EP,
159 MTP_FORMAT_TIFF,
160 MTP_FORMAT_DJVU,
161 MTP_FORMAT_DJV,
162 MTP_FORMAT_ICO,
163 MTP_FORMAT_WBMP,
164 MTP_FORMAT_CR2,
165 MTP_FORMAT_CRW,
166 MTP_FORMAT_RAS,
167 MTP_FORMAT_CDR,
168 MTP_FORMAT_PAT,
169 MTP_FORMAT_CDT,
170 MTP_FORMAT_CPT,
171 MTP_FORMAT_ERF,
172 MTP_FORMAT_ART,
173 MTP_FORMAT_JNG,
174 MTP_FORMAT_NEF,
175 MTP_FORMAT_ORF,
176 MTP_FORMAT_PSD,
177 MTP_FORMAT_PNM,
178 MTP_FORMAT_PBM,
179 MTP_FORMAT_PGM,
180 MTP_FORMAT_PPM,
181 MTP_FORMAT_RGB,
182 MTP_FORMAT_XBM,
183 MTP_FORMAT_XPM,
184 MTP_FORMAT_XWD
185 };
186
187 static const set<std::string> UndefinedVideoFormatSet = {
188 MTP_FORMAT_3GPP2,
189 MTP_FORMAT_3GP2,
190 MTP_FORMAT_3G2,
191 MTP_FORMAT_3GPP,
192 MTP_FORMAT_M4V,
193 MTP_FORMAT_F4V,
194 MTP_FORMAT_MP4V,
195 MTP_FORMAT_MPEG4,
196 MTP_FORMAT_M2TS,
197 MTP_FORMAT_MTS,
198 MTP_FORMAT_TS,
199 MTP_FORMAT_YT,
200 MTP_FORMAT_WRF,
201 MTP_FORMAT_MPEG2,
202 MTP_FORMAT_MPV2,
203 MTP_FORMAT_MP2V,
204 MTP_FORMAT_M2V,
205 MTP_FORMAT_M2T,
206 MTP_FORMAT_MPEG1,
207 MTP_FORMAT_MPV1,
208 MTP_FORMAT_MP1V,
209 MTP_FORMAT_M1V,
210 MTP_FORMAT_MPG,
211 MTP_FORMAT_MOV,
212 MTP_FORMAT_MKV,
213 MTP_FORMAT_WEBM,
214 MTP_FORMAT_MPEG,
215 MTP_FORMAT_MPE,
216 MTP_FORMAT_AVI,
217 MTP_FORMAT_H264,
218 MTP_FORMAT_RMVB,
219 MTP_FORMAT_AXV,
220 MTP_FORMAT_DL,
221 MTP_FORMAT_DIF,
222 MTP_FORMAT_DV,
223 MTP_FORMAT_DLI,
224 MTP_FORMAT_GL,
225 MTP_FORMAT_QT,
226 MTP_FORMAT_OGV,
227 MTP_FORMAT_MXU,
228 MTP_FORMAT_FLV,
229 MTP_FORMAT_LSF,
230 MTP_FORMAT_LSX,
231 MTP_FORMAT_MNG,
232 MTP_FORMAT_WM,
233 MTP_FORMAT_WMX,
234 MTP_FORMAT_MOVIE,
235 MTP_FORMAT_MPV,
236 MTP_FORMAT_ASF,
237 MTP_FORMAT_ASX_PLAYLIST,
238 MTP_FORMAT_WVX,
239 MTP_FORMAT_FMP4
240 };
241
242 static const map<std::string, MediaType> FormatAllMap = {
243 { MTP_FORMAT_ALL, MEDIA_TYPE_ALL },
244 { MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST, MEDIA_TYPE_AUDIO },
245 { MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST, MEDIA_TYPE_VIDEO },
246 { MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST, MEDIA_TYPE_VIDEO },
247 { MTP_FORMAT_ASSOCIATION, MEDIA_TYPE_ALBUM }
248 };
249
250 static const map<uint16_t, MediaType> FormatMediaTypeMap = {
251 { 0, MEDIA_TYPE_ALL },
252 { MTP_FORMAT_UNDEFINED_CODE, MEDIA_TYPE_FILE },
253 { MTP_FORMAT_DEFINED_CODE, MEDIA_TYPE_IMAGE },
254 { MTP_FORMAT_EXIF_JPEG_CODE, MEDIA_TYPE_IMAGE },
255 { MTP_FORMAT_FLASHPIX_CODE, MEDIA_TYPE_IMAGE },
256 { MTP_FORMAT_BMP_CODE, MEDIA_TYPE_IMAGE },
257 { MTP_FORMAT_CIFF_CODE, MEDIA_TYPE_IMAGE },
258 { MTP_FORMAT_GIF_CODE, MEDIA_TYPE_IMAGE },
259 { MTP_FORMAT_JFIF_CODE, MEDIA_TYPE_IMAGE },
260 { MTP_FORMAT_CD_CODE, MEDIA_TYPE_IMAGE },
261 { MTP_FORMAT_PICT_CODE, MEDIA_TYPE_IMAGE },
262 { MTP_FORMAT_PNG_CODE, MEDIA_TYPE_IMAGE },
263 { MTP_FORMAT_TIFF_CODE, MEDIA_TYPE_IMAGE },
264 { MTP_FORMAT_JP2_CODE, MEDIA_TYPE_IMAGE },
265 { MTP_FORMAT_JPX_CODE, MEDIA_TYPE_IMAGE },
266 { MTP_FORMAT_UNDEFINED_AUDIO_CODE, MEDIA_TYPE_AUDIO },
267 { MTP_FORMAT_WMA_CODE, MEDIA_TYPE_AUDIO },
268 { MTP_FORMAT_OGG_CODE, MEDIA_TYPE_AUDIO },
269 { MTP_FORMAT_AAC_CODE, MEDIA_TYPE_AUDIO },
270 { MTP_FORMAT_AUDIBLE_CODE, MEDIA_TYPE_AUDIO },
271 { MTP_FORMAT_FLAC_CODE, MEDIA_TYPE_AUDIO },
272 { MTP_FORMAT_UNDEFINED_VIDEO_CODE, MEDIA_TYPE_VIDEO },
273 { MTP_FORMAT_WMV_CODE, MEDIA_TYPE_VIDEO },
274 { MTP_FORMAT_MP4_CONTAINER_CODE, MEDIA_TYPE_VIDEO },
275 { MTP_FORMAT_MP3_CODE, MEDIA_TYPE_AUDIO },
276 { MTP_FORMAT_MP2_CODE, MEDIA_TYPE_VIDEO },
277 { MTP_FORMAT_3GP_CONTAINER_CODE, MEDIA_TYPE_VIDEO },
278 { MTP_FORMAT_ASSOCIATION_CODE, MEDIA_TYPE_ALBUM}
279 };
280
281 static const map<uint32_t, std::string> ObjMediaPropMap = {
282 { MTP_PROPERTY_OBJECT_FILE_NAME_CODE, MEDIA_DATA_DB_NAME },
283 { MTP_PROPERTY_PARENT_OBJECT_CODE, MEDIA_DATA_DB_PARENT_ID }
284 };
285
286 static const map<uint16_t, int> ObjMediaPropTypeMap = {
287 { MTP_PROPERTY_OBJECT_FILE_NAME_CODE, MTP_TYPE_STRING_CODE },
288 { MTP_PROPERTY_PARENT_OBJECT_CODE, MTP_TYPE_UINT32_CODE }
289 };
290
291 static const map<std::string, uint16_t> ColumnToPropTypeMap = {
292 { MEDIA_DATA_DB_SIZE, MTP_PROPERTY_OBJECT_SIZE_CODE },
293 { MEDIA_DATA_DB_NAME, MTP_PROPERTY_OBJECT_FILE_NAME_CODE },
294 { MEDIA_DATA_DB_DATE_MODIFIED, MTP_PROPERTY_DATE_MODIFIED_CODE },
295 { MEDIA_DATA_DB_PARENT_ID, MTP_PROPERTY_PARENT_OBJECT_CODE },
296 { MEDIA_DATA_DB_NAME, MTP_PROPERTY_NAME_CODE },
297 { MEDIA_DATA_DB_NAME, MTP_PROPERTY_DISPLAY_NAME_CODE },
298 { MEDIA_DATA_DB_DATE_ADDED, MTP_PROPERTY_DATE_ADDED_CODE },
299 { MEDIA_DATA_DB_ARTIST, MTP_PROPERTY_ARTIST_CODE },
300 { MEDIA_DATA_DB_DURATION, MTP_PROPERTY_DURATION_CODE },
301 { MEDIA_DATA_DB_DESCRIPTION, MTP_PROPERTY_DESCRIPTION_CODE },
302 };
303
304 static const map<std::string, ResultSetDataType> ColumnTypeMap = {
305 { MEDIA_DATA_DB_ID, TYPE_INT32 },
306 { MEDIA_DATA_DB_SIZE, TYPE_INT64 },
307 { MEDIA_DATA_DB_PARENT_ID, TYPE_INT32 },
308 { MEDIA_DATA_DB_DATE_MODIFIED, TYPE_INT64 },
309 { MEDIA_DATA_DB_DATE_ADDED, TYPE_INT64 },
310 { MEDIA_DATA_DB_NAME, TYPE_STRING },
311 { MEDIA_DATA_DB_DESCRIPTION, TYPE_STRING },
312 { MEDIA_DATA_DB_DURATION, TYPE_INT32 },
313 { MEDIA_DATA_DB_ARTIST, TYPE_STRING },
314 { MEDIA_DATA_DB_AUDIO_ALBUM, TYPE_STRING },
315 { MEDIA_DATA_DB_FORMAT, TYPE_INT32 },
316 { MEDIA_DATA_DB_ALBUM_NAME, TYPE_STRING },
317 { MEDIA_DATA_DB_COMPOSER, TYPE_STRING },
318 };
319
320 static const map<uint16_t, std::string> PropColumnMap = {
321 { MTP_PROPERTY_OBJECT_FORMAT_CODE, MEDIA_DATA_DB_FORMAT },
322 { MTP_PROPERTY_OBJECT_SIZE_CODE, MEDIA_DATA_DB_SIZE },
323 { MTP_PROPERTY_OBJECT_FILE_NAME_CODE, MEDIA_DATA_DB_NAME },
324 { MTP_PROPERTY_DATE_MODIFIED_CODE, MEDIA_DATA_DB_DATE_MODIFIED },
325 { MTP_PROPERTY_PARENT_OBJECT_CODE, MEDIA_DATA_DB_PARENT_ID },
326 { MTP_PROPERTY_NAME_CODE, MEDIA_DATA_DB_NAME },
327 { MTP_PROPERTY_DISPLAY_NAME_CODE, MEDIA_DATA_DB_NAME },
328 { MTP_PROPERTY_DATE_ADDED_CODE, MEDIA_DATA_DB_DATE_ADDED },
329 { MTP_PROPERTY_ARTIST_CODE, MEDIA_DATA_DB_ARTIST },
330 { MTP_PROPERTY_DURATION_CODE, MEDIA_DATA_DB_DURATION },
331 { MTP_PROPERTY_DESCRIPTION_CODE, MEDIA_DATA_DB_DESCRIPTION},
332 };
333
334 static const map<uint16_t, int32_t> PropDefaultMap = {
335 { MTP_PROPERTY_STORAGE_ID_CODE, DEFAULT_STORAGE_ID },
336 { MTP_PROPERTY_PROTECTION_STATUS_CODE, INTTYPE16 },
337 { MTP_PROPERTY_PERSISTENT_UID_CODE, INTTYPE128 },
338 { MTP_PROPERTY_ALBUM_NAME_CODE, STRINGTYPE },
339 { MTP_PROPERTY_ALBUM_ARTIST_CODE, STRINGTYPE },
340 { MTP_PROPERTY_TRACK_CODE, INTTYPE16 },
341 { MTP_PROPERTY_ORIGINAL_RELEASE_DATE_CODE, STRINGTYPE },
342 { MTP_PROPERTY_GENRE_CODE, STRINGTYPE },
343 { MTP_PROPERTY_COMPOSER_CODE, STRINGTYPE },
344 { MTP_PROPERTY_AUDIO_WAVE_CODEC_CODE, INTTYPE16 },
345 { MTP_PROPERTY_BITRATE_TYPE_CODE, INTTYPE16 },
346 { MTP_PROPERTY_AUDIO_BITRATE_CODE, INTTYPE16 },
347 { MTP_PROPERTY_NUMBER_OF_CHANNELS_CODE, INTTYPE16 },
348 { MTP_PROPERTY_SAMPLE_RATE_CODE, INTTYPE16 },
349 };
350
SolveHandlesFormatData(const uint16_t format,std::string & outExtension,MediaType & outMediaType)351 int32_t MtpDataUtils::SolveHandlesFormatData(const uint16_t format, std::string &outExtension, MediaType &outMediaType)
352 {
353 CHECK_AND_RETURN_RET_LOG(FormatMap.find(format) != FormatMap.end(), MTP_ERROR_INVALID_OBJECTHANDLE,
354 "Can not find format");
355 outExtension = FormatMap.at(format);
356 if (FormatAllMap.find(outExtension) != FormatAllMap.end()) {
357 outMediaType = FormatAllMap.at(outExtension);
358 return MTP_SUCCESS;
359 }
360 outMediaType = MEDIA_TYPE_DEFAULT;
361 return MTP_SUCCESS;
362 }
363
SolveSendObjectFormatData(const uint16_t format,MediaType & outMediaType)364 int32_t MtpDataUtils::SolveSendObjectFormatData(const uint16_t format, MediaType &outMediaType)
365 {
366 if (FormatMediaTypeMap.find(format) == FormatMediaTypeMap.end()) {
367 MEDIA_ERR_LOG("Can not find format");
368 outMediaType = MEDIA_TYPE_FILE;
369 } else {
370 outMediaType = FormatMediaTypeMap.at(format);
371 }
372 return MTP_SUCCESS;
373 }
374
SolveSetObjectPropValueData(const shared_ptr<MtpOperationContext> & context,std::string & outColName,variant<int64_t,std::string> & outColVal)375 int32_t MtpDataUtils::SolveSetObjectPropValueData(const shared_ptr<MtpOperationContext> &context,
376 std::string &outColName, variant<int64_t, std::string> &outColVal)
377 {
378 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "context is nullptr");
379
380 bool cond = ObjMediaPropTypeMap.find(context->property) == ObjMediaPropTypeMap.end();
381 CHECK_AND_RETURN_RET_LOG(!cond, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "Can not support propertyType");
382 if (ObjMediaPropMap.find(context->property) == ObjMediaPropMap.end()) {
383 MEDIA_ERR_LOG("Can not support this property");
384 return MTP_ERROR_INVALID_OBJECTPROP_VALUE;
385 } else {
386 outColName = ObjMediaPropMap.at(context->property);
387 }
388 if (context->properType == MTP_TYPE_STRING_CODE) {
389 outColVal = context->properStrValue;
390 MEDIA_INFO_LOG("context->properStrValue = %{public}s", context->properStrValue.c_str());
391 } else {
392 outColVal = context->properIntValue;
393 }
394 return MTP_SUCCESS;
395 }
396
GetMediaTypeByformat(const uint16_t format,MediaType & outMediaType)397 void MtpDataUtils::GetMediaTypeByformat(const uint16_t format, MediaType &outMediaType)
398 {
399 if (FormatMediaTypeMap.find(format) == FormatMediaTypeMap.end()) {
400 MEDIA_ERR_LOG("Can not find format");
401 outMediaType = MEDIA_TYPE_DEFAULT;
402 }
403 if (FormatMediaTypeMap.find(format) != FormatMediaTypeMap.end()) {
404 outMediaType = FormatMediaTypeMap.at(format);
405 }
406 }
407
GetPropListBySet(const std::shared_ptr<MtpOperationContext> & context,const shared_ptr<DataShare::DataShareResultSet> & resultSet,shared_ptr<vector<Property>> & outProps)408 int32_t MtpDataUtils::GetPropListBySet(const std::shared_ptr<MtpOperationContext> &context,
409 const shared_ptr<DataShare::DataShareResultSet> &resultSet, shared_ptr<vector<Property>> &outProps)
410 {
411 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "context is nullptr");
412
413 shared_ptr<UInt16List> properties = make_shared<UInt16List>();
414 CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "properties is nullptr");
415
416 if (context->property == MTP_PROPERTY_ALL_CODE) {
417 shared_ptr<MtpOperationContext> ptpContext = make_shared<MtpOperationContext>();
418 CHECK_AND_RETURN_RET_LOG(ptpContext != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "ptpContext is nullptr");
419
420 ptpContext->format = context->format;
421 shared_ptr<GetObjectPropsSupportedData> payLoadData = make_shared<GetObjectPropsSupportedData>(ptpContext);
422 CHECK_AND_RETURN_RET_LOG(payLoadData != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "payLoadData is nullptr");
423
424 payLoadData->GetObjectProps(*properties);
425 } else {
426 properties->push_back(context->property);
427 }
428 return GetPropList(context, resultSet, properties, outProps);
429 }
430
GetPropList(const std::shared_ptr<MtpOperationContext> & context,const shared_ptr<DataShare::DataShareResultSet> & resultSet,const shared_ptr<UInt16List> & properties,shared_ptr<vector<Property>> & outProps)431 int32_t MtpDataUtils::GetPropList(const std::shared_ptr<MtpOperationContext> &context,
432 const shared_ptr<DataShare::DataShareResultSet> &resultSet,
433 const shared_ptr<UInt16List> &properties, shared_ptr<vector<Property>> &outProps)
434 {
435 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "context is nullptr");
436 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "resultSet is nullptr");
437 CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "properties is nullptr");
438
439 int count = 0;
440 resultSet->GetRowCount(count);
441 CHECK_AND_RETURN_RET_LOG(count > 0, MTP_ERROR_INVALID_OBJECTHANDLE, "have no row");
442 CHECK_AND_RETURN_RET(properties->size() != 0, MTP_INVALID_OBJECTPROPCODE_CODE);
443 ResultSetDataType idType = TYPE_INT32;
444 int32_t handle = 0;
445 for (int32_t row = 0; row < count; row++) {
446 resultSet->GoToRow(row);
447 if (context->handle > EDITED_PHOTOS_OFFSET) {
448 string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
449 string displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
450 int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
451 string path = GetMovingOrEnditSourcePath(data, subtype, context);
452 int32_t parent = GetInt32Val(PARENT, resultSet);
453 CHECK_AND_RETURN_RET_LOG(!path.empty(), E_FAIL, "MtpDataUtils::GetPropList get sourcePath failed");
454 MovingType movingType;
455 movingType.displayName = displayName;
456 movingType.parent = static_cast<uint64_t>(parent);
457 GetMovingOrEnditOneRowPropList(properties, path, context, outProps, movingType);
458 } else {
459 handle = get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_ID, resultSet, idType));
460 MEDIA_INFO_LOG("GetPropList %{public}d",
461 get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_ID, resultSet, idType)));
462 GetOneRowPropList(static_cast<uint32_t>(handle), resultSet, properties, outProps);
463 }
464 }
465 return MTP_SUCCESS;
466 }
467
GetMovingOrEnditOneRowPropList(const shared_ptr<UInt16List> & properties,const std::string & path,const std::shared_ptr<MtpOperationContext> & context,shared_ptr<vector<Property>> & outProps,const MovingType & movingType)468 void MtpDataUtils::GetMovingOrEnditOneRowPropList(const shared_ptr<UInt16List> &properties, const std::string &path,
469 const std::shared_ptr<MtpOperationContext> &context, shared_ptr<vector<Property>> &outProps,
470 const MovingType &movingType)
471 {
472 CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
473 CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
474 CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
475
476 std::string column;
477 for (uint16_t property : *properties) {
478 if (PropColumnMap.find(property) != PropColumnMap.end()) {
479 auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
480 Property prop(property, properType);
481 prop.handle_ = context->handle;
482 column = PropColumnMap.at(property);
483 if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
484 uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
485 GetMtpFormatByPath(path, format);
486 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
487
488 prop.currentValue->bin_.ui16 = format;
489 } else {
490 SetPtpProperty(column, path, movingType, prop);
491 }
492 outProps->push_back(prop);
493 } else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
494 SetOneDefaultlPropList(context->handle, property, outProps);
495 }
496 }
497 }
498
ReturnError(const std::string & errMsg,const ResultSetDataType & type)499 variant<int32_t, int64_t, std::string> MtpDataUtils::ReturnError(const std::string &errMsg,
500 const ResultSetDataType &type)
501 {
502 MEDIA_ERR_LOG("%{public}s", errMsg.c_str());
503 if ((type) == TYPE_STRING) {
504 return "";
505 } else {
506 return 0;
507 }
508 }
509
GetFormatByPath(const std::string & path,uint16_t & outFormat)510 void MtpDataUtils::GetFormatByPath(const std::string &path, uint16_t &outFormat)
511 {
512 CHECK_AND_RETURN_LOG(!path.empty(), "path is nullptr");
513 if (MediaFileUtils::IsDirectory(path)) {
514 MEDIA_ERR_LOG("path is dir");
515 outFormat = MTP_FORMAT_ASSOCIATION_CODE;
516 return;
517 }
518 size_t slashIndex = path.rfind('/');
519 std::string displayName;
520 if (slashIndex != std::string::npos) {
521 displayName = path.substr(slashIndex + 1);
522 }
523 size_t extensionIndex = displayName.rfind(".");
524 std::string extension;
525 if (extensionIndex != std::string::npos) {
526 extension = displayName.substr(extensionIndex);
527 } else {
528 MEDIA_ERR_LOG("get extensionIndex failed");
529 outFormat = MTP_FORMAT_UNDEFINED_CODE;
530 return;
531 }
532 for (auto pair : FormatMap) {
533 if ((pair.second).find(extension) != std::string::npos) {
534 outFormat = pair.first;
535 break;
536 }
537 }
538 }
539
GetFormat(const shared_ptr<DataShare::DataShareResultSet> & resultSet,uint16_t & outFormat)540 int32_t MtpDataUtils::GetFormat(const shared_ptr<DataShare::DataShareResultSet> &resultSet,
541 uint16_t &outFormat)
542 {
543 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_FAIL, "resultSet is nullptr");
544
545 int index;
546 int status;
547 int mediaType;
548 status = resultSet->GetColumnIndex(MEDIA_DATA_DB_MEDIA_TYPE, index);
549 CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetColumnIndex failed");
550 resultSet->GetInt(index, mediaType);
551 if (mediaType == MEDIA_TYPE_ALBUM) {
552 outFormat = MTP_FORMAT_ASSOCIATION_CODE;
553 return E_SUCCESS;
554 }
555 status = resultSet->GetColumnIndex(MEDIA_DATA_DB_FILE_PATH, index);
556 CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetColumnIndex failed");
557 std::string pathVal;
558 status = resultSet->GetString(index, pathVal);
559 CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetString failed");
560 CHECK_AND_RETURN_RET_LOG(!pathVal.empty(), E_FAIL, "path is empty");
561 GetFormatByPath(pathVal, outFormat);
562 return E_SUCCESS;
563 }
564
LocalTime(struct tm & t,time_t curTime)565 void LocalTime(struct tm &t, time_t curTime)
566 {
567 time_t curTimeTemp = curTime;
568 if (curTimeTemp == 0) {
569 curTimeTemp = time(nullptr);
570 }
571 auto tm = localtime(&curTimeTemp);
572 if (tm) {
573 t = *tm;
574 }
575 }
576
Strftime(const std::string & format,time_t curTime)577 std::string Strftime(const std::string &format, time_t curTime)
578 {
579 if (format.empty()) {
580 return format;
581 }
582 struct tm t = {};
583 LocalTime(t, curTime);
584 char szDTime[32] = "";
585 (void)strftime(szDTime, sizeof(szDTime), format.c_str(), &t);
586 return szDTime;
587 }
588
SetProperty(const std::string & column,const shared_ptr<DataShare::DataShareResultSet> & resultSet,ResultSetDataType & type,Property & prop)589 void MtpDataUtils::SetProperty(const std::string &column, const shared_ptr<DataShare::DataShareResultSet> &resultSet,
590 ResultSetDataType &type, Property &prop)
591 {
592 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
593
594 variant<int32_t, std::string, int64_t, double> columnValue =
595 ResultSetUtils::GetValFromColumn(column, resultSet, type);
596 switch (type) {
597 case TYPE_STRING:
598 prop.currentValue->str_ = make_shared<std::string>(get<std::string>(columnValue));
599 break;
600 case TYPE_INT32:
601 prop.currentValue->bin_.i32 = get<int32_t>(columnValue);
602 break;
603 case TYPE_INT64:
604 if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
605 prop.currentValue->str_ = make_shared<std::string>(
606 MtpPacketTool::FormatDateTime(get<int64_t>(columnValue) / MILLI_TO_SECOND));
607 } else {
608 prop.currentValue->bin_.i64 = get<int64_t>(columnValue);
609 }
610 break;
611 default:
612 break;
613 }
614 }
615
GetOneRowPropList(uint32_t handle,const shared_ptr<DataShare::DataShareResultSet> & resultSet,const shared_ptr<UInt16List> & properties,shared_ptr<vector<Property>> & outProps)616 void MtpDataUtils::GetOneRowPropList(uint32_t handle, const shared_ptr<DataShare::DataShareResultSet> &resultSet,
617 const shared_ptr<UInt16List> &properties, shared_ptr<vector<Property>> &outProps)
618 {
619 CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
620 CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
621
622 std::string column;
623 ResultSetDataType type;
624 for (uint16_t property : *properties) {
625 if (PropColumnMap.find(property) != PropColumnMap.end()) {
626 auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
627 Property prop(property, properType);
628 prop.handle_ = handle;
629 column = PropColumnMap.at(property);
630 type = ColumnTypeMap.at(column);
631 if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
632 uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
633 GetFormat(resultSet, format);
634 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
635
636 prop.currentValue->bin_.ui16 = format;
637 MEDIA_INFO_LOG("prop.currentValue->bin_.ui16 %{public}u", format);
638 } else if (column.compare(MEDIA_DATA_DB_SIZE) == 0 && GetInt32Val(PARENT, resultSet) != PARENT_ROOT_ID) {
639 string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
640 struct stat statInfo;
641 CHECK_AND_RETURN_LOG(stat(filePath.c_str(), &statInfo) == 0, "GetOneRowPropList stat failed");
642 prop.currentValue->bin_.i64 = statInfo.st_size;
643 } else {
644 SetProperty(column, resultSet, type, prop);
645 }
646 outProps->push_back(prop);
647 } else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
648 SetOneDefaultlPropList(handle, property, outProps);
649 }
650 }
651 }
652
GetPropValueForVideoOfMovingPhoto(const std::string & path,const uint32_t property,PropertyValue & outPropValue)653 int32_t MtpDataUtils::GetPropValueForVideoOfMovingPhoto(const std::string &path,
654 const uint32_t property, PropertyValue &outPropValue)
655 {
656 CHECK_AND_RETURN_RET_LOG(PropColumnMap.find(property) != PropColumnMap.end(), MTP_ERROR_INVALID_OBJECTPROP_VALUE,
657 "Can not support this property");
658 std::string column = PropColumnMap.at(property);
659 if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
660 outPropValue.outStrVal = std::filesystem::path(path).filename().string();
661 return MTP_SUCCESS;
662 }
663 struct stat statInfo;
664 CHECK_AND_RETURN_RET_LOG(stat(path.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
665 "GetPropValueForMovingMp4 stat failed");
666 if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
667 outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
668 return MTP_SUCCESS;
669 }
670 if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
671 outPropValue.outStrVal = Strftime("%Y-%m-%d %H:%M:%S", statInfo.st_mtime);
672 return MTP_SUCCESS;
673 }
674 if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
675 outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_ctime);
676 }
677
678 return MTP_SUCCESS;
679 }
680
GetPropValueBySet(const uint32_t property,const shared_ptr<DataShare::DataShareResultSet> & resultSet,PropertyValue & outPropValue,bool isVideoOfMovingPhoto)681 int32_t MtpDataUtils::GetPropValueBySet(const uint32_t property,
682 const shared_ptr<DataShare::DataShareResultSet> &resultSet, PropertyValue &outPropValue, bool isVideoOfMovingPhoto)
683 {
684 CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "resultSet is nullptr");
685
686 CHECK_AND_RETURN_RET(resultSet->GoToFirstRow() == 0, MTP_ERROR_INVALID_OBJECTHANDLE);
687 if (isVideoOfMovingPhoto && property != MTP_PROPERTY_PARENT_OBJECT_CODE) {
688 string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
689 string mp4FilePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(filePath);
690 return GetPropValueForVideoOfMovingPhoto(mp4FilePath, property, outPropValue);
691 }
692
693 if (GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet) == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO) &&
694 property == MTP_PROPERTY_OBJECT_SIZE_CODE) {
695 string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
696 struct stat statInfo;
697 CHECK_AND_RETURN_RET_LOG(stat(filePath.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
698 "GetPropValueBySet stat failed");
699 outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
700 return MTP_SUCCESS;
701 }
702
703 if (PropColumnMap.find(property) != PropColumnMap.end()) {
704 std::string column = PropColumnMap.at(property);
705 ResultSetDataType type = ColumnTypeMap.at(column);
706 variant<int32_t, std::string, int64_t, double> columnValue =
707 ResultSetUtils::GetValFromColumn(column, resultSet, type);
708 switch (type) {
709 case TYPE_STRING:
710 outPropValue.outStrVal = get<std::string>(columnValue);
711 break;
712 case TYPE_INT32:
713 outPropValue.outIntVal = static_cast<uint64_t>(get<int32_t>(columnValue));
714 break;
715 case TYPE_INT64:
716 if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
717 std::string timeFormat = "%Y-%m-%d %H:%M:%S";
718 outPropValue.outStrVal = Strftime(timeFormat, (get<int64_t>(columnValue) / MILLI_TO_SECOND));
719 } else {
720 outPropValue.outIntVal = static_cast<uint64_t>(get<int64_t>(columnValue));
721 }
722 break;
723 default:
724 break;
725 }
726 }
727 return MTP_SUCCESS;
728 }
729
SetOneDefaultlPropList(uint32_t handle,uint16_t property,shared_ptr<vector<Property>> & outProps)730 void MtpDataUtils::SetOneDefaultlPropList(uint32_t handle, uint16_t property, shared_ptr<vector<Property>> &outProps)
731 {
732 auto propType = PropDefaultMap.at(property);
733 auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
734 Property prop(property, properType);
735 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
736
737 prop.handle_ = handle;
738 switch (propType) {
739 case INTTYPE16:
740 prop.currentValue->bin_.i16 = 0;
741 break;
742 case INTTYPE128:
743 prop.currentValue->bin_.i128[OFFSET_0] = static_cast<int32_t>(handle);
744 prop.currentValue->bin_.i128[OFFSET_1] = 0;
745 prop.currentValue->bin_.i128[OFFSET_2] = 0;
746 prop.currentValue->bin_.i128[OFFSET_3] = 0;
747 break;
748 case STRINGTYPE:
749 prop.currentValue->str_ = make_shared<string>("");
750 break;
751 default:
752 prop.currentValue->bin_.i32 = DEFAULT_STORAGE_ID;
753 break;
754 }
755 outProps->push_back(prop);
756 }
757
GetMediaTypeByName(std::string & displayName,MediaType & outMediaType)758 int32_t MtpDataUtils::GetMediaTypeByName(std::string &displayName, MediaType &outMediaType)
759 {
760 size_t displayNameIndex = displayName.find_last_of('.');
761 std::string extension;
762 if (displayNameIndex != std::string::npos) {
763 extension = displayName.substr(displayNameIndex);
764 transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
765 } else {
766 MEDIA_ERR_LOG("is dir displayName");
767 outMediaType = MEDIA_TYPE_ALBUM;
768 return E_SUCCESS;
769 }
770 uint16_t format;
771 for (auto pair : FormatMap) {
772 if ((pair.second).find(extension) != std::string::npos) {
773 format = pair.first;
774 break;
775 } else {
776 format = MTP_FORMAT_UNDEFINED_CODE;
777 }
778 }
779 if (UndefinedImageFormatSet.find(extension) != UndefinedImageFormatSet.end()) {
780 format = MTP_FORMAT_DEFINED_CODE;
781 } else if (UndefinedVideoFormatSet.find(extension) != UndefinedVideoFormatSet.end()) {
782 format = MTP_FORMAT_UNDEFINED_VIDEO_CODE;
783 }
784 GetMediaTypeByformat(format, outMediaType);
785 MEDIA_DEBUG_LOG("GetMediaTypeByName format:%{public}x, outMediaType:%{public}d", format, outMediaType);
786 return E_SUCCESS;
787 }
788
GetMtpPropList(const std::shared_ptr<std::unordered_map<uint32_t,std::string>> & handles,const std::unordered_map<std::string,uint32_t> & pathHandles,const std::shared_ptr<MtpOperationContext> & context,shared_ptr<vector<Property>> & outProps)789 int32_t MtpDataUtils::GetMtpPropList(const std::shared_ptr<std::unordered_map<uint32_t, std::string>> &handles,
790 const std::unordered_map<std::string, uint32_t> &pathHandles,
791 const std::shared_ptr<MtpOperationContext> &context, shared_ptr<vector<Property>> &outProps)
792 {
793 CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
794 CHECK_AND_RETURN_RET_LOG(handles != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "handles is nullptr");
795 for (auto it = handles->begin(); it != handles->end(); it++) {
796 shared_ptr<UInt16List> properties = make_shared<UInt16List>();
797 CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "properties is nullptr");
798
799 if (context->property == MTP_PROPERTY_ALL_CODE) {
800 shared_ptr<MtpOperationContext> mtpContext = make_shared<MtpOperationContext>();
801 CHECK_AND_RETURN_RET_LOG(mtpContext != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "mtpContext is nullptr");
802
803 if (context->format == 0) {
804 GetMtpFormatByPath(it->second, mtpContext->format);
805 } else {
806 mtpContext->format = context->format;
807 }
808 shared_ptr<GetObjectPropsSupportedData> payLoadData = make_shared<GetObjectPropsSupportedData>(mtpContext);
809 CHECK_AND_RETURN_RET_LOG(payLoadData != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "payLoadData is nullptr");
810
811 payLoadData->GetObjectProps(*properties);
812 } else {
813 properties->push_back(context->property);
814 }
815 if (properties->size() == 0) {
816 MEDIA_ERR_LOG("MtpDataUtils::GetMtpPropList properties is empty");
817 return MTP_INVALID_OBJECTPROPCODE_CODE;
818 }
819
820 uint32_t parentId = DEFAULT_STORAGE_ID;
821 auto iterator = pathHandles.find(std::filesystem::path(it->second).parent_path().string());
822 if (iterator != pathHandles.end()) {
823 parentId = iterator->second;
824 } else {
825 parentId = 0;
826 }
827 GetMtpOneRowProp(properties, parentId, it, outProps, context->storageID);
828 }
829 return MTP_SUCCESS;
830 }
831
GetMtpOneRowProp(const std::shared_ptr<UInt16List> & properties,const uint32_t parentId,std::unordered_map<uint32_t,std::string>::iterator it,shared_ptr<vector<Property>> & outProps,int32_t storageId)832 void MtpDataUtils::GetMtpOneRowProp(const std::shared_ptr<UInt16List> &properties, const uint32_t parentId,
833 std::unordered_map<uint32_t, std::string>::iterator it, shared_ptr<vector<Property>> &outProps, int32_t storageId)
834 {
835 CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
836 CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
837
838 std::string column;
839 ResultSetDataType type;
840 for (uint16_t property : *properties) {
841 if (PropColumnMap.find(property) != PropColumnMap.end()) {
842 auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
843 Property prop(property, properType);
844 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
845
846 prop.handle_ = it->first;
847 column = PropColumnMap.at(property);
848 type = ColumnTypeMap.at(column);
849 if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
850 uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
851 GetMtpFormatByPath(it->second, format);
852 prop.currentValue->bin_.ui16 = format;
853 } else if (column.compare(MEDIA_DATA_DB_PARENT_ID) == 0) {
854 prop.currentValue->bin_.ui32 = parentId;
855 } else {
856 SetMtpProperty(column, it->second, type, prop);
857 }
858 outProps->push_back(prop);
859 } else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
860 SetMtpOneDefaultlPropList(it->first, property, outProps, storageId);
861 } else {
862 MEDIA_DEBUG_LOG("other property:0x%{public}x", property);
863 }
864 }
865 }
866
GetMtpFormatByPath(const std::string & path,uint16_t & outFormat)867 uint32_t MtpDataUtils::GetMtpFormatByPath(const std::string &path, uint16_t &outFormat)
868 {
869 outFormat = MTP_FORMAT_UNDEFINED_CODE;
870 CHECK_AND_RETURN_RET_LOG(!path.empty(), MTP_ERROR_INVALID_OBJECTPROP_VALUE, "path is nullptr");
871 CHECK_AND_RETURN_RET_LOG(access(path.c_str(), R_OK) == 0, E_ERR, "access failed path[%{public}s]", path.c_str());
872 if (std::filesystem::is_directory(path)) {
873 outFormat = MTP_FORMAT_ASSOCIATION_CODE;
874 return MTP_SUCCESS;
875 }
876
877 std::filesystem::path filePath(path);
878 CHECK_AND_RETURN_RET(filePath.filename().has_extension(), MTP_ERROR_INVALID_OBJECTPROP_VALUE);
879 // ↑ has_extension already checked for file extension
880 std::string extension = filePath.filename().extension().c_str();
881 for (auto it = FormatMap.begin(); it != FormatMap.end(); it++) {
882 if (it->second.compare(extension) != 0) {
883 continue;
884 }
885 // outFormat should also be in 'Playback Formats' return array of GetDeviceInfo cmd
886 uint16_t size = sizeof(PLAYBACK_FORMATS) / sizeof(uint16_t);
887 for (uint16_t i = 0; i < size; i++) {
888 if (it->first == PLAYBACK_FORMATS[i]) {
889 outFormat = it->first;
890 return MTP_SUCCESS;
891 }
892 }
893 }
894 if (extension.compare(MTP_FORMAT_JPG) == 0 || extension.compare(MTP_FORMAT_JPEG) == 0) {
895 outFormat = MTP_FORMAT_EXIF_JPEG_CODE;
896 return MTP_SUCCESS;
897 }
898 return MTP_ERROR_INVALID_OBJECTPROP_VALUE;
899 }
900
SetMtpProperty(const std::string & column,const std::string & path,ResultSetDataType & type,Property & prop)901 void MtpDataUtils::SetMtpProperty(const std::string &column, const std::string &path,
902 ResultSetDataType &type, Property &prop)
903 {
904 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
905
906 if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
907 prop.currentValue->str_ = make_shared<std::string>(std::filesystem::path(path).filename().string());
908 return;
909 }
910 struct stat statInfo;
911 CHECK_AND_RETURN_LOG(stat(path.c_str(), &statInfo) == 0, "SetMtpProperty stat failed");
912 if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
913 prop.currentValue->bin_.i64 = statInfo.st_size;
914 return;
915 }
916 if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
917 prop.currentValue->str_ = make_shared<std::string>(MtpPacketTool::FormatDateTime((statInfo.st_mtime)));
918 return;
919 }
920 if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
921 prop.currentValue->bin_.i64 = statInfo.st_ctime;
922 return;
923 }
924 if (column.compare(MEDIA_DATA_DB_DESCRIPTION) == 0) {
925 prop.currentValue->str_ = make_shared<std::string>("");
926 return;
927 }
928 if (column.compare(MEDIA_DATA_DB_DURATION) == 0) {
929 prop.currentValue->bin_.ui32 = 0;
930 return;
931 }
932 if (column.compare(MEDIA_DATA_DB_ARTIST) == 0) {
933 prop.currentValue->str_ = make_shared<std::string>("");
934 return;
935 }
936 if (column.compare(MEDIA_DATA_DB_ALBUM_NAME) == 0) {
937 prop.currentValue->str_ = make_shared<std::string>("");
938 return;
939 }
940 if (column.compare(MEDIA_DATA_DB_COMPOSER) == 0) {
941 prop.currentValue->str_ = make_shared<std::string>("");
942 return;
943 }
944 }
945
SetPtpProperty(const std::string & column,const std::string & path,const MovingType & movingType,Property & prop)946 void MtpDataUtils::SetPtpProperty(const std::string &column, const std::string &path, const MovingType &movingType,
947 Property &prop)
948 {
949 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
950
951 std::string displayName = movingType.displayName;
952 if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
953 std::string filename = std::filesystem::path(path).filename();
954 size_t filename_pos = filename.find_last_of('.');
955 CHECK_AND_RETURN_LOG(filename_pos != std::string::npos, "get file name failed");
956 size_t displayName_pos = displayName.find_last_of('.');
957 CHECK_AND_RETURN_LOG(displayName_pos != std::string::npos, "get displayName name failed");
958 std::string value;
959 CHECK_AND_RETURN_LOG(filename_pos + 1 < filename.size(), "get fileName failed");
960 value = displayName.substr(0, displayName_pos) + "." + filename.substr(filename_pos + 1);
961 prop.currentValue->str_ = make_shared<std::string>(value);
962 }
963 if (column.compare(MEDIA_DATA_DB_PARENT_ID) == 0) {
964 prop.currentValue->bin_.i64 = movingType.parent;
965 }
966
967 struct stat statInfo;
968 CHECK_AND_RETURN_LOG(stat(path.c_str(), &statInfo) == 0, "SetMtpProperty stat failed");
969 if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
970 prop.currentValue->bin_.i64 = statInfo.st_size;
971 }
972 if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
973 prop.currentValue->str_ = make_shared<std::string>(MtpPacketTool::FormatDateTime((statInfo.st_mtime)));
974 }
975 if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
976 prop.currentValue->bin_.i64 = statInfo.st_ctime;
977 }
978 }
979
GetMovingOrEnditSourcePath(const std::string & path,const int32_t & subtype,const shared_ptr<MtpOperationContext> & context)980 string MtpDataUtils::GetMovingOrEnditSourcePath(const std::string &path, const int32_t &subtype,
981 const shared_ptr<MtpOperationContext> &context)
982 {
983 string sourcePath;
984 CHECK_AND_RETURN_RET_LOG(context != nullptr, sourcePath, "context is nullptr");
985
986 MEDIA_INFO_LOG("mtp GetMovingOrEnditSourcePath path:%{public}s, subtype:%{public}d", path.c_str(), subtype);
987 switch (static_cast<int32_t>(context->handle / COMMON_PHOTOS_OFFSET)) {
988 case EDITED_PHOTO_TYPE:
989 if (subtype == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO)) {
990 sourcePath = MovingPhotoFileUtils::GetSourceMovingPhotoImagePath(path);
991 } else {
992 sourcePath = PhotoFileUtils::GetEditDataSourcePath(path);
993 }
994 break;
995 case MOVING_PHOTO_TYPE:
996 sourcePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(path);
997 break;
998 case EDITED_MOVING_TYPE:
999 sourcePath = MovingPhotoFileUtils::GetSourceMovingPhotoVideoPath(path);
1000 break;
1001 default:
1002 break;
1003 }
1004 MEDIA_INFO_LOG("Mtp GetMovingOrEnditSourcePath sourcePath:%{public}s", sourcePath.c_str());
1005 return sourcePath;
1006 }
1007
GetMtpPropValue(const std::string & path,const uint32_t property,const uint16_t format,PropertyValue & outPropValue)1008 int32_t MtpDataUtils::GetMtpPropValue(const std::string &path,
1009 const uint32_t property, const uint16_t format, PropertyValue &outPropValue)
1010 {
1011 CHECK_AND_RETURN_RET_LOG(PropColumnMap.find(property) != PropColumnMap.end(), MTP_ERROR_INVALID_OBJECTPROP_VALUE,
1012 "Can not support this property");
1013
1014 std::string column = PropColumnMap.at(property);
1015 if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
1016 outPropValue.outStrVal = std::filesystem::path(path).filename().string();
1017 return MTP_SUCCESS;
1018 }
1019
1020 struct stat statInfo;
1021 CHECK_AND_RETURN_RET_LOG(stat(path.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
1022 "GetMtpPropValue stat failed");
1023 if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
1024 outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
1025 return MTP_SUCCESS;
1026 }
1027 if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
1028 outPropValue.outStrVal = Strftime("%Y-%m-%d %H:%M:%S", statInfo.st_mtime);
1029 return MTP_SUCCESS;
1030 }
1031 if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
1032 outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_ctime);
1033 }
1034
1035 return MTP_SUCCESS;
1036 }
1037
SetMtpOneDefaultlPropList(uint32_t handle,uint16_t property,std::shared_ptr<std::vector<Property>> & outProps,int32_t storageId)1038 void MtpDataUtils::SetMtpOneDefaultlPropList(uint32_t handle,
1039 uint16_t property, std::shared_ptr<std::vector<Property>> &outProps, int32_t storageId)
1040 {
1041 CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
1042 auto propType = PropDefaultMap.at(property);
1043 auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
1044 Property prop(property, properType);
1045 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
1046 prop.handle_ = handle;
1047 switch (propType) {
1048 case INTTYPE16:
1049 prop.currentValue->bin_.i16 = 0;
1050 break;
1051 case INTTYPE128:
1052 prop.currentValue->bin_.i128[OFFSET_0] = static_cast<int32_t>(handle);
1053 prop.currentValue->bin_.i128[OFFSET_1] = 0;
1054 prop.currentValue->bin_.i128[OFFSET_2] = 0;
1055 prop.currentValue->bin_.i128[OFFSET_3] = 0;
1056 break;
1057 case STRINGTYPE:
1058 prop.currentValue->str_ = make_shared<string>("");
1059 break;
1060 default:
1061 prop.currentValue->bin_.i32 = storageId;
1062 break;
1063 }
1064 outProps->push_back(prop);
1065 }
1066
1067 } // namespace Media
1068 } // namespace OHOS
1069