• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_manager.h"
28 #include "mtp_packet_tools.h"
29 #include "mtp_ptp_const.h"
30 #include "payload_data/get_object_props_supported_data.h"
31 #include "payload_data.h"
32 #include "rdb_errno.h"
33 #include "playback_formats.h"
34 #include "moving_photo_file_utils.h"
35 
36 using namespace std;
37 namespace OHOS {
38 namespace Media {
39 struct NormalProperty {
40     int32_t intValue;
41     string strValue;
42 };
43 static constexpr int32_t INTTYPE16 = 16;
44 static constexpr int32_t INTTYPE128 = 128;
45 static constexpr int32_t STRINGTYPE = -1;
46 static const string MEDIA_DATA_DB_FORMAT = "format";
47 static const string MEDIA_DATA_DB_COMPOSER = "composer";
48 static constexpr int32_t MOVING_PHOTO_TYPE = 3;
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     for (int32_t row = 0; row < count; row++) {
445         resultSet->GoToRow(row);
446         if (context->handle > EDITED_PHOTOS_OFFSET) {
447             string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
448             string displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
449             int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
450             string path = GetMovingOrEnditSourcePath(data, subtype, context);
451             int32_t parent = GetInt32Val(PARENT, resultSet);
452             CHECK_AND_RETURN_RET_LOG(!path.empty(), E_FAIL, "MtpDataUtils::GetPropList get sourcePath failed");
453             MovingType movingType;
454             movingType.displayName = displayName;
455             movingType.parent = static_cast<uint64_t>(parent);
456             GetMovingOrEnditOneRowPropList(properties, path, context, outProps, movingType);
457         } else {
458             MEDIA_INFO_LOG("GetPropList %{public}d",
459                 get<int32_t>(ResultSetUtils::GetValFromColumn(MEDIA_DATA_DB_ID, resultSet, idType)));
460             GetOneRowPropList(static_cast<uint32_t>(context->handle), resultSet, properties, outProps);
461         }
462     }
463     return MTP_SUCCESS;
464 }
465 
GetMovingOrEnditOneRowPropList(const shared_ptr<UInt16List> & properties,const std::string & path,const std::shared_ptr<MtpOperationContext> & context,shared_ptr<vector<Property>> & outProps,const MovingType & movingType)466 void MtpDataUtils::GetMovingOrEnditOneRowPropList(const shared_ptr<UInt16List> &properties, const std::string &path,
467     const std::shared_ptr<MtpOperationContext> &context, shared_ptr<vector<Property>> &outProps,
468     const MovingType &movingType)
469 {
470     CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
471     CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
472     CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
473 
474     std::string column;
475     for (uint16_t property : *properties) {
476         if (PropColumnMap.find(property) != PropColumnMap.end()) {
477             auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
478             Property prop(property, properType);
479             prop.handle_ = context->handle;
480             column = PropColumnMap.at(property);
481             if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
482                 uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
483                 GetMtpFormatByPath(path, format);
484                 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
485 
486                 prop.currentValue->bin_.ui16 = format;
487             } else {
488                 SetPtpProperty(column, path, movingType, prop);
489             }
490             outProps->push_back(prop);
491         } else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
492             SetOneDefaultlPropList(context->handle, property, outProps);
493         }
494     }
495 }
496 
ReturnError(const std::string & errMsg,const ResultSetDataType & type)497 variant<int32_t, int64_t, std::string> MtpDataUtils::ReturnError(const std::string &errMsg,
498     const ResultSetDataType &type)
499 {
500     MEDIA_ERR_LOG("%{public}s", errMsg.c_str());
501     if ((type) == TYPE_STRING) {
502         return "";
503     } else {
504         return 0;
505     }
506 }
507 
GetFormatByPath(const std::string & path,uint16_t & outFormat)508 void MtpDataUtils::GetFormatByPath(const std::string &path, uint16_t &outFormat)
509 {
510     CHECK_AND_RETURN_LOG(!path.empty(), "path is nullptr");
511     if (MediaFileUtils::IsDirectory(path)) {
512         MEDIA_ERR_LOG("path is dir");
513         outFormat = MTP_FORMAT_ASSOCIATION_CODE;
514         return;
515     }
516     size_t slashIndex = path.rfind('/');
517     std::string displayName;
518     if (slashIndex != std::string::npos) {
519         displayName = path.substr(slashIndex + 1);
520     }
521     size_t extensionIndex = displayName.rfind(".");
522     std::string extension;
523     if (extensionIndex != std::string::npos) {
524         extension = displayName.substr(extensionIndex);
525     } else {
526         MEDIA_ERR_LOG("get extensionIndex failed");
527         outFormat = MTP_FORMAT_UNDEFINED_CODE;
528         return;
529     }
530     for (auto pair : FormatMap) {
531         if ((pair.second).find(extension) != std::string::npos) {
532             outFormat = pair.first;
533             break;
534         }
535     }
536 }
537 
GetFormat(const shared_ptr<DataShare::DataShareResultSet> & resultSet,uint16_t & outFormat)538 int32_t MtpDataUtils::GetFormat(const shared_ptr<DataShare::DataShareResultSet> &resultSet,
539     uint16_t &outFormat)
540 {
541     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_FAIL, "resultSet is nullptr");
542 
543     int index;
544     int status;
545     int mediaType;
546     status = resultSet->GetColumnIndex(MEDIA_DATA_DB_MEDIA_TYPE, index);
547     CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetColumnIndex failed");
548     resultSet->GetInt(index, mediaType);
549     if (mediaType == MEDIA_TYPE_ALBUM) {
550         outFormat = MTP_FORMAT_ASSOCIATION_CODE;
551         return E_SUCCESS;
552     }
553     status = resultSet->GetColumnIndex(MEDIA_DATA_DB_FILE_PATH, index);
554     CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetColumnIndex failed");
555     std::string pathVal;
556     status = resultSet->GetString(index, pathVal);
557     CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetString failed");
558     CHECK_AND_RETURN_RET_LOG(!pathVal.empty(), E_FAIL, "path is empty");
559     GetFormatByPath(pathVal, outFormat);
560     return E_SUCCESS;
561 }
562 
LocalTime(struct tm & t,time_t curTime)563 void LocalTime(struct tm &t, time_t curTime)
564 {
565     time_t curTimeTemp = curTime;
566     if (curTimeTemp == 0) {
567         curTimeTemp = time(nullptr);
568     }
569     auto tm = localtime(&curTimeTemp);
570     if (tm) {
571         t = *tm;
572     }
573 }
574 
Strftime(const std::string & format,time_t curTime)575 std::string Strftime(const std::string &format, time_t curTime)
576 {
577     if (format.empty()) {
578         return format;
579     }
580     struct tm t = {};
581     LocalTime(t, curTime);
582     char szDTime[32] = "";
583     (void)strftime(szDTime, sizeof(szDTime), format.c_str(), &t);
584     return szDTime;
585 }
586 
SetProperty(const std::string & column,const shared_ptr<DataShare::DataShareResultSet> & resultSet,ResultSetDataType & type,Property & prop)587 void MtpDataUtils::SetProperty(const std::string &column, const shared_ptr<DataShare::DataShareResultSet> &resultSet,
588     ResultSetDataType &type, Property &prop)
589 {
590     CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
591 
592     variant<int32_t, std::string, int64_t, double> columnValue =
593         ResultSetUtils::GetValFromColumn(column, resultSet, type);
594     switch (type) {
595         case TYPE_STRING:
596             prop.currentValue->str_ = make_shared<std::string>(get<std::string>(columnValue));
597             break;
598         case TYPE_INT32:
599             prop.currentValue->bin_.i32 = get<int32_t>(columnValue);
600             {
601                 // if ptp in mtp mode, set parent id to PTP_IN_MTP_ID
602                 bool isParent = column.compare(MEDIA_DATA_DB_PARENT_ID) == 0;
603                 if (isParent && MtpManager::GetInstance().IsMtpMode() && prop.currentValue->bin_.i32 == 0) {
604                     prop.currentValue->bin_.i32 = PTP_IN_MTP_ID;
605                 }
606             }
607             break;
608         case TYPE_INT64:
609             if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
610                 prop.currentValue->str_ = make_shared<std::string>(
611                     MtpPacketTool::FormatDateTime(get<int64_t>(columnValue) / MILLI_TO_SECOND));
612             } else {
613                 prop.currentValue->bin_.i64 = get<int64_t>(columnValue);
614             }
615             break;
616         default:
617             break;
618     }
619 }
620 
GetOneRowPropList(uint32_t handle,const shared_ptr<DataShare::DataShareResultSet> & resultSet,const shared_ptr<UInt16List> & properties,shared_ptr<vector<Property>> & outProps)621 void MtpDataUtils::GetOneRowPropList(uint32_t handle, const shared_ptr<DataShare::DataShareResultSet> &resultSet,
622     const shared_ptr<UInt16List> &properties, shared_ptr<vector<Property>> &outProps)
623 {
624     CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
625     CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
626 
627     std::string column;
628     ResultSetDataType type;
629     for (uint16_t property : *properties) {
630         if (PropColumnMap.find(property) != PropColumnMap.end()) {
631             auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
632             Property prop(property, properType);
633             prop.handle_ = handle;
634             column = PropColumnMap.at(property);
635             type = ColumnTypeMap.at(column);
636             if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
637                 uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
638                 GetFormat(resultSet, format);
639                 CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
640 
641                 prop.currentValue->bin_.ui16 = format;
642                 MEDIA_INFO_LOG("prop.currentValue->bin_.ui16 %{public}u", format);
643             } else if (column.compare(MEDIA_DATA_DB_SIZE) == 0 && GetInt32Val(PARENT, resultSet) != PARENT_ROOT_ID) {
644                 string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
645                 struct stat statInfo;
646                 CHECK_AND_RETURN_LOG(stat(filePath.c_str(), &statInfo) == 0, "GetOneRowPropList stat failed");
647                 prop.currentValue->bin_.i64 = statInfo.st_size;
648             } else {
649                 SetProperty(column, resultSet, type, prop);
650             }
651             outProps->push_back(prop);
652         } else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
653             SetOneDefaultlPropList(handle, property, outProps);
654         }
655     }
656 }
657 
GetPropValueForVideoOfMovingPhoto(const std::string & path,const uint32_t property,PropertyValue & outPropValue)658 int32_t MtpDataUtils::GetPropValueForVideoOfMovingPhoto(const std::string &path,
659     const uint32_t property, PropertyValue &outPropValue)
660 {
661     CHECK_AND_RETURN_RET_LOG(PropColumnMap.find(property) != PropColumnMap.end(), MTP_ERROR_INVALID_OBJECTPROP_VALUE,
662         "Can not support this property");
663     std::string column = PropColumnMap.at(property);
664     if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
665         outPropValue.outStrVal = std::filesystem::path(path).filename().string();
666         return MTP_SUCCESS;
667     }
668     struct stat statInfo;
669     CHECK_AND_RETURN_RET_LOG(stat(path.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
670         "GetPropValueForMovingMp4 stat failed");
671     if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
672         outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
673         return MTP_SUCCESS;
674     }
675     if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
676         outPropValue.outStrVal = Strftime("%Y-%m-%d %H:%M:%S", statInfo.st_mtime);
677         return MTP_SUCCESS;
678     }
679     if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
680         outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_ctime);
681     }
682 
683     return MTP_SUCCESS;
684 }
685 
GetPropValueBySet(const uint32_t property,const shared_ptr<DataShare::DataShareResultSet> & resultSet,PropertyValue & outPropValue,bool isVideoOfMovingPhoto)686 int32_t MtpDataUtils::GetPropValueBySet(const uint32_t property,
687     const shared_ptr<DataShare::DataShareResultSet> &resultSet, PropertyValue &outPropValue, bool isVideoOfMovingPhoto)
688 {
689     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "resultSet is nullptr");
690 
691     CHECK_AND_RETURN_RET(resultSet->GoToFirstRow() == 0, MTP_ERROR_INVALID_OBJECTHANDLE);
692     if (isVideoOfMovingPhoto && property != MTP_PROPERTY_PARENT_OBJECT_CODE) {
693         string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
694         string mp4FilePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(filePath);
695         return GetPropValueForVideoOfMovingPhoto(mp4FilePath, property, outPropValue);
696     }
697     int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
698     int32_t effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
699     if (IsMtpMovingPhoto(subtype, effectMode) && property == MTP_PROPERTY_OBJECT_SIZE_CODE) {
700         string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
701         struct stat statInfo;
702         CHECK_AND_RETURN_RET_LOG(stat(filePath.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
703             "GetPropValueBySet stat failed");
704         outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
705         return MTP_SUCCESS;
706     }
707 
708     if (PropColumnMap.find(property) != PropColumnMap.end()) {
709         std::string column = PropColumnMap.at(property);
710         ResultSetDataType type = ColumnTypeMap.at(column);
711         variant<int32_t, std::string, int64_t, double> columnValue =
712             ResultSetUtils::GetValFromColumn(column, resultSet, type);
713         switch (type) {
714             case TYPE_STRING:
715                 outPropValue.outStrVal = get<std::string>(columnValue);
716                 break;
717             case TYPE_INT32:
718                 outPropValue.outIntVal = static_cast<uint64_t>(get<int32_t>(columnValue));
719                 break;
720             case TYPE_INT64:
721                 if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
722                     std::string timeFormat = "%Y-%m-%d %H:%M:%S";
723                     outPropValue.outStrVal = Strftime(timeFormat, (get<int64_t>(columnValue) / MILLI_TO_SECOND));
724                 } else {
725                     outPropValue.outIntVal = static_cast<uint64_t>(get<int64_t>(columnValue));
726                 }
727                 break;
728             default:
729                 break;
730         }
731     }
732     return MTP_SUCCESS;
733 }
734 
SetOneDefaultlPropList(uint32_t handle,uint16_t property,shared_ptr<vector<Property>> & outProps)735 void MtpDataUtils::SetOneDefaultlPropList(uint32_t handle, uint16_t property, shared_ptr<vector<Property>> &outProps)
736 {
737     CHECK_AND_RETURN_LOG(PropDefaultMap.find(property) != PropDefaultMap.end(),
738         "SetMtpOneDefaultlPropList property not found in PropDefaultMap");
739     auto propType = PropDefaultMap.at(property);
740     auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
741     Property prop(property, properType);
742     CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
743 
744     prop.handle_ = handle;
745     switch (propType) {
746         case INTTYPE16:
747             prop.currentValue->bin_.i16 = 0;
748             break;
749         case INTTYPE128:
750             prop.currentValue->bin_.i128[OFFSET_0] = static_cast<int32_t>(handle);
751             prop.currentValue->bin_.i128[OFFSET_1] = 0;
752             prop.currentValue->bin_.i128[OFFSET_2] = 0;
753             prop.currentValue->bin_.i128[OFFSET_3] = 0;
754             break;
755         case STRINGTYPE:
756             prop.currentValue->str_ = make_shared<string>("");
757             break;
758         default:
759             prop.currentValue->bin_.i32 = DEFAULT_STORAGE_ID;
760             break;
761     }
762     outProps->push_back(prop);
763 }
764 
GetMediaTypeByName(std::string & displayName,MediaType & outMediaType)765 int32_t MtpDataUtils::GetMediaTypeByName(std::string &displayName, MediaType &outMediaType)
766 {
767     size_t displayNameIndex = displayName.find_last_of('.');
768     std::string extension;
769     if (displayNameIndex != std::string::npos) {
770         extension = displayName.substr(displayNameIndex);
771         transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
772     } else {
773         MEDIA_ERR_LOG("is dir displayName");
774         outMediaType = MEDIA_TYPE_ALBUM;
775         return E_SUCCESS;
776     }
777     uint16_t format;
778     for (auto pair : FormatMap) {
779         if ((pair.second).find(extension) != std::string::npos) {
780             format = pair.first;
781             break;
782         } else {
783             format = MTP_FORMAT_UNDEFINED_CODE;
784         }
785     }
786     if (UndefinedImageFormatSet.find(extension) != UndefinedImageFormatSet.end()) {
787         format = MTP_FORMAT_DEFINED_CODE;
788     } else if (UndefinedVideoFormatSet.find(extension) != UndefinedVideoFormatSet.end()) {
789         format = MTP_FORMAT_UNDEFINED_VIDEO_CODE;
790     }
791     GetMediaTypeByformat(format, outMediaType);
792     MEDIA_DEBUG_LOG("GetMediaTypeByName format:%{public}x, outMediaType:%{public}d", format, outMediaType);
793     return E_SUCCESS;
794 }
795 
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)796 int32_t MtpDataUtils::GetMtpPropList(const std::shared_ptr<std::unordered_map<uint32_t, std::string>> &handles,
797     const std::unordered_map<std::string, uint32_t> &pathHandles,
798     const std::shared_ptr<MtpOperationContext> &context, shared_ptr<vector<Property>> &outProps)
799 {
800     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
801     CHECK_AND_RETURN_RET_LOG(handles != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "handles is nullptr");
802     for (auto it = handles->begin(); it != handles->end(); it++) {
803         shared_ptr<UInt16List> properties = make_shared<UInt16List>();
804         CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "properties is nullptr");
805 
806         if (context->property == MTP_PROPERTY_ALL_CODE) {
807             shared_ptr<MtpOperationContext> mtpContext = make_shared<MtpOperationContext>();
808             CHECK_AND_RETURN_RET_LOG(mtpContext != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "mtpContext is nullptr");
809 
810             if (context->format == 0) {
811                 GetMtpFormatByPath(it->second, mtpContext->format);
812             } else {
813                 mtpContext->format = context->format;
814             }
815             shared_ptr<GetObjectPropsSupportedData> payLoadData = make_shared<GetObjectPropsSupportedData>(mtpContext);
816             CHECK_AND_RETURN_RET_LOG(payLoadData != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "payLoadData is nullptr");
817 
818             payLoadData->GetObjectProps(*properties);
819         } else {
820             properties->push_back(context->property);
821         }
822         if (properties->size() == 0) {
823             MEDIA_ERR_LOG("MtpDataUtils::GetMtpPropList properties is empty");
824             return MTP_INVALID_OBJECTPROPCODE_CODE;
825         }
826 
827         uint32_t parentId = DEFAULT_STORAGE_ID;
828         auto iterator = pathHandles.find(std::filesystem::path(it->second).parent_path().string());
829         if (iterator != pathHandles.end()) {
830             parentId = iterator->second;
831         } else {
832             parentId = 0;
833         }
834         GetMtpOneRowProp(properties, parentId, it, outProps, context->storageID);
835     }
836     return MTP_SUCCESS;
837 }
838 
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)839 void MtpDataUtils::GetMtpOneRowProp(const std::shared_ptr<UInt16List> &properties, const uint32_t parentId,
840     std::unordered_map<uint32_t, std::string>::iterator it, shared_ptr<vector<Property>> &outProps, int32_t storageId)
841 {
842     CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
843     CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
844 
845     std::string column;
846     ResultSetDataType type;
847     for (uint16_t property : *properties) {
848         if (PropColumnMap.find(property) != PropColumnMap.end()) {
849             auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
850             Property prop(property, properType);
851             CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
852 
853             prop.handle_ = it->first;
854             column = PropColumnMap.at(property);
855             type = ColumnTypeMap.at(column);
856             if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
857                 uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
858                 GetMtpFormatByPath(it->second, format);
859                 prop.currentValue->bin_.ui16 = format;
860             } else if (column.compare(MEDIA_DATA_DB_PARENT_ID) == 0) {
861                 prop.currentValue->bin_.ui32 = parentId;
862             } else {
863                 SetMtpProperty(column, it->second, type, prop);
864             }
865             outProps->push_back(prop);
866         } else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
867             SetMtpOneDefaultlPropList(it->first, property, outProps, storageId);
868         } else {
869             MEDIA_DEBUG_LOG("other property:0x%{public}x", property);
870         }
871     }
872 }
873 
GetMtpFormatByPath(const std::string & path,uint16_t & outFormat)874 uint32_t MtpDataUtils::GetMtpFormatByPath(const std::string &path, uint16_t &outFormat)
875 {
876     outFormat = MTP_FORMAT_UNDEFINED_CODE;
877     CHECK_AND_RETURN_RET_LOG(!path.empty(), MTP_ERROR_INVALID_OBJECTPROP_VALUE, "path is nullptr");
878     CHECK_AND_RETURN_RET_LOG(access(path.c_str(), R_OK) == 0, E_ERR, "access failed path[%{public}s]", path.c_str());
879     if (std::filesystem::is_directory(path)) {
880         outFormat = MTP_FORMAT_ASSOCIATION_CODE;
881         return MTP_SUCCESS;
882     }
883 
884     std::filesystem::path filePath(path);
885     CHECK_AND_RETURN_RET(filePath.filename().has_extension(), MTP_ERROR_INVALID_OBJECTPROP_VALUE);
886     // ↑ has_extension already checked for file extension
887     std::string extension = filePath.filename().extension().c_str();
888     for (auto it = FormatMap.begin(); it != FormatMap.end(); it++) {
889         if (it->second.compare(extension) != 0) {
890             continue;
891         }
892         // outFormat should also be in 'Playback Formats' return array of GetDeviceInfo cmd
893         uint16_t size = sizeof(PLAYBACK_FORMATS) / sizeof(uint16_t);
894         for (uint16_t i = 0; i < size; i++) {
895             if (it->first == PLAYBACK_FORMATS[i]) {
896                 outFormat = it->first;
897                 return MTP_SUCCESS;
898             }
899         }
900     }
901     if (extension.compare(MTP_FORMAT_JPG) == 0 || extension.compare(MTP_FORMAT_JPEG) == 0) {
902         outFormat = MTP_FORMAT_EXIF_JPEG_CODE;
903         return MTP_SUCCESS;
904     }
905     return MTP_ERROR_INVALID_OBJECTPROP_VALUE;
906 }
907 
SetMtpProperty(const std::string & column,const std::string & path,ResultSetDataType & type,Property & prop)908 void MtpDataUtils::SetMtpProperty(const std::string &column, const std::string &path,
909     ResultSetDataType &type, Property &prop)
910 {
911     CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
912 
913     if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
914         prop.currentValue->str_ = make_shared<std::string>(std::filesystem::path(path).filename().string());
915         return;
916     }
917     struct stat statInfo;
918     CHECK_AND_RETURN_LOG(stat(path.c_str(), &statInfo) == 0, "SetMtpProperty stat failed");
919     if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
920         prop.currentValue->bin_.i64 = statInfo.st_size;
921         return;
922     }
923     if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
924         prop.currentValue->str_ = make_shared<std::string>(MtpPacketTool::FormatDateTime((statInfo.st_mtime)));
925         return;
926     }
927     if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
928         prop.currentValue->bin_.i64 = statInfo.st_ctime;
929         return;
930     }
931     if (column.compare(MEDIA_DATA_DB_DESCRIPTION) == 0) {
932         prop.currentValue->str_ = make_shared<std::string>("");
933         return;
934     }
935     if (column.compare(MEDIA_DATA_DB_DURATION) == 0) {
936         prop.currentValue->bin_.ui32 = 0;
937         return;
938     }
939     if (column.compare(MEDIA_DATA_DB_ARTIST) == 0) {
940         prop.currentValue->str_ = make_shared<std::string>("");
941         return;
942     }
943     if (column.compare(MEDIA_DATA_DB_ALBUM_NAME) == 0) {
944         prop.currentValue->str_ = make_shared<std::string>("");
945         return;
946     }
947     if (column.compare(MEDIA_DATA_DB_COMPOSER) == 0) {
948         prop.currentValue->str_ = make_shared<std::string>("");
949         return;
950     }
951 }
952 
SetPtpProperty(const std::string & column,const std::string & path,const MovingType & movingType,Property & prop)953 void MtpDataUtils::SetPtpProperty(const std::string &column, const std::string &path, const MovingType &movingType,
954     Property &prop)
955 {
956     CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
957 
958     std::string displayName = movingType.displayName;
959     if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
960         std::string filename = std::filesystem::path(path).filename();
961         size_t filename_pos = filename.find_last_of('.');
962         CHECK_AND_RETURN_LOG(filename_pos != std::string::npos, "get file name failed");
963         size_t displayName_pos = displayName.find_last_of('.');
964         CHECK_AND_RETURN_LOG(displayName_pos != std::string::npos, "get displayName name failed");
965         std::string value;
966         CHECK_AND_RETURN_LOG(filename_pos + 1 < filename.size(), "get fileName failed");
967         value = displayName.substr(0, displayName_pos) + "." + filename.substr(filename_pos + 1);
968         prop.currentValue->str_ = make_shared<std::string>(value);
969     }
970     if (column.compare(MEDIA_DATA_DB_PARENT_ID) == 0) {
971         prop.currentValue->bin_.i64 = movingType.parent;
972     }
973 
974     struct stat statInfo;
975     CHECK_AND_RETURN_LOG(stat(path.c_str(), &statInfo) == 0, "SetMtpProperty stat failed");
976     if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
977         prop.currentValue->bin_.i64 = statInfo.st_size;
978     }
979     if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
980         prop.currentValue->str_ = make_shared<std::string>(MtpPacketTool::FormatDateTime((statInfo.st_mtime)));
981     }
982     if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
983         prop.currentValue->bin_.i64 = statInfo.st_ctime;
984     }
985 }
986 
GetMovingOrEnditSourcePath(const std::string & path,const int32_t & subtype,const shared_ptr<MtpOperationContext> & context)987 string MtpDataUtils::GetMovingOrEnditSourcePath(const std::string &path, const int32_t &subtype,
988     const shared_ptr<MtpOperationContext> &context)
989 {
990     string sourcePath;
991     CHECK_AND_RETURN_RET_LOG(context != nullptr, sourcePath, "context is nullptr");
992 
993     MEDIA_INFO_LOG("mtp GetMovingOrEnditSourcePath path:%{public}s", path.c_str());
994     if (static_cast<int32_t>(context->handle / COMMON_PHOTOS_OFFSET) == MOVING_PHOTO_TYPE) {
995         sourcePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(path);
996     }
997     MEDIA_INFO_LOG("Mtp GetMovingOrEnditSourcePath sourcePath:%{public}s", sourcePath.c_str());
998     return sourcePath;
999 }
1000 
GetMtpPropValue(const std::string & path,const uint32_t property,const uint16_t format,PropertyValue & outPropValue)1001 int32_t MtpDataUtils::GetMtpPropValue(const std::string &path,
1002     const uint32_t property, const uint16_t format, PropertyValue &outPropValue)
1003 {
1004     CHECK_AND_RETURN_RET_LOG(PropColumnMap.find(property) != PropColumnMap.end(), MTP_ERROR_INVALID_OBJECTPROP_VALUE,
1005         "Can not support this property");
1006 
1007     std::string column = PropColumnMap.at(property);
1008     if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
1009         outPropValue.outStrVal = std::filesystem::path(path).filename().string();
1010         return MTP_SUCCESS;
1011     }
1012 
1013     struct stat statInfo;
1014     CHECK_AND_RETURN_RET_LOG(stat(path.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
1015         "GetMtpPropValue stat failed");
1016     if (column.compare(MEDIA_DATA_DB_SIZE) == 0) {
1017         outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
1018         return MTP_SUCCESS;
1019     }
1020     if (column.compare(MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
1021         outPropValue.outStrVal = Strftime("%Y-%m-%d %H:%M:%S", statInfo.st_mtime);
1022         return MTP_SUCCESS;
1023     }
1024     if (column.compare(MEDIA_DATA_DB_DATE_ADDED) == 0) {
1025         outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_ctime);
1026     }
1027 
1028     return MTP_SUCCESS;
1029 }
1030 
SetMtpOneDefaultlPropList(uint32_t handle,uint16_t property,std::shared_ptr<std::vector<Property>> & outProps,int32_t storageId)1031 void MtpDataUtils::SetMtpOneDefaultlPropList(uint32_t handle,
1032     uint16_t property, std::shared_ptr<std::vector<Property>> &outProps, int32_t storageId)
1033 {
1034     CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
1035     CHECK_AND_RETURN_LOG(PropDefaultMap.find(property) != PropDefaultMap.end(),
1036         "SetMtpOneDefaultlPropList property not found in PropDefaultMap");
1037     auto propType = PropDefaultMap.at(property);
1038     auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
1039     Property prop(property, properType);
1040     CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
1041     prop.handle_ = handle;
1042     switch (propType) {
1043         case INTTYPE16:
1044             prop.currentValue->bin_.i16 = 0;
1045             break;
1046         case INTTYPE128:
1047             prop.currentValue->bin_.i128[OFFSET_0] = static_cast<int32_t>(handle);
1048             prop.currentValue->bin_.i128[OFFSET_1] = 0;
1049             prop.currentValue->bin_.i128[OFFSET_2] = 0;
1050             prop.currentValue->bin_.i128[OFFSET_3] = 0;
1051             break;
1052         case STRINGTYPE:
1053             prop.currentValue->str_ = make_shared<string>("");
1054             break;
1055         default:
1056             prop.currentValue->bin_.i32 = storageId;
1057             break;
1058     }
1059     outProps->push_back(prop);
1060 }
1061 
GetGalleryPropList(const std::shared_ptr<MtpOperationContext> & context,std::shared_ptr<std::vector<Property>> & outProps,const std::string & name)1062 int32_t MtpDataUtils::GetGalleryPropList(const std::shared_ptr<MtpOperationContext> &context,
1063     std::shared_ptr<std::vector<Property>> &outProps, const std::string &name)
1064 {
1065     CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
1066     CHECK_AND_RETURN_RET_LOG(outProps != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "outProps is nullptr");
1067     auto properties = std::make_shared<UInt16List>();
1068     CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "properties is nullptr");
1069     if (context->property == MTP_PROPERTY_ALL_CODE) {
1070         auto mtpContext = std::make_shared<MtpOperationContext>();
1071         CHECK_AND_RETURN_RET_LOG(mtpContext != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "mtpContext is nullptr");
1072         mtpContext->format = (context->format == 0) ? MTP_FORMAT_ASSOCIATION_CODE : context->format;
1073 
1074         auto payLoadData = std::make_shared<GetObjectPropsSupportedData>(mtpContext);
1075         CHECK_AND_RETURN_RET_LOG(payLoadData != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "payLoadData is nullptr");
1076         payLoadData->GetObjectProps(*properties);
1077     } else {
1078         properties->push_back(context->property);
1079     }
1080     CHECK_AND_RETURN_RET_LOG(properties->size() > 0, MTP_INVALID_OBJECTPROPCODE_CODE, "properties is empty");
1081 
1082     std::string column;
1083     for (uint16_t property : *properties) {
1084         if (PropColumnMap.find(property) != PropColumnMap.end()) {
1085             auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
1086             Property prop(property, properType);
1087             CHECK_AND_RETURN_RET_LOG(prop.currentValue != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "prop is nullptr");
1088 
1089             prop.handle_ = PTP_IN_MTP_ID;
1090             column = PropColumnMap.at(property);
1091             if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
1092                 prop.currentValue->bin_.ui16 = MTP_FORMAT_ASSOCIATION_CODE;
1093             } else if (column.compare(MEDIA_DATA_DB_PARENT_ID) == 0) {
1094                 prop.currentValue->bin_.ui32 = DEFAULT_PARENT_ROOT;
1095             } else if (column.compare(MEDIA_DATA_DB_NAME) == 0) {
1096                 prop.currentValue->str_ = std::make_shared<std::string>(name);
1097             } else {
1098                 continue;
1099             }
1100             outProps->push_back(prop);
1101         } else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
1102             SetMtpOneDefaultlPropList(PTP_IN_MTP_ID, property, outProps, DEFAULT_STORAGE_ID);
1103         } else {
1104             MEDIA_DEBUG_LOG("other property:0x%{public}x", property);
1105         }
1106     }
1107     return MTP_SUCCESS;
1108 }
1109 
IsNumber(const string & str)1110 bool MtpDataUtils::IsNumber(const string& str)
1111 {
1112     CHECK_AND_RETURN_RET_LOG(!str.empty(), false, "IsNumber input is empty");
1113     for (char const& c : str) {
1114         CHECK_AND_RETURN_RET(isdigit(c) != 0, false);
1115     }
1116     return true;
1117 }
1118 
IsMtpMovingPhoto(int32_t subtype,int32_t effectMode)1119 bool MtpDataUtils::IsMtpMovingPhoto(int32_t subtype, int32_t effectMode)
1120 {
1121     return (subtype == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO) ||
1122         effectMode == static_cast<int32_t>(MovingPhotoEffectMode::IMAGE_ONLY));
1123 }
1124 } // namespace Media
1125 } // namespace OHOS
1126