blob: 6970cffa2c6e0fe89a281a90e4a3fd4247caa303 [file] [log] [blame]
Mike Lockwood8182e722010-12-30 15:38:45 -05001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.mtp;
18
Daichi Hirono60fa3612016-04-19 12:50:34 +090019import android.annotation.NonNull;
20import android.annotation.Nullable;
Mike Lockwoodc4308f02011-03-01 08:04:54 -080021import android.hardware.usb.UsbDevice;
Mike Lockwoodacc29cc2011-03-11 08:18:08 -050022import android.hardware.usb.UsbDeviceConnection;
Daichi Hirono0b494662015-09-10 20:38:15 +090023import android.os.CancellationSignal;
Tomasz Mikolajewski74d4ff82015-08-04 18:34:03 +090024import android.os.ParcelFileDescriptor;
Mike Lockwood8182e722010-12-30 15:38:45 -050025
Daichi Hirono2dd48252016-01-12 15:46:41 +090026import com.android.internal.util.Preconditions;
27
Daichi Hirono52da3ad2015-12-24 17:52:10 +090028import java.io.IOException;
29
Mike Lockwood8182e722010-12-30 15:38:45 -050030/**
Scott Main0cdd9f72011-05-05 15:53:44 -070031 * This class represents an MTP or PTP device connected on the USB host bus. An application can
32 * instantiate an object of this type, by referencing an attached {@link
33 * android.hardware.usb.UsbDevice} and then use methods in this class to get information about the
34 * device and objects stored on it, as well as open the connection and transfer data.
Mike Lockwood8182e722010-12-30 15:38:45 -050035 */
36public final class MtpDevice {
37
38 private static final String TAG = "MtpDevice";
39
40 private final UsbDevice mDevice;
41
42 static {
43 System.loadLibrary("media_jni");
44 }
45
Mike Lockwood540380f2011-02-09 21:48:53 -050046 /**
47 * MtpClient constructor
48 *
Mike Lockwoodc4308f02011-03-01 08:04:54 -080049 * @param device the {@link android.hardware.usb.UsbDevice} for the MTP or PTP device
Mike Lockwood540380f2011-02-09 21:48:53 -050050 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +090051 public MtpDevice(@NonNull UsbDevice device) {
52 Preconditions.checkNotNull(device);
Mike Lockwood8182e722010-12-30 15:38:45 -050053 mDevice = device;
54 }
55
Mike Lockwood540380f2011-02-09 21:48:53 -050056 /**
Mike Lockwoodacc29cc2011-03-11 08:18:08 -050057 * Opens the MTP device. Once the device is open it takes ownership of the
Daichi Hirono0b494662015-09-10 20:38:15 +090058 * {@link android.hardware.usb.UsbDeviceConnection}.
Mike Lockwoodacc29cc2011-03-11 08:18:08 -050059 * The connection will be closed when you call {@link #close()}
60 * The connection will also be closed if this method fails.
Mike Lockwood540380f2011-02-09 21:48:53 -050061 *
Mike Lockwoodacc29cc2011-03-11 08:18:08 -050062 * @param connection an open {@link android.hardware.usb.UsbDeviceConnection} for the device
Mike Lockwood540380f2011-02-09 21:48:53 -050063 * @return true if the device was successfully opened.
64 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +090065 public boolean open(@NonNull UsbDeviceConnection connection) {
Mike Lockwoodacc29cc2011-03-11 08:18:08 -050066 boolean result = native_open(mDevice.getDeviceName(), connection.getFileDescriptor());
67 if (!result) {
68 connection.close();
Mike Lockwood8182e722010-12-30 15:38:45 -050069 }
Mike Lockwoodacc29cc2011-03-11 08:18:08 -050070 return result;
Mike Lockwood8182e722010-12-30 15:38:45 -050071 }
72
Mike Lockwood540380f2011-02-09 21:48:53 -050073 /**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -040074 * Closes all resources related to the MtpDevice object.
75 * After this is called, the object can not be used until {@link #open} is called again
76 * with a new {@link android.hardware.usb.UsbDeviceConnection}.
Mike Lockwood540380f2011-02-09 21:48:53 -050077 */
Mike Lockwood8182e722010-12-30 15:38:45 -050078 public void close() {
Mike Lockwood8182e722010-12-30 15:38:45 -050079 native_close();
80 }
81
82 @Override
83 protected void finalize() throws Throwable {
Mike Lockwood8182e722010-12-30 15:38:45 -050084 try {
85 native_close();
86 } finally {
87 super.finalize();
88 }
89 }
90
Mike Lockwood540380f2011-02-09 21:48:53 -050091 /**
92 * Returns the name of the USB device
Mike Lockwood11dd5ae2011-04-01 14:00:08 -040093 * This returns the same value as {@link android.hardware.usb.UsbDevice#getDeviceName}
94 * for the device's {@link android.hardware.usb.UsbDevice}
Mike Lockwood540380f2011-02-09 21:48:53 -050095 *
96 * @return the device name
97 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +090098 public @NonNull String getDeviceName() {
Mike Lockwood8182e722010-12-30 15:38:45 -050099 return mDevice.getDeviceName();
100 }
101
Mike Lockwood540380f2011-02-09 21:48:53 -0500102 /**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400103 * Returns the USB ID of the USB device.
104 * This returns the same value as {@link android.hardware.usb.UsbDevice#getDeviceId}
105 * for the device's {@link android.hardware.usb.UsbDevice}
Mike Lockwood540380f2011-02-09 21:48:53 -0500106 *
107 * @return the device ID
108 */
Mike Lockwood8182e722010-12-30 15:38:45 -0500109 public int getDeviceId() {
110 return mDevice.getDeviceId();
111 }
112
113 @Override
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900114 public @NonNull String toString() {
Mike Lockwood8182e722010-12-30 15:38:45 -0500115 return mDevice.getDeviceName();
116 }
117
Mike Lockwood540380f2011-02-09 21:48:53 -0500118 /**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400119 * Returns the {@link MtpDeviceInfo} for this device
Mike Lockwood540380f2011-02-09 21:48:53 -0500120 *
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900121 * @return the device info, or null if fetching device info fails
Mike Lockwood540380f2011-02-09 21:48:53 -0500122 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900123 public @Nullable MtpDeviceInfo getDeviceInfo() {
Mike Lockwood8182e722010-12-30 15:38:45 -0500124 return native_get_device_info();
125 }
126
Mike Lockwood540380f2011-02-09 21:48:53 -0500127 /**
128 * Returns the list of IDs for all storage units on this device
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400129 * Information about each storage unit can be accessed via {@link #getStorageInfo}.
Mike Lockwood540380f2011-02-09 21:48:53 -0500130 *
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900131 * @return the list of storage IDs, or null if fetching storage IDs fails
Mike Lockwood540380f2011-02-09 21:48:53 -0500132 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900133 public @Nullable int[] getStorageIds() {
Mike Lockwood8182e722010-12-30 15:38:45 -0500134 return native_get_storage_ids();
135 }
136
Mike Lockwood540380f2011-02-09 21:48:53 -0500137 /**
138 * Returns the list of object handles for all objects on the given storage unit,
139 * with the given format and parent.
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400140 * Information about each object can be accessed via {@link #getObjectInfo}.
Mike Lockwood540380f2011-02-09 21:48:53 -0500141 *
142 * @param storageId the storage unit to query
143 * @param format the format of the object to return, or zero for all formats
Daichi Hirono660727c2015-06-12 10:45:08 +0900144 * @param objectHandle the parent object to query, -1 for the storage root,
145 * or zero for all objects
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900146 * @return the object handles, or null if fetching object handles fails
Mike Lockwood540380f2011-02-09 21:48:53 -0500147 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900148 public @Nullable int[] getObjectHandles(int storageId, int format, int objectHandle) {
Mike Lockwood8182e722010-12-30 15:38:45 -0500149 return native_get_object_handles(storageId, format, objectHandle);
150 }
151
Mike Lockwood540380f2011-02-09 21:48:53 -0500152 /**
153 * Returns the data for an object as a byte array.
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400154 * This call may block for an arbitrary amount of time depending on the size
155 * of the data and speed of the devices.
Mike Lockwood540380f2011-02-09 21:48:53 -0500156 *
157 * @param objectHandle handle of the object to read
158 * @param objectSize the size of the object (this should match
Daichi Hironoe0e66542016-01-15 14:42:53 +0900159 * {@link MtpObjectInfo#getCompressedSize})
Mike Lockwood540380f2011-02-09 21:48:53 -0500160 * @return the object's data, or null if reading fails
161 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900162 public @Nullable byte[] getObject(int objectHandle, int objectSize) {
Daichi Hironoe0e66542016-01-15 14:42:53 +0900163 Preconditions.checkArgumentNonnegative(objectSize, "objectSize should not be negative");
Mike Lockwood8182e722010-12-30 15:38:45 -0500164 return native_get_object(objectHandle, objectSize);
165 }
166
Mike Lockwood540380f2011-02-09 21:48:53 -0500167 /**
Daichi Hirono52da3ad2015-12-24 17:52:10 +0900168 * Obtains object bytes in the specified range and writes it to an array.
169 * This call may block for an arbitrary amount of time depending on the size
170 * of the data and speed of the devices.
171 *
172 * @param objectHandle handle of the object to read
Daichi Hirono2dd48252016-01-12 15:46:41 +0900173 * @param offset Start index of reading range. It must be a non-negative value at most
174 * 0xffffffff.
Daichi Hirono399df702016-04-13 11:07:44 +0900175 * @param size Size of reading range. It must be a non-negative value at most Integer.MAX_VALUE
176 * or 0xffffffff. If 0xffffffff is specified, the method obtains the full bytes of object.
Daichi Hirono52da3ad2015-12-24 17:52:10 +0900177 * @param buffer Array to write data.
178 * @return Size of bytes that are actually read.
179 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900180 public long getPartialObject(int objectHandle, long offset, long size, @NonNull byte[] buffer)
Daichi Hirono52da3ad2015-12-24 17:52:10 +0900181 throws IOException {
182 return native_get_partial_object(objectHandle, offset, size, buffer);
183 }
184
185 /**
Daichi Hirono038832b2016-01-22 19:34:25 +0900186 * Obtains object bytes in the specified range and writes it to an array.
187 * This call may block for an arbitrary amount of time depending on the size
188 * of the data and speed of the devices.
189 *
190 * This is a vender-extended operation supported by Android that enables us to pass
191 * unsigned 64-bit offset. Check if the MTP device supports the operation by using
192 * {@link MtpDeviceInfo#getOperationsSupported()}.
193 *
194 * @param objectHandle handle of the object to read
195 * @param offset Start index of reading range. It must be a non-negative value.
Daichi Hirono399df702016-04-13 11:07:44 +0900196 * @param size Size of reading range. It must be a non-negative value at most Integer.MAX_VALUE.
Daichi Hirono038832b2016-01-22 19:34:25 +0900197 * @param buffer Array to write data.
198 * @return Size of bytes that are actually read.
199 * @see MtpConstants#OPERATION_GET_PARTIAL_OBJECT_64
200 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900201 public long getPartialObject64(int objectHandle, long offset, long size, @NonNull byte[] buffer)
Daichi Hirono038832b2016-01-22 19:34:25 +0900202 throws IOException {
203 return native_get_partial_object_64(objectHandle, offset, size, buffer);
204 }
205
206 /**
Mike Lockwood540380f2011-02-09 21:48:53 -0500207 * Returns the thumbnail data for an object as a byte array.
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400208 * The size and format of the thumbnail data can be determined via
209 * {@link MtpObjectInfo#getThumbCompressedSize} and
210 * {@link MtpObjectInfo#getThumbFormat}.
211 * For typical devices the format is JPEG.
Mike Lockwood540380f2011-02-09 21:48:53 -0500212 *
213 * @param objectHandle handle of the object to read
214 * @return the object's thumbnail, or null if reading fails
215 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900216 public @Nullable byte[] getThumbnail(int objectHandle) {
Mike Lockwood8182e722010-12-30 15:38:45 -0500217 return native_get_thumbnail(objectHandle);
218 }
219
Mike Lockwood540380f2011-02-09 21:48:53 -0500220 /**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400221 * Retrieves the {@link MtpStorageInfo} for a storage unit.
Mike Lockwood540380f2011-02-09 21:48:53 -0500222 *
223 * @param storageId the ID of the storage unit
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900224 * @return the MtpStorageInfo, or null if fetching storage info fails
Mike Lockwood540380f2011-02-09 21:48:53 -0500225 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900226 public @Nullable MtpStorageInfo getStorageInfo(int storageId) {
Mike Lockwood8182e722010-12-30 15:38:45 -0500227 return native_get_storage_info(storageId);
228 }
229
Mike Lockwood540380f2011-02-09 21:48:53 -0500230 /**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400231 * Retrieves the {@link MtpObjectInfo} for an object.
Mike Lockwood540380f2011-02-09 21:48:53 -0500232 *
233 * @param objectHandle the handle of the object
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900234 * @return the MtpObjectInfo, or null if fetching object info fails
Mike Lockwood540380f2011-02-09 21:48:53 -0500235 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900236 public @Nullable MtpObjectInfo getObjectInfo(int objectHandle) {
Mike Lockwood8182e722010-12-30 15:38:45 -0500237 return native_get_object_info(objectHandle);
238 }
239
Mike Lockwood540380f2011-02-09 21:48:53 -0500240 /**
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400241 * Deletes an object on the device. This call may block, since
242 * deleting a directory containing many files may take a long time
243 * on some devices.
Mike Lockwood540380f2011-02-09 21:48:53 -0500244 *
245 * @param objectHandle handle of the object to delete
246 * @return true if the deletion succeeds
247 */
Mike Lockwood8182e722010-12-30 15:38:45 -0500248 public boolean deleteObject(int objectHandle) {
249 return native_delete_object(objectHandle);
250 }
251
Mike Lockwood540380f2011-02-09 21:48:53 -0500252 /**
253 * Retrieves the object handle for the parent of an object on the device.
254 *
255 * @param objectHandle handle of the object to query
256 * @return the parent's handle, or zero if it is in the root of the storage
257 */
Mike Lockwood8182e722010-12-30 15:38:45 -0500258 public long getParent(int objectHandle) {
259 return native_get_parent(objectHandle);
260 }
261
Mike Lockwood540380f2011-02-09 21:48:53 -0500262 /**
263 * Retrieves the ID of the storage unit containing the given object on the device.
264 *
265 * @param objectHandle handle of the object to query
266 * @return the object's storage unit ID
267 */
Mike Lockwood62cfeeb2011-03-11 18:39:03 -0500268 public long getStorageId(int objectHandle) {
Mike Lockwood8182e722010-12-30 15:38:45 -0500269 return native_get_storage_id(objectHandle);
270 }
271
Mike Lockwood540380f2011-02-09 21:48:53 -0500272 /**
273 * Copies the data for an object to a file in external storage.
Mike Lockwood11dd5ae2011-04-01 14:00:08 -0400274 * This call may block for an arbitrary amount of time depending on the size
275 * of the data and speed of the devices.
Mike Lockwood540380f2011-02-09 21:48:53 -0500276 *
277 * @param objectHandle handle of the object to read
278 * @param destPath path to destination for the file transfer.
279 * This path should be in the external storage as defined by
280 * {@link android.os.Environment#getExternalStorageDirectory}
281 * @return true if the file transfer succeeds
282 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900283 public boolean importFile(int objectHandle, @NonNull String destPath) {
Mike Lockwood8182e722010-12-30 15:38:45 -0500284 return native_import_file(objectHandle, destPath);
285 }
286
Tomasz Mikolajewski74d4ff82015-08-04 18:34:03 +0900287 /**
288 * Copies the data for an object to a file descriptor.
289 * This call may block for an arbitrary amount of time depending on the size
290 * of the data and speed of the devices. The file descriptor is not closed
291 * on completion, and must be done by the caller.
292 *
293 * @param objectHandle handle of the object to read
294 * @param descriptor file descriptor to write the data to for the file transfer.
295 * @return true if the file transfer succeeds
296 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900297 public boolean importFile(int objectHandle, @NonNull ParcelFileDescriptor descriptor) {
Tomasz Mikolajewski74d4ff82015-08-04 18:34:03 +0900298 return native_import_file(objectHandle, descriptor.getFd());
299 }
300
Tomasz Mikolajewskib0499052015-08-06 19:13:09 +0900301 /**
302 * Copies the data for an object from a file descriptor.
303 * This call may block for an arbitrary amount of time depending on the size
304 * of the data and speed of the devices. The file descriptor is not closed
305 * on completion, and must be done by the caller.
306 *
307 * @param objectHandle handle of the target file
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900308 * @param size size of the file in bytes
Tomasz Mikolajewskib0499052015-08-06 19:13:09 +0900309 * @param descriptor file descriptor to read the data from.
310 * @return true if the file transfer succeeds
311 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900312 public boolean sendObject(
313 int objectHandle, long size, @NonNull ParcelFileDescriptor descriptor) {
Tomasz Mikolajewskib80a3cf2015-08-24 16:10:51 +0900314 return native_send_object(objectHandle, size, descriptor.getFd());
Tomasz Mikolajewskib0499052015-08-06 19:13:09 +0900315 }
316
317 /**
318 * Uploads an object metadata for a new entry. The {@link MtpObjectInfo} can be
319 * created with the {@link MtpObjectInfo.Builder} class.
320 *
321 * The returned {@link MtpObjectInfo} has the new object handle field filled in.
322 *
323 * @param info metadata of the entry
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900324 * @return object info of the created entry, or null if sending object info fails
Tomasz Mikolajewskib0499052015-08-06 19:13:09 +0900325 */
Daichi Hirono452e8fe2016-07-05 17:29:48 +0900326 public @Nullable MtpObjectInfo sendObjectInfo(@NonNull MtpObjectInfo info) {
Tomasz Mikolajewskib0499052015-08-06 19:13:09 +0900327 return native_send_object_info(info);
328 }
329
Daichi Hirono0b494662015-09-10 20:38:15 +0900330 /**
331 * Reads an event from the device. It blocks the current thread until it gets an event.
332 * It throws OperationCanceledException if it is cancelled by signal.
333 *
334 * @param signal signal for cancellation
335 * @return obtained event
Daichi Hirono60fa3612016-04-19 12:50:34 +0900336 * @throws IOException
Daichi Hirono0b494662015-09-10 20:38:15 +0900337 */
Daichi Hirono60fa3612016-04-19 12:50:34 +0900338 public @NonNull MtpEvent readEvent(@Nullable CancellationSignal signal) throws IOException {
Daichi Hirono0b494662015-09-10 20:38:15 +0900339 final int handle = native_submit_event_request();
Daichi Hirono60fa3612016-04-19 12:50:34 +0900340 Preconditions.checkState(handle >= 0, "Other thread is reading an event.");
Daichi Hirono0b494662015-09-10 20:38:15 +0900341
342 if (signal != null) {
343 signal.setOnCancelListener(new CancellationSignal.OnCancelListener() {
344 @Override
345 public void onCancel() {
346 native_discard_event_request(handle);
347 }
348 });
349 }
350
351 try {
352 return native_reap_event_request(handle);
353 } finally {
354 if (signal != null) {
355 signal.setOnCancelListener(null);
356 }
357 }
358 }
359
Daichi Hirono787821b2016-03-24 21:05:51 +0900360 /**
361 * Returns object size in 64-bit integer.
362 *
Daichi Hirono1337deb2016-03-28 08:53:15 +0900363 * Though MtpObjectInfo#getCompressedSize returns the object size in 32-bit unsigned integer,
364 * this method returns the object size in 64-bit integer from the object property. Thus it can
365 * fetch 4GB+ object size correctly. If the device does not support objectSize property, it
366 * throws IOException.
Daichi Hirono787821b2016-03-24 21:05:51 +0900367 * @hide
368 */
369 public long getObjectSizeLong(int handle, int format) throws IOException {
370 return native_get_object_size_long(handle, format);
371 }
372
Mike Lockwood8182e722010-12-30 15:38:45 -0500373 // used by the JNI code
Ashok Bhate2e59322013-12-17 19:04:19 +0000374 private long mNativeContext;
Mike Lockwood8182e722010-12-30 15:38:45 -0500375
376 private native boolean native_open(String deviceName, int fd);
377 private native void native_close();
378 private native MtpDeviceInfo native_get_device_info();
379 private native int[] native_get_storage_ids();
380 private native MtpStorageInfo native_get_storage_info(int storageId);
381 private native int[] native_get_object_handles(int storageId, int format, int objectHandle);
382 private native MtpObjectInfo native_get_object_info(int objectHandle);
Daichi Hironoe0e66542016-01-15 14:42:53 +0900383 private native byte[] native_get_object(int objectHandle, long objectSize);
Daichi Hirono2dd48252016-01-12 15:46:41 +0900384 private native long native_get_partial_object(
385 int objectHandle, long offset, long objectSize, byte[] buffer) throws IOException;
Daichi Hirono038832b2016-01-22 19:34:25 +0900386 private native int native_get_partial_object_64(
387 int objectHandle, long offset, long objectSize, byte[] buffer) throws IOException;
Mike Lockwood8182e722010-12-30 15:38:45 -0500388 private native byte[] native_get_thumbnail(int objectHandle);
389 private native boolean native_delete_object(int objectHandle);
Daichi Hironoe0e66542016-01-15 14:42:53 +0900390 private native int native_get_parent(int objectHandle);
391 private native int native_get_storage_id(int objectHandle);
Mike Lockwood8182e722010-12-30 15:38:45 -0500392 private native boolean native_import_file(int objectHandle, String destPath);
Tomasz Mikolajewski74d4ff82015-08-04 18:34:03 +0900393 private native boolean native_import_file(int objectHandle, int fd);
Daichi Hironoe0e66542016-01-15 14:42:53 +0900394 private native boolean native_send_object(int objectHandle, long size, int fd);
Tomasz Mikolajewskib0499052015-08-06 19:13:09 +0900395 private native MtpObjectInfo native_send_object_info(MtpObjectInfo info);
Daichi Hirono60fa3612016-04-19 12:50:34 +0900396 private native int native_submit_event_request() throws IOException;
397 private native MtpEvent native_reap_event_request(int handle) throws IOException;
Daichi Hirono0b494662015-09-10 20:38:15 +0900398 private native void native_discard_event_request(int handle);
Daichi Hirono787821b2016-03-24 21:05:51 +0900399 private native long native_get_object_size_long(int handle, int format) throws IOException;
Mike Lockwood8182e722010-12-30 15:38:45 -0500400}