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

Commit 5c705e11 authored by John Huang's avatar John Huang Committed by Android (Google) Code Review
Browse files

Merge "Enable Bluetooth sharing of downloaded files." into jb-mr1-dev

parents ad0b2752 6f1c0a30
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -246,12 +246,15 @@ public class BluetoothOppManager {
        if (V) Log.v(TAG, "Application data stored to SharedPreference! ");
    }

    public void saveSendingFileInfo(String mimeType, String uri, boolean isHandover) {
    public void saveSendingFileInfo(String mimeType, String uriString, boolean isHandover) {
        synchronized (BluetoothOppManager.this) {
            mMultipleFlag = false;
            mMimeTypeOfSendingFile = mimeType;
            mUriOfSendingFile = uri;
            mUriOfSendingFile = uriString;
            mIsHandoverInitiated = isHandover;
            Uri uri = Uri.parse(uriString);
            BluetoothOppUtility.putSendFileInfo(uri,
                    BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType));
            storeApplicationData();
        }
    }
@@ -262,6 +265,10 @@ public class BluetoothOppManager {
            mMimeTypeOfSendingFiles = mimeType;
            mUrisOfSendingFiles = uris;
            mIsHandoverInitiated = isHandover;
            for (Uri uri : uris) {
                BluetoothOppUtility.putSendFileInfo(uri,
                        BluetoothOppSendFileInfo.generateFileInfo(mContext, uri, mimeType));
            }
            storeApplicationData();
        }
    }
+5 −8
Original line number Diff line number Diff line
@@ -305,8 +305,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
        private BluetoothOppSendFileInfo processShareInfo() {
            if (V) Log.v(TAG, "Client thread processShareInfo() " + mInfo.mId);

            BluetoothOppSendFileInfo fileInfo = BluetoothOppSendFileInfo.generateFileInfo(
                    mContext1, mInfo.mUri, mInfo.mMimetype, mInfo.mDestination);
            BluetoothOppSendFileInfo fileInfo = BluetoothOppUtility.getSendFileInfo(mInfo.mUri);
            if (fileInfo.mFileName == null || fileInfo.mLength == 0) {
                if (V) Log.v(TAG, "BluetoothOppSendFileInfo get invalid file");
                    Constants.updateShareStatus(mContext1, mInfo.mId, fileInfo.mStatus);
@@ -343,7 +342,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
            request.setHeader(HeaderSet.NAME, fileInfo.mFileName);
            request.setHeader(HeaderSet.TYPE, fileInfo.mMimetype);

            applyRemoteDeviceQuirks(request, fileInfo);
            applyRemoteDeviceQuirks(request, mInfo.mDestination, fileInfo.mFileName);

            Constants.updateShareStatus(mContext1, mInfo.mId, BluetoothShare.STATUS_RUNNING);

@@ -500,7 +499,8 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
                handleSendException(e.toString());
            } finally {
                try {
                    fileInfo.mInputStream.close();
                    // Close InputStream and remove SendFileInfo from map
                    BluetoothOppUtility.closeSendFileInfo(mInfo.mUri);
                    if (!error) {
                        responseCode = putOperation.getResponseCode();
                        if (responseCode != -1) {
@@ -566,8 +566,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
        }
    }

    public static void applyRemoteDeviceQuirks(HeaderSet request, BluetoothOppSendFileInfo info) {
        String address = info.mDestAddr;
    public static void applyRemoteDeviceQuirks(HeaderSet request, String address, String filename) {
        if (address == null) {
            return;
        }
@@ -576,8 +575,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession {
            // Rejects filenames with more than one '.'. Rename to '_'.
            // for example: 'a.b.jpg' -> 'a_b.jpg'
            //              'abc.jpg' NOT CHANGED
            String filename = info.mFileName;

            char[] c = filename.toCharArray();
            boolean firstDot = true;
            boolean modified = false;
+29 −36
Original line number Diff line number Diff line
@@ -32,19 +32,18 @@

package com.android.bluetooth.opp;

import java.io.File;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import android.util.Log;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.OpenableColumns;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
 * This class stores information about a single sending file It will only be
@@ -57,6 +56,10 @@ public class BluetoothOppSendFileInfo {

    private static final boolean V = Constants.VERBOSE;

    /** Reusable SendFileInfo for error status. */
    static final BluetoothOppSendFileInfo SEND_FILE_INFO_ERROR = new BluetoothOppSendFileInfo(
            null, null, 0, null, BluetoothShare.STATUS_FILE_ERROR);

    /** readable media file name */
    public final String mFileName;

@@ -72,46 +75,40 @@ public class BluetoothOppSendFileInfo {

    public final long mLength;

    public final String mDestAddr;

    /** for media file */
    public BluetoothOppSendFileInfo(String fileName, String type, long length,
            FileInputStream inputStream, int status, String dest) {
            FileInputStream inputStream, int status) {
        mFileName = fileName;
        mMimetype = type;
        mLength = length;
        mInputStream = inputStream;
        mStatus = status;
        mDestAddr = dest;
        mData = null;
    }

    /** for vCard, or later for vCal, vNote. Not used currently */
    public BluetoothOppSendFileInfo(String data, String type, long length, int status,
            String dest) {
    public BluetoothOppSendFileInfo(String data, String type, long length, int status) {
        mFileName = null;
        mInputStream = null;
        mData = data;
        mMimetype = type;
        mLength = length;
        mStatus = status;
        mDestAddr = dest;
    }

    public static BluetoothOppSendFileInfo generateFileInfo(Context context, String uri,
            String type, String dest) {
    public static BluetoothOppSendFileInfo generateFileInfo(Context context, Uri uri,
            String type) {
        ContentResolver contentResolver = context.getContentResolver();
        Uri u = Uri.parse(uri);
        String scheme = u.getScheme();
        String scheme = uri.getScheme();
        String fileName = null;
        String contentType = null;
        String contentType;
        long length = 0;
        // Support all Uri with "content" scheme
        // This will allow more 3rd party applications to share files via
        // bluetooth
        if (scheme.equals("content")) {
            contentType = contentResolver.getType(u);
            Cursor metadataCursor = contentResolver.query(u, new String[] {
        if ("content".equals(scheme)) {
            contentType = contentResolver.getType(uri);
            Cursor metadataCursor = contentResolver.query(uri, new String[] {
                    OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE
            }, null, null, null);
            if (metadataCursor != null) {
@@ -125,25 +122,23 @@ public class BluetoothOppSendFileInfo {
                    metadataCursor.close();
                }
            }
        } else if (scheme.equals("file")) {
            fileName = u.getLastPathSegment();
        } else if ("file".equals(scheme)) {
            fileName = uri.getLastPathSegment();
            contentType = type;
            File f = new File(u.getPath());
            File f = new File(uri.getPath());
            length = f.length();
        } else {
            // currently don't accept other scheme
            return new BluetoothOppSendFileInfo(null, null, 0, null,
                    BluetoothShare.STATUS_FILE_ERROR, dest);
            return SEND_FILE_INFO_ERROR;
        }
        FileInputStream is = null;
        if (scheme.equals("content")) {
            AssetFileDescriptor fd = null;
            try {
                // We've found that content providers don't always have the
                // right size in _OpenableColumns.SIZE
                // As a second source of getting the correct file length,
                // get a file descriptor and get the stat length
                fd = contentResolver.openAssetFileDescriptor(u, "r");
                AssetFileDescriptor fd = contentResolver.openAssetFileDescriptor(uri, "r");
                long statLength = fd.getLength();
                if (length != statLength && statLength > 0) {
                    Log.e(TAG, "Content provider length is wrong (" + Long.toString(length) +
@@ -154,7 +149,7 @@ public class BluetoothOppSendFileInfo {
                    // This creates an auto-closing input-stream, so
                    // the file descriptor will be closed whenever the InputStream
                    // is closed.
                    is = (FileInputStream)fd.createInputStream();
                    is = fd.createInputStream();
                } catch (IOException e) {
                    try {
                        fd.close();
@@ -168,10 +163,9 @@ public class BluetoothOppSendFileInfo {
        }
        if (is == null) {
            try {
                is = (FileInputStream)contentResolver.openInputStream(u);
                is = (FileInputStream) contentResolver.openInputStream(uri);
            } catch (FileNotFoundException e) {
                return new BluetoothOppSendFileInfo(null, null, 0, null,
                        BluetoothShare.STATUS_FILE_ERROR, dest);
                return SEND_FILE_INFO_ERROR;
            }
        }
        // If we can not get file length from content provider, we can try to
@@ -182,11 +176,10 @@ public class BluetoothOppSendFileInfo {
                if (V) Log.v(TAG, "file length is " + length);
            } catch (IOException e) {
                Log.e(TAG, "Read stream exception: ", e);
                return new BluetoothOppSendFileInfo(null, null, 0, null,
                        BluetoothShare.STATUS_FILE_ERROR, dest);
                return SEND_FILE_INFO_ERROR;
            }
        }

        return new BluetoothOppSendFileInfo(fileName, contentType, length, is, 0, dest);
        return new BluetoothOppSendFileInfo(fileName, contentType, length, is, 0);
    }
}
+20 −17
Original line number Diff line number Diff line
@@ -543,9 +543,18 @@ public class BluetoothOppService extends Service {
    }

    private void insertShare(Cursor cursor, int arrayPos) {
        String uriString = cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.URI));
        Uri uri;
        if (uriString != null) {
            uri = Uri.parse(uriString);
            Log.d(TAG, "insertShare parsed URI: " + uri);
        } else {
            uri = null;
            Log.e(TAG, "insertShare found null URI at cursor!");
        }
        BluetoothOppShareInfo info = new BluetoothOppShareInfo(
                cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID)),
                cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.URI)),
                uri,
                cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.FILENAME_HINT)),
                cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare._DATA)),
                cursor.getString(cursor.getColumnIndexOrThrow(BluetoothShare.MIMETYPE)),
@@ -597,23 +606,12 @@ public class BluetoothOppService extends Service {
        if (info.isReadyToStart()) {
            if (info.mDirection == BluetoothShare.DIRECTION_OUTBOUND) {
                /* check if the file exists */
                InputStream i;
                try {
                    i = getContentResolver().openInputStream(Uri.parse(info.mUri));
                } catch (FileNotFoundException e) {
                BluetoothOppSendFileInfo sendFileInfo = BluetoothOppUtility.getSendFileInfo(
                        info.mUri);
                if (sendFileInfo == null || sendFileInfo.mInputStream == null) {
                    Log.e(TAG, "Can't open file for OUTBOUND info " + info.mId);
                    Constants.updateShareStatus(this, info.mId, BluetoothShare.STATUS_BAD_REQUEST);
                    return;
                } catch (SecurityException e) {
                    Log.e(TAG, "Exception:" + e.toString() + " for OUTBOUND info " + info.mId);
                    Constants.updateShareStatus(this, info.mId, BluetoothShare.STATUS_BAD_REQUEST);
                    return;
                }

                try {
                    i.close();
                } catch (IOException ex) {
                    Log.e(TAG, "IO error when close file for OUTBOUND info " + info.mId);
                    BluetoothOppUtility.closeSendFileInfo(info.mUri);
                    return;
                }
            }
@@ -678,7 +676,12 @@ public class BluetoothOppService extends Service {
        int statusColumn = cursor.getColumnIndexOrThrow(BluetoothShare.STATUS);

        info.mId = cursor.getInt(cursor.getColumnIndexOrThrow(BluetoothShare._ID));
        info.mUri = stringFromCursor(info.mUri, cursor, BluetoothShare.URI);
        if (info.mUri != null) {
            info.mUri = Uri.parse(stringFromCursor(info.mUri.toString(), cursor,
                    BluetoothShare.URI));
        } else {
            Log.d(TAG, "updateShare() called for ID " + info.mId + " with null URI");
        }
        info.mHint = stringFromCursor(info.mHint, cursor, BluetoothShare.FILENAME_HINT);
        info.mFilename = stringFromCursor(info.mFilename, cursor, BluetoothShare._DATA);
        info.mMimetype = stringFromCursor(info.mMimetype, cursor, BluetoothShare.MIMETYPE);
+4 −2
Original line number Diff line number Diff line
@@ -32,6 +32,8 @@

package com.android.bluetooth.opp;

import android.net.Uri;

/**
 * This class stores information about a single OBEX share, e.g. one object
 * send/receive to a destination address.
@@ -40,7 +42,7 @@ public class BluetoothOppShareInfo {

    public int mId;

    public String mUri;
    public Uri mUri;

    public String mHint;

@@ -66,7 +68,7 @@ public class BluetoothOppShareInfo {

    public boolean mMediaScanned;

    public BluetoothOppShareInfo(int id, String uri, String hint, String filename, String mimetype,
    public BluetoothOppShareInfo(int id, Uri uri, String hint, String filename, String mimetype,
            int direction, String destination, int visibility, int confirm, int status,
            int totalBytes, int currentBytes, int timestamp, boolean mediaScanned) {
        mId = id;
Loading