Opp: close the transport if opp tx is blocked when bt turning off
Use Case:
1. DUT paired with remote phone.
2. DUT enable wifi hot spot and remote phone connects with it.
3. DUT send file to remote phone.
4. DUT turn off BT during file transfer, observe
Failure:
DUT doesn't display file transfer failed notification and
file transfer progress bar always displayed there.
Root Cause:
When bt is turning off and file is transfering,
in putOperation.abort() of sendFile(), we will send
abort cmd to remote and wait remote's respone. Because there are
many pending data to send and the tx rate is very very low in this use case,
we cannot get the remote's respone. So the stop() in
BluetoothOppObexClientSession will be stuck until BREDR_STOP_TIMEOUT,
After that we cannot save failed file info to database, and cannot
dismiss the file transfer progess bar.
Fix:
close the transport if opp tx is blocked when bt turning off.
Change-Id: I0ff119ba4b78d0924ab86c52d633eeedca6f148e
CRs-Fixed: 2541429
diff --git a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
index 349951c..ada8ab4 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppObexClientSession.java
@@ -32,6 +32,7 @@
package com.android.bluetooth.opp;
+import android.bluetooth.BluetoothAdapter;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
@@ -80,12 +81,15 @@
private int mNumFilesAttemptedToSend;
+ private BluetoothAdapter mAdapter;
+
public BluetoothOppObexClientSession(Context context, ObexTransport transport) {
if (transport == null) {
throw new NullPointerException("transport is null");
}
mContext = context;
mTransport = transport;
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
}
@Override
@@ -99,7 +103,7 @@
}
@Override
- public void stop() {
+ public synchronized void stop() {
if (D) {
Log.d(TAG, "Stop!");
}
@@ -110,7 +114,23 @@
if (V) {
Log.v(TAG, "waiting for thread to terminate");
}
- mThread.join();
+ if (mAdapter.getState() == BluetoothAdapter.STATE_TURNING_OFF) {
+ Log.d(TAG, "stop, bt is turning off");
+ mThread.join(1500);
+ if (mThread.isAlive()) {
+ Log.d(TAG, "stop, close the transport");
+ mThread.interrupt();
+ try {
+ mTransport.close();
+ } catch (IOException e) {
+ Log.e(TAG, "mTransport.close error");
+ }
+ Log.d(TAG, "stop, close the transport, done");
+ mThread.join();
+ }
+ } else {
+ mThread.join();
+ }
mThread = null;
} catch (InterruptedException e) {
if (V) {
diff --git a/src/com/android/bluetooth/opp/BluetoothOppService.java b/src/com/android/bluetooth/opp/BluetoothOppService.java
index f432635..e22284e 100644
--- a/src/com/android/bluetooth/opp/BluetoothOppService.java
+++ b/src/com/android/bluetooth/opp/BluetoothOppService.java
@@ -244,6 +244,7 @@
@Override
public boolean stop() {
+ if (D) Log.d(TAG," stop");
setBluetoothOppService(null);
mHandler.sendMessage(mHandler.obtainMessage(STOP_LISTENER));
return true;
@@ -255,8 +256,8 @@
if (V) {
Log.v(TAG, "Starting RfcommListener");
}
- mHandler.sendMessage(mHandler.obtainMessage(START_LISTENER));
mListenStarted = true;
+ mHandler.sendMessage(mHandler.obtainMessage(START_LISTENER));
}
}
}
@@ -319,8 +320,12 @@
Log.i(TAG, " handleMessage :" + msg.what);
switch (msg.what) {
case STOP_LISTENER:
- stopListeners();
+ if (!mListenStarted) { // Extra check to avoid redundant call
+ if (V) Log.v(TAG," stop_listener already called");
+ return;
+ }
mListenStarted = false;
+ stopListeners();
//Stop Active INBOUND Transfer
if (mServerTransfer != null) {
mServerTransfer.onBatchCanceled();