diff options
author | Tao Liejun <L.J.Tao@motorola.com> | 2009-08-07 15:01:24 +0800 |
---|---|---|
committer | Nick Pelly <npelly@google.com> | 2009-08-19 14:05:55 -0700 |
commit | 1ac5507790a87810061a19dadec36eb328a222ea (patch) | |
tree | 3de6d663ced1002afc6dd0148039b0d9bd15448b /src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java | |
parent | 41ef8d494511c040451f2f887cb31c3100746b61 (diff) | |
download | android_packages_apps_Bluetooth-1ac5507790a87810061a19dadec36eb328a222ea.tar.gz android_packages_apps_Bluetooth-1ac5507790a87810061a19dadec36eb328a222ea.tar.bz2 android_packages_apps_Bluetooth-1ac5507790a87810061a19dadec36eb328a222ea.zip |
OPP update
Rewrite provider permission to allow LiveFolders work
Support file:// uri to share file
Support multiple share from gallery
Fully support sending file queue
Hold incoming connection for a while when OPP is busy instead of reject directly
Move notification update to a thread
Handle many error cases to display correct error messages
Improve server/client timeout
Delete empty file after reject incoming file
Support upper case incoming file extension
Avoid multiple mediascanner connections
Diffstat (limited to 'src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java')
-rw-r--r-- | src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java | 242 |
1 files changed, 120 insertions, 122 deletions
diff --git a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java index 0283c07f6..0464e6b8f 100644 --- a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java +++ b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java @@ -59,7 +59,7 @@ import java.lang.Thread; */ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { - private static final String TAG = "BtOpp Client"; + private static final String TAG = "BtOpp ObexClient"; private ClientThread mThread; @@ -117,16 +117,8 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } private class ClientThread extends Thread { - public ClientThread(Context context, ObexTransport transport) { - super("BtOpp ClientThread"); - mContext1 = context; - mTransport1 = transport; - waitingForShare = true; - mWaitingForRemote = false; - PowerManager pm = (PowerManager)mContext1.getSystemService(Context.POWER_SERVICE); - wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - } + private static final int sSleepTime = 500; private Context mContext1; @@ -134,8 +126,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { private volatile boolean waitingForShare; - private int mTimeoutRemainingMs = 500; - private ObexTransport mTransport1; private ClientSession mCs; @@ -144,6 +134,19 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { private BluetoothOppSendFileInfo mFileInfo = null; + private boolean mConnected = false; + + public ClientThread(Context context, ObexTransport transport) { + super("BtOpp ClientThread"); + mContext1 = context; + mTransport1 = transport; + waitingForShare = true; + mWaitingForRemote = false; + + PowerManager pm = (PowerManager)mContext1.getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + } + public void addShare(BluetoothOppShareInfo info) { mInfo = info; mFileInfo = processShareInfo(); @@ -170,6 +173,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { if (!mInterrupted) { connect(); } + while (!mInterrupted) { if (!waitingForShare) { doSend(); @@ -177,9 +181,9 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { try { if (Constants.LOGV) { Log.v(TAG, "Client thread waiting for next share, sleep for " - + mTimeoutRemainingMs); + + sSleepTime); } - Thread.sleep(mTimeoutRemainingMs); + Thread.sleep(sSleepTime); } catch (InterruptedException e) { } @@ -187,15 +191,17 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } disconnect(); - if (Constants.LOGVV) { - Log.v(TAG, "release partial WakeLock"); + if (wakeLock.isHeld()) { + if (Constants.LOGVV) { + Log.v(TAG, "release partial WakeLock"); + } + wakeLock.release(); } - wakeLock.release(); - Message msg = Message.obtain(mCallback); msg.what = BluetoothOppObexSession.MSG_SESSION_COMPLETE; msg.obj = mInfo; msg.sendToTarget(); + } private void disconnect() { @@ -208,7 +214,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { Log.v(TAG, "OBEX session disconnected"); } } catch (IOException e) { - Log.e(TAG, "OBEX session disconnect error" + e); + Log.w(TAG, "OBEX session disconnect error" + e); } try { if (mCs != null) { @@ -221,7 +227,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } } } catch (IOException e) { - Log.e(TAG, "OBEX session close error" + e); + Log.w(TAG, "OBEX session close error" + e); } if (mTransport1 != null) { try { @@ -231,7 +237,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } } - } private void connect() { @@ -240,22 +245,26 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } try { mCs = new ClientSession(mTransport1); + mConnected = true; } catch (IOException e1) { Log.e(TAG, "OBEX session create error"); } - HeaderSet hs = new HeaderSet(); - synchronized (this) { - mWaitingForRemote = true; - } - try { - mCs.connect(hs); - if (Constants.LOGV) { - Log.v(TAG, "OBEX session created"); + if (mConnected) { + mConnected = false; + HeaderSet hs = new HeaderSet(); + synchronized (this) { + mWaitingForRemote = true; + } + try { + mCs.connect(hs); + if (Constants.LOGV) { + Log.v(TAG, "OBEX session created"); + } + mConnected = true; + } catch (IOException e) { + Log.e(TAG, "OBEX session connect error"); } - } catch (IOException e) { - Log.e(TAG, "OBEX session connect error"); } - synchronized (this) { mWaitingForRemote = false; } @@ -273,7 +282,11 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { status = BluetoothShare.STATUS_CANCELED; } } - if (status != BluetoothShare.STATUS_CANCELED) { + if (!mConnected) { + // Obex connection error + status = BluetoothShare.STATUS_CONNECTION_ERROR; + } + if (status == BluetoothShare.STATUS_SUCCESS) { /* do real send */ if (mFileInfo.mFileName != null) { status = sendFile(mFileInfo); @@ -281,8 +294,10 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { /* this is invalid request */ status = mFileInfo.mStatus; } + waitingForShare = true; + } else { + Constants.updateShareStatus(mContext1, mInfo.mId, status); } - waitingForShare = true; if (status == BluetoothShare.STATUS_SUCCESS) { Message msg = Message.obtain(mCallback); @@ -292,6 +307,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } else { Message msg = Message.obtain(mCallback); msg.what = BluetoothOppObexSession.MSG_SESSION_ERROR; + mInfo.mStatus = status; msg.obj = mInfo; msg.sendToTarget(); } @@ -306,10 +322,10 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } BluetoothOppSendFileInfo fileInfo = BluetoothOppSendFileInfo.generateFileInfo( - mContext1, mInfo.mUri); - if (fileInfo.mFileName == null) { + mContext1, mInfo.mUri, mInfo.mMimetype); + if (fileInfo.mFileName == null || fileInfo.mLength == 0) { if (Constants.LOGVV) { - Log.v(TAG, "BluetoothOppSendFileInfo get null filename"); + Log.v(TAG, "BluetoothOppSendFileInfo get invalid file"); Constants.updateShareStatus(mContext1, mInfo.mId, fileInfo.mStatus); } @@ -334,29 +350,6 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { return fileInfo; } - private void logHeader(final HeaderSet hs) { - Log.v(TAG, "Dumping HeaderSet " + hs.toString()); - try { - - Log.v(TAG, "COUNT : " + hs.getHeader(HeaderSet.COUNT)); - Log.v(TAG, "NAME : " + hs.getHeader(HeaderSet.NAME)); - Log.v(TAG, "TYPE : " + hs.getHeader(HeaderSet.TYPE)); - Log.v(TAG, "LENGTH : " + hs.getHeader(HeaderSet.LENGTH)); - Log.v(TAG, "TIME_ISO_8601 : " + hs.getHeader(HeaderSet.TIME_ISO_8601)); - Log.v(TAG, "TIME_4_BYTE : " + hs.getHeader(HeaderSet.TIME_4_BYTE)); - Log.v(TAG, "DESCRIPTION : " + hs.getHeader(HeaderSet.DESCRIPTION)); - Log.v(TAG, "TARGET : " + hs.getHeader(HeaderSet.TARGET)); - Log.v(TAG, "HTTP : " + hs.getHeader(HeaderSet.HTTP)); - Log.v(TAG, "WHO : " + hs.getHeader(HeaderSet.WHO)); - Log.v(TAG, "OBJECT_CLASS : " + hs.getHeader(HeaderSet.OBJECT_CLASS)); - Log.v(TAG, "APPLICATION_PARAMETER : " - + hs.getHeader(HeaderSet.APPLICATION_PARAMETER)); - } catch (IOException e) { - Log.e(TAG, "dump HeaderSet error " + e); - } - - } - private int sendFile(BluetoothOppSendFileInfo fileInfo) { boolean error = false; int responseCode = -1; @@ -424,44 +417,62 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { byte[] buffer = new byte[outputBufferSize]; BufferedInputStream a = new BufferedInputStream(fileInfo.mInputStream, 0x4000); - while (!mInterrupted && (position != fileInfo.mLength)) { - - if (Constants.LOGVV) { - timestamp = System.currentTimeMillis(); - } - + if (!mInterrupted && (position != fileInfo.mLength)) { readLength = a.read(buffer, 0, outputBufferSize); - if (!okToProceed) { - mCallback.sendMessageDelayed(mCallback - .obtainMessage(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT), - BluetoothOppObexSession.SESSION_TIMEOUT); + mCallback.sendMessageDelayed(mCallback + .obtainMessage(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT), + BluetoothOppObexSession.SESSION_TIMEOUT); + synchronized (this) { + mWaitingForRemote = true; } + + // first packet will block here outputStream.write(buffer, 0, readLength); - mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); position += readLength; - if (!okToProceed) { - /* check remote accept or reject */ - if (responseCode == -1 && position == fileInfo.mLength) { - // file length is smaller than buffer size, so - // only one packet - outputStream.close(); + if (position != fileInfo.mLength) { + mCallback.removeMessages(BluetoothOppObexSession.MSG_CONNECT_TIMEOUT); + synchronized (this) { + mWaitingForRemote = false; } - responseCode = putOperation.getResponseCode(); + } 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(); - if (responseCode == ResponseCodes.OBEX_HTTP_CONTINUE - || responseCode == ResponseCodes.OBEX_HTTP_OK) { - if (Constants.LOGVV) { - Log.v(TAG, "OK! Response code is " + responseCode); - } - okToProceed = true; - } else { - Log.e(TAG, "Error! Response code is " + responseCode); - break; + if (responseCode == ResponseCodes.OBEX_HTTP_CONTINUE + || responseCode == ResponseCodes.OBEX_HTTP_OK) { + if (Constants.LOGVV) { + Log.v(TAG, "Remote accept"); } + okToProceed = true; + updateValues = new ContentValues(); + updateValues.put(BluetoothShare.CURRENT_BYTES, position); + mContext1.getContentResolver().update(contentUri, updateValues, null, + null); } else { + Log.i(TAG, "Remote reject, Response code is " + responseCode); + } + } + + while (!mInterrupted && okToProceed && (position != fileInfo.mLength)) { + { + if (Constants.LOGVV) { + timestamp = System.currentTimeMillis(); + } + + readLength = a.read(buffer, 0, outputBufferSize); + outputStream.write(buffer, 0, readLength); + /* check remote abort */ responseCode = putOperation.getResponseCode(); if (Constants.LOGVV) { @@ -470,40 +481,24 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { if (responseCode != ResponseCodes.OBEX_HTTP_CONTINUE && responseCode != ResponseCodes.OBEX_HTTP_OK) { /* abort happens */ - break; - } - } - - if (Constants.LOGVV) { - Log.v(TAG, "Sending file position = " + position + " readLength " - + readLength + " bytes took " - + (System.currentTimeMillis() - timestamp) + " ms"); - } - - if (Constants.USE_EMULATOR_DEBUG) { - synchronized (this) { - try { - wait(300); - } catch (InterruptedException e) { - error = true; - status = BluetoothShare.STATUS_CANCELED; - // interrupted - if (Constants.LOGVV) { - Log.v(TAG, "SendFile interrupted when send out file " - + fileInfo.mFileName + " at " + position + " of " - + position); - } - Constants.updateShareStatus(mContext1, mInfo.mId, status); + okToProceed = false; + } else { + position += readLength; + if (Constants.LOGVV) { + Log.v(TAG, "Sending file position = " + position + + " readLength " + readLength + " bytes took " + + (System.currentTimeMillis() - timestamp) + " ms"); } + updateValues = new ContentValues(); + updateValues.put(BluetoothShare.CURRENT_BYTES, position); + mContext1.getContentResolver().update(contentUri, updateValues, + null, null); } } - - updateValues = new ContentValues(); - updateValues.put(BluetoothShare.CURRENT_BYTES, position); - mContext1.getContentResolver().update(contentUri, updateValues, null, null); } - if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN) { + if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN + || responseCode == ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE) { Log.i(TAG, "Remote reject file " + fileInfo.mFileName + " length " + fileInfo.mLength); status = BluetoothShare.STATUS_FORBIDDEN; @@ -519,9 +514,8 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { status = BluetoothShare.STATUS_CANCELED; putOperation.abort(); /* interrupted */ - Log.e(TAG, "SendFile interrupted when send out file " - + fileInfo.mFileName + " at " + position + " of " - + fileInfo.mLength); + Log.i(TAG, "SendFile interrupted when send out file " + fileInfo.mFileName + + " at " + position + " of " + fileInfo.mLength); } } } catch (IOException e) { @@ -539,12 +533,13 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { Log.v(TAG, "Get response code " + responseCode); } if (responseCode != ResponseCodes.OBEX_HTTP_OK) { - Log.i(TAG, "Response error code is "+ responseCode); + Log.i(TAG, "Response error code is " + responseCode); status = BluetoothShare.STATUS_UNHANDLED_OBEX_CODE; if (responseCode == ResponseCodes.OBEX_HTTP_UNSUPPORTED_TYPE) { status = BluetoothShare.STATUS_NOT_ACCEPTABLE; } - if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN) { + if (responseCode == ResponseCodes.OBEX_HTTP_FORBIDDEN + || responseCode == ResponseCodes.OBEX_HTTP_NOT_ACCEPTABLE) { status = BluetoothShare.STATUS_FORBIDDEN; } } @@ -584,6 +579,9 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } Message msg = Message.obtain(mCallback); msg.what = BluetoothOppObexSession.MSG_SHARE_INTERRUPTED; + if (mInfo != null) { + msg.obj = mInfo; + } msg.sendToTarget(); } } @@ -591,7 +589,7 @@ public class BluetoothOppObexClientSession implements BluetoothOppObexSession { } public void unblock() { - + // Not used for client case } } |