summaryrefslogtreecommitdiffstats
path: root/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
diff options
context:
space:
mode:
authorTao Liejun <L.J.Tao@motorola.com>2009-08-07 15:01:24 +0800
committerNick Pelly <npelly@google.com>2009-08-19 14:05:55 -0700
commit1ac5507790a87810061a19dadec36eb328a222ea (patch)
tree3de6d663ced1002afc6dd0148039b0d9bd15448b /src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
parent41ef8d494511c040451f2f887cb31c3100746b61 (diff)
downloadandroid_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.java242
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
}
}