Loading media/java/android/mtp/MtpDatabase.java +35 −2 Original line number Diff line number Diff line Loading @@ -101,6 +101,8 @@ public class MtpDatabase implements AutoCloseable { private int mBatteryLevel; private int mBatteryScale; private int mDeviceType; private String mHostType; private boolean mSkipThumbForHost = false; private MtpServer mServer; private MtpStorageManager mManager; Loading Loading @@ -192,6 +194,7 @@ public class MtpDatabase implements AutoCloseable { MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE, MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL, MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, }; @VisibleForNative Loading Loading @@ -408,6 +411,8 @@ public class MtpDatabase implements AutoCloseable { } context.deleteDatabase(devicePropertiesName); } mHostType = ""; mSkipThumbForHost = false; } @VisibleForNative Loading Loading @@ -672,12 +677,24 @@ public class MtpDatabase implements AutoCloseable { @VisibleForNative private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { int length; String value; switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writable string properties kept in shared preferences String value = mDeviceProperties.getString(Integer.toString(property), ""); int length = value.length(); value = mDeviceProperties.getString(Integer.toString(property), ""); length = value.length(); if (length > 255) { length = 255; } value.getChars(0, length, outStringValue, 0); outStringValue[length] = 0; return MtpConstants.RESPONSE_OK; case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: value = mHostType; length = value.length(); if (length > 255) { length = 255; } Loading Loading @@ -717,6 +734,14 @@ public class MtpDatabase implements AutoCloseable { e.putString(Integer.toString(property), stringValue); return (e.commit() ? MtpConstants.RESPONSE_OK : MtpConstants.RESPONSE_GENERAL_ERROR); case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: mHostType = stringValue; if (stringValue.startsWith("Android/")) { Log.d(TAG, "setDeviceProperty." + Integer.toHexString(property) + "=" + stringValue); mSkipThumbForHost = true; } return MtpConstants.RESPONSE_OK; } return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; Loading Loading @@ -838,6 +863,10 @@ public class MtpDatabase implements AutoCloseable { outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0; outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0); outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_DIMENSION, 0); if (mSkipThumbForHost) { Log.d(TAG, "getThumbnailInfo: Skip runtime thumbnail."); return true; } if (exif.getThumbnailRange() != null) { if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) { Log.d(TAG, "getThumbnailInfo: check thumb info:" Loading Loading @@ -880,6 +909,10 @@ public class MtpDatabase implements AutoCloseable { try { ExifInterface exif = new ExifInterface(path); if (mSkipThumbForHost) { Log.d(TAG, "getThumbnailData: Skip runtime thumbnail."); return exif.getThumbnail(); } if (exif.getThumbnailRange() != null) return exif.getThumbnail(); } catch (IOException e) { Loading media/java/android/mtp/MtpDevice.java +13 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,18 @@ public final class MtpDevice { return native_get_device_info(); } /** * Set device property SESSION_INITIATOR_VERSION_INFO * * @param propertyStr string value for device property SESSION_INITIATOR_VERSION_INFO * @return -1 for error, 0 for success * * {@hide} */ public int setDevicePropertyInitVersion(@NonNull String propertyStr) { return native_set_device_property_init_version(propertyStr); } /** * Returns the list of IDs for all storage units on this device * Information about each storage unit can be accessed via {@link #getStorageInfo}. Loading Loading @@ -421,6 +433,7 @@ public final class MtpDevice { private native boolean native_open(String deviceName, int fd); private native void native_close(); private native MtpDeviceInfo native_get_device_info(); private native int native_set_device_property_init_version(String propertyStr); private native int[] native_get_storage_ids(); private native MtpStorageInfo native_get_storage_info(int storageId); private native int[] native_get_object_handles(int storageId, int format, int objectHandle); Loading media/java/android/mtp/MtpDeviceInfo.java +27 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ public class MtpDeviceInfo { private String mSerialNumber; private int[] mOperationsSupported; private int[] mEventsSupported; private int[] mDevicePropertySupported; // only instantiated via JNI private MtpDeviceInfo() { Loading Loading @@ -143,6 +144,21 @@ public class MtpDeviceInfo { return mEventsSupported; } /** * Returns Device property code supported by the device. * * @return supported Device property code. Can be null if device does not provide the property. * * @see MtpConstants#DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER * @see MtpConstants#DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME * @see MtpConstants#DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO * * {@hide} */ public final @NonNull int[] getDevicePropertySupported() { return mDevicePropertySupported; } /** * Returns if the given operation is supported by the device or not. * @param code Operation code. Loading @@ -161,6 +177,17 @@ public class MtpDeviceInfo { return isSupported(mEventsSupported, code); } /** * Returns if the given Device property is supported by the device or not. * @param code Device property code. * @return If the given Device property is supported by the device or not. * * {@hide} */ public boolean isDevicePropertySupported(int code) { return isSupported(mDevicePropertySupported, code); } /** * Returns if the code set contains code. * @hide Loading media/jni/android_mtp_MtpDatabase.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -1131,6 +1131,7 @@ static const PropertyTableEntry kDevicePropertyTable[] = { { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR }, { MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 }, { MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MTP_TYPE_UINT32 }, { MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, MTP_TYPE_STR }, }; bool MtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) { Loading Loading @@ -1289,6 +1290,7 @@ MtpProperty* MtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { switch (property) { case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: case MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: writable = true; // fall through FALLTHROUGH_INTENDED; Loading media/jni/android_mtp_MtpDevice.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ static jfieldID field_deviceInfo_version; static jfieldID field_deviceInfo_serialNumber; static jfieldID field_deviceInfo_operationsSupported; static jfieldID field_deviceInfo_eventsSupported; static jfieldID field_deviceInfo_devicePropertySupported; // MtpStorageInfo fields static jfieldID field_storageInfo_storageId; Loading Loading @@ -129,6 +130,8 @@ static void initializeJavaIDs(JNIEnv* env) { GetFieldIDOrDie(env, clazz_deviceInfo, "mOperationsSupported", "[I"); field_deviceInfo_eventsSupported = GetFieldIDOrDie(env, clazz_deviceInfo, "mEventsSupported", "[I"); field_deviceInfo_devicePropertySupported = GetFieldIDOrDie(env, clazz_deviceInfo, "mDevicePropertySupported", "[I"); clazz_storageInfo = (jclass)env->NewGlobalRef(FindClassOrDie(env, "android/mtp/MtpStorageInfo")); Loading Loading @@ -377,9 +380,65 @@ android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz) } } assert(deviceInfo->mDeviceProperties); { const size_t size = deviceInfo->mDeviceProperties->size(); ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size))); { ScopedIntArrayRW elements(env, events.get()); if (elements.get() == NULL) { ALOGE("Could not create devicePropertySupported element."); return NULL; } for (size_t i = 0; i < size; ++i) { elements[i] = static_cast<int>(deviceInfo->mDeviceProperties->at(i)); } env->SetObjectField(info, field_deviceInfo_devicePropertySupported, events.get()); } } return info; } static jint android_mtp_MtpDevice_set_device_property_init_version(JNIEnv *env, jobject thiz, jstring property_str) { MtpDevice* const device = get_device_from_object(env, thiz); if (!device) { ALOGD("%s device is null\n", __func__); env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice."); return -1; } const char *propertyStr = env->GetStringUTFChars(property_str, NULL); if (propertyStr == NULL) { return -1; } MtpProperty* property = new MtpProperty(MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, MTP_TYPE_STR, true); if (!property) { env->ThrowNew(clazz_io_exception, "Failed to obtain property."); return -1; } if (property->getDataType() != MTP_TYPE_STR) { env->ThrowNew(clazz_io_exception, "Unexpected property data type."); return -1; } property->setCurrentValue(propertyStr); if (!device->setDevicePropValueStr(property)) { env->ThrowNew(clazz_io_exception, "Failed to obtain property value."); return -1; } env->ReleaseStringUTFChars(property_str, propertyStr); return 0; } static jintArray android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz) { Loading Loading @@ -847,6 +906,8 @@ static const JNINativeMethod gMethods[] = { {"native_close", "()V", (void *)android_mtp_MtpDevice_close}, {"native_get_device_info", "()Landroid/mtp/MtpDeviceInfo;", (void *)android_mtp_MtpDevice_get_device_info}, {"native_set_device_property_init_version", "(Ljava/lang/String;)I", (void *)android_mtp_MtpDevice_set_device_property_init_version}, {"native_get_storage_ids", "()[I", (void *)android_mtp_MtpDevice_get_storage_ids}, {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;", (void *)android_mtp_MtpDevice_get_storage_info}, Loading Loading
media/java/android/mtp/MtpDatabase.java +35 −2 Original line number Diff line number Diff line Loading @@ -101,6 +101,8 @@ public class MtpDatabase implements AutoCloseable { private int mBatteryLevel; private int mBatteryScale; private int mDeviceType; private String mHostType; private boolean mSkipThumbForHost = false; private MtpServer mServer; private MtpStorageManager mManager; Loading Loading @@ -192,6 +194,7 @@ public class MtpDatabase implements AutoCloseable { MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE, MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL, MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, }; @VisibleForNative Loading Loading @@ -408,6 +411,8 @@ public class MtpDatabase implements AutoCloseable { } context.deleteDatabase(devicePropertiesName); } mHostType = ""; mSkipThumbForHost = false; } @VisibleForNative Loading Loading @@ -672,12 +677,24 @@ public class MtpDatabase implements AutoCloseable { @VisibleForNative private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { int length; String value; switch (property) { case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: // writable string properties kept in shared preferences String value = mDeviceProperties.getString(Integer.toString(property), ""); int length = value.length(); value = mDeviceProperties.getString(Integer.toString(property), ""); length = value.length(); if (length > 255) { length = 255; } value.getChars(0, length, outStringValue, 0); outStringValue[length] = 0; return MtpConstants.RESPONSE_OK; case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: value = mHostType; length = value.length(); if (length > 255) { length = 255; } Loading Loading @@ -717,6 +734,14 @@ public class MtpDatabase implements AutoCloseable { e.putString(Integer.toString(property), stringValue); return (e.commit() ? MtpConstants.RESPONSE_OK : MtpConstants.RESPONSE_GENERAL_ERROR); case MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: mHostType = stringValue; if (stringValue.startsWith("Android/")) { Log.d(TAG, "setDeviceProperty." + Integer.toHexString(property) + "=" + stringValue); mSkipThumbForHost = true; } return MtpConstants.RESPONSE_OK; } return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED; Loading Loading @@ -838,6 +863,10 @@ public class MtpDatabase implements AutoCloseable { outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0; outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0); outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_DIMENSION, 0); if (mSkipThumbForHost) { Log.d(TAG, "getThumbnailInfo: Skip runtime thumbnail."); return true; } if (exif.getThumbnailRange() != null) { if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) { Log.d(TAG, "getThumbnailInfo: check thumb info:" Loading Loading @@ -880,6 +909,10 @@ public class MtpDatabase implements AutoCloseable { try { ExifInterface exif = new ExifInterface(path); if (mSkipThumbForHost) { Log.d(TAG, "getThumbnailData: Skip runtime thumbnail."); return exif.getThumbnail(); } if (exif.getThumbnailRange() != null) return exif.getThumbnail(); } catch (IOException e) { Loading
media/java/android/mtp/MtpDevice.java +13 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,18 @@ public final class MtpDevice { return native_get_device_info(); } /** * Set device property SESSION_INITIATOR_VERSION_INFO * * @param propertyStr string value for device property SESSION_INITIATOR_VERSION_INFO * @return -1 for error, 0 for success * * {@hide} */ public int setDevicePropertyInitVersion(@NonNull String propertyStr) { return native_set_device_property_init_version(propertyStr); } /** * Returns the list of IDs for all storage units on this device * Information about each storage unit can be accessed via {@link #getStorageInfo}. Loading Loading @@ -421,6 +433,7 @@ public final class MtpDevice { private native boolean native_open(String deviceName, int fd); private native void native_close(); private native MtpDeviceInfo native_get_device_info(); private native int native_set_device_property_init_version(String propertyStr); private native int[] native_get_storage_ids(); private native MtpStorageInfo native_get_storage_info(int storageId); private native int[] native_get_object_handles(int storageId, int format, int objectHandle); Loading
media/java/android/mtp/MtpDeviceInfo.java +27 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ public class MtpDeviceInfo { private String mSerialNumber; private int[] mOperationsSupported; private int[] mEventsSupported; private int[] mDevicePropertySupported; // only instantiated via JNI private MtpDeviceInfo() { Loading Loading @@ -143,6 +144,21 @@ public class MtpDeviceInfo { return mEventsSupported; } /** * Returns Device property code supported by the device. * * @return supported Device property code. Can be null if device does not provide the property. * * @see MtpConstants#DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER * @see MtpConstants#DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME * @see MtpConstants#DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO * * {@hide} */ public final @NonNull int[] getDevicePropertySupported() { return mDevicePropertySupported; } /** * Returns if the given operation is supported by the device or not. * @param code Operation code. Loading @@ -161,6 +177,17 @@ public class MtpDeviceInfo { return isSupported(mEventsSupported, code); } /** * Returns if the given Device property is supported by the device or not. * @param code Device property code. * @return If the given Device property is supported by the device or not. * * {@hide} */ public boolean isDevicePropertySupported(int code) { return isSupported(mDevicePropertySupported, code); } /** * Returns if the code set contains code. * @hide Loading
media/jni/android_mtp_MtpDatabase.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -1131,6 +1131,7 @@ static const PropertyTableEntry kDevicePropertyTable[] = { { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR }, { MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 }, { MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MTP_TYPE_UINT32 }, { MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, MTP_TYPE_STR }, }; bool MtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) { Loading Loading @@ -1289,6 +1290,7 @@ MtpProperty* MtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) { switch (property) { case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: case MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO: writable = true; // fall through FALLTHROUGH_INTENDED; Loading
media/jni/android_mtp_MtpDevice.cpp +61 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ static jfieldID field_deviceInfo_version; static jfieldID field_deviceInfo_serialNumber; static jfieldID field_deviceInfo_operationsSupported; static jfieldID field_deviceInfo_eventsSupported; static jfieldID field_deviceInfo_devicePropertySupported; // MtpStorageInfo fields static jfieldID field_storageInfo_storageId; Loading Loading @@ -129,6 +130,8 @@ static void initializeJavaIDs(JNIEnv* env) { GetFieldIDOrDie(env, clazz_deviceInfo, "mOperationsSupported", "[I"); field_deviceInfo_eventsSupported = GetFieldIDOrDie(env, clazz_deviceInfo, "mEventsSupported", "[I"); field_deviceInfo_devicePropertySupported = GetFieldIDOrDie(env, clazz_deviceInfo, "mDevicePropertySupported", "[I"); clazz_storageInfo = (jclass)env->NewGlobalRef(FindClassOrDie(env, "android/mtp/MtpStorageInfo")); Loading Loading @@ -377,9 +380,65 @@ android_mtp_MtpDevice_get_device_info(JNIEnv *env, jobject thiz) } } assert(deviceInfo->mDeviceProperties); { const size_t size = deviceInfo->mDeviceProperties->size(); ScopedLocalRef<jintArray> events(env, static_cast<jintArray>(env->NewIntArray(size))); { ScopedIntArrayRW elements(env, events.get()); if (elements.get() == NULL) { ALOGE("Could not create devicePropertySupported element."); return NULL; } for (size_t i = 0; i < size; ++i) { elements[i] = static_cast<int>(deviceInfo->mDeviceProperties->at(i)); } env->SetObjectField(info, field_deviceInfo_devicePropertySupported, events.get()); } } return info; } static jint android_mtp_MtpDevice_set_device_property_init_version(JNIEnv *env, jobject thiz, jstring property_str) { MtpDevice* const device = get_device_from_object(env, thiz); if (!device) { ALOGD("%s device is null\n", __func__); env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice."); return -1; } const char *propertyStr = env->GetStringUTFChars(property_str, NULL); if (propertyStr == NULL) { return -1; } MtpProperty* property = new MtpProperty(MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO, MTP_TYPE_STR, true); if (!property) { env->ThrowNew(clazz_io_exception, "Failed to obtain property."); return -1; } if (property->getDataType() != MTP_TYPE_STR) { env->ThrowNew(clazz_io_exception, "Unexpected property data type."); return -1; } property->setCurrentValue(propertyStr); if (!device->setDevicePropValueStr(property)) { env->ThrowNew(clazz_io_exception, "Failed to obtain property value."); return -1; } env->ReleaseStringUTFChars(property_str, propertyStr); return 0; } static jintArray android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz) { Loading Loading @@ -847,6 +906,8 @@ static const JNINativeMethod gMethods[] = { {"native_close", "()V", (void *)android_mtp_MtpDevice_close}, {"native_get_device_info", "()Landroid/mtp/MtpDeviceInfo;", (void *)android_mtp_MtpDevice_get_device_info}, {"native_set_device_property_init_version", "(Ljava/lang/String;)I", (void *)android_mtp_MtpDevice_set_device_property_init_version}, {"native_get_storage_ids", "()[I", (void *)android_mtp_MtpDevice_get_storage_ids}, {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;", (void *)android_mtp_MtpDevice_get_storage_info}, Loading