summaryrefslogtreecommitdiffstats
path: root/src/com/android/bluetooth/sap/SapService.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/bluetooth/sap/SapService.java')
-rw-r--r--src/com/android/bluetooth/sap/SapService.java99
1 files changed, 63 insertions, 36 deletions
diff --git a/src/com/android/bluetooth/sap/SapService.java b/src/com/android/bluetooth/sap/SapService.java
index b3cc74d5c..9199d7fd1 100644
--- a/src/com/android/bluetooth/sap/SapService.java
+++ b/src/com/android/bluetooth/sap/SapService.java
@@ -65,6 +65,7 @@ public class SapService extends ProfileService {
public static final int MSG_ACQUIRE_WAKE_LOCK = 5005;
public static final int MSG_RELEASE_WAKE_LOCK = 5006;
+ public static final int MSG_CHANGE_STATE = 5007;
/* Each time a transaction between the SIM and the BT Client is detected a wakelock is taken.
* After an idle period of RELEASE_WAKE_LOCK_DELAY ms the wakelock is released.
*
@@ -95,6 +96,7 @@ public class SapService extends ProfileService {
private boolean mRemoveTimeoutMsg = false;
private boolean mIsWaitingAuthorization = false;
+ private boolean mIsRegistered = false;
private SapServiceMessageHandler mSessionStatusHandler = null;
@@ -151,9 +153,12 @@ public class SapService extends ProfileService {
// for multiple connections.
mServerSocket = mAdapter.listenUsingRfcommOn(
BluetoothAdapter.SOCKET_CHANNEL_AUTO_STATIC_NO_SDP, true, true);
- if (mSdpHandle >= 0) {
- SdpManager.getDefaultManager().removeSdpRecord(mSdpHandle);
+ if (mAdapter != null && mSdpHandle >= 0 &&
+ SdpManager.getDefaultManager() != null) {
if (DEBUG) Log.d(TAG, "Removing SDP record");
+ boolean status = SdpManager.getDefaultManager().removeSdpRecord(mSdpHandle);
+ Log.d(TAG, "RemoveSDPrecord returns " + status);
+ mSdpHandle = -1;
}
mSdpHandle = SdpManager.getDefaultManager().createSapsRecord(SDP_SAP_SERVICE_NAME,
mServerSocket.getChannel(), SDP_SAP_VERSION);
@@ -181,11 +186,6 @@ public class SapService extends ProfileService {
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 ");
@@ -201,6 +201,7 @@ public class SapService extends ProfileService {
if (mServerSocket != null) {
try {
// this will cause mServerSocket.accept() return early with IOException
+ if (VERBOSE) Log.v(TAG, "Closing server socket");
mServerSocket.close();
mServerSocket = null;
} catch (IOException ex) {
@@ -212,6 +213,7 @@ public class SapService extends ProfileService {
private final synchronized void closeConnectionSocket() {
if (mConnSocket != null) {
try {
+ if (VERBOSE) Log.v(TAG, "Closing conenction socket");
mConnSocket.close();
mConnSocket = null;
} catch (IOException e) {
@@ -235,7 +237,7 @@ public class SapService extends ProfileService {
mAcceptThread.shutdown();
mAcceptThread.join();
} catch (InterruptedException ex) {
- Log.w(TAG, "mAcceptThread close error", ex);
+ Log.e(TAG, "mAcceptThread close error", ex);
}
mAcceptThread = null;
}
@@ -248,7 +250,7 @@ public class SapService extends ProfileService {
}
synchronized private void releaseWakeLockResources() {
- if (mWakeLock != null) {
+ if ((mWakeLock != null) && (mSessionStatusHandler != null)) {
mSessionStatusHandler.removeMessages(MSG_ACQUIRE_WAKE_LOCK);
mSessionStatusHandler.removeMessages(MSG_RELEASE_WAKE_LOCK);
mWakeLock.release();
@@ -261,6 +263,7 @@ public class SapService extends ProfileService {
// E.g. we cannot have multiple receivers registered nor have multiple servers attached
// to the RIL socket.
if(mSapServer != null) {
+ if (DEBUG) Log.d(TAG, "Awaiting SapServerSessionStop");
boolean retry = true;
while(retry == true) {
retry = false;
@@ -286,8 +289,6 @@ public class SapService extends ProfileService {
mWakeLock.acquire();
}
- setState(BluetoothSap.STATE_CONNECTED);
-
/* Start the SAP I/O thread and associate with message handler */
mSapServer = new SapServer(mSessionStatusHandler, this, mConnSocket.getInputStream(), mConnSocket.getOutputStream());
mSapServer.start();
@@ -351,14 +352,14 @@ public class SapService extends ProfileService {
if (VERBOSE) Log.v(TAG, "Accepting socket connection...");
serverSocket = mServerSocket;
if (serverSocket == null) {
- Log.w(TAG, "mServerSocket is null");
+ Log.e(TAG, "mServerSocket is null");
break;
}
mConnSocket = mServerSocket.accept();
- if (VERBOSE) Log.v(TAG, "Accepted socket connection...");
+ if (DEBUG) Log.d(TAG, "Accepted socket connection...");
synchronized (SapService.this) {
if (mConnSocket == null) {
- Log.w(TAG, "mConnSocket is null");
+ Log.e(TAG, "mConnSocket is null");
break;
}
mRemoteDevice = mConnSocket.getRemoteDevice();
@@ -375,7 +376,7 @@ public class SapService extends ProfileService {
}
int permission = mRemoteDevice.getSimAccessPermission();
- if (VERBOSE) Log.v(TAG, "getSimAccessPermission() = " + permission);
+ if (DEBUG) Log.d(TAG, "getSimAccessPermission() = " + permission);
if (permission == BluetoothDevice.ACCESS_ALLOWED) {
try {
@@ -408,7 +409,7 @@ public class SapService extends ProfileService {
stopped = true; // job done ,close this thread;
} catch (IOException ex) {
stopped=true;
- if (VERBOSE) Log.v(TAG, "Accept exception: ", ex);
+ if (DEBUG) Log.d(TAG, "Accept exception: ", ex);
}
}
}
@@ -473,6 +474,10 @@ public class SapService extends ProfileService {
if (DEBUG) Log.d(TAG, " Released Wake Lock by message");
}
break;
+ case MSG_CHANGE_STATE:
+ if (VERBOSE) Log.v(TAG, "change state message: newState = " + msg.arg1);
+ setState(msg.arg1);
+ break;
case SHUTDOWN:
/* Ensure to call close from this handler to avoid starting new stuff
because of pending messages */
@@ -625,6 +630,7 @@ public class SapService extends ProfileService {
try {
registerReceiver(mSapReceiver, filter);
+ mIsRegistered = true;
} catch (Exception e) {
Log.w(TAG,"Unable to register sap receiver",e);
}
@@ -643,7 +649,13 @@ public class SapService extends ProfileService {
@Override
protected boolean stop() {
if (VERBOSE) Log.v(TAG, "Stoping SAPService");
+
+ if (!mIsRegistered){
+ Log.i(TAG, "Avoid unregister when receiver it is not registered");
+ return true;
+ }
try {
+ mIsRegistered = false;
unregisterReceiver(mSapReceiver);
} catch (Exception e) {
Log.w(TAG,"Unable to unregister sap receiver",e);
@@ -723,19 +735,29 @@ public class SapService extends ProfileService {
mIsWaitingAuthorization = false;
cancelUserTimeoutAlarm();
}
- mSessionStatusHandler.removeCallbacksAndMessages(null);
- // Request release of all resources
- Message msg = mSessionStatusHandler.obtainMessage(SHUTDOWN,latch);
- if( mSessionStatusHandler.sendMessage(msg) == false) {
- /* most likely caused by shutdown being called from multiple sources - e.g.BT off
- * signaled through intent and a service shutdown simultaneously.
- * Intended behavior not documented, hence we need to be able to handle all cases. */
- Log.e(TAG, "mSessionStatusHandler.sendMessage() failed trigger latch locally");
- if(latch != null) {
- latch.countDown();
+ if (mAdapter != null && mSdpHandle >= 0 &&
+ SdpManager.getDefaultManager() != null) {
+ if (DEBUG) Log.d(TAG, "Removing SDP record");
+ boolean status = SdpManager.getDefaultManager().removeSdpRecord(mSdpHandle);
+ Log.d(TAG, "RemoveSDPrecord returns " + status);
+ mSdpHandle = -1;
+ }
+ if (mSessionStatusHandler != null) {
+ mSessionStatusHandler.removeCallbacksAndMessages(null);
+ // Request release of all resources
+ Message msg = mSessionStatusHandler.obtainMessage(SHUTDOWN,latch);
+ if( mSessionStatusHandler.sendMessage(msg) == false) {
+ /* most likely caused by shutdown being called from multiple sources - e.g.BT off
+ * signaled through intent and a service shutdown simultaneously.
+ * Intended behavior not documented, hence we need to be able to handle all cases.
+ */
+ Log.e(TAG, "mSessionStatusHandler.sendMessage() failed trigger latch locally");
+ if(latch != null) {
+ latch.countDown();
+ }
+ } else {
+ if(DEBUG) Log.e(TAG, "mSessionStatusHandler.sendMessage() dispatched shutdown msg");
}
- } else {
- if(DEBUG) Log.e(TAG, "mSessionStatusHandler.sendMessage() dispatched shutdown message");
}
}
@@ -764,7 +786,8 @@ public class SapService extends ProfileService {
} else if (state == BluetoothAdapter.STATE_ON) {
if (DEBUG) Log.d(TAG, "STATE_ON");
// start RFCOMM listener
- mSessionStatusHandler.sendMessage(mSessionStatusHandler
+ if (mSessionStatusHandler != null)
+ mSessionStatusHandler.sendMessage(mSessionStatusHandler
.obtainMessage(START_LISTENER));
}
} else if (action.equals(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY)) {
@@ -806,7 +829,8 @@ public class SapService extends ProfileService {
}
}
// Ensure proper cleanup, and prepare for new connect.
- mSessionStatusHandler.sendEmptyMessage(MSG_SERVERSESSION_CLOSE);
+ if (mSessionStatusHandler != null)
+ mSessionStatusHandler.sendEmptyMessage(MSG_SERVERSESSION_CLOSE);
}
} else if (action.equals(USER_CONFIRM_TIMEOUT_ACTION)){
if (DEBUG) Log.d(TAG, "USER_CONFIRM_TIMEOUT ACTION Received.");
@@ -823,13 +847,16 @@ public class SapService extends ProfileService {
if (DEBUG) Log.d(TAG,"ACL disconnected for " + device);
- if (mRemoteDevice.equals(device) && mRemoveTimeoutMsg) {
- // Send any pending timeout now, as ACL got disconnected.
- cancelUserTimeoutAlarm();
- mSessionStatusHandler.removeMessages(USER_TIMEOUT);
- sendCancelUserConfirmationIntent(mRemoteDevice);
+ if (mRemoteDevice.equals(device)) {
+ if (mRemoveTimeoutMsg) {
+ // Send any pending timeout now, as ACL got disconnected.
+ cancelUserTimeoutAlarm();
+ mSessionStatusHandler.removeMessages(USER_TIMEOUT);
+ sendCancelUserConfirmationIntent(mRemoteDevice);
+ mRemoveTimeoutMsg = false;
+ }
mIsWaitingAuthorization = false;
- mRemoveTimeoutMsg = false;
+ setState(BluetoothSap.STATE_DISCONNECTED);
// Ensure proper cleanup, and prepare for new connect.
mSessionStatusHandler.sendEmptyMessage(MSG_SERVERSESSION_CLOSE);
}