/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.mtp;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;

import android.os.UserManager;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import dalvik.system.CloseGuard;

import java.io.IOException;

/**
 * This class represents an MTP or PTP device connected on the USB host bus. An application can
 * instantiate an object of this type, by referencing an attached {@link
 * android.hardware.usb.UsbDevice} and then use methods in this class to get information about the
 * device and objects stored on it, as well as open the connection and transfer data.
 */
public final class MtpDevice {

    private static final String TAG = "MtpDevice";

    private final UsbDevice mDevice;

    static {
        System.loadLibrary("media_jni");
    }

    /** Make sure that MTP device is closed properly */
    @GuardedBy("mLock")
    private CloseGuard mCloseGuard = CloseGuard.get();

    /** Current connection to the {@link #mDevice}, or null if device is not connected */
    @GuardedBy("mLock")
    private UsbDeviceConnection mConnection;

    private final Object mLock = new Object();

    /**
     * MtpClient constructor
     *
     * @param device the {@link android.hardware.usb.UsbDevice} for the MTP or PTP device
     */
    public MtpDevice(@NonNull UsbDevice device) {
        Preconditions.checkNotNull(device);
        mDevice = device;
    }

    /**
     * Opens the MTP device.  Once the device is open it takes ownership of the
     * {@link android.hardware.usb.UsbDeviceConnection}.
     * The connection will be closed when you call {@link #close()}
     * The connection will also be closed if this method fails.
     *
     * @param connection an open {@link android.hardware.usb.UsbDeviceConnection} for the device
     * @return true if the device was successfully opened.
     */
    public boolean open(@NonNull UsbDeviceConnection connection) {
        boolean result = false;

        Context context = connection.getContext();

        synchronized (mLock) {
            if (context != null) {
                UserManager userManager = (UserManager) context
                        .getSystemService(Context.USER_SERVICE);

                if (!userManager.hasUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER)) {
                    result = native_open(mDevice.getDeviceName(), connection.getFileDescriptor());
                }
            }

            if (!result) {
                connection.close();
            } else {
                mConnection = connection;
                mCloseGuard.open("close");
            }
        }

        return result;
    }

    /**
     * Closes all resources related to the MtpDevice object.
     * After this is called, the object can not be used until {@link #open} is called again
     * with a new {@link android.hardware.usb.UsbDeviceConnection}.
     */
    public void close() {
        synchronized (mLock) {
            if (mConnection != null) {
                mCloseGuard.close();

                native_close();

                mConnection.close();
                mConnection = null;
            }
        }
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            if (mCloseGuard != null) {
                mCloseGuard.warnIfOpen();
            }

            close();
        } finally {
            super.finalize();
        }
    }

    /**
     * Returns the name of the USB device
     * This returns the same value as {@link android.hardware.usb.UsbDevice#getDeviceName}
     * for the device's {@link android.hardware.usb.UsbDevice}
     *
     * @return the device name
     */
    public @NonNull String getDeviceName() {
        return mDevice.getDeviceName();
    }

    /**
     * Returns the USB ID of the USB device.
     * This returns the same value as {@link android.hardware.usb.UsbDevice#getDeviceId}
     * for the device's {@link android.hardware.usb.UsbDevice}
     *
     * @return the device ID
     */
    public int getDeviceId() {
        return mDevice.getDeviceId();
    }

    @Override
    public @NonNull String toString() {
        return mDevice.getDeviceName();
    }

    /**
     * Returns the {@link MtpDeviceInfo} for this device
     *
     * @return the device info, or null if fetching device info fails
     */
    public @Nullable MtpDeviceInfo getDeviceInfo() {
        return native_get_device_info();
    }

    /**
     * Returns the list of IDs for all storage units on this device
     * Information about each storage unit can be accessed via {@link #getStorageInfo}.
     *
     * @return the list of storage IDs, or null if fetching storage IDs fails
     */
    public @Nullable int[] getStorageIds() {
        return native_get_storage_ids();
    }

    /**
     * Returns the list of object handles for all objects on the given storage unit,
     * with the given format and parent.
     * Information about each object can be accessed via {@link #getObjectInfo}.
     *
     * @param storageId the storage unit to query
     * @param format the format of the object to return, or zero for all formats
     * @param objectHandle the parent object to query, -1 for the storage root,
     *     or zero for all objects
     * @return the object handles, or null if fetching object handles fails
     */
    public @Nullable int[] getObjectHandles(int storageId, int format, int objectHandle) {
        return native_get_object_handles(storageId, format, objectHandle);
    }

    /**
     * Returns the data for an object as a byte array.
     * This call may block for an arbitrary amount of time depending on the size
     * of the data and speed of the devices.
     *
     * @param objectHandle handle of the object to read
     * @param objectSize the size of the object (this should match
     *      {@link MtpObjectInfo#getCompressedSize})
     * @return the object's data, or null if reading fails
     */
    public @Nullable byte[] getObject(int objectHandle, int objectSize) {
        Preconditions.checkArgumentNonnegative(objectSize, "objectSize should not be negative");
        return native_get_object(objectHandle, objectSize);
    }

    /**
     * Obtains object bytes in the specified range and writes it to an array.
     * This call may block for an arbitrary amount of time depending on the size
     * of the data and speed of the devices.
     *
     * @param objectHandle handle of the object to read
     * @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 Integer.MAX_VALUE
     *     or 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 long getPartialObject(int objectHandle, long offset, long size, @NonNull byte[] buffer)
            throws IOException {
        return native_get_partial_object(objectHandle, offset, size, buffer);
    }

    /**
     * Obtains object bytes in the specified range and writes it to an array.
     * This call may block for an arbitrary amount of time depending on the size
     * of the data and speed of the devices.
     *
     * This is a vender-extended operation supported by Android that enables us to pass
     * unsigned 64-bit offset. Check if the MTP device supports the operation by using
     * {@link MtpDeviceInfo#getOperationsSupported()}.
     *
     * @param objectHandle handle of the object to read
     * @param offset Start index of reading range. It must be a non-negative value.
     * @param size Size of reading range. It must be a non-negative value at most Integer.MAX_VALUE.
     * @param buffer Array to write data.
     * @return Size of bytes that are actually read.
     * @see MtpConstants#OPERATION_GET_PARTIAL_OBJECT_64
     */
    public long getPartialObject64(int objectHandle, long offset, long size, @NonNull byte[] buffer)
            throws IOException {
        return native_get_partial_object_64(objectHandle, offset, size, buffer);
    }

    /**
     * Returns the thumbnail data for an object as a byte array.
     * The size and format of the thumbnail data can be determined via
     * {@link MtpObjectInfo#getThumbCompressedSize} and
     * {@link MtpObjectInfo#getThumbFormat}.
     * For typical devices the format is JPEG.
     *
     * @param objectHandle handle of the object to read
     * @return the object's thumbnail, or null if reading fails
     */
    public @Nullable byte[] getThumbnail(int objectHandle) {
        return native_get_thumbnail(objectHandle);
    }

    /**
     * Retrieves the {@link MtpStorageInfo} for a storage unit.
     *
     * @param storageId the ID of the storage unit
     * @return the MtpStorageInfo, or null if fetching storage info fails
     */
    public @Nullable MtpStorageInfo getStorageInfo(int storageId) {
        return native_get_storage_info(storageId);
    }

    /**
     * Retrieves the {@link MtpObjectInfo} for an object.
     *
     * @param objectHandle the handle of the object
     * @return the MtpObjectInfo, or null if fetching object info fails
     */
    public @Nullable MtpObjectInfo getObjectInfo(int objectHandle) {
        return native_get_object_info(objectHandle);
    }

    /**
     * Deletes an object on the device.  This call may block, since
     * deleting a directory containing many files may take a long time
     * on some devices.
     *
     * @param objectHandle handle of the object to delete
     * @return true if the deletion succeeds
     */
    public boolean deleteObject(int objectHandle) {
        return native_delete_object(objectHandle);
    }

    /**
     * Retrieves the object handle for the parent of an object on the device.
     *
     * @param objectHandle handle of the object to query
     * @return the parent's handle, or zero if it is in the root of the storage
     */
    public long getParent(int objectHandle) {
        return native_get_parent(objectHandle);
    }

    /**
     * Retrieves the ID of the storage unit containing the given object on the device.
     *
     * @param objectHandle handle of the object to query
     * @return the object's storage unit ID
     */
    public long getStorageId(int objectHandle) {
        return native_get_storage_id(objectHandle);
    }

    /**
     * Copies the data for an object to a file in external storage.
     * This call may block for an arbitrary amount of time depending on the size
     * of the data and speed of the devices.
     *
     * @param objectHandle handle of the object to read
     * @param destPath path to destination for the file transfer.
     *      This path should be in the external storage as defined by
     *      {@link android.os.Environment#getExternalStorageDirectory}
     * @return true if the file transfer succeeds
     */
    public boolean importFile(int objectHandle, @NonNull String destPath) {
        return native_import_file(objectHandle, destPath);
    }

    /**
     * Copies the data for an object to a file descriptor.
     * This call may block for an arbitrary amount of time depending on the size
     * of the data and speed of the devices. The file descriptor is not closed
     * on completion, and must be done by the caller.
     *
     * @param objectHandle handle of the object to read
     * @param descriptor file descriptor to write the data to for the file transfer.
     * @return true if the file transfer succeeds
     */
    public boolean importFile(int objectHandle, @NonNull ParcelFileDescriptor descriptor) {
        return native_import_file(objectHandle, descriptor.getFd());
    }

    /**
     * Copies the data for an object from a file descriptor.
     * This call may block for an arbitrary amount of time depending on the size
     * of the data and speed of the devices. The file descriptor is not closed
     * on completion, and must be done by the caller.
     *
     * @param objectHandle handle of the target file
     * @param size size of the file in bytes
     * @param descriptor file descriptor to read the data from.
     * @return true if the file transfer succeeds
     */
    public boolean sendObject(
            int objectHandle, long size, @NonNull ParcelFileDescriptor descriptor) {
        return native_send_object(objectHandle, size, descriptor.getFd());
    }

    /**
     * Uploads an object metadata for a new entry. The {@link MtpObjectInfo} can be
     * created with the {@link MtpObjectInfo.Builder} class.
     *
     * The returned {@link MtpObjectInfo} has the new object handle field filled in.
     *
     * @param info metadata of the entry
     * @return object info of the created entry, or null if sending object info fails
     */
    public @Nullable MtpObjectInfo sendObjectInfo(@NonNull MtpObjectInfo info) {
        return native_send_object_info(info);
    }

    /**
     * Reads an event from the device. It blocks the current thread until it gets an event.
     * It throws OperationCanceledException if it is cancelled by signal.
     *
     * @param signal signal for cancellation
     * @return obtained event
     * @throws IOException
     */
    public @NonNull MtpEvent readEvent(@Nullable CancellationSignal signal) throws IOException {
        final int handle = native_submit_event_request();
        Preconditions.checkState(handle >= 0, "Other thread is reading an event.");

        if (signal != null) {
            signal.setOnCancelListener(new CancellationSignal.OnCancelListener() {
                @Override
                public void onCancel() {
                    native_discard_event_request(handle);
                }
            });
        }

        try {
            return native_reap_event_request(handle);
        } finally {
            if (signal != null) {
                signal.setOnCancelListener(null);
            }
        }
    }

    /**
     * Returns object size in 64-bit integer.
     *
     * Though MtpObjectInfo#getCompressedSize returns the object size in 32-bit unsigned integer,
     * this method returns the object size in 64-bit integer from the object property. Thus it can
     * fetch 4GB+ object size correctly. If the device does not support objectSize property, it
     * throws IOException.
     * @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;

    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_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);
    private native MtpObjectInfo native_get_object_info(int objectHandle);
    private native byte[] native_get_object(int objectHandle, long objectSize);
    private native long native_get_partial_object(
            int objectHandle, long offset, long objectSize, byte[] buffer) throws IOException;
    private native int native_get_partial_object_64(
            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 int native_get_parent(int objectHandle);
    private native int native_get_storage_id(int objectHandle);
    private native boolean native_import_file(int objectHandle, String destPath);
    private native boolean native_import_file(int objectHandle, int fd);
    private native boolean native_send_object(int objectHandle, long size, int fd);
    private native MtpObjectInfo native_send_object_info(MtpObjectInfo info);
    private native int native_submit_event_request() throws IOException;
    private native MtpEvent native_reap_event_request(int handle) throws IOException;
    private native void native_discard_event_request(int handle);
    private native long native_get_object_size_long(int handle, int format) throws IOException;
}
