Merge "MTP: Skip runtime thumbnail generation for Android Host" into sc-dev

This commit is contained in:
James Wei
2021-06-23 03:53:24 +00:00
committed by Android (Google) Code Review
5 changed files with 138 additions and 2 deletions

View File

@@ -101,6 +101,8 @@ public class MtpDatabase implements AutoCloseable {
private int mBatteryLevel; private int mBatteryLevel;
private int mBatteryScale; private int mBatteryScale;
private int mDeviceType; private int mDeviceType;
private String mHostType;
private boolean mSkipThumbForHost = false;
private MtpServer mServer; private MtpServer mServer;
private MtpStorageManager mManager; private MtpStorageManager mManager;
@@ -192,6 +194,7 @@ public class MtpDatabase implements AutoCloseable {
MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE, MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE,
MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL, MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL,
MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE,
MtpConstants.DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO,
}; };
@VisibleForNative @VisibleForNative
@@ -408,6 +411,8 @@ public class MtpDatabase implements AutoCloseable {
} }
context.deleteDatabase(devicePropertiesName); context.deleteDatabase(devicePropertiesName);
} }
mHostType = "";
mSkipThumbForHost = false;
} }
@VisibleForNative @VisibleForNative
@@ -672,12 +677,24 @@ public class MtpDatabase implements AutoCloseable {
@VisibleForNative @VisibleForNative
private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) { private int getDeviceProperty(int property, long[] outIntValue, char[] outStringValue) {
int length;
String value;
switch (property) { switch (property) {
case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MtpConstants.DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: case MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
// writable string properties kept in shared preferences // writable string properties kept in shared preferences
String value = mDeviceProperties.getString(Integer.toString(property), ""); value = mDeviceProperties.getString(Integer.toString(property), "");
int length = value.length(); 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) { if (length > 255) {
length = 255; length = 255;
} }
@@ -717,6 +734,14 @@ public class MtpDatabase implements AutoCloseable {
e.putString(Integer.toString(property), stringValue); e.putString(Integer.toString(property), stringValue);
return (e.commit() ? MtpConstants.RESPONSE_OK return (e.commit() ? MtpConstants.RESPONSE_OK
: MtpConstants.RESPONSE_GENERAL_ERROR); : 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; return MtpConstants.RESPONSE_DEVICE_PROP_NOT_SUPPORTED;
@@ -838,6 +863,10 @@ public class MtpDatabase implements AutoCloseable {
outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0; outLongs[0] = thumbOffsetAndSize != null ? thumbOffsetAndSize[1] : 0;
outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0); outLongs[1] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_X_DIMENSION, 0);
outLongs[2] = exif.getAttributeInt(ExifInterface.TAG_PIXEL_Y_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 (exif.getThumbnailRange() != null) {
if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) { if ((outLongs[0] == 0) || (outLongs[1] == 0) || (outLongs[2] == 0)) {
Log.d(TAG, "getThumbnailInfo: check thumb info:" Log.d(TAG, "getThumbnailInfo: check thumb info:"
@@ -880,6 +909,10 @@ public class MtpDatabase implements AutoCloseable {
try { try {
ExifInterface exif = new ExifInterface(path); ExifInterface exif = new ExifInterface(path);
if (mSkipThumbForHost) {
Log.d(TAG, "getThumbnailData: Skip runtime thumbnail.");
return exif.getThumbnail();
}
if (exif.getThumbnailRange() != null) if (exif.getThumbnailRange() != null)
return exif.getThumbnail(); return exif.getThumbnail();
} catch (IOException e) { } catch (IOException e) {

View File

@@ -169,6 +169,18 @@ public final class MtpDevice {
return native_get_device_info(); 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 * Returns the list of IDs for all storage units on this device
* Information about each storage unit can be accessed via {@link #getStorageInfo}. * Information about each storage unit can be accessed via {@link #getStorageInfo}.
@@ -421,6 +433,7 @@ public final class MtpDevice {
private native boolean native_open(String deviceName, int fd); private native boolean native_open(String deviceName, int fd);
private native void native_close(); private native void native_close();
private native MtpDeviceInfo native_get_device_info(); 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 int[] native_get_storage_ids();
private native MtpStorageInfo native_get_storage_info(int storageId); private native MtpStorageInfo native_get_storage_info(int storageId);
private native int[] native_get_object_handles(int storageId, int format, int objectHandle); private native int[] native_get_object_handles(int storageId, int format, int objectHandle);

View File

@@ -31,6 +31,7 @@ public class MtpDeviceInfo {
private String mSerialNumber; private String mSerialNumber;
private int[] mOperationsSupported; private int[] mOperationsSupported;
private int[] mEventsSupported; private int[] mEventsSupported;
private int[] mDevicePropertySupported;
// only instantiated via JNI // only instantiated via JNI
private MtpDeviceInfo() { private MtpDeviceInfo() {
@@ -143,6 +144,21 @@ public class MtpDeviceInfo {
return mEventsSupported; 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. * Returns if the given operation is supported by the device or not.
* @param code Operation code. * @param code Operation code.
@@ -161,6 +177,17 @@ public class MtpDeviceInfo {
return isSupported(mEventsSupported, code); 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. * Returns if the code set contains code.
* @hide * @hide

View File

@@ -1131,6 +1131,7 @@ static const PropertyTableEntry kDevicePropertyTable[] = {
{ MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR }, { MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
{ MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 }, { MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 },
{ MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MTP_TYPE_UINT32 }, { 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) { bool MtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
@@ -1289,6 +1290,7 @@ MtpProperty* MtpDatabase::getDevicePropertyDesc(MtpDeviceProperty property) {
switch (property) { switch (property) {
case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER: case MTP_DEVICE_PROPERTY_SYNCHRONIZATION_PARTNER:
case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME: case MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME:
case MTP_DEVICE_PROPERTY_SESSION_INITIATOR_VERSION_INFO:
writable = true; writable = true;
// fall through // fall through
FALLTHROUGH_INTENDED; FALLTHROUGH_INTENDED;

View File

@@ -72,6 +72,7 @@ static jfieldID field_deviceInfo_version;
static jfieldID field_deviceInfo_serialNumber; static jfieldID field_deviceInfo_serialNumber;
static jfieldID field_deviceInfo_operationsSupported; static jfieldID field_deviceInfo_operationsSupported;
static jfieldID field_deviceInfo_eventsSupported; static jfieldID field_deviceInfo_eventsSupported;
static jfieldID field_deviceInfo_devicePropertySupported;
// MtpStorageInfo fields // MtpStorageInfo fields
static jfieldID field_storageInfo_storageId; static jfieldID field_storageInfo_storageId;
@@ -129,6 +130,8 @@ static void initializeJavaIDs(JNIEnv* env) {
GetFieldIDOrDie(env, clazz_deviceInfo, "mOperationsSupported", "[I"); GetFieldIDOrDie(env, clazz_deviceInfo, "mOperationsSupported", "[I");
field_deviceInfo_eventsSupported = field_deviceInfo_eventsSupported =
GetFieldIDOrDie(env, clazz_deviceInfo, "mEventsSupported", "[I"); GetFieldIDOrDie(env, clazz_deviceInfo, "mEventsSupported", "[I");
field_deviceInfo_devicePropertySupported =
GetFieldIDOrDie(env, clazz_deviceInfo, "mDevicePropertySupported", "[I");
clazz_storageInfo = clazz_storageInfo =
(jclass)env->NewGlobalRef(FindClassOrDie(env, "android/mtp/MtpStorageInfo")); (jclass)env->NewGlobalRef(FindClassOrDie(env, "android/mtp/MtpStorageInfo"));
@@ -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; 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 static jintArray
android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz) android_mtp_MtpDevice_get_storage_ids(JNIEnv *env, jobject thiz)
{ {
@@ -847,6 +906,8 @@ static const JNINativeMethod gMethods[] = {
{"native_close", "()V", (void *)android_mtp_MtpDevice_close}, {"native_close", "()V", (void *)android_mtp_MtpDevice_close},
{"native_get_device_info", "()Landroid/mtp/MtpDeviceInfo;", {"native_get_device_info", "()Landroid/mtp/MtpDeviceInfo;",
(void *)android_mtp_MtpDevice_get_device_info}, (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_ids", "()[I", (void *)android_mtp_MtpDevice_get_storage_ids},
{"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;", {"native_get_storage_info", "(I)Landroid/mtp/MtpStorageInfo;",
(void *)android_mtp_MtpDevice_get_storage_info}, (void *)android_mtp_MtpDevice_get_storage_info},