Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4f1a6d6f authored by James Wei's avatar James Wei
Browse files

MTP: Skip runtime thumbnail generation for Android Host

Android Host is not capable to deal with the long processing time for
runtime thumbnail generation.
Skip runtime thumbnail generation for Android Host
but keep no impact to other Host

Bug: 188752500
Test: atest MtpTests
Test: atest MtpServerTest
Test: atest MtpServiceTests
Test: manual test on Windows 10 File Explorer
Test: manual test on Android Host Files App
Change-Id: I24ed3bb29c5a6912398a9e00e7748fd406cf6a64
parent 9c44e61f
Loading
Loading
Loading
Loading
+35 −2
Original line number Diff line number Diff line
@@ -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) {
+13 −0
Original line number Diff line number Diff line
@@ -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);
+27 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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;
+61 −0
Original line number Diff line number Diff line
@@ -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},