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