Change offset and size arguments of MtpDevice#getPartialObject to Java
long.
To represents full range of 32-bit unsigned integer, we should use
jlong instead of jint.
BUG=26284424
Change-Id: Id3fa9e3daa778c204ab8e38f821d454c709c317a
diff --git a/api/current.txt b/api/current.txt
index 4189409..5a85f6f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -22556,7 +22556,7 @@
method public int[] getObjectHandles(int, int, int);
method public android.mtp.MtpObjectInfo getObjectInfo(int);
method public long getParent(int);
- method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+ method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
method public long getStorageId(int);
method public int[] getStorageIds();
method public android.mtp.MtpStorageInfo getStorageInfo(int);
diff --git a/api/system-current.txt b/api/system-current.txt
index 35f4214..b203a92 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24103,7 +24103,7 @@
method public int[] getObjectHandles(int, int, int);
method public android.mtp.MtpObjectInfo getObjectInfo(int);
method public long getParent(int);
- method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+ method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
method public long getStorageId(int);
method public int[] getStorageIds();
method public android.mtp.MtpStorageInfo getStorageInfo(int);
diff --git a/api/test-current.txt b/api/test-current.txt
index f15ab58..335b783 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -22564,7 +22564,7 @@
method public int[] getObjectHandles(int, int, int);
method public android.mtp.MtpObjectInfo getObjectInfo(int);
method public long getParent(int);
- method public int getPartialObject(int, int, int, byte[]) throws java.io.IOException;
+ method public long getPartialObject(int, long, long, byte[]) throws java.io.IOException;
method public long getStorageId(int);
method public int[] getStorageIds();
method public android.mtp.MtpStorageInfo getStorageInfo(int);
diff --git a/core/java/com/android/internal/util/Preconditions.java b/core/java/com/android/internal/util/Preconditions.java
index b692a18..5127408 100644
--- a/core/java/com/android/internal/util/Preconditions.java
+++ b/core/java/com/android/internal/util/Preconditions.java
@@ -218,6 +218,33 @@
}
/**
+ * Ensures that the argument long value is within the inclusive range.
+ *
+ * @param value a long value
+ * @param lower the lower endpoint of the inclusive range
+ * @param upper the upper endpoint of the inclusive range
+ * @param valueName the name of the argument to use if the check fails
+ *
+ * @return the validated long value
+ *
+ * @throws IllegalArgumentException if {@code value} was not within the range
+ */
+ public static long checkArgumentInRange(long value, long lower, long upper,
+ String valueName) {
+ if (value < lower) {
+ throw new IllegalArgumentException(
+ String.format(
+ "%s is out of range of [%d, %d] (too low)", valueName, lower, upper));
+ } else if (value > upper) {
+ throw new IllegalArgumentException(
+ String.format(
+ "%s is out of range of [%d, %d] (too high)", valueName, lower, upper));
+ }
+
+ return value;
+ }
+
+ /**
* Ensures that the array is not {@code null}, and none of its elements are {@code null}.
*
* @param value an array of boxed objects
diff --git a/media/java/android/mtp/MtpDevice.java b/media/java/android/mtp/MtpDevice.java
index d24c5e8..4379a99 100644
--- a/media/java/android/mtp/MtpDevice.java
+++ b/media/java/android/mtp/MtpDevice.java
@@ -21,6 +21,8 @@
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
+import com.android.internal.util.Preconditions;
+
import java.io.IOException;
/**
@@ -164,12 +166,14 @@
* of the data and speed of the devices.
*
* @param objectHandle handle of the object to read
- * @param offset Start index of reading range.
- * @param size Size of reading range.
+ * @param offset Start index of reading range. It must be a non-negative value at most
+ * 0xffffffff.
+ * @param size Size of reading range. It must be a non-negative value at most 0xffffffff. If
+ * 0xffffffff is specified, the method obtains the full bytes of object.
* @param buffer Array to write data.
* @return Size of bytes that are actually read.
*/
- public int getPartialObject(int objectHandle, int offset, int size, byte[] buffer)
+ public long getPartialObject(int objectHandle, long offset, long size, byte[] buffer)
throws IOException {
return native_get_partial_object(objectHandle, offset, size, buffer);
}
@@ -340,8 +344,8 @@
private native int[] native_get_object_handles(int storageId, int format, int objectHandle);
private native MtpObjectInfo native_get_object_info(int objectHandle);
private native byte[] native_get_object(int objectHandle, int objectSize);
- private native int native_get_partial_object(
- int objectHandle, int offset, int objectSize, byte[] buffer) throws IOException;
+ private native long native_get_partial_object(
+ int objectHandle, long offset, long objectSize, byte[] buffer) throws IOException;
private native byte[] native_get_thumbnail(int objectHandle);
private native boolean native_delete_object(int objectHandle);
private native long native_get_parent(int objectHandle);
diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp
index 130dfe5..b1b3b62 100644
--- a/media/jni/android_mtp_MtpDevice.cpp
+++ b/media/jni/android_mtp_MtpDevice.cpp
@@ -372,12 +372,12 @@
return nullptr;
}
-static jint
+static jlong
android_mtp_MtpDevice_get_partial_object(JNIEnv *env,
jobject thiz,
jint objectID,
- jint offset,
- jint size,
+ jlong offset,
+ jlong size,
jbyteArray array)
{
if (!array) {
@@ -385,6 +385,22 @@
return -1;
}
+ if (offset < 0 || 0xffffffffL < offset) {
+ jniThrowException(
+ env,
+ "java/lang/IllegalArgumentException",
+ "Offset argument must be a 32-bit unsigned integer.");
+ return -1;
+ }
+
+ if (size < 0 || 0xffffffffL < size) {
+ jniThrowException(
+ env,
+ "java/lang/IllegalArgumentException",
+ "Size argument must be a 32-bit unsigned integer.");
+ return -1;
+ }
+
MtpDevice* const device = get_device_from_object(env, thiz);
if (!device) {
jniThrowException(env, "java/io/IOException", "Failed to obtain MtpDevice.");
@@ -393,16 +409,13 @@
JavaArrayWriter writer(env, array);
uint32_t written_size;
- bool success = device->readPartialObject(
+ const bool success = device->readPartialObject(
objectID, offset, size, &written_size, JavaArrayWriter::writeTo, &writer);
if (!success) {
jniThrowException(env, "java/io/IOException", "Failed to read data.");
return -1;
}
- // Note: assumption here is that a negative value will be treated as unsigned on the Java
- // level.
- // TODO: Make sure that actually holds.
- return static_cast<jint>(written_size);
+ return static_cast<jlong>(written_size);
}
static jbyteArray
@@ -615,7 +628,7 @@
{"native_get_object_info", "(I)Landroid/mtp/MtpObjectInfo;",
(void *)android_mtp_MtpDevice_get_object_info},
{"native_get_object", "(II)[B",(void *)android_mtp_MtpDevice_get_object},
- {"native_get_partial_object", "(III[B)I", (void *)android_mtp_MtpDevice_get_partial_object},
+ {"native_get_partial_object", "(IJJ[B)J", (void *)android_mtp_MtpDevice_get_partial_object},
{"native_get_thumbnail", "(I)[B",(void *)android_mtp_MtpDevice_get_thumbnail},
{"native_delete_object", "(I)Z", (void *)android_mtp_MtpDevice_delete_object},
{"native_get_parent", "(I)J", (void *)android_mtp_MtpDevice_get_parent},