Bluetooth: Don't call beginBroadcast() while in a broadcast

Block duplicate calls to beginBroadcast() and add try/finally
to ensure finishBroadcast() is always called.

Bug: 22800686
Change-Id: Ie8d4005f4cd50dd2544a2832773d72eab0015d92
This commit is contained in:
Andre Eisenbach
2015-07-30 08:59:32 -07:00
parent 26ae600b5f
commit 3bf1ac54ed

View File

@@ -805,6 +805,7 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
IBinder mService; IBinder mService;
ComponentName mClassName; ComponentName mClassName;
Intent mIntent; Intent mIntent;
boolean mInvokingProxyCallbacks = false;
ProfileServiceConnections(Intent intent) { ProfileServiceConnections(Intent intent) {
mService = null; mService = null;
@@ -871,34 +872,54 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(TAG, "Unable to linkToDeath", e); Log.e(TAG, "Unable to linkToDeath", e);
} }
int n = mProxies.beginBroadcast();
for (int i = 0; i < n; i++) { if (mInvokingProxyCallbacks) {
try { Log.e(TAG, "Proxy callbacks already in progress.");
mProxies.getBroadcastItem(i).onServiceConnected(className, service); return;
} catch (RemoteException e) { }
Log.e(TAG, "Unable to connect to proxy", e); mInvokingProxyCallbacks = true;
}
final int n = mProxies.beginBroadcast();
try {
for (int i = 0; i < n; i++) {
try {
mProxies.getBroadcastItem(i).onServiceConnected(className, service);
} catch (RemoteException e) {
Log.e(TAG, "Unable to connect to proxy", e);
}
}
} finally {
mProxies.finishBroadcast();
mInvokingProxyCallbacks = false;
} }
mProxies.finishBroadcast();
} }
@Override @Override
public void onServiceDisconnected(ComponentName className) { public void onServiceDisconnected(ComponentName className) {
if (mService == null) { if (mService == null) return;
return;
}
mService.unlinkToDeath(this, 0); mService.unlinkToDeath(this, 0);
mService = null; mService = null;
mClassName = null; mClassName = null;
int n = mProxies.beginBroadcast();
for (int i = 0; i < n; i++) { if (mInvokingProxyCallbacks) {
try { Log.e(TAG, "Proxy callbacks already in progress.");
mProxies.getBroadcastItem(i).onServiceDisconnected(className); return;
} catch (RemoteException e) { }
Log.e(TAG, "Unable to disconnect from proxy", e); mInvokingProxyCallbacks = true;
}
final int n = mProxies.beginBroadcast();
try {
for (int i = 0; i < n; i++) {
try {
mProxies.getBroadcastItem(i).onServiceDisconnected(className);
} catch (RemoteException e) {
Log.e(TAG, "Unable to disconnect from proxy", e);
}
}
} finally {
mProxies.finishBroadcast();
mInvokingProxyCallbacks = false;
} }
mProxies.finishBroadcast();
} }
@Override @Override
@@ -916,16 +937,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
} }
private void sendBluetoothStateCallback(boolean isUp) { private void sendBluetoothStateCallback(boolean isUp) {
int n = mStateChangeCallbacks.beginBroadcast(); try {
if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers."); int n = mStateChangeCallbacks.beginBroadcast();
for (int i=0; i <n;i++) { if (DBG) Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
try { for (int i=0; i <n;i++) {
mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp); try {
} catch (RemoteException e) { mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e); } catch (RemoteException e) {
Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
}
} }
} finally {
mStateChangeCallbacks.finishBroadcast();
} }
mStateChangeCallbacks.finishBroadcast();
} }
/** /**
@@ -934,16 +958,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private void sendBluetoothServiceUpCallback() { private void sendBluetoothServiceUpCallback() {
if (!mConnection.isGetNameAddressOnly()) { if (!mConnection.isGetNameAddressOnly()) {
if (DBG) Log.d(TAG,"Calling onBluetoothServiceUp callbacks"); if (DBG) Log.d(TAG,"Calling onBluetoothServiceUp callbacks");
int n = mCallbacks.beginBroadcast(); try {
Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers."); int n = mCallbacks.beginBroadcast();
for (int i=0; i <n;i++) { Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
try { for (int i=0; i <n;i++) {
mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth); try {
} catch (RemoteException e) { mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e); } catch (RemoteException e) {
Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
}
} }
} finally {
mCallbacks.finishBroadcast();
} }
mCallbacks.finishBroadcast();
} }
} }
/** /**
@@ -952,16 +979,19 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
private void sendBluetoothServiceDownCallback() { private void sendBluetoothServiceDownCallback() {
if (!mConnection.isGetNameAddressOnly()) { if (!mConnection.isGetNameAddressOnly()) {
if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks"); if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks");
int n = mCallbacks.beginBroadcast(); try {
Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers."); int n = mCallbacks.beginBroadcast();
for (int i=0; i <n;i++) { Log.d(TAG,"Broadcasting onBluetoothServiceDown() to " + n + " receivers.");
try { for (int i=0; i <n;i++) {
mCallbacks.getBroadcastItem(i).onBluetoothServiceDown(); try {
} catch (RemoteException e) { mCallbacks.getBroadcastItem(i).onBluetoothServiceDown();
Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e); } catch (RemoteException e) {
Log.e(TAG, "Unable to call onBluetoothServiceDown() on callback #" + i, e);
}
} }
} finally {
mCallbacks.finishBroadcast();
} }
mCallbacks.finishBroadcast();
} }
} }