diff options
author | bigbiff bigbiff <bigbiff@teamw.in> | 2018-12-19 00:39:53 +0100 |
---|---|---|
committer | Ethan Yonker <dees_troy@teamw.in> | 2019-03-20 20:28:21 +0100 |
commit | af32bb9c4f4f06e92de3435ed2db3153c0701094 (patch) | |
tree | 622948fb3167dc17bb436c948d61df581d2e75f7 /mtp/ffs/mtp_MtpDatabase.cpp | |
parent | Adding Edl button in reboot menu (diff) | |
download | android_bootable_recovery-af32bb9c4f4f06e92de3435ed2db3153c0701094.tar android_bootable_recovery-af32bb9c4f4f06e92de3435ed2db3153c0701094.tar.gz android_bootable_recovery-af32bb9c4f4f06e92de3435ed2db3153c0701094.tar.bz2 android_bootable_recovery-af32bb9c4f4f06e92de3435ed2db3153c0701094.tar.lz android_bootable_recovery-af32bb9c4f4f06e92de3435ed2db3153c0701094.tar.xz android_bootable_recovery-af32bb9c4f4f06e92de3435ed2db3153c0701094.tar.zst android_bootable_recovery-af32bb9c4f4f06e92de3435ed2db3153c0701094.zip |
Diffstat (limited to 'mtp/ffs/mtp_MtpDatabase.cpp')
-rwxr-xr-x | mtp/ffs/mtp_MtpDatabase.cpp | 850 |
1 files changed, 850 insertions, 0 deletions
diff --git a/mtp/ffs/mtp_MtpDatabase.cpp b/mtp/ffs/mtp_MtpDatabase.cpp new file mode 100755 index 000000000..30076982b --- /dev/null +++ b/mtp/ffs/mtp_MtpDatabase.cpp @@ -0,0 +1,850 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * 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. + * + * Copyright (C) 2014 TeamWin - bigbiff and Dees_Troy mtp database conversion to C++ + */ + +#include <utils/Log.h> + +#include <assert.h> +#include <cutils/properties.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <libgen.h> +#include <limits.h> +#include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <map> +#include <string> + +#include "MtpDataPacket.h" +#include "MtpDatabase.h" +#include "MtpDebug.h" +#include "MtpObjectInfo.h" +#include "MtpProperty.h" +#include "MtpStorage.h" +#include "MtpStringBuffer.h" +#include "MtpUtils.h" +#include "mtp.h" +#include "mtp_MtpDatabase.hpp" + +IMtpDatabase::IMtpDatabase() { + storagenum = 0; + count = -1; +} + +IMtpDatabase::~IMtpDatabase() { + std::map<int, MtpStorage*>::iterator i; + for (i = storagemap.begin(); i != storagemap.end(); i++) { + delete i->second; + } +} + +int IMtpDatabase::DEVICE_PROPERTIES[3] = { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, + MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, + MTP_DEVICE_PROPERTY_IMAGE_SIZE }; + +int IMtpDatabase::FILE_PROPERTIES[10] = { + // NOTE must match beginning of AUDIO_PROPERTIES, VIDEO_PROPERTIES + // and IMAGE_PROPERTIES below + MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, + MTP_PROPERTY_OBJECT_SIZE, MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, + MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID, MTP_PROPERTY_NAME, + // TODO: why is DISPLAY_NAME not here? + MTP_PROPERTY_DATE_ADDED +}; + +int IMtpDatabase::AUDIO_PROPERTIES[19] = { + // NOTE must match FILE_PROPERTIES above + MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, + MTP_PROPERTY_OBJECT_SIZE, MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, + MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID, MTP_PROPERTY_NAME, + MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_ADDED, + + // audio specific properties + MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME, MTP_PROPERTY_ALBUM_ARTIST, MTP_PROPERTY_TRACK, + MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_PROPERTY_DURATION, MTP_PROPERTY_GENRE, + MTP_PROPERTY_COMPOSER +}; + +int IMtpDatabase::VIDEO_PROPERTIES[15] = { + // NOTE must match FILE_PROPERTIES above + MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, + MTP_PROPERTY_OBJECT_SIZE, MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, + MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID, MTP_PROPERTY_NAME, + MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_ADDED, + + // video specific properties + MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME, MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION +}; + +int IMtpDatabase::IMAGE_PROPERTIES[12] = { + // NOTE must match FILE_PROPERTIES above + MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, + MTP_PROPERTY_OBJECT_SIZE, MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, + MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID, MTP_PROPERTY_NAME, + MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_ADDED, + + // image specific properties + MTP_PROPERTY_DESCRIPTION +}; + +int IMtpDatabase::ALL_PROPERTIES[25] = { + // NOTE must match FILE_PROPERTIES above + MTP_PROPERTY_STORAGE_ID, MTP_PROPERTY_OBJECT_FORMAT, MTP_PROPERTY_PROTECTION_STATUS, + MTP_PROPERTY_OBJECT_SIZE, MTP_PROPERTY_OBJECT_FILE_NAME, MTP_PROPERTY_DATE_MODIFIED, + MTP_PROPERTY_PARENT_OBJECT, MTP_PROPERTY_PERSISTENT_UID, MTP_PROPERTY_NAME, + MTP_PROPERTY_DISPLAY_NAME, MTP_PROPERTY_DATE_ADDED, + + // image specific properties + MTP_PROPERTY_DESCRIPTION, + + // audio specific properties + MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME, MTP_PROPERTY_ALBUM_ARTIST, MTP_PROPERTY_TRACK, + MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_PROPERTY_DURATION, MTP_PROPERTY_GENRE, + MTP_PROPERTY_COMPOSER, + + // video specific properties + MTP_PROPERTY_ARTIST, MTP_PROPERTY_ALBUM_NAME, MTP_PROPERTY_DURATION, MTP_PROPERTY_DESCRIPTION, + + // image specific properties + MTP_PROPERTY_DESCRIPTION +}; + +int IMtpDatabase::SUPPORTED_PLAYBACK_FORMATS[26] = { SUPPORTED_PLAYBACK_FORMAT_UNDEFINED, + SUPPORTED_PLAYBACK_FORMAT_ASSOCIATION, + SUPPORTED_PLAYBACK_FORMAT_TEXT, + SUPPORTED_PLAYBACK_FORMAT_HTML, + SUPPORTED_PLAYBACK_FORMAT_WAV, + SUPPORTED_PLAYBACK_FORMAT_MP3, + SUPPORTED_PLAYBACK_FORMAT_MPEG, + SUPPORTED_PLAYBACK_FORMAT_EXIF_JPEG, + SUPPORTED_PLAYBACK_FORMAT_TIFF_EP, + SUPPORTED_PLAYBACK_FORMAT_BMP, + SUPPORTED_PLAYBACK_FORMAT_GIF, + SUPPORTED_PLAYBACK_FORMAT_JFIF, + SUPPORTED_PLAYBACK_FORMAT_PNG, + SUPPORTED_PLAYBACK_FORMAT_TIFF, + SUPPORTED_PLAYBACK_FORMAT_WMA, + SUPPORTED_PLAYBACK_FORMAT_OGG, + SUPPORTED_PLAYBACK_FORMAT_AAC, + SUPPORTED_PLAYBACK_FORMAT_MP4_CONTAINER, + SUPPORTED_PLAYBACK_FORMAT_MP2, + SUPPORTED_PLAYBACK_FORMAT_3GP_CONTAINER, + SUPPORTED_PLAYBACK_FORMAT_ABSTRACT_AV_PLAYLIST, + SUPPORTED_PLAYBACK_FORMAT_WPL_PLAYLIST, + SUPPORTED_PLAYBACK_FORMAT_M3U_PLAYLIST, + SUPPORTED_PLAYBACK_FORMAT_PLS_PLAYLIST, + SUPPORTED_PLAYBACK_FORMAT_XML_DOCUMENT, + SUPPORTED_PLAYBACK_FORMAT_FLAC }; + +MtpObjectHandle IMtpDatabase::beginSendObject(const char* path, MtpObjectFormat format, + MtpObjectHandle parent, MtpStorageID storageID, + uint64_t size, time_t modified) { + if (storagemap.find(storageID) == storagemap.end()) return kInvalidObjectHandle; + return storagemap[storageID]->beginSendObject(path, format, parent, size, modified); +} + +void IMtpDatabase::endSendObject(const char* path, MtpObjectHandle handle, MtpObjectFormat format, + bool succeeded) { + MTPD("endSendObject() %s\n", path); + if (!succeeded) { + MTPE("endSendObject() failed, unlinking %s\n", path); + unlink(path); + } + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) + storit->second->endSendObject(path, handle, format, succeeded); +} + +void IMtpDatabase::createDB(MtpStorage* storage, MtpStorageID storageID) { + storagemap[storageID] = storage; + storage->createDB(); +} + +void IMtpDatabase::destroyDB(MtpStorageID storageID) { + MtpStorage* storage = storagemap[storageID]; + storagemap.erase(storageID); + delete storage; +} + +MtpObjectHandleList* IMtpDatabase::getObjectList(MtpStorageID storageID, + __attribute__((unused)) MtpObjectFormat format, + MtpObjectHandle parent) { + MTPD("IMtpDatabase::getObjectList::storageID: %d\n", storageID); + MtpObjectHandleList* list = storagemap[storageID]->getObjectList(storageID, parent); + MTPD("IMtpDatabase::getObjectList::list size: %d\n", list->size()); + return list; +} + +int IMtpDatabase::getNumObjects(MtpStorageID storageID, + __attribute__((unused)) MtpObjectFormat format, + MtpObjectHandle parent) { + MtpObjectHandleList* list = storagemap[storageID]->getObjectList(storageID, parent); + int size = list->size(); + delete list; + return size; +} + +MtpObjectFormatList* IMtpDatabase::getSupportedPlaybackFormats() { + // This function tells the host PC which file formats the device supports + MtpObjectFormatList* list = new MtpObjectFormatList(); + int length = sizeof(SUPPORTED_PLAYBACK_FORMATS) / sizeof(SUPPORTED_PLAYBACK_FORMATS[0]); + MTPD("IMtpDatabase::getSupportedPlaybackFormats length: %i\n", length); + for (int i = 0; i < length; i++) { + MTPD("supported playback format: %x\n", SUPPORTED_PLAYBACK_FORMATS[i]); + list->push_back(SUPPORTED_PLAYBACK_FORMATS[i]); + } + return list; +} + +MtpObjectFormatList* IMtpDatabase::getSupportedCaptureFormats() { + // Android OS implementation of this function returns NULL + // so we are not implementing this function either. + MTPD( + "IMtpDatabase::getSupportedCaptureFormats returning NULL (This is what Android does as " + "well).\n"); + return NULL; +} + +MtpObjectPropertyList* IMtpDatabase::getSupportedObjectProperties(MtpObjectFormat format) { + int* properties; + MtpObjectPropertyList* list = new MtpObjectPropertyList(); + int length = 0; + switch (format) { + case MTP_FORMAT_MP3: + case MTP_FORMAT_WAV: + case MTP_FORMAT_WMA: + case MTP_FORMAT_OGG: + case MTP_FORMAT_AAC: + properties = AUDIO_PROPERTIES; + length = sizeof(AUDIO_PROPERTIES) / sizeof(AUDIO_PROPERTIES[0]); + break; + case MTP_FORMAT_MPEG: + case MTP_FORMAT_3GP_CONTAINER: + case MTP_FORMAT_WMV: + properties = VIDEO_PROPERTIES; + length = sizeof(VIDEO_PROPERTIES) / sizeof(VIDEO_PROPERTIES[0]); + break; + case MTP_FORMAT_EXIF_JPEG: + case MTP_FORMAT_GIF: + case MTP_FORMAT_PNG: + case MTP_FORMAT_BMP: + properties = IMAGE_PROPERTIES; + length = sizeof(IMAGE_PROPERTIES) / sizeof(IMAGE_PROPERTIES[0]); + break; + case 0: + properties = ALL_PROPERTIES; + length = sizeof(ALL_PROPERTIES) / sizeof(ALL_PROPERTIES[0]); + break; + default: + properties = FILE_PROPERTIES; + length = sizeof(FILE_PROPERTIES) / sizeof(FILE_PROPERTIES[0]); + } + MTPD("IMtpDatabase::getSupportedObjectProperties length is: %i, format: %x", length, format); + for (int i = 0; i < length; i++) { + MTPD("supported object property: %x\n", properties[i]); + list->push_back(properties[i]); + } + return list; +} + +MtpDevicePropertyList* IMtpDatabase::getSupportedDeviceProperties() { + MtpDevicePropertyList* list = new MtpDevicePropertyList(); + int length = sizeof(DEVICE_PROPERTIES) / sizeof(DEVICE_PROPERTIES[0]); + MTPD("IMtpDatabase::getSupportedDeviceProperties length was: %i\n", length); + for (int i = 0; i < length; i++) list->push_back(DEVICE_PROPERTIES[i]); + return list; +} + +MtpResponseCode IMtpDatabase::getObjectPropertyValue(MtpObjectHandle handle, + MtpObjectProperty property, + MtpDataPacket& packet) { + MTPD("IMtpDatabase::getObjectPropertyValue mtpid: %u, property: %x\n", handle, property); + int type; + MtpResponseCode result = MTP_RESPONSE_INVALID_OBJECT_HANDLE; + MtpStorage::PropEntry prop; + if (!getObjectPropertyInfo(property, type)) { + MTPE("IMtpDatabase::getObjectPropertyValue returning MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED\n"); + return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; + } + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + if (storit->second->getObjectPropertyValue(handle, property, prop) == 0) { + result = MTP_RESPONSE_OK; + break; + } + } + + if (result != MTP_RESPONSE_OK) { + MTPE("IMtpDatabase::getObjectPropertyValue unable to locate handle: %u\n", handle); + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; + } + + uint64_t longValue = prop.intvalue; + // special case date properties, which are strings to MTP + // but stored internally as a uint64 + if (property == MTP_PROPERTY_DATE_MODIFIED || property == MTP_PROPERTY_DATE_ADDED) { + char date[20]; + formatDateTime(longValue, date, sizeof(date)); + packet.putString(date); + goto out; + } + + switch (type) { + case MTP_TYPE_INT8: + packet.putInt8(longValue); + break; + case MTP_TYPE_UINT8: + packet.putUInt8(longValue); + break; + case MTP_TYPE_INT16: + packet.putInt16(longValue); + break; + case MTP_TYPE_UINT16: + packet.putUInt16(longValue); + break; + case MTP_TYPE_INT32: + packet.putInt32(longValue); + break; + case MTP_TYPE_UINT32: + packet.putUInt32(longValue); + break; + case MTP_TYPE_INT64: + packet.putInt64(longValue); + break; + case MTP_TYPE_UINT64: + packet.putUInt64(longValue); + break; + case MTP_TYPE_INT128: + packet.putInt128(longValue); + break; + case MTP_TYPE_UINT128: + packet.putUInt128(longValue); + break; + case MTP_TYPE_STR: { + /*std::string stringValue = (string)stringValuesArray[0]; + if (stringValue) { + const char* str = stringValue.c_str(); + if (str == NULL) { + return MTP_RESPONSE_GENERAL_ERROR; + } + packet.putString(str); + } else { + packet.putEmptyString(); + }*/ + packet.putString(prop.strvalue.c_str()); + MTPD("MTP_TYPE_STR: %x = %s\n", prop.property, prop.strvalue.c_str()); + // MTPE("STRING unsupported type in getObjectPropertyValue\n"); + // result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; + break; + } + default: + MTPE("unsupported type in getObjectPropertyValue\n"); + result = MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; + } +out: + return result; +} + +MtpResponseCode IMtpDatabase::setObjectPropertyValue(MtpObjectHandle handle, + MtpObjectProperty property, + MtpDataPacket& packet) { + int type; + MTPD("IMtpDatabase::setObjectPropertyValue start\n"); + if (!getObjectPropertyInfo(property, type)) { + MTPE("IMtpDatabase::setObjectPropertyValue returning MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED\n"); + return MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; + } + MTPD("IMtpDatabase::setObjectPropertyValue continuing\n"); + + int8_t int8_t_value; + uint8_t uint8_t_value; + int16_t int16_t_value; + uint16_t uint16_t_value; + int32_t int32_t_value; + uint32_t uint32_t_value; + int64_t int64_t_value; + uint64_t uint64_t_value; + std::string stringValue; + + switch (type) { + case MTP_TYPE_INT8: + MTPD("int8\n"); + packet.getInt8(int8_t_value); + break; + case MTP_TYPE_UINT8: + MTPD("uint8\n"); + packet.getUInt8(uint8_t_value); + break; + case MTP_TYPE_INT16: + MTPD("int16\n"); + packet.getInt16(int16_t_value); + break; + case MTP_TYPE_UINT16: + MTPD("uint16\n"); + packet.getUInt16(uint16_t_value); + break; + case MTP_TYPE_INT32: + MTPD("int32\n"); + packet.getInt32(int32_t_value); + break; + case MTP_TYPE_UINT32: + MTPD("uint32\n"); + packet.getUInt32(uint32_t_value); + break; + case MTP_TYPE_INT64: + MTPD("int64\n"); + packet.getInt64(int64_t_value); + break; + case MTP_TYPE_UINT64: + MTPD("uint64\n"); + packet.getUInt64(uint64_t_value); + break; + case MTP_TYPE_STR: { + MTPD("string\n"); + MtpStringBuffer buffer; + packet.getString(buffer); + stringValue = buffer; + break; + } + default: + MTPE("IMtpDatabase::setObjectPropertyValue unsupported type %i in getObjectPropertyValue\n", + type); + return MTP_RESPONSE_INVALID_OBJECT_PROP_FORMAT; + } + + int result = MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; + + switch (property) { + case MTP_PROPERTY_OBJECT_FILE_NAME: { + MTPD("IMtpDatabase::setObjectPropertyValue renaming file, handle: %d, new name: '%s'\n", + handle, stringValue.c_str()); + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + if (storit->second->renameObject(handle, stringValue) == 0) { + MTPD("MTP_RESPONSE_OK\n"); + result = MTP_RESPONSE_OK; + break; + } + } + } break; + + default: + MTPE("IMtpDatabase::setObjectPropertyValue property %x not supported.\n", property); + result = MTP_RESPONSE_OBJECT_PROP_NOT_SUPPORTED; + } + MTPD("IMtpDatabase::setObjectPropertyValue returning %d\n", result); + return result; +} + +MtpResponseCode IMtpDatabase::getDevicePropertyValue(MtpDeviceProperty property, + MtpDataPacket& packet) { + int type, result = 0; + char prop_value[PROPERTY_VALUE_MAX]; + MTPD("property %s\n", MtpDebug::getDevicePropCodeName(property)); + if (!getDevicePropertyInfo(property, type)) { + MTPE("IMtpDatabase::getDevicePropertyValue MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED\n"); + return MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; + } + MTPD("property %s\n", MtpDebug::getDevicePropCodeName(property)); + MTPD("property %x\n", property); + MTPD("MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME %x\n", MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME); + switch (property) { + case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: + case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: + result = MTP_RESPONSE_OK; + break; + default: { + MTPE("IMtpDatabase::getDevicePropertyValue property %x not supported\n", property); + result = MTP_RESPONSE_DEVICE_PROP_NOT_SUPPORTED; + break; + } + } + + if (result != MTP_RESPONSE_OK) { + MTPD("MTP_REPONSE_OK NOT OK\n"); + return result; + } + + long longValue = 0; + property_get("ro.build.product", prop_value, "unknown manufacturer"); + switch (type) { + case MTP_TYPE_INT8: { + MTPD("MTP_TYPE_INT8\n"); + packet.putInt8(longValue); + break; + } + case MTP_TYPE_UINT8: { + MTPD("MTP_TYPE_UINT8\n"); + packet.putUInt8(longValue); + break; + } + case MTP_TYPE_INT16: { + MTPD("MTP_TYPE_INT16\n"); + packet.putInt16(longValue); + break; + } + case MTP_TYPE_UINT16: { + MTPD("MTP_TYPE_UINT16\n"); + packet.putUInt16(longValue); + break; + } + case MTP_TYPE_INT32: { + MTPD("MTP_TYPE_INT32\n"); + packet.putInt32(longValue); + break; + } + case MTP_TYPE_UINT32: { + MTPD("MTP_TYPE_UINT32\n"); + packet.putUInt32(longValue); + break; + } + case MTP_TYPE_INT64: { + MTPD("MTP_TYPE_INT64\n"); + packet.putInt64(longValue); + break; + } + case MTP_TYPE_UINT64: { + MTPD("MTP_TYPE_UINT64\n"); + packet.putUInt64(longValue); + break; + } + case MTP_TYPE_INT128: { + MTPD("MTP_TYPE_INT128\n"); + packet.putInt128(longValue); + break; + } + case MTP_TYPE_UINT128: { + MTPD("MTP_TYPE_UINT128\n"); + packet.putInt128(longValue); + break; + } + case MTP_TYPE_STR: { + MTPD("MTP_TYPE_STR\n"); + char* str = prop_value; + packet.putString(str); + break; + } + default: + MTPE("IMtpDatabase::getDevicePropertyValue unsupported type %i in getDevicePropertyValue\n", + type); + return MTP_RESPONSE_INVALID_DEVICE_PROP_FORMAT; + } + + return MTP_RESPONSE_OK; +} + +MtpResponseCode IMtpDatabase::setDevicePropertyValue(__attribute__((unused)) + MtpDeviceProperty property, + __attribute__((unused)) + MtpDataPacket& packet) { + MTPE("IMtpDatabase::setDevicePropertyValue not implemented, returning 0\n"); + return 0; +} + +MtpResponseCode IMtpDatabase::resetDeviceProperty(__attribute__((unused)) + MtpDeviceProperty property) { + MTPE("IMtpDatabase::resetDeviceProperty not implemented, returning -1\n"); + return -1; +} + +MtpResponseCode IMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, uint32_t format, + uint32_t property, int groupCode, int depth, + MtpDataPacket& packet) { + MTPD("getObjectPropertyList()\n"); + MTPD("property: %x\n", property); + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + MTPD("IMtpDatabase::getObjectPropertyList calling getObjectPropertyList\n"); + if (storit->second->getObjectPropertyList(handle, format, property, groupCode, depth, packet) == + 0) { + MTPD("MTP_RESPONSE_OK\n"); + return MTP_RESPONSE_OK; + } + } + MTPE("IMtpDatabase::getObjectPropertyList MTP_RESPOSNE_INVALID_OBJECT_HANDLE %i\n", handle); + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +} + +MtpResponseCode IMtpDatabase::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) { + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + if (storit->second->getObjectInfo(handle, info) == 0) { + MTPD("MTP_RESPONSE_OK\n"); + return MTP_RESPONSE_OK; + } + } + MTPE("IMtpDatabase::getObjectInfo MTP_RESPONSE_INVALID_OBJECT_HANDLE %i\n", handle); + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +} + +void* IMtpDatabase::getThumbnail(__attribute__((unused)) MtpObjectHandle handle, + __attribute__((unused)) size_t& outThumbSize) { + MTPE("IMtpDatabase::getThumbnail not implemented, returning 0\n"); + return 0; +} + +MtpResponseCode IMtpDatabase::getObjectFilePath(MtpObjectHandle handle, + MtpStringBuffer& outFilePath, + int64_t& outFileLength, + MtpObjectFormat& outFormat) { + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + MTPD("IMtpDatabase::getObjectFilePath calling getObjectFilePath\n"); + if (storit->second->getObjectFilePath(handle, outFilePath, outFileLength, outFormat) == 0) { + MTPD("MTP_RESPONSE_OK\n"); + return MTP_RESPONSE_OK; + } + } + MTPE("IMtpDatabase::getObjectFilePath MTP_RESPOSNE_INVALID_OBJECT_HANDLE %i\n", handle); + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +} + +// MtpResponseCode IMtpDatabase::deleteFile(MtpObjectHandle handle) { +// MTPD("IMtpDatabase::deleteFile\n"); +// std::map<int, MtpStorage*>::iterator storit; +// for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { +// if (storit->second->deleteFile(handle) == 0) { +// MTPD("MTP_RESPONSE_OK\n"); +// return MTP_RESPONSE_OK; +// } +// } +// MTPE("IMtpDatabase::deleteFile MTP_RESPONSE_INVALID_OBJECT_HANDLE %i\n", handle); +// return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +// } + +struct PropertyTableEntry { + MtpObjectProperty property; + int type; +}; + +static const PropertyTableEntry kObjectPropertyTable[] = { + { MTP_PROPERTY_STORAGE_ID, MTP_TYPE_UINT32 }, + { MTP_PROPERTY_OBJECT_FORMAT, MTP_TYPE_UINT16 }, + { MTP_PROPERTY_PROTECTION_STATUS, MTP_TYPE_UINT16 }, + { MTP_PROPERTY_OBJECT_SIZE, MTP_TYPE_UINT64 }, + { MTP_PROPERTY_OBJECT_FILE_NAME, MTP_TYPE_STR }, + { MTP_PROPERTY_DATE_MODIFIED, MTP_TYPE_STR }, + { MTP_PROPERTY_PARENT_OBJECT, MTP_TYPE_UINT32 }, + { MTP_PROPERTY_PERSISTENT_UID, MTP_TYPE_UINT128 }, + { MTP_PROPERTY_NAME, MTP_TYPE_STR }, + { MTP_PROPERTY_DISPLAY_NAME, MTP_TYPE_STR }, + { MTP_PROPERTY_DATE_ADDED, MTP_TYPE_STR }, + { MTP_PROPERTY_ARTIST, MTP_TYPE_STR }, + { MTP_PROPERTY_ALBUM_NAME, MTP_TYPE_STR }, + { MTP_PROPERTY_ALBUM_ARTIST, MTP_TYPE_STR }, + { MTP_PROPERTY_TRACK, MTP_TYPE_UINT16 }, + { MTP_PROPERTY_ORIGINAL_RELEASE_DATE, MTP_TYPE_STR }, + { MTP_PROPERTY_GENRE, MTP_TYPE_STR }, + { MTP_PROPERTY_COMPOSER, MTP_TYPE_STR }, + { MTP_PROPERTY_DURATION, MTP_TYPE_UINT32 }, + { MTP_PROPERTY_DESCRIPTION, MTP_TYPE_STR }, +}; + +static const PropertyTableEntry kDevicePropertyTable[] = { + { MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER, MTP_TYPE_STR }, + { MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR }, + { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR }, +}; + +bool IMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) { + int count = sizeof(kObjectPropertyTable) / sizeof(kObjectPropertyTable[0]); + const PropertyTableEntry* entry = kObjectPropertyTable; + MTPD("IMtpDatabase::getObjectPropertyInfo size is: %i\n", count); + for (int i = 0; i < count; i++, entry++) { + if (entry->property == property) { + type = entry->type; + return true; + } + } + return false; +} + +bool IMtpDatabase::getDevicePropertyInfo(MtpDeviceProperty property, int& type) { + int count = sizeof(kDevicePropertyTable) / sizeof(kDevicePropertyTable[0]); + const PropertyTableEntry* entry = kDevicePropertyTable; + MTPD("IMtpDatabase::getDevicePropertyInfo count is: %i\n", count); + for (int i = 0; i < count; i++, entry++) { + if (entry->property == property) { + type = entry->type; + MTPD("type: %x\n", type); + return true; + } + } + return false; +} + +MtpObjectHandleList* IMtpDatabase::getObjectReferences(MtpObjectHandle handle) { + // call function and place files with associated handles into int array + MTPD( + "IMtpDatabase::getObjectReferences returning null, this seems to be what Android always " + "does.\n"); + MTPD("handle: %d\n", handle); + // Windows + Android seems to always return a NULL in this function, c == null path + // The way that this is handled in Android then is to do this: + return NULL; +} + +MtpResponseCode IMtpDatabase::setObjectReferences(__attribute__((unused)) MtpObjectHandle handle, + __attribute__((unused)) + MtpObjectHandleList* references) { + MTPE("IMtpDatabase::setObjectReferences not implemented, returning 0\n"); + return 0; +} + +MtpProperty* IMtpDatabase::getObjectPropertyDesc(MtpObjectProperty property, + MtpObjectFormat format) { + MTPD("IMtpDatabase::getObjectPropertyDesc start\n"); + MtpProperty* result = NULL; + switch (property) { + case MTP_PROPERTY_OBJECT_FORMAT: + // use format as default value + result = new MtpProperty(property, MTP_TYPE_UINT16, false, format); + break; + case MTP_PROPERTY_PROTECTION_STATUS: + case MTP_PROPERTY_TRACK: + result = new MtpProperty(property, MTP_TYPE_UINT16); + break; + case MTP_PROPERTY_STORAGE_ID: + case MTP_PROPERTY_PARENT_OBJECT: + case MTP_PROPERTY_DURATION: + result = new MtpProperty(property, MTP_TYPE_UINT32); + break; + case MTP_PROPERTY_OBJECT_SIZE: + result = new MtpProperty(property, MTP_TYPE_UINT64); + break; + case MTP_PROPERTY_PERSISTENT_UID: + result = new MtpProperty(property, MTP_TYPE_UINT128); + break; + case MTP_PROPERTY_NAME: + case MTP_PROPERTY_DISPLAY_NAME: + case MTP_PROPERTY_ARTIST: + case MTP_PROPERTY_ALBUM_NAME: + case MTP_PROPERTY_ALBUM_ARTIST: + case MTP_PROPERTY_GENRE: + case MTP_PROPERTY_COMPOSER: + case MTP_PROPERTY_DESCRIPTION: + result = new MtpProperty(property, MTP_TYPE_STR); + break; + case MTP_PROPERTY_DATE_MODIFIED: + case MTP_PROPERTY_DATE_ADDED: + case MTP_PROPERTY_ORIGINAL_RELEASE_DATE: + result = new MtpProperty(property, MTP_TYPE_STR); + result->setFormDateTime(); + break; + case MTP_PROPERTY_OBJECT_FILE_NAME: + // We allow renaming files and folders + result = new MtpProperty(property, MTP_TYPE_STR, true); + break; + } + return result; +} + +MtpProperty* IMtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { + MtpProperty* result = NULL; + bool writable = false; + switch (property) { + case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: + case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: + writable = true; + // fall through + case MTP_DEVICE_PROPERTY_IMAGE_SIZE: + result = new MtpProperty(property, MTP_TYPE_STR, writable); + + // get current value + // TODO: add actual values + result->setCurrentValue(0); + result->setDefaultValue(0); + break; + } + + return result; +} + +void IMtpDatabase::sessionStarted() { + MTPD("IMtpDatabase::sessionStarted not implemented or does nothing, returning\n"); + return; +} + +void IMtpDatabase::sessionEnded() { + MTPD("IMtpDatabase::sessionEnded not implemented or does nothing, returning\n"); + return; +} + +// ---------------------------------------------------------------------------- + +void IMtpDatabase::lockMutex(void) { + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + storit->second->lockMutex(0); + } +} + +void IMtpDatabase::unlockMutex(void) { + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + storit->second->unlockMutex(0); + } +} + +MtpResponseCode IMtpDatabase::beginDeleteObject(MtpObjectHandle handle) { + MTPD("IMtoDatabase::beginDeleteObject handle: %u\n", handle); + std::map<int, MtpStorage*>::iterator storit; + for (storit = storagemap.begin(); storit != storagemap.end(); storit++) { + if (storit->second->deleteFile(handle) == 0) { + MTPD("IMtpDatabase::beginDeleteObject::MTP_RESPONSE_OK\n"); + return MTP_RESPONSE_OK; + } + } + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +} + +void IMtpDatabase::endDeleteObject(MtpObjectHandle handle __unused, bool succeeded __unused) { + MTPD("IMtpDatabase::endDeleteObject not implemented yet\n"); +} + +void IMtpDatabase::rescanFile(const char* path __unused, MtpObjectHandle handle __unused, + MtpObjectFormat format __unused) { + MTPD("IMtpDatabase::rescanFile not implemented yet\n"); +} + +MtpResponseCode IMtpDatabase::beginMoveObject(MtpObjectHandle handle __unused, + MtpObjectHandle newParent __unused, + MtpStorageID newStorage __unused) { + MTPD("IMtpDatabase::beginMoveObject not implemented yet\n"); + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +} + +void IMtpDatabase::endMoveObject(MtpObjectHandle oldParent __unused, + MtpObjectHandle newParent __unused, + MtpStorageID oldStorage __unused, MtpStorageID newStorage __unused, + MtpObjectHandle handle __unused, bool succeeded __unused) { + MTPD("IMtpDatabase::endMoveObject not implemented yet\n"); +} + +MtpResponseCode IMtpDatabase::beginCopyObject(MtpObjectHandle handle __unused, + MtpObjectHandle newParent __unused, + MtpStorageID newStorage __unused) { + MTPD("IMtpDatabase::beginCopyObject not implemented yet\n"); + return MTP_RESPONSE_INVALID_OBJECT_HANDLE; +} + +void IMtpDatabase::endCopyObject(MtpObjectHandle handle __unused, bool succeeded __unused) { + MTPD("IMtpDatabase::endCopyObject not implemented yet\n"); +} |