diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index f66b5ff466c3f..353c6400ffd74 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -30,8 +30,11 @@ import android.os.ParcelUuid; import android.os.RemoteException; import android.util.Log; +import com.android.internal.annotations.GuardedBy; + import java.util.ArrayList; import java.util.List; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** @@ -114,7 +117,8 @@ public final class BluetoothA2dp implements BluetoothProfile { private Context mContext; private ServiceListener mServiceListener; - private IBluetoothA2dp mService; + private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); + @GuardedBy("mServiceLock") private IBluetoothA2dp mService; private BluetoothAdapter mAdapter; final private IBluetoothStateChangeCallback mBluetoothStateChangeCallback = @@ -122,25 +126,27 @@ public final class BluetoothA2dp implements BluetoothProfile { public void onBluetoothStateChange(boolean up) { if (DBG) Log.d(TAG, "onBluetoothStateChange: up=" + up); if (!up) { - if (VDBG) Log.d(TAG,"Unbinding service..."); - synchronized (mConnection) { - try { - mService = null; - mContext.unbindService(mConnection); - } catch (Exception re) { - Log.e(TAG,"",re); - } + if (VDBG) Log.d(TAG, "Unbinding service..."); + try { + mServiceLock.writeLock().lock(); + mService = null; + mContext.unbindService(mConnection); + } catch (Exception re) { + Log.e(TAG, "", re); + } finally { + mServiceLock.writeLock().unlock(); } } else { - synchronized (mConnection) { - try { - if (mService == null) { - if (VDBG) Log.d(TAG,"Binding service..."); - doBind(); - } - } catch (Exception re) { - Log.e(TAG,"",re); + try { + mServiceLock.readLock().lock(); + if (mService == null) { + if (VDBG) Log.d(TAG,"Binding service..."); + doBind(); } + } catch (Exception re) { + Log.e(TAG,"",re); + } finally { + mServiceLock.readLock().unlock(); } } } @@ -189,15 +195,16 @@ public final class BluetoothA2dp implements BluetoothProfile { } } - synchronized (mConnection) { + try { + mServiceLock.writeLock().lock(); if (mService != null) { - try { - mService = null; - mContext.unbindService(mConnection); - } catch (Exception re) { - Log.e(TAG,"",re); - } + mService = null; + mContext.unbindService(mConnection); } + } catch (Exception re) { + Log.e(TAG, "", re); + } finally { + mServiceLock.writeLock().unlock(); } } @@ -229,17 +236,20 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public boolean connect(BluetoothDevice device) { if (DBG) log("connect(" + device + ")"); - if (mService != null && isEnabled() && - isValidDevice(device)) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled() && + isValidDevice(device)) { return mService.connect(device); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return false; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return false; } /** @@ -270,17 +280,20 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public boolean disconnect(BluetoothDevice device) { if (DBG) log("disconnect(" + device + ")"); - if (mService != null && isEnabled() && - isValidDevice(device)) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled() && + isValidDevice(device)) { return mService.disconnect(device); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return false; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return false; } /** @@ -288,16 +301,19 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public List getConnectedDevices() { if (VDBG) log("getConnectedDevices()"); - if (mService != null && isEnabled()) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled()) { return mService.getConnectedDevices(); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return new ArrayList(); } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return new ArrayList(); + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return new ArrayList(); + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return new ArrayList(); } /** @@ -305,16 +321,19 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public List getDevicesMatchingConnectionStates(int[] states) { if (VDBG) log("getDevicesMatchingStates()"); - if (mService != null && isEnabled()) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled()) { return mService.getDevicesMatchingConnectionStates(states); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return new ArrayList(); } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return new ArrayList(); + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return new ArrayList(); + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return new ArrayList(); } /** @@ -322,17 +341,20 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public int getConnectionState(BluetoothDevice device) { if (VDBG) log("getState(" + device + ")"); - if (mService != null && isEnabled() - && isValidDevice(device)) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled() + && isValidDevice(device)) { return mService.getConnectionState(device); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return BluetoothProfile.STATE_DISCONNECTED; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return BluetoothProfile.STATE_DISCONNECTED; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return BluetoothProfile.STATE_DISCONNECTED; + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return BluetoothProfile.STATE_DISCONNECTED; } /** @@ -352,21 +374,24 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public boolean setPriority(BluetoothDevice device, int priority) { if (DBG) log("setPriority(" + device + ", " + priority + ")"); - if (mService != null && isEnabled() - && isValidDevice(device)) { - if (priority != BluetoothProfile.PRIORITY_OFF && - priority != BluetoothProfile.PRIORITY_ON){ - return false; - } - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled() + && isValidDevice(device)) { + if (priority != BluetoothProfile.PRIORITY_OFF && + priority != BluetoothProfile.PRIORITY_ON) { + return false; + } return mService.setPriority(device, priority); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return false; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return false; } /** @@ -385,17 +410,20 @@ public final class BluetoothA2dp implements BluetoothProfile { @RequiresPermission(Manifest.permission.BLUETOOTH) public int getPriority(BluetoothDevice device) { if (VDBG) log("getPriority(" + device + ")"); - if (mService != null && isEnabled() - && isValidDevice(device)) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled() + && isValidDevice(device)) { return mService.getPriority(device); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return BluetoothProfile.PRIORITY_OFF; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return BluetoothProfile.PRIORITY_OFF; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return BluetoothProfile.PRIORITY_OFF; + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return BluetoothProfile.PRIORITY_OFF; } /** @@ -406,16 +434,19 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public boolean isAvrcpAbsoluteVolumeSupported() { if (DBG) Log.d(TAG, "isAvrcpAbsoluteVolumeSupported"); - if (mService != null && isEnabled()) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled()) { return mService.isAvrcpAbsoluteVolumeSupported(); - } catch (RemoteException e) { - Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e); - return false; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Error talking to BT service in isAvrcpAbsoluteVolumeSupported()", e); + return false; + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return false; } /** @@ -433,16 +464,17 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public void adjustAvrcpAbsoluteVolume(int direction) { if (DBG) Log.d(TAG, "adjustAvrcpAbsoluteVolume"); - if (mService != null && isEnabled()) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled()) { mService.adjustAvrcpAbsoluteVolume(direction); - return; - } catch (RemoteException e) { - Log.e(TAG, "Error talking to BT service in adjustAvrcpAbsoluteVolume()", e); - return; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + } catch (RemoteException e) { + Log.e(TAG, "Error talking to BT service in adjustAvrcpAbsoluteVolume()", e); + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); } /** @@ -453,16 +485,17 @@ public final class BluetoothA2dp implements BluetoothProfile { */ public void setAvrcpAbsoluteVolume(int volume) { if (DBG) Log.d(TAG, "setAvrcpAbsoluteVolume"); - if (mService != null && isEnabled()) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled()) { mService.setAvrcpAbsoluteVolume(volume); - return; - } catch (RemoteException e) { - Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e); - return; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + } catch (RemoteException e) { + Log.e(TAG, "Error talking to BT service in setAvrcpAbsoluteVolume()", e); + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); } /** @@ -473,17 +506,20 @@ public final class BluetoothA2dp implements BluetoothProfile { * @param device BluetoothDevice device */ public boolean isA2dpPlaying(BluetoothDevice device) { - if (mService != null && isEnabled() - && isValidDevice(device)) { - try { + try { + mServiceLock.readLock().lock(); + if (mService != null && isEnabled() + && isValidDevice(device)) { return mService.isA2dpPlaying(device); - } catch (RemoteException e) { - Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); - return false; } + if (mService == null) Log.w(TAG, "Proxy not attached to service"); + return false; + } catch (RemoteException e) { + Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable())); + return false; + } finally { + mServiceLock.readLock().unlock(); } - if (mService == null) Log.w(TAG, "Proxy not attached to service"); - return false; } /** @@ -534,7 +570,12 @@ public final class BluetoothA2dp implements BluetoothProfile { private final ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { if (DBG) Log.d(TAG, "Proxy object connected"); - mService = IBluetoothA2dp.Stub.asInterface(service); + try { + mServiceLock.writeLock().lock(); + mService = IBluetoothA2dp.Stub.asInterface(service); + } finally { + mServiceLock.writeLock().unlock(); + } if (mServiceListener != null) { mServiceListener.onServiceConnected(BluetoothProfile.A2DP, BluetoothA2dp.this); @@ -542,7 +583,12 @@ public final class BluetoothA2dp implements BluetoothProfile { } public void onServiceDisconnected(ComponentName className) { if (DBG) Log.d(TAG, "Proxy object disconnected"); - mService = null; + try { + mServiceLock.writeLock().lock(); + mService = null; + } finally { + mServiceLock.writeLock().unlock(); + } if (mServiceListener != null) { mServiceListener.onServiceDisconnected(BluetoothProfile.A2DP); }