* Copyright (C) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define MLOG_TAG "MtpDataUtils"
#include <map>
#include <filesystem>
#include <sys/stat.h>
#include <sys/types.h>
#include "medialibrary_errno.h"
#include "medialibrary_db_const.h"
#include "media_file_utils.h"
#include "media_log.h"
#include "media_mtp_utils.h"
#include "mtp_data_utils.h"
#include "mtp_constants.h"
#include "mtp_manager.h"
#include "mtp_packet_tools.h"
#include "mtp_ptp_const.h"
#include "payload_data/get_object_props_supported_data.h"
#include "payload_data.h"
#include "rdb_errno.h"
#include "playback_formats.h"
#include "moving_photo_file_utils.h"
#include "ptp_special_handles.h"
using namespace std;
namespace OHOS {
namespace Media {
struct NormalProperty {
int32_t intValue;
string strValue;
};
static constexpr int32_t INTTYPE16 = 16;
static constexpr int32_t INTTYPE128 = 128;
static constexpr int32_t STRINGTYPE = -1;
static const string MEDIA_DATA_DB_FORMAT = "format";
static const string MEDIA_DATA_DB_COMPOSER = "composer";
static constexpr int32_t MOVING_PHOTO_TYPE = 3;
static constexpr int64_t MILLI_TO_SECOND = 1000;
static const string PARENT = "parent";
constexpr int32_t PARENT_ROOT_ID = 0;
static const map<uint16_t, string> FormatMap = {
{ 0, MTP_FORMAT_ALL},
{ MTP_FORMAT_UNDEFINED_CODE, MTP_FORMAT_UNDEFINED },
{ MTP_FORMAT_ASSOCIATION_CODE, MTP_FORMAT_ASSOCIATION },
{ MTP_FORMAT_SCRIPT_CODE, MTP_FORMAT_SCRIPT },
{ MTP_FORMAT_EXECUTABLE_CODE, MTP_FORMAT_EXECUTABLE },
{ MTP_FORMAT_TEXT_CODE, MTP_FORMAT_TEXT },
{ MTP_FORMAT_DPOF_CODE, MTP_FORMAT_DPOF },
{ MTP_FORMAT_AIFF_CODE, MTP_FORMAT_AIFF },
{ MTP_FORMAT_WAV_CODE, MTP_FORMAT_WAV },
{ MTP_FORMAT_HTML_CODE, MTP_FORMAT_HTML },
{ MTP_FORMAT_MP3_CODE, MTP_FORMAT_MP3 },
{ MTP_FORMAT_AVI_CODE, MTP_FORMAT_AVI },
{ MTP_FORMAT_MPEG_CODE, MTP_FORMAT_MPEG },
{ MTP_FORMAT_DEFINED_CODE, MTP_FORMAT_DEFINED },
{ MTP_FORMAT_EXIF_JPEG_CODE, MTP_FORMAT_EXIF_JPEG },
{ MTP_FORMAT_FLASHPIX_CODE, MTP_FORMAT_FLASHPIX },
{ MTP_FORMAT_BMP_CODE, MTP_FORMAT_BMP },
{ MTP_FORMAT_CIFF_CODE, MTP_FORMAT_CIFF },
{ MTP_FORMAT_GIF_CODE, MTP_FORMAT_GIF },
{ MTP_FORMAT_JFIF_CODE, MTP_FORMAT_JFIF },
{ MTP_FORMAT_CD_CODE, MTP_FORMAT_CD },
{ MTP_FORMAT_PICT_CODE, MTP_FORMAT_PICT },
{ MTP_FORMAT_PNG_CODE, MTP_FORMAT_PNG },
{ MTP_FORMAT_TIFF_CODE, MTP_FORMAT_TIFF },
{ MTP_FORMAT_JP2_CODE, MTP_FORMAT_JP2 },
{ MTP_FORMAT_JPX_CODE, MTP_FORMAT_JPX },
{ MTP_FORMAT_UNDEFINED_FIRMWARE_CODE, MTP_FORMAT_UNDEFINED_FIRMWARE },
{ MTP_FORMAT_WINDOWS_IMAGE_FORMAT_CODE, MTP_FORMAT_WINDOWS_IMAGE_FORMAT },
{ MTP_FORMAT_UNDEFINED_AUDIO_CODE, MTP_FORMAT_UNDEFINED_AUDIO },
{ MTP_FORMAT_WMA_CODE, MTP_FORMAT_WMA },
{ MTP_FORMAT_OGG_CODE, MTP_FORMAT_OGG },
{ MTP_FORMAT_AAC_CODE, MTP_FORMAT_AAC },
{ MTP_FORMAT_AUDIBLE_CODE, MTP_FORMAT_AUDIBLE },
{ MTP_FORMAT_FLAC_CODE, MTP_FORMAT_FLAC },
{ MTP_FORMAT_UNDEFINED_VIDEO_CODE, MTP_FORMAT_UNDEFINED_VIDEO },
{ MTP_FORMAT_WMV_CODE, MTP_FORMAT_WMV },
{ MTP_FORMAT_MP4_CONTAINER_CODE, MTP_FORMAT_MP4_CONTAINER },
{ MTP_FORMAT_MP2_CODE, MTP_FORMAT_MP2 },
{ MTP_FORMAT_3GP_CONTAINER_CODE, MTP_FORMAT_3GP_CONTAINER },
{ MTP_FORMAT_UNDEFINED_COLLECTION_CODE, MTP_FORMAT_UNDEFINED_COLLECTION },
{ MTP_FORMAT_ABSTRACT_MULTIMEDIA_ALBUM_CODE, MTP_FORMAT_ABSTRACT_MULTIMEDIA_ALBUM },
{ MTP_FORMAT_ABSTRACT_IMAGE_ALBUM_CODE, MTP_FORMAT_ABSTRACT_IMAGE_ALBUM },
{ MTP_FORMAT_ABSTRACT_AUDIO_ALBUM_CODE, MTP_FORMAT_ABSTRACT_AUDIO_ALBUM },
{ MTP_FORMAT_ABSTRACT_VIDEO_ALBUM_CODE, MTP_FORMAT_ABSTRACT_VIDEO_ALBUM },
{ MTP_FORMAT_ABSTRACT_AUDIO_VIDEO_PLAYLIST_CODE, MTP_FORMAT_ABSTRACT_AUDIO_VIDEO_PLAYLIST },
{ MTP_FORMAT_ABSTRACT_CONTACT_GROUP_CODE, MTP_FORMAT_ABSTRACT_CONTACT_GROUP },
{ MTP_FORMAT_ABSTRACT_MESSAGE_FOLDER_CODE, MTP_FORMAT_ABSTRACT_MESSAGE_FOLDER },
{ MTP_FORMAT_ABSTRACT_CHAPTERED_PRODUCTION_CODE, MTP_FORMAT_ABSTRACT_CHAPTERED_PRODUCTION },
{ MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST_CODE, MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST },
{ MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST_CODE, MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST },
{ MTP_FORMAT_ABSTRACT_MEDIACAST_CODE, MTP_FORMAT_ABSTRACT_MEDIACAST },
{ MTP_FORMAT_WPL_PLAYLIST_CODE, MTP_FORMAT_WPL_PLAYLIST },
{ MTP_FORMAT_M3U_PLAYLIST_CODE, MTP_FORMAT_M3U_PLAYLIST },
{ MTP_FORMAT_MPL_PLAYLIST_CODE, MTP_FORMAT_MPL_PLAYLIST },
{ MTP_FORMAT_ASX_PLAYLIST_CODE, MTP_FORMAT_ASX_PLAYLIST },
{ MTP_FORMAT_PLS_PLAYLIST_CODE, MTP_FORMAT_PLS_PLAYLIST },
{ MTP_FORMAT_UNDEFINED_DOCUMENT_CODE, MTP_FORMAT_UNDEFINED_DOCUMENT },
{ MTP_FORMAT_XML_DOCUMENT_CODE, MTP_FORMAT_XML_DOCUMENT },
{ MTP_FORMAT_ABSTRACT_DOCUMENT_CODE, MTP_FORMAT_ABSTRACT_DOCUMENT },
{ MTP_FORMAT_MICROSOFT_WORD_DOCUMENT_CODE, MTP_FORMAT_MICROSOFT_WORD_DOCUMENT },
{ MTP_FORMAT_MHT_COMPILED_HTML_DOCUMENT_CODE, MTP_FORMAT_MHT_COMPILED_HTML_DOCUMENT },
{ MTP_FORMAT_MICROSOFT_EXCEL_SPREADSHEET_CODE, MTP_FORMAT_MICROSOFT_EXCEL_SPREADSHEET },
{ MTP_FORMAT_UNDEFINED_MESSAGE_CODE, MTP_FORMAT_UNDEFINED_MESSAGE },
{ MTP_FORMAT_ABSTRACT_MESSAGE_CODE, MTP_FORMAT_ABSTRACT_MESSAGE },
{ MTP_FORMAT_UNDEFINED_CONTACT_CODE, MTP_FORMAT_UNDEFINED_CONTACT },
{ MTP_FORMAT_ABSTRACT_CONTACT_CODE, MTP_FORMAT_ABSTRACT_CONTACT },
{ MTP_FORMAT_MICROSOFT_POWERPOINT_PRESENTATION_CODE, MTP_FORMAT_MICROSOFT_POWERPOINT_PRESENTATION },
{ MTP_FORMAT_VCARD_2_CODE, MTP_FORMAT_VCARD_2 }
};
static const set<std::string> UndefinedImageFormatSet = {
MTP_FORMAT_HEIC,
MTP_FORMAT_HEICS,
MTP_FORMAT_HEIFS,
MTP_FORMAT_BM,
MTP_FORMAT_HEIF,
MTP_FORMAT_HIF,
MTP_FORMAT_AVIF,
MTP_FORMAT_CUR,
MTP_FORMAT_WEBP,
MTP_FORMAT_DNG,
MTP_FORMAT_RAF,
MTP_FORMAT_ICO,
MTP_FORMAT_NRW,
MTP_FORMAT_RW2,
MTP_FORMAT_PEF,
MTP_FORMAT_SRW,
MTP_FORMAT_ARW,
MTP_FORMAT_SVG,
MTP_FORMAT_RAW,
MTP_FORMAT_IEF,
MTP_FORMAT_JP2,
MTP_FORMAT_JPG2,
MTP_FORMAT_JPM,
MTP_FORMAT_JPX,
MTP_FORMAT_JPF,
MTP_FORMAT_PCX,
MTP_FORMAT_SVGZ,
MTP_FORMAT_TIFF_EP,
MTP_FORMAT_TIFF,
MTP_FORMAT_DJVU,
MTP_FORMAT_DJV,
MTP_FORMAT_ICO,
MTP_FORMAT_WBMP,
MTP_FORMAT_CR2,
MTP_FORMAT_CRW,
MTP_FORMAT_RAS,
MTP_FORMAT_CDR,
MTP_FORMAT_PAT,
MTP_FORMAT_CDT,
MTP_FORMAT_CPT,
MTP_FORMAT_ERF,
MTP_FORMAT_ART,
MTP_FORMAT_JNG,
MTP_FORMAT_NEF,
MTP_FORMAT_ORF,
MTP_FORMAT_PSD,
MTP_FORMAT_PNM,
MTP_FORMAT_PBM,
MTP_FORMAT_PGM,
MTP_FORMAT_PPM,
MTP_FORMAT_RGB,
MTP_FORMAT_XBM,
MTP_FORMAT_XPM,
MTP_FORMAT_XWD
};
static const set<std::string> UndefinedVideoFormatSet = {
MTP_FORMAT_3GPP2,
MTP_FORMAT_3GP2,
MTP_FORMAT_3G2,
MTP_FORMAT_3GPP,
MTP_FORMAT_M4V,
MTP_FORMAT_F4V,
MTP_FORMAT_MP4V,
MTP_FORMAT_MPEG4,
MTP_FORMAT_M2TS,
MTP_FORMAT_MTS,
MTP_FORMAT_TS,
MTP_FORMAT_YT,
MTP_FORMAT_WRF,
MTP_FORMAT_MPEG2,
MTP_FORMAT_MPV2,
MTP_FORMAT_MP2V,
MTP_FORMAT_M2V,
MTP_FORMAT_M2T,
MTP_FORMAT_MPEG1,
MTP_FORMAT_MPV1,
MTP_FORMAT_MP1V,
MTP_FORMAT_M1V,
MTP_FORMAT_MPG,
MTP_FORMAT_MOV,
MTP_FORMAT_MKV,
MTP_FORMAT_WEBM,
MTP_FORMAT_MPEG,
MTP_FORMAT_MPE,
MTP_FORMAT_AVI,
MTP_FORMAT_H264,
MTP_FORMAT_RMVB,
MTP_FORMAT_AXV,
MTP_FORMAT_DL,
MTP_FORMAT_DIF,
MTP_FORMAT_DV,
MTP_FORMAT_DLI,
MTP_FORMAT_GL,
MTP_FORMAT_QT,
MTP_FORMAT_OGV,
MTP_FORMAT_MXU,
MTP_FORMAT_FLV,
MTP_FORMAT_LSF,
MTP_FORMAT_LSX,
MTP_FORMAT_MNG,
MTP_FORMAT_WM,
MTP_FORMAT_WMX,
MTP_FORMAT_MOVIE,
MTP_FORMAT_MPV,
MTP_FORMAT_ASF,
MTP_FORMAT_ASX_PLAYLIST,
MTP_FORMAT_WVX,
MTP_FORMAT_FMP4
};
static const map<std::string, MediaType> FormatAllMap = {
{ MTP_FORMAT_ALL, MEDIA_TYPE_ALL },
{ MTP_FORMAT_ABSTRACT_AUDIO_PLAYLIST, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST, MEDIA_TYPE_VIDEO },
{ MTP_FORMAT_ABSTRACT_VIDEO_PLAYLIST, MEDIA_TYPE_VIDEO },
{ MTP_FORMAT_ASSOCIATION, MEDIA_TYPE_ALBUM }
};
static const map<uint16_t, MediaType> FormatMediaTypeMap = {
{ 0, MEDIA_TYPE_ALL },
{ MTP_FORMAT_UNDEFINED_CODE, MEDIA_TYPE_FILE },
{ MTP_FORMAT_DEFINED_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_EXIF_JPEG_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_FLASHPIX_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_BMP_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_CIFF_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_GIF_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_JFIF_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_CD_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_PICT_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_PNG_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_TIFF_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_JP2_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_JPX_CODE, MEDIA_TYPE_IMAGE },
{ MTP_FORMAT_UNDEFINED_AUDIO_CODE, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_WMA_CODE, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_OGG_CODE, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_AAC_CODE, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_AUDIBLE_CODE, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_FLAC_CODE, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_UNDEFINED_VIDEO_CODE, MEDIA_TYPE_VIDEO },
{ MTP_FORMAT_WMV_CODE, MEDIA_TYPE_VIDEO },
{ MTP_FORMAT_MP4_CONTAINER_CODE, MEDIA_TYPE_VIDEO },
{ MTP_FORMAT_MP3_CODE, MEDIA_TYPE_AUDIO },
{ MTP_FORMAT_MP2_CODE, MEDIA_TYPE_VIDEO },
{ MTP_FORMAT_3GP_CONTAINER_CODE, MEDIA_TYPE_VIDEO },
{ MTP_FORMAT_ASSOCIATION_CODE, MEDIA_TYPE_ALBUM}
};
static const map<uint32_t, std::string> ObjMediaPropMap = {
{ MTP_PROPERTY_OBJECT_FILE_NAME_CODE, CONST_MEDIA_DATA_DB_NAME },
{ MTP_PROPERTY_PARENT_OBJECT_CODE, CONST_MEDIA_DATA_DB_PARENT_ID }
};
static const map<uint16_t, int> ObjMediaPropTypeMap = {
{ MTP_PROPERTY_OBJECT_FILE_NAME_CODE, MTP_TYPE_STRING_CODE },
{ MTP_PROPERTY_PARENT_OBJECT_CODE, MTP_TYPE_UINT32_CODE }
};
static const map<std::string, ResultSetDataType> ColumnTypeMap = {
{ CONST_MEDIA_DATA_DB_ID, TYPE_INT32 },
{ CONST_MEDIA_DATA_DB_SIZE, TYPE_INT64 },
{ CONST_MEDIA_DATA_DB_PARENT_ID, TYPE_INT32 },
{ CONST_MEDIA_DATA_DB_DATE_MODIFIED, TYPE_INT64 },
{ CONST_MEDIA_DATA_DB_DATE_ADDED, TYPE_INT64 },
{ CONST_MEDIA_DATA_DB_NAME, TYPE_STRING },
{ CONST_MEDIA_DATA_DB_DESCRIPTION, TYPE_STRING },
{ CONST_MEDIA_DATA_DB_DURATION, TYPE_INT32 },
{ CONST_MEDIA_DATA_DB_ARTIST, TYPE_STRING },
{ CONST_MEDIA_DATA_DB_AUDIO_ALBUM, TYPE_STRING },
{ MEDIA_DATA_DB_FORMAT, TYPE_INT32 },
{ CONST_MEDIA_DATA_DB_ALBUM_NAME, TYPE_STRING },
{ MEDIA_DATA_DB_COMPOSER, TYPE_STRING },
};
static const map<uint16_t, std::string> PropColumnMap = {
{ MTP_PROPERTY_OBJECT_FORMAT_CODE, MEDIA_DATA_DB_FORMAT },
{ MTP_PROPERTY_OBJECT_SIZE_CODE, CONST_MEDIA_DATA_DB_SIZE },
{ MTP_PROPERTY_OBJECT_FILE_NAME_CODE, CONST_MEDIA_DATA_DB_NAME },
{ MTP_PROPERTY_DATE_MODIFIED_CODE, CONST_MEDIA_DATA_DB_DATE_MODIFIED },
{ MTP_PROPERTY_PARENT_OBJECT_CODE, CONST_MEDIA_DATA_DB_PARENT_ID },
{ MTP_PROPERTY_NAME_CODE, CONST_MEDIA_DATA_DB_NAME },
{ MTP_PROPERTY_DISPLAY_NAME_CODE, CONST_MEDIA_DATA_DB_NAME },
{ MTP_PROPERTY_DATE_ADDED_CODE, CONST_MEDIA_DATA_DB_DATE_ADDED },
{ MTP_PROPERTY_ARTIST_CODE, CONST_MEDIA_DATA_DB_ARTIST },
{ MTP_PROPERTY_DURATION_CODE, CONST_MEDIA_DATA_DB_DURATION },
{ MTP_PROPERTY_DESCRIPTION_CODE, CONST_MEDIA_DATA_DB_DESCRIPTION},
};
static const map<uint16_t, int32_t> PropDefaultMap = {
{ MTP_PROPERTY_STORAGE_ID_CODE, DEFAULT_STORAGE_ID },
{ MTP_PROPERTY_PROTECTION_STATUS_CODE, INTTYPE16 },
{ MTP_PROPERTY_PERSISTENT_UID_CODE, INTTYPE128 },
{ MTP_PROPERTY_ALBUM_NAME_CODE, STRINGTYPE },
{ MTP_PROPERTY_ALBUM_ARTIST_CODE, STRINGTYPE },
{ MTP_PROPERTY_TRACK_CODE, INTTYPE16 },
{ MTP_PROPERTY_ORIGINAL_RELEASE_DATE_CODE, STRINGTYPE },
{ MTP_PROPERTY_GENRE_CODE, STRINGTYPE },
{ MTP_PROPERTY_COMPOSER_CODE, STRINGTYPE },
{ MTP_PROPERTY_AUDIO_WAVE_CODEC_CODE, INTTYPE16 },
{ MTP_PROPERTY_BITRATE_TYPE_CODE, INTTYPE16 },
{ MTP_PROPERTY_AUDIO_BITRATE_CODE, INTTYPE16 },
{ MTP_PROPERTY_NUMBER_OF_CHANNELS_CODE, INTTYPE16 },
{ MTP_PROPERTY_SAMPLE_RATE_CODE, INTTYPE16 },
};
int32_t MtpDataUtils::SolveHandlesFormatData(const uint16_t format, std::string &outExtension, MediaType &outMediaType)
{
CHECK_AND_RETURN_RET_LOG(FormatMap.find(format) != FormatMap.end(), MTP_ERROR_INVALID_OBJECTHANDLE,
"Can not find format");
outExtension = FormatMap.at(format);
if (FormatAllMap.find(outExtension) != FormatAllMap.end()) {
outMediaType = FormatAllMap.at(outExtension);
return MTP_SUCCESS;
}
outMediaType = MEDIA_TYPE_DEFAULT;
return MTP_SUCCESS;
}
int32_t MtpDataUtils::SolveSendObjectFormatData(const uint16_t format, MediaType &outMediaType)
{
if (FormatMediaTypeMap.find(format) == FormatMediaTypeMap.end()) {
MEDIA_ERR_LOG("Can not find format");
outMediaType = MEDIA_TYPE_FILE;
} else {
outMediaType = FormatMediaTypeMap.at(format);
}
return MTP_SUCCESS;
}
int32_t MtpDataUtils::SolveSetObjectPropValueData(const shared_ptr<MtpOperationContext> &context,
std::string &outColName, variant<int64_t, std::string> &outColVal)
{
CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "context is nullptr");
bool cond = ObjMediaPropTypeMap.find(context->property) == ObjMediaPropTypeMap.end();
CHECK_AND_RETURN_RET_LOG(!cond, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "Can not support propertyType");
if (ObjMediaPropMap.find(context->property) == ObjMediaPropMap.end()) {
MEDIA_ERR_LOG("Can not support this property");
return MTP_ERROR_INVALID_OBJECTPROP_VALUE;
} else {
outColName = ObjMediaPropMap.at(context->property);
}
if (context->properType == MTP_TYPE_STRING_CODE) {
outColVal = context->properStrValue;
MEDIA_INFO_LOG("context->properStrValue = %{public}s", context->properStrValue.c_str());
} else {
outColVal = context->properIntValue;
}
return MTP_SUCCESS;
}
void MtpDataUtils::GetMediaTypeByformat(const uint16_t format, MediaType &outMediaType)
{
outMediaType = MEDIA_TYPE_DEFAULT;
if (FormatMediaTypeMap.find(format) != FormatMediaTypeMap.end()) {
outMediaType = FormatMediaTypeMap.at(format);
}
}
int32_t MtpDataUtils::GetPropListBySet(const std::shared_ptr<MtpOperationContext> &context,
const shared_ptr<DataShare::DataShareResultSet> &resultSet, shared_ptr<vector<Property>> &outProps)
{
CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "context is nullptr");
shared_ptr<UInt16List> properties = make_shared<UInt16List>();
CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "properties is nullptr");
if (context->property == MTP_PROPERTY_ALL_CODE) {
shared_ptr<MtpOperationContext> ptpContext = make_shared<MtpOperationContext>();
CHECK_AND_RETURN_RET_LOG(ptpContext != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "ptpContext is nullptr");
ptpContext->format = context->format;
shared_ptr<GetObjectPropsSupportedData> payLoadData = make_shared<GetObjectPropsSupportedData>(ptpContext);
CHECK_AND_RETURN_RET_LOG(payLoadData != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "payLoadData is nullptr");
payLoadData->GetObjectProps(*properties);
} else {
properties->push_back(context->property);
}
return GetPropList(context, resultSet, properties, outProps);
}
uint32_t MtpDataUtils::HandleConvertToDeleted(int32_t realHandle)
{
auto ptpSpecialHandles = PtpSpecialHandles::GetInstance();
CHECK_AND_RETURN_RET_LOG(ptpSpecialHandles != nullptr, E_ERR, "ptpSpecialHandles is nullptr");
uint32_t parentId = ptpSpecialHandles->HandleConvertToDeleted(static_cast<uint32_t>(realHandle));
return parentId;
}
int32_t MtpDataUtils::GetPropList(const std::shared_ptr<MtpOperationContext> &context,
const shared_ptr<DataShare::DataShareResultSet> &resultSet,
const shared_ptr<UInt16List> &properties, shared_ptr<vector<Property>> &outProps)
{
CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "context is nullptr");
CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "resultSet is nullptr");
CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTPROP_VALUE, "properties is nullptr");
int count = 0;
resultSet->GetRowCount(count);
CHECK_AND_RETURN_RET_LOG(count > 0, MTP_ERROR_INVALID_OBJECTHANDLE, "have no row");
CHECK_AND_RETURN_RET(properties->size() != 0, MTP_INVALID_OBJECTPROPCODE_CODE);
ResultSetDataType idType = TYPE_INT32;
for (int32_t row = 0; row < count; row++) {
resultSet->GoToRow(row);
if (context->handle > EDITED_PHOTOS_OFFSET) {
string data = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
string displayName = GetStringVal(MediaColumn::MEDIA_NAME, resultSet);
int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
string path = GetMovingOrEnditSourcePath(data, subtype, context);
int32_t parent = GetInt32Val(PARENT, resultSet);
CHECK_AND_RETURN_RET_LOG(!path.empty(), E_FAIL, "MtpDataUtils::GetPropList get sourcePath failed");
MovingType movingType;
movingType.displayName = displayName;
movingType.parent = static_cast<uint64_t>(HandleConvertToDeleted(parent));
GetMovingOrEnditOneRowPropList(properties, path, context, outProps, movingType);
} else {
MEDIA_INFO_LOG("GetPropList %{public}d",
get<int32_t>(ResultSetUtils::GetValFromColumn(CONST_MEDIA_DATA_DB_ID, resultSet, idType)));
GetOneRowPropList(static_cast<uint32_t>(context->handle), resultSet, properties, outProps);
}
}
return MTP_SUCCESS;
}
void MtpDataUtils::GetMovingOrEnditOneRowPropList(const shared_ptr<UInt16List> &properties, const std::string &path,
const std::shared_ptr<MtpOperationContext> &context, shared_ptr<vector<Property>> &outProps,
const MovingType &movingType)
{
CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
CHECK_AND_RETURN_LOG(context != nullptr, "context is nullptr");
CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
std::string column;
for (uint16_t property : *properties) {
auto it = PropColumnMap.find(property);
if (it != PropColumnMap.end()) {
auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
Property prop(property, properType);
prop.handle_ = context->handle;
column = it->second;
if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
GetMtpFormatByPath(path, format);
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
prop.currentValue->bin_.ui16 = format;
} else {
SetPtpProperty(column, path, movingType, prop);
}
outProps->push_back(prop);
} else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
SetOneDefaultlPropList(context->handle, property, outProps);
}
}
}
variant<int32_t, int64_t, std::string> MtpDataUtils::ReturnError(const std::string &errMsg,
const ResultSetDataType &type)
{
MEDIA_ERR_LOG("%{public}s", errMsg.c_str());
if ((type) == TYPE_STRING) {
return "";
} else {
return 0;
}
}
void MtpDataUtils::GetFormatByPath(const std::string &path, uint16_t &outFormat)
{
CHECK_AND_RETURN_LOG(!path.empty(), "path is nullptr");
if (MediaFileUtils::IsDirectory(path)) {
MEDIA_ERR_LOG("path is dir");
outFormat = MTP_FORMAT_ASSOCIATION_CODE;
return;
}
size_t slashIndex = path.rfind('/');
std::string displayName;
if (slashIndex != std::string::npos) {
displayName = path.substr(slashIndex + 1);
}
size_t extensionIndex = displayName.rfind(".");
std::string extension;
if (extensionIndex != std::string::npos) {
extension = displayName.substr(extensionIndex);
} else {
MEDIA_ERR_LOG("get extensionIndex failed");
outFormat = MTP_FORMAT_UNDEFINED_CODE;
return;
}
for (auto pair : FormatMap) {
if ((pair.second).find(extension) != std::string::npos) {
outFormat = pair.first;
break;
}
}
}
int32_t MtpDataUtils::GetFormat(const shared_ptr<DataShare::DataShareResultSet> &resultSet,
uint16_t &outFormat)
{
CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, E_FAIL, "resultSet is nullptr");
int index;
int status;
int mediaType;
status = resultSet->GetColumnIndex(CONST_MEDIA_DATA_DB_MEDIA_TYPE, index);
CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetColumnIndex failed");
resultSet->GetInt(index, mediaType);
if (mediaType == MEDIA_TYPE_ALBUM) {
outFormat = MTP_FORMAT_ASSOCIATION_CODE;
return E_SUCCESS;
}
status = resultSet->GetColumnIndex(CONST_MEDIA_DATA_DB_FILE_PATH, index);
CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetColumnIndex failed");
std::string pathVal;
status = resultSet->GetString(index, pathVal);
CHECK_AND_RETURN_RET_LOG(status == NativeRdb::E_OK, E_FAIL, "GetString failed");
CHECK_AND_RETURN_RET_LOG(!pathVal.empty(), E_FAIL, "path is empty");
GetFormatByPath(pathVal, outFormat);
return E_SUCCESS;
}
void LocalTime(struct tm &t, time_t curTime)
{
time_t curTimeTemp = curTime;
if (curTimeTemp == 0) {
curTimeTemp = time(nullptr);
}
auto tm = localtime(&curTimeTemp);
if (tm) {
t = *tm;
}
}
std::string Strftime(const std::string &format, time_t curTime)
{
if (format.empty()) {
return format;
}
struct tm t = {};
LocalTime(t, curTime);
char szDTime[32] = "";
(void)strftime(szDTime, sizeof(szDTime), format.c_str(), &t);
return szDTime;
}
void MtpDataUtils::SetProperty(const std::string &column, const shared_ptr<DataShare::DataShareResultSet> &resultSet,
ResultSetDataType &type, Property &prop)
{
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
variant<int32_t, std::string, int64_t, double> columnValue =
ResultSetUtils::GetValFromColumn(column, resultSet, type);
switch (type) {
case TYPE_STRING:
prop.currentValue->str_ = make_shared<std::string>(get<std::string>(columnValue));
break;
case TYPE_INT32:
if (column.compare(CONST_MEDIA_DATA_DB_PARENT_ID) == 0) {
prop.currentValue->bin_.i32 = static_cast<int32_t>(HandleConvertToDeleted(get<int32_t>(columnValue)));
} else {
prop.currentValue->bin_.i32 = get<int32_t>(columnValue);
}
{
bool isParent = column.compare(CONST_MEDIA_DATA_DB_PARENT_ID) == 0;
if (isParent && MtpManager::GetInstance().IsMtpMode() && prop.currentValue->bin_.i32 == 0) {
prop.currentValue->bin_.i32 = PTP_IN_MTP_ID;
}
}
break;
case TYPE_INT64:
if (column.compare(CONST_MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
prop.currentValue->str_ = make_shared<std::string>(
MtpPacketTool::FormatDateTime(get<int64_t>(columnValue) / MILLI_TO_SECOND));
} else {
prop.currentValue->bin_.i64 = get<int64_t>(columnValue);
}
break;
default:
break;
}
}
static bool IsUseStoragePath(int32_t type)
{
return type == static_cast<int32_t>(FileSourceType::FILE_MANAGER) ||
type == static_cast<int32_t>(FileSourceType::MEDIA_HO_LAKE);
}
void MtpDataUtils::GetOneRowPropList(uint32_t handle, const shared_ptr<DataShare::DataShareResultSet> &resultSet,
const shared_ptr<UInt16List> &properties, shared_ptr<vector<Property>> &outProps)
{
CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
std::string column;
ResultSetDataType type;
auto parentId = GetInt32Val(PARENT, resultSet);
for (uint16_t property : *properties) {
if (PropColumnMap.find(property) != PropColumnMap.end()) {
auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
Property prop(property, properType);
prop.handle_ = handle;
column = PropColumnMap.at(property);
type = ColumnTypeMap.at(column);
if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
GetFormat(resultSet, format);
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
prop.currentValue->bin_.ui16 = format;
MEDIA_INFO_LOG("prop.currentValue->bin_.ui16 %{public}u", format);
} else if (column.compare(CONST_MEDIA_DATA_DB_SIZE) == 0 &&
parentId != PARENT_ROOT_ID && parentId != FILE_MANAGER_IN_PTP_ID) {
int32_t type = GetInt32Val(PhotoColumn::PHOTO_FILE_SOURCE_TYPE, resultSet);
string filePath = IsUseStoragePath(type) ? GetStringVal(PhotoColumn::PHOTO_STORAGE_PATH, resultSet) :
GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
struct stat statInfo;
CHECK_AND_RETURN_LOG(stat(filePath.c_str(), &statInfo) == 0, "GetOneRowPropList stat failed");
prop.currentValue->bin_.i64 = statInfo.st_size;
} else {
SetProperty(column, resultSet, type, prop);
}
outProps->push_back(prop);
} else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
SetOneDefaultlPropList(handle, property, outProps);
}
}
}
int32_t MtpDataUtils::GetPropValueForVideoOfMovingPhoto(const std::string &path,
const uint32_t property, PropertyValue &outPropValue)
{
CHECK_AND_RETURN_RET_LOG(PropColumnMap.find(property) != PropColumnMap.end(), MTP_ERROR_INVALID_OBJECTPROP_VALUE,
"Can not support this property");
std::string column = PropColumnMap.at(property);
if (column.compare(CONST_MEDIA_DATA_DB_NAME) == 0) {
outPropValue.outStrVal = std::filesystem::path(path).filename().string();
return MTP_SUCCESS;
}
struct stat statInfo;
CHECK_AND_RETURN_RET_LOG(stat(path.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
"GetPropValueForMovingMp4 stat failed");
if (column.compare(CONST_MEDIA_DATA_DB_SIZE) == 0) {
outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
return MTP_SUCCESS;
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
outPropValue.outStrVal = Strftime("%Y-%m-%d %H:%M:%S", statInfo.st_mtime);
return MTP_SUCCESS;
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_ADDED) == 0) {
outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_ctime);
}
return MTP_SUCCESS;
}
int32_t MtpDataUtils::GetPropValueBySet(const uint32_t property,
const shared_ptr<DataShare::DataShareResultSet> &resultSet, PropertyValue &outPropValue, bool isVideoOfMovingPhoto)
{
CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "resultSet is nullptr");
CHECK_AND_RETURN_RET(resultSet->GoToFirstRow() == 0, MTP_ERROR_INVALID_OBJECTHANDLE);
if (isVideoOfMovingPhoto && property != MTP_PROPERTY_PARENT_OBJECT_CODE) {
string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
string mp4FilePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(filePath);
return GetPropValueForVideoOfMovingPhoto(mp4FilePath, property, outPropValue);
}
int32_t subtype = GetInt32Val(PhotoColumn::PHOTO_SUBTYPE, resultSet);
int32_t effectMode = GetInt32Val(PhotoColumn::MOVING_PHOTO_EFFECT_MODE, resultSet);
if (IsMtpMovingPhoto(subtype, effectMode) && property == MTP_PROPERTY_OBJECT_SIZE_CODE) {
string filePath = GetStringVal(MediaColumn::MEDIA_FILE_PATH, resultSet);
struct stat statInfo;
CHECK_AND_RETURN_RET_LOG(stat(filePath.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
"GetPropValueBySet stat failed");
outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
return MTP_SUCCESS;
}
if (PropColumnMap.find(property) != PropColumnMap.end()) {
std::string column = PropColumnMap.at(property);
ResultSetDataType type = ColumnTypeMap.at(column);
variant<int32_t, std::string, int64_t, double> columnValue =
ResultSetUtils::GetValFromColumn(column, resultSet, type);
switch (type) {
case TYPE_STRING:
outPropValue.outStrVal = get<std::string>(columnValue);
break;
case TYPE_INT32:
if (column.compare(CONST_MEDIA_DATA_DB_PARENT_ID) == 0) {
outPropValue.outIntVal = static_cast<uint64_t>(HandleConvertToDeleted(get<int32_t>(columnValue)));
break;
}
outPropValue.outIntVal = static_cast<uint64_t>(get<int32_t>(columnValue));
break;
case TYPE_INT64:
if (column.compare(CONST_MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
std::string timeFormat = "%Y-%m-%d %H:%M:%S";
outPropValue.outStrVal = Strftime(timeFormat, (get<int64_t>(columnValue) / MILLI_TO_SECOND));
} else {
outPropValue.outIntVal = static_cast<uint64_t>(get<int64_t>(columnValue));
}
break;
default:
break;
}
}
return MTP_SUCCESS;
}
void MtpDataUtils::SetOneDefaultlPropList(uint32_t handle, uint16_t property, shared_ptr<vector<Property>> &outProps)
{
CHECK_AND_RETURN_LOG(PropDefaultMap.find(property) != PropDefaultMap.end(),
"SetMtpOneDefaultlPropList property not found in PropDefaultMap");
auto propType = PropDefaultMap.at(property);
auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
Property prop(property, properType);
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
prop.handle_ = handle;
switch (propType) {
case INTTYPE16:
prop.currentValue->bin_.i16 = 0;
break;
case INTTYPE128:
prop.currentValue->bin_.i128[OFFSET_0] = static_cast<int32_t>(handle);
prop.currentValue->bin_.i128[OFFSET_1] = 0;
prop.currentValue->bin_.i128[OFFSET_2] = 0;
prop.currentValue->bin_.i128[OFFSET_3] = 0;
break;
case STRINGTYPE:
prop.currentValue->str_ = make_shared<string>("");
break;
default:
prop.currentValue->bin_.i32 = DEFAULT_STORAGE_ID;
break;
}
outProps->push_back(prop);
}
int32_t MtpDataUtils::GetMediaTypeByName(std::string &displayName, MediaType &outMediaType)
{
CHECK_AND_RETURN_RET_LOG(!displayName.empty(), E_ERR, "displayName is empty");
size_t displayNameIndex = displayName.find_last_of('.');
std::string extension;
if (displayNameIndex != std::string::npos) {
extension = displayName.substr(displayNameIndex);
transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
} else {
MEDIA_ERR_LOG("is dir displayName");
outMediaType = MEDIA_TYPE_ALBUM;
return E_SUCCESS;
}
uint16_t format;
for (auto pair : FormatMap) {
if ((pair.second).find(extension) != std::string::npos) {
format = pair.first;
break;
} else {
format = MTP_FORMAT_UNDEFINED_CODE;
}
}
if (UndefinedImageFormatSet.find(extension) != UndefinedImageFormatSet.end()) {
format = MTP_FORMAT_DEFINED_CODE;
} else if (UndefinedVideoFormatSet.find(extension) != UndefinedVideoFormatSet.end()) {
format = MTP_FORMAT_UNDEFINED_VIDEO_CODE;
}
GetMediaTypeByformat(format, outMediaType);
MEDIA_DEBUG_LOG("GetMediaTypeByName format:%{public}x, outMediaType:%{public}d", format, outMediaType);
return E_SUCCESS;
}
int32_t MtpDataUtils::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)
{
CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
CHECK_AND_RETURN_RET_LOG(handles != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "handles is nullptr");
for (auto it = handles->begin(); it != handles->end(); it++) {
shared_ptr<UInt16List> properties = make_shared<UInt16List>();
CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "properties is nullptr");
if (context->property == MTP_PROPERTY_ALL_CODE) {
shared_ptr<MtpOperationContext> mtpContext = make_shared<MtpOperationContext>();
CHECK_AND_RETURN_RET_LOG(mtpContext != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "mtpContext is nullptr");
if (context->format == 0) {
GetMtpFormatByPath(it->second, mtpContext->format);
} else {
mtpContext->format = context->format;
}
shared_ptr<GetObjectPropsSupportedData> payLoadData = make_shared<GetObjectPropsSupportedData>(mtpContext);
CHECK_AND_RETURN_RET_LOG(payLoadData != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "payLoadData is nullptr");
payLoadData->GetObjectProps(*properties);
} else {
properties->push_back(context->property);
}
if (properties->size() == 0) {
MEDIA_ERR_LOG("MtpDataUtils::GetMtpPropList properties is empty");
return MTP_INVALID_OBJECTPROPCODE_CODE;
}
uint32_t parentId = DEFAULT_STORAGE_ID;
auto iterator = pathHandles.find(std::filesystem::path(it->second).parent_path().string());
if (iterator != pathHandles.end()) {
parentId = iterator->second;
} else {
parentId = 0;
}
GetMtpOneRowProp(properties, parentId, it, outProps, context->storageID);
}
return MTP_SUCCESS;
}
void MtpDataUtils::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)
{
CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
CHECK_AND_RETURN_LOG(properties != nullptr, "properties is nullptr");
std::string column;
ResultSetDataType type;
for (uint16_t property : *properties) {
if (PropColumnMap.find(property) != PropColumnMap.end()) {
auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
Property prop(property, properType);
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
prop.handle_ = it->first;
column = PropColumnMap.at(property);
type = ColumnTypeMap.at(column);
if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
uint16_t format = MTP_FORMAT_UNDEFINED_CODE;
GetMtpFormatByPath(it->second, format);
prop.currentValue->bin_.ui16 = format;
} else if (column.compare(CONST_MEDIA_DATA_DB_PARENT_ID) == 0) {
prop.currentValue->bin_.ui32 = parentId;
} else {
SetMtpProperty(column, it->second, type, prop);
}
outProps->push_back(prop);
} else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
SetMtpOneDefaultlPropList(it->first, property, outProps, storageId);
} else {
MEDIA_DEBUG_LOG("other property:0x%{public}x", property);
}
}
}
uint32_t MtpDataUtils::GetMtpFormatByPath(const std::string &path, uint16_t &outFormat)
{
outFormat = MTP_FORMAT_UNDEFINED_CODE;
CHECK_AND_RETURN_RET_LOG(!path.empty(), MTP_ERROR_INVALID_OBJECTPROP_VALUE, "path is nullptr");
CHECK_AND_RETURN_RET_LOG(access(path.c_str(), R_OK) == 0, E_ERR, "access failed path[%{public}s]", path.c_str());
if (std::filesystem::is_directory(path)) {
outFormat = MTP_FORMAT_ASSOCIATION_CODE;
return MTP_SUCCESS;
}
std::filesystem::path filePath(path);
CHECK_AND_RETURN_RET(filePath.filename().has_extension(), MTP_ERROR_INVALID_OBJECTPROP_VALUE);
std::string extension = filePath.filename().extension().c_str();
for (auto it = FormatMap.begin(); it != FormatMap.end(); it++) {
if (it->second.compare(extension) != 0) {
continue;
}
uint16_t size = sizeof(PLAYBACK_FORMATS) / sizeof(uint16_t);
for (uint16_t i = 0; i < size; i++) {
if (it->first == PLAYBACK_FORMATS[i]) {
outFormat = it->first;
return MTP_SUCCESS;
}
}
}
if (extension.compare(MTP_FORMAT_JPG) == 0 || extension.compare(MTP_FORMAT_JPEG) == 0) {
outFormat = MTP_FORMAT_EXIF_JPEG_CODE;
return MTP_SUCCESS;
}
return MTP_ERROR_INVALID_OBJECTPROP_VALUE;
}
void MtpDataUtils::SetMtpProperty(const std::string &column, const std::string &path,
ResultSetDataType &type, Property &prop)
{
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
if (column.compare(CONST_MEDIA_DATA_DB_NAME) == 0) {
prop.currentValue->str_ = make_shared<std::string>(std::filesystem::path(path).filename().string());
return;
}
struct stat statInfo;
CHECK_AND_RETURN_LOG(stat(path.c_str(), &statInfo) == 0, "SetMtpProperty stat failed");
if (column.compare(CONST_MEDIA_DATA_DB_SIZE) == 0) {
prop.currentValue->bin_.i64 = statInfo.st_size;
return;
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
prop.currentValue->str_ = make_shared<std::string>(MtpPacketTool::FormatDateTime((statInfo.st_mtime)));
return;
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_ADDED) == 0) {
prop.currentValue->bin_.i64 = statInfo.st_ctime;
return;
}
if (column.compare(CONST_MEDIA_DATA_DB_DESCRIPTION) == 0) {
prop.currentValue->str_ = make_shared<std::string>("");
return;
}
if (column.compare(CONST_MEDIA_DATA_DB_DURATION) == 0) {
prop.currentValue->bin_.ui32 = 0;
return;
}
if (column.compare(CONST_MEDIA_DATA_DB_ARTIST) == 0) {
prop.currentValue->str_ = make_shared<std::string>("");
return;
}
if (column.compare(CONST_MEDIA_DATA_DB_ALBUM_NAME) == 0) {
prop.currentValue->str_ = make_shared<std::string>("");
return;
}
if (column.compare(MEDIA_DATA_DB_COMPOSER) == 0) {
prop.currentValue->str_ = make_shared<std::string>("");
return;
}
}
void MtpDataUtils::SetPtpProperty(const std::string &column, const std::string &path, const MovingType &movingType,
Property &prop)
{
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
std::string displayName = movingType.displayName;
if (column.compare(CONST_MEDIA_DATA_DB_NAME) == 0) {
std::string filename = std::filesystem::path(path).filename();
size_t filename_pos = filename.find_last_of('.');
CHECK_AND_RETURN_LOG(filename_pos != std::string::npos, "get file name failed");
size_t displayName_pos = displayName.find_last_of('.');
CHECK_AND_RETURN_LOG(displayName_pos != std::string::npos, "get displayName name failed");
std::string value;
CHECK_AND_RETURN_LOG(filename_pos + 1 < filename.size(), "get fileName failed");
value = displayName.substr(0, displayName_pos) + "." + filename.substr(filename_pos + 1);
prop.currentValue->str_ = make_shared<std::string>(value);
}
if (column.compare(CONST_MEDIA_DATA_DB_PARENT_ID) == 0) {
prop.currentValue->bin_.i64 = movingType.parent;
}
struct stat statInfo;
CHECK_AND_RETURN_LOG(stat(path.c_str(), &statInfo) == 0, "SetMtpProperty stat failed");
if (column.compare(CONST_MEDIA_DATA_DB_SIZE) == 0) {
prop.currentValue->bin_.i64 = statInfo.st_size;
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
prop.currentValue->str_ = make_shared<std::string>(MtpPacketTool::FormatDateTime((statInfo.st_mtime)));
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_ADDED) == 0) {
prop.currentValue->bin_.i64 = statInfo.st_ctime;
}
}
string MtpDataUtils::GetMovingOrEnditSourcePath(const std::string &path, const int32_t &subtype,
const shared_ptr<MtpOperationContext> &context)
{
string sourcePath;
CHECK_AND_RETURN_RET_LOG(context != nullptr, sourcePath, "context is nullptr");
MEDIA_INFO_LOG("mtp GetMovingOrEnditSourcePath path:%{public}s", path.c_str());
if (static_cast<int32_t>(context->handle / COMMON_PHOTOS_OFFSET) == MOVING_PHOTO_TYPE) {
sourcePath = MovingPhotoFileUtils::GetMovingPhotoVideoPath(path);
}
MEDIA_INFO_LOG("Mtp GetMovingOrEnditSourcePath sourcePath:%{public}s", sourcePath.c_str());
return sourcePath;
}
int32_t MtpDataUtils::GetMtpPropValue(const std::string &path,
const uint32_t property, const uint16_t format, PropertyValue &outPropValue)
{
CHECK_AND_RETURN_RET_LOG(PropColumnMap.find(property) != PropColumnMap.end(), MTP_ERROR_INVALID_OBJECTPROP_VALUE,
"Can not support this property");
std::string column = PropColumnMap.at(property);
if (column.compare(CONST_MEDIA_DATA_DB_NAME) == 0) {
outPropValue.outStrVal = std::filesystem::path(path).filename().string();
return MTP_SUCCESS;
}
struct stat statInfo;
CHECK_AND_RETURN_RET_LOG(stat(path.c_str(), &statInfo) == 0, MTP_ERROR_INVALID_OBJECTPROP_VALUE,
"GetMtpPropValue stat failed");
if (column.compare(CONST_MEDIA_DATA_DB_SIZE) == 0) {
outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_size);
return MTP_SUCCESS;
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_MODIFIED) == 0) {
outPropValue.outStrVal = Strftime("%Y-%m-%d %H:%M:%S", statInfo.st_mtime);
return MTP_SUCCESS;
}
if (column.compare(CONST_MEDIA_DATA_DB_DATE_ADDED) == 0) {
outPropValue.outIntVal = static_cast<uint64_t>(statInfo.st_ctime);
}
return MTP_SUCCESS;
}
void MtpDataUtils::SetMtpOneDefaultlPropList(uint32_t handle,
uint16_t property, std::shared_ptr<std::vector<Property>> &outProps, int32_t storageId)
{
CHECK_AND_RETURN_LOG(outProps != nullptr, "outProps is nullptr");
CHECK_AND_RETURN_LOG(PropDefaultMap.find(property) != PropDefaultMap.end(),
"SetMtpOneDefaultlPropList property not found in PropDefaultMap");
auto propType = PropDefaultMap.at(property);
auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
Property prop(property, properType);
CHECK_AND_RETURN_LOG(prop.currentValue != nullptr, "prop.currentValue is nullptr");
prop.handle_ = handle;
switch (propType) {
case INTTYPE16:
prop.currentValue->bin_.i16 = 0;
break;
case INTTYPE128:
prop.currentValue->bin_.i128[OFFSET_0] = static_cast<int32_t>(handle);
prop.currentValue->bin_.i128[OFFSET_1] = 0;
prop.currentValue->bin_.i128[OFFSET_2] = 0;
prop.currentValue->bin_.i128[OFFSET_3] = 0;
break;
case STRINGTYPE:
prop.currentValue->str_ = make_shared<string>("");
break;
default:
prop.currentValue->bin_.i32 = storageId;
break;
}
outProps->push_back(prop);
}
int32_t MtpDataUtils::GetGalleryPropList(const std::shared_ptr<MtpOperationContext> &context,
std::shared_ptr<std::vector<Property>> &outProps, const std::string &name, uint32_t handle)
{
CHECK_AND_RETURN_RET_LOG(context != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "context is nullptr");
CHECK_AND_RETURN_RET_LOG(outProps != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "outProps is nullptr");
auto properties = std::make_shared<UInt16List>();
CHECK_AND_RETURN_RET_LOG(properties != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "properties is nullptr");
if (context->property == MTP_PROPERTY_ALL_CODE) {
auto mtpContext = std::make_shared<MtpOperationContext>();
CHECK_AND_RETURN_RET_LOG(mtpContext != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "mtpContext is nullptr");
mtpContext->format = (context->format == 0) ? MTP_FORMAT_ASSOCIATION_CODE : context->format;
auto payLoadData = std::make_shared<GetObjectPropsSupportedData>(mtpContext);
CHECK_AND_RETURN_RET_LOG(payLoadData != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "payLoadData is nullptr");
payLoadData->GetObjectProps(*properties);
} else {
properties->push_back(context->property);
}
CHECK_AND_RETURN_RET_LOG(properties->size() > 0, MTP_INVALID_OBJECTPROPCODE_CODE, "properties is empty");
std::string column;
for (uint16_t property : *properties) {
if (PropColumnMap.find(property) != PropColumnMap.end()) {
auto properType = MtpPacketTool::GetObjectPropTypeByPropCode(property);
Property prop(property, properType);
CHECK_AND_RETURN_RET_LOG(prop.currentValue != nullptr, MTP_ERROR_INVALID_OBJECTHANDLE, "prop is nullptr");
prop.handle_ = handle;
column = PropColumnMap.at(property);
if (column.compare(MEDIA_DATA_DB_FORMAT) == 0) {
prop.currentValue->bin_.ui16 = MTP_FORMAT_ASSOCIATION_CODE;
} else if (column.compare(CONST_MEDIA_DATA_DB_PARENT_ID) == 0) {
prop.currentValue->bin_.ui32 = DEFAULT_PARENT_ROOT;
} else if (column.compare(CONST_MEDIA_DATA_DB_NAME) == 0) {
prop.currentValue->str_ = std::make_shared<std::string>(name);
} else {
continue;
}
outProps->push_back(prop);
} else if (PropDefaultMap.find(property) != PropDefaultMap.end()) {
SetMtpOneDefaultlPropList(handle, property, outProps, DEFAULT_STORAGE_ID);
} else {
MEDIA_DEBUG_LOG("other property:0x%{public}x", property);
}
}
return MTP_SUCCESS;
}
bool MtpDataUtils::IsNumber(const string& str)
{
CHECK_AND_RETURN_RET_LOG(!str.empty(), false, "IsNumber input is empty");
for (char const& c : str) {
CHECK_AND_RETURN_RET(isdigit(c) != 0, false);
}
return true;
}
bool MtpDataUtils::IsMtpMovingPhoto(int32_t subtype, int32_t effectMode)
{
return (subtype == static_cast<int32_t>(PhotoSubType::MOVING_PHOTO) ||
effectMode == static_cast<int32_t>(MovingPhotoEffectMode::IMAGE_ONLY));
}
}
}