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

Commit 787821bc authored by Daichi Hirono's avatar Daichi Hirono
Browse files

Add getObjectSizeLong hidden API to MtpDevice class.

In the MTP spec, the object size is stored in MtpObjectInfo as unsigned
32-bit integer and fetched by the getObjectInfo operation. For the
objects that are more than 4GB, the object size is provided as one of
extra properties, which are fetched by different operation.

The CL adds to getObjectSizeLong hidden method to Java MtpDevice class
so that client code can obtain 4GB+ object size.

BUG=27805369

Change-Id: I8a5b85c8db39734f00e49709c61b271eb48ff33d
parent fe952f3a
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -355,6 +355,18 @@ public final class MtpDevice {
        }
    }

    /**
     * Returns object size in 64-bit integer.
     *
     * The object size stored in MtpObjectInfo is unsigned 32-bit integer.
     * The methods reads 64-bit object size from the object property so that it can fetch 4GB+
     * object size correctly.
     * @hide
     */
    public long getObjectSizeLong(int handle, int format) throws IOException {
        return native_get_object_size_long(handle, format);
    }

    // used by the JNI code
    private long mNativeContext;

@@ -381,4 +393,5 @@ public final class MtpDevice {
    private native int native_submit_event_request();
    private native MtpEvent native_reap_event_request(int handle);
    private native void native_discard_event_request(int handle);
    private native long native_get_object_size_long(int handle, int format) throws IOException;
}
+37 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include "MtpDeviceInfo.h"
#include "MtpStorageInfo.h"
#include "MtpObjectInfo.h"
#include "MtpProperty.h"

using namespace android;

@@ -700,6 +701,40 @@ static void android_mtp_MtpDevice_discard_event_request(JNIEnv *env, jobject thi
    device->discardEventRequest(seq);
}

static jlong android_mtp_MtpDevice_get_object_size_long(
        JNIEnv *env, jobject thiz, jint handle, jint format) {
    MtpDevice* const device = get_device_from_object(env, thiz);
    if (!device) {
        env->ThrowNew(clazz_io_exception, "Failed to obtain MtpDevice.");
        return 0;
    }

    std::unique_ptr<MtpProperty> property(
            device->getObjectPropDesc(MTP_PROPERTY_OBJECT_SIZE, format));
    if (!property) {
        env->ThrowNew(clazz_io_exception, "Failed to obtain property desc.");
        return 0;
    }

    if (property->getDataType() != MTP_TYPE_UINT64) {
        env->ThrowNew(clazz_io_exception, "Unexpected property data type.");
        return 0;
    }

    if (!device->getObjectPropValue(handle, property.get())) {
        env->ThrowNew(clazz_io_exception, "Failed to obtain property value.");
        return 0;
    }

    const jlong object_size = static_cast<jlong>(property->getCurrentValue().u.u64);
    if (object_size < 0) {
        env->ThrowNew(clazz_io_exception, "Object size is too large to express as jlong.");
        return 0;
    }

    return object_size;
}

// ----------------------------------------------------------------------------

static const JNINativeMethod gMethods[] = {
@@ -733,6 +768,8 @@ static const JNINativeMethod gMethods[] = {
    {"native_reap_event_request",   "(I)Landroid/mtp/MtpEvent;",
                                            (void *)android_mtp_MtpDevice_reap_event_request},
    {"native_discard_event_request", "(I)V", (void *)android_mtp_MtpDevice_discard_event_request},

    {"native_get_object_size_long", "(II)J", (void *)android_mtp_MtpDevice_get_object_size_long},
};

int register_android_mtp_MtpDevice(JNIEnv *env)