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

Commit 147e19fe authored by Ajay Panicker's avatar Ajay Panicker
Browse files

Fix how file size is calculated if not provided

Currently if there is no file size provided, InputStream.available()
is used to guess how many bytes are available. According to the
java documentation, available() should not be used to calculate
file sizes, as it isn't guarenteed to return the total number of
bytes in the stream. This is fixed by reading the stream to
calculate the length, then resetting the stream.

Bug: 29334784
Change-Id: Ic851c46d053157e4d5404352d76f9ff87a509607
parent ce689a23
Loading
Loading
Loading
Loading
+34 −44
Original line number Diff line number Diff line
@@ -416,20 +416,10 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {

                        position += readLength;

                        if (position != fileInfo.mLength) {
                            mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
                            synchronized (this) {
                                mWaitingForRemote = false;
                            }
                        } else {
                            // if file length is smaller than buffer size, only one packet
                            // so block point is here
                            outputStream.close();
                        mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT);
                        synchronized (this) {
                            mWaitingForRemote = false;
                        }
                        }
                        /* check remote accept or reject */
                        responseCode = putOperation.getResponseCode();

@@ -446,8 +436,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
                        }
                    }

                    while (!mInterrupted && okToProceed && (position != fileInfo.mLength)) {
                        {
                    while (!mInterrupted && okToProceed && (position < fileInfo.mLength)) {
                        if (V) timestamp = System.currentTimeMillis();

                        readLength = a.read(buffer, 0, outputBufferSize);
@@ -478,7 +467,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
                            }
                        }
                    }
                    }

                    if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN
                            || responseCode == ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE) {
@@ -491,7 +479,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
                    } else if (!mInterrupted && position == fileInfo.mLength) {
                        Log.i(TAG, "SendFile finished send out file " + fileInfo.mFileName
                                + " length " + fileInfo.mLength);
                        outputStream.close();
                    } else {
                        error = true;
                        status = BluetoothShare.STATUS_CANCELED;
@@ -537,6 +524,9 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
                    if (inputStream != null) {
                        inputStream.close();
                    }
                    if (outputStream != null) {
                        outputStream.close();
                    }
                    if (putOperation != null) {
                        putOperation.close();
                    }
+39 −11
Original line number Diff line number Diff line
@@ -121,8 +121,10 @@ public class BluetoothOppSendFileInfo {
            if (metadataCursor != null) {
                try {
                    if (metadataCursor.moveToFirst()) {
                        fileName = metadataCursor.getString(0);
                        length = metadataCursor.getLong(1);
                        fileName = metadataCursor.getString(
                                metadataCursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                        length = metadataCursor.getLong(
                                metadataCursor.getColumnIndex(OpenableColumns.SIZE));
                        if (D) Log.d(TAG, "fileName = " + fileName + " length = " + length);
                    }
                } finally {
@@ -156,11 +158,23 @@ public class BluetoothOppSendFileInfo {
                            "), using stat length (" + Long.toString(statLength) + ")");
                    length = statLength;
                }

                try {
                    // This creates an auto-closing input-stream, so
                    // the file descriptor will be closed whenever the InputStream
                    // is closed.
                    is = fd.createInputStream();

                    // If the database doesn't contain the file size, get the size
                    // by reading through the entire stream
                    if (length == 0) {
                        length = getStreamSize(is);
                        Log.w(TAG, "File length not provided. Length from stream = "
                                   + length);
                        // Reset the stream
                        fd = contentResolver.openAssetFileDescriptor(uri, "r");
                        is = fd.createInputStream();
                    }
                } catch (IOException e) {
                    try {
                        fd.close();
@@ -172,25 +186,39 @@ public class BluetoothOppSendFileInfo {
                // Ignore
            }
        }

        if (is == null) {
            try {
                is = (FileInputStream) contentResolver.openInputStream(uri);

                // If the database doesn't contain the file size, get the size
                // by reading through the entire stream
                if (length == 0) {
                    length = getStreamSize(is);
                    // Reset the stream
                    is = (FileInputStream) contentResolver.openInputStream(uri);
                }
            } catch (FileNotFoundException e) {
                return SEND_FILE_INFO_ERROR;
            } catch (IOException e) {
                return SEND_FILE_INFO_ERROR;
            }
        }
        // If we can not get file length from content provider, we can try to
        // get the length via the opened stream.

        if (length == 0) {
            try {
                length = is.available();
                if (V) Log.v(TAG, "file length is " + length);
            } catch (IOException e) {
                Log.e(TAG, "Read stream exception: ", e);
            Log.e(TAG, "Could not determine size of file");
            return SEND_FILE_INFO_ERROR;
        }
        }

        return new BluetoothOppSendFileInfo(fileName, contentType, length, is, 0);
    }

    private static long getStreamSize(FileInputStream is) throws IOException {
        long length = 0;
        byte unused[] = new byte[4096];
        while (is.available() > 0) {
            length += is.read(unused, 0, 4096);
        }
        return length;
    }
}