Merge "Null pointer exception in SocketAcceptThread of BluetoothPbapService." into jb-mr2-dev
diff --git a/src/com/android/bluetooth/pbap/BluetoothPbapService.java b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
index 49e19e5..a45bc9a 100755
--- a/src/com/android/bluetooth/pbap/BluetoothPbapService.java
+++ b/src/com/android/bluetooth/pbap/BluetoothPbapService.java
@@ -297,10 +297,6 @@
super.onDestroy();
setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
- if (mWakeLock != null) {
- mWakeLock.release();
- mWakeLock = null;
- }
closeService();
if(mSessionStatusHandler != null) {
mSessionStatusHandler.removeCallbacksAndMessages(null);
@@ -326,11 +322,12 @@
private final boolean initSocket() {
if (VERBOSE) Log.v(TAG, "Pbap Service initSocket");
- boolean initSocketOK = true;
+ boolean initSocketOK = false;
final int CREATE_RETRY_TIME = 10;
// It's possible that create will fail in some cases. retry for 10 times
for (int i = 0; i < CREATE_RETRY_TIME && !mInterrupted; i++) {
+ initSocketOK = true;
try {
// It is mandatory for PSE to support initiation of bonding and
// encryption.
@@ -350,20 +347,24 @@
Log.w(TAG, "initServerSocket failed as BT is (being) turned off");
break;
}
- synchronized (this) {
- try {
- if (VERBOSE) Log.v(TAG, "wait 300 ms");
- Thread.sleep(300);
- } catch (InterruptedException e) {
- Log.e(TAG, "socketAcceptThread thread was interrupted (3)");
- mInterrupted = true;
- }
+ try {
+ if (VERBOSE) Log.v(TAG, "wait 300 ms");
+ Thread.sleep(300);
+ } catch (InterruptedException e) {
+ Log.e(TAG, "socketAcceptThread thread was interrupted (3)");
+ break;
}
} else {
break;
}
}
+ if (mInterrupted) {
+ initSocketOK = false;
+ // close server socket to avoid resource leakage
+ closeServerSocket();
+ }
+
if (initSocketOK) {
if (VERBOSE) Log.v(TAG, "Succeed to create listening socket ");
@@ -373,21 +374,26 @@
return initSocketOK;
}
- private final void closeSocket(boolean server, boolean accept) throws IOException {
- if (server == true) {
- // Stop the possible trying to init serverSocket
- mInterrupted = true;
-
- if (mServerSocket != null) {
+ private final synchronized void closeServerSocket() {
+ // exit SocketAcceptThread early
+ if (mServerSocket != null) {
+ try {
+ // this will cause mServerSocket.accept() return early with IOException
mServerSocket.close();
mServerSocket = null;
+ } catch (IOException ex) {
+ Log.e(TAG, "Close Server Socket error: " + ex);
}
}
+ }
- if (accept == true) {
- if (mConnSocket != null) {
+ private final synchronized void closeConnectionSocket() {
+ if (mConnSocket != null) {
+ try {
mConnSocket.close();
mConnSocket = null;
+ } catch (IOException e) {
+ Log.e(TAG, "Close Connection Socket error: " + e.toString());
}
}
}
@@ -395,11 +401,9 @@
private final void closeService() {
if (VERBOSE) Log.v(TAG, "Pbap Service closeService in");
- try {
- closeSocket(true, true);
- } catch (IOException ex) {
- Log.e(TAG, "CloseSocket error: " + ex);
- }
+ // exit initSocket early
+ mInterrupted = true;
+ closeServerSocket();
if (mAcceptThread != null) {
try {
@@ -410,11 +414,19 @@
Log.w(TAG, "mAcceptThread close error" + ex);
}
}
+
+ if (mWakeLock != null) {
+ mWakeLock.release();
+ mWakeLock = null;
+ }
+
if (mServerSession != null) {
mServerSession.close();
mServerSession = null;
}
+ closeConnectionSocket();
+
mHasStarted = false;
if (mStartId != -1 && stopSelfResult(mStartId)) {
if (VERBOSE) Log.v(TAG, "successfully stopped pbap service");
@@ -473,12 +485,8 @@
mAcceptThread = null;
- try {
- closeSocket(false, true);
- mConnSocket = null;
- } catch (IOException e) {
- Log.e(TAG, "closeSocket error: " + e.toString());
- }
+ closeConnectionSocket();
+
// Last obex transaction is finished, we start to listen for incoming
// connection again
if (mAdapter.isEnabled()) {
@@ -516,9 +524,9 @@
@Override
public void run() {
+ BluetoothServerSocket serverSocket;
if (mServerSocket == null) {
if (!initSocket()) {
- closeService();
return;
}
}
@@ -526,10 +534,21 @@
while (!stopped) {
try {
if (VERBOSE) Log.v(TAG, "Accepting socket connection...");
- mConnSocket = mServerSocket.accept();
+ serverSocket = mServerSocket;
+ if (serverSocket == null) {
+ Log.w(TAG, "mServerSocket is null");
+ break;
+ }
+ mConnSocket = serverSocket.accept();
if (VERBOSE) Log.v(TAG, "Accepted socket connection...");
- mRemoteDevice = mConnSocket.getRemoteDevice();
+ synchronized (BluetoothPbapService.this) {
+ if (mConnSocket == null) {
+ Log.w(TAG, "mConnSocket is null");
+ break;
+ }
+ mRemoteDevice = mConnSocket.getRemoteDevice();
+ }
if (mRemoteDevice == null) {
Log.i(TAG, "getRemoteDevice() = null");
break;
@@ -783,12 +802,9 @@
mServerSession.close();
mServerSession = null;
}
- try {
- closeSocket(false, true);
- mConnSocket = null;
- } catch (IOException ex) {
- Log.e(TAG, "Caught the error: " + ex);
- }
+
+ closeConnectionSocket();
+
setState(BluetoothPbap.STATE_DISCONNECTED, BluetoothPbap.RESULT_CANCELED);
break;
default: