Loading src/com/android/bluetooth/map/BluetoothMapMasInstance.java +1 −1 Original line number Diff line number Diff line Loading @@ -396,7 +396,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { return (mConnSocket != null); } public void shutdown() { public synchronized void shutdown() { if (D) Log.d(TAG, "MAP Service shutdown"); if (mServerSession != null) { Loading src/com/android/bluetooth/map/BluetoothMapService.java +54 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter.MalformedMimeTypeException; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.PowerManager; Loading @@ -50,6 +52,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; public class BluetoothMapService extends ProfileService { private static final String TAG = "BluetoothMapService"; Loading @@ -65,7 +68,6 @@ public class BluetoothMapService extends ProfileService { public static final boolean DEBUG = true; //FIXME set to false; public static boolean VERBOSE = Log.isLoggable(LOG_TAG, Log.VERBOSE); /** * Intent indicating timeout for user confirmation, which is sent to * BluetoothMapActivity Loading Loading @@ -146,6 +148,7 @@ public class BluetoothMapService extends ProfileService { private boolean mAccountChanged = false; private boolean mSdpSearchInitiated = false; SdpMnsRecord mMnsRecord = null; private MapServiceMessageHandler mSessionStatusHandler; // package and class name to which we send intent to check phone book access permission private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings"; Loading @@ -163,7 +166,7 @@ public class BluetoothMapService extends ProfileService { } private final void closeService() { private synchronized void closeService(CountDownLatch latch) { if (DEBUG) Log.d(TAG, "MAP Service closeService in"); if (mBluetoothMnsObexClient != null) { Loading Loading @@ -192,6 +195,9 @@ public class BluetoothMapService extends ProfileService { mRemoteDevice = null; if (VERBOSE) Log.v(TAG, "MAP Service closeService out"); if(latch != null) { latch.countDown(); } } /** Loading Loading @@ -317,7 +323,10 @@ public class BluetoothMapService extends ProfileService { } } private final Handler mSessionStatusHandler = new Handler() { private final class MapServiceMessageHandler extends Handler { private MapServiceMessageHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { if (DEBUG) Log.v(TAG, "Handler(): got msg=" + msg.what); Loading Loading @@ -369,7 +378,8 @@ public class BluetoothMapService extends ProfileService { case SHUTDOWN: /* Ensure to call close from this handler to avoid starting new stuff because of pending messages */ closeService(); CountDownLatch latch = (CountDownLatch) msg.obj; closeService(latch); break; case MSG_ACQUIRE_WAKE_LOCK: if (VERBOSE) Log.v(TAG, "Acquire Wake Lock request message"); Loading Loading @@ -580,6 +590,12 @@ public class BluetoothMapService extends ProfileService { } if (VERBOSE) Log.v(TAG, "verbose logging is enabled"); HandlerThread thread = new HandlerThread("BluetoothMapHandler"); thread.start(); Looper looper = thread.getLooper(); mSessionStatusHandler = new MapServiceMessageHandler(looper); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); Loading Loading @@ -775,9 +791,26 @@ public class BluetoothMapService extends ProfileService { } catch (Exception e) { Log.w(TAG,"Unable to unregister map receiver",e); } CountDownLatch latch = new CountDownLatch(1); sendShutdownMessage(latch); // We need to wait for shutdown to complete to avoid being garbage collected before // shutdown completes. if(DEBUG) Log.i(TAG, "Waiting for shutdown to complete"); try { latch.await(); } catch (InterruptedException e) { Log.e(TAG, "Interrupt received while waiting for shutdown to complete", e); } if (mSessionStatusHandler != null) { mSessionStatusHandler.removeCallbacksAndMessages(null); Looper looper = mSessionStatusHandler.getLooper(); if (looper != null) { looper.quit(); } mSessionStatusHandler = null; } setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED); sendShutdownMessage(); if (VERBOSE) Log.d(TAG, "stop() out"); return true; } Loading @@ -785,7 +818,7 @@ public class BluetoothMapService extends ProfileService { if (DEBUG) Log.d(TAG, "cleanup()"); setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED); // TODO: Change to use message? - do we need to wait for completion? closeService(); closeService(null); // Stop() should be called to handle cleanup - hence this is not needed return true; } Loading Loading @@ -911,7 +944,7 @@ public class BluetoothMapService extends ProfileService { } // Can only be null during shutdown } private void sendShutdownMessage() { private void sendShutdownMessage(CountDownLatch latch) { /* Any pending messages are no longer valid. To speed up things, simply delete them. */ if (mRemoveTimeoutMsg) { Loading @@ -923,7 +956,18 @@ public class BluetoothMapService extends ProfileService { } mSessionStatusHandler.removeCallbacksAndMessages(null); // Request release of all resources mSessionStatusHandler.obtainMessage(SHUTDOWN).sendToTarget(); 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 message"); } } private MapBroadcastReceiver mMapReceiver = new MapBroadcastReceiver(); Loading @@ -939,7 +983,7 @@ public class BluetoothMapService extends ProfileService { BluetoothAdapter.ERROR); if (state == BluetoothAdapter.STATE_TURNING_OFF) { if (DEBUG) Log.d(TAG, "STATE_TURNING_OFF"); sendShutdownMessage(); sendShutdownMessage(null); } else if (state == BluetoothAdapter.STATE_ON) { if (DEBUG) Log.d(TAG, "STATE_ON"); // start ServerSocket listener threads Loading Loading
src/com/android/bluetooth/map/BluetoothMapMasInstance.java +1 −1 Original line number Diff line number Diff line Loading @@ -396,7 +396,7 @@ public class BluetoothMapMasInstance implements IObexConnectionHandler { return (mConnSocket != null); } public void shutdown() { public synchronized void shutdown() { if (D) Log.d(TAG, "MAP Service shutdown"); if (mServerSession != null) { Loading
src/com/android/bluetooth/map/BluetoothMapService.java +54 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.IntentFilter.MalformedMimeTypeException; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.ParcelUuid; import android.os.PowerManager; Loading @@ -50,6 +52,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Set; import java.util.concurrent.CountDownLatch; public class BluetoothMapService extends ProfileService { private static final String TAG = "BluetoothMapService"; Loading @@ -65,7 +68,6 @@ public class BluetoothMapService extends ProfileService { public static final boolean DEBUG = true; //FIXME set to false; public static boolean VERBOSE = Log.isLoggable(LOG_TAG, Log.VERBOSE); /** * Intent indicating timeout for user confirmation, which is sent to * BluetoothMapActivity Loading Loading @@ -146,6 +148,7 @@ public class BluetoothMapService extends ProfileService { private boolean mAccountChanged = false; private boolean mSdpSearchInitiated = false; SdpMnsRecord mMnsRecord = null; private MapServiceMessageHandler mSessionStatusHandler; // package and class name to which we send intent to check phone book access permission private static final String ACCESS_AUTHORITY_PACKAGE = "com.android.settings"; Loading @@ -163,7 +166,7 @@ public class BluetoothMapService extends ProfileService { } private final void closeService() { private synchronized void closeService(CountDownLatch latch) { if (DEBUG) Log.d(TAG, "MAP Service closeService in"); if (mBluetoothMnsObexClient != null) { Loading Loading @@ -192,6 +195,9 @@ public class BluetoothMapService extends ProfileService { mRemoteDevice = null; if (VERBOSE) Log.v(TAG, "MAP Service closeService out"); if(latch != null) { latch.countDown(); } } /** Loading Loading @@ -317,7 +323,10 @@ public class BluetoothMapService extends ProfileService { } } private final Handler mSessionStatusHandler = new Handler() { private final class MapServiceMessageHandler extends Handler { private MapServiceMessageHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { if (DEBUG) Log.v(TAG, "Handler(): got msg=" + msg.what); Loading Loading @@ -369,7 +378,8 @@ public class BluetoothMapService extends ProfileService { case SHUTDOWN: /* Ensure to call close from this handler to avoid starting new stuff because of pending messages */ closeService(); CountDownLatch latch = (CountDownLatch) msg.obj; closeService(latch); break; case MSG_ACQUIRE_WAKE_LOCK: if (VERBOSE) Log.v(TAG, "Acquire Wake Lock request message"); Loading Loading @@ -580,6 +590,12 @@ public class BluetoothMapService extends ProfileService { } if (VERBOSE) Log.v(TAG, "verbose logging is enabled"); HandlerThread thread = new HandlerThread("BluetoothMapHandler"); thread.start(); Looper looper = thread.getLooper(); mSessionStatusHandler = new MapServiceMessageHandler(looper); IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_CONNECTION_ACCESS_REPLY); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); Loading Loading @@ -775,9 +791,26 @@ public class BluetoothMapService extends ProfileService { } catch (Exception e) { Log.w(TAG,"Unable to unregister map receiver",e); } CountDownLatch latch = new CountDownLatch(1); sendShutdownMessage(latch); // We need to wait for shutdown to complete to avoid being garbage collected before // shutdown completes. if(DEBUG) Log.i(TAG, "Waiting for shutdown to complete"); try { latch.await(); } catch (InterruptedException e) { Log.e(TAG, "Interrupt received while waiting for shutdown to complete", e); } if (mSessionStatusHandler != null) { mSessionStatusHandler.removeCallbacksAndMessages(null); Looper looper = mSessionStatusHandler.getLooper(); if (looper != null) { looper.quit(); } mSessionStatusHandler = null; } setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED); sendShutdownMessage(); if (VERBOSE) Log.d(TAG, "stop() out"); return true; } Loading @@ -785,7 +818,7 @@ public class BluetoothMapService extends ProfileService { if (DEBUG) Log.d(TAG, "cleanup()"); setState(BluetoothMap.STATE_DISCONNECTED, BluetoothMap.RESULT_CANCELED); // TODO: Change to use message? - do we need to wait for completion? closeService(); closeService(null); // Stop() should be called to handle cleanup - hence this is not needed return true; } Loading Loading @@ -911,7 +944,7 @@ public class BluetoothMapService extends ProfileService { } // Can only be null during shutdown } private void sendShutdownMessage() { private void sendShutdownMessage(CountDownLatch latch) { /* Any pending messages are no longer valid. To speed up things, simply delete them. */ if (mRemoveTimeoutMsg) { Loading @@ -923,7 +956,18 @@ public class BluetoothMapService extends ProfileService { } mSessionStatusHandler.removeCallbacksAndMessages(null); // Request release of all resources mSessionStatusHandler.obtainMessage(SHUTDOWN).sendToTarget(); 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 message"); } } private MapBroadcastReceiver mMapReceiver = new MapBroadcastReceiver(); Loading @@ -939,7 +983,7 @@ public class BluetoothMapService extends ProfileService { BluetoothAdapter.ERROR); if (state == BluetoothAdapter.STATE_TURNING_OFF) { if (DEBUG) Log.d(TAG, "STATE_TURNING_OFF"); sendShutdownMessage(); sendShutdownMessage(null); } else if (state == BluetoothAdapter.STATE_ON) { if (DEBUG) Log.d(TAG, "STATE_ON"); // start ServerSocket listener threads Loading