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 mBatteryScale;
private int mDeviceType;
private String mHostType;
private boolean mSkipThumbForHost = false;
private MtpServer mServer;
private MtpStorageManager mManager;
@@ -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
@@ -408,6 +411,8 @@ public class MtpDatabase implements AutoCloseable {
}
context.deleteDatabase(devicePropertiesName);
}
mHostType = "";
mSkipThumbForHost = false;
}
@VisibleForNative
@@ -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;
}
@@ -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;
@@ -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:"
@@ -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) {

View File

@@ -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}.
@@ -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);

View File

@@ -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() {
@@ -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.
@@ -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

View File

@@ -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) {
@@ -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;

View File

@@ -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;
@@ -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"));
@@ -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)
{
@@ -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},