Moved BluetoothAdapter.ACTION_STATE_CHANGED broadcast from AdapterService to BluetoothManagerService
Change-Id: I88e5f3fe050cf11eae9c5cf1b7c393a178b8f9b1
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index c08705c..dc18029 100755
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -464,12 +464,15 @@
synchronized(mManagerCallback) {
if (mService != null)
{
- return mService.getState();
+ int state= mService.getState();
+ if (DBG) Log.d(TAG, "" + hashCode() + ": getState(). Returning " + state);
+ return state;
}
// TODO(BT) there might be a small gap during STATE_TURNING_ON that
// mService is null, handle that case
}
} catch (RemoteException e) {Log.e(TAG, "", e);}
+ if (DBG) Log.d(TAG, "" + hashCode() + ": getState() : mService = null. Returning STATE_OFF");
return STATE_OFF;
}
@@ -1208,7 +1211,7 @@
if (DBG) Log.d(TAG, "onBluetoothServiceUp: " + bluetoothService);
synchronized (mManagerCallback) {
mService = bluetoothService;
- for (IBluetoothManagerCallback cb : mBluetoothManagerCallbackList ){
+ for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
try {
if (cb != null) {
cb.onBluetoothServiceUp(bluetoothService);
@@ -1224,7 +1227,7 @@
if (DBG) Log.d(TAG, "onBluetoothServiceDown: " + mService);
synchronized (mManagerCallback) {
mService = null;
- for (IBluetoothManagerCallback cb : mBluetoothManagerCallbackList ){
+ for (IBluetoothManagerCallback cb : mProxyServiceStateCallbacks ){
try {
if (cb != null) {
cb.onBluetoothServiceDown();
@@ -1368,14 +1371,14 @@
return mManagerService;
}
- private ArrayList<IBluetoothManagerCallback> mBluetoothManagerCallbackList = new ArrayList<IBluetoothManagerCallback>();
+ private ArrayList<IBluetoothManagerCallback> mProxyServiceStateCallbacks = new ArrayList<IBluetoothManagerCallback>();
/*package*/ IBluetooth getBluetoothService(IBluetoothManagerCallback cb) {
synchronized (mManagerCallback) {
if (cb == null) {
- Log.w(TAG, "Unable to register null state change callback", new Exception());
- } else if (!mBluetoothManagerCallbackList.contains(cb)) {
- mBluetoothManagerCallbackList.add(cb);
+ Log.w(TAG, "getBluetoothService() called with no BluetoothManagerCallback");
+ } else if (!mProxyServiceStateCallbacks.contains(cb)) {
+ mProxyServiceStateCallbacks.add(cb);
}
}
return mService;
@@ -1383,7 +1386,7 @@
/*package*/ void removeServiceStateCallback(IBluetoothManagerCallback cb) {
synchronized (mManagerCallback) {
- mBluetoothManagerCallbackList.remove(cb);
+ mProxyServiceStateCallbacks.remove(cb);
}
}
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 9653de2..eff780d 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -72,6 +72,9 @@
void sendConnectionStateChange(in BluetoothDevice device, int profile, int state, int prevState);
+ void registerCallback(in IBluetoothCallback callback);
+ void unregisterCallback(in IBluetoothCallback callback);
+
// For Socket
ParcelFileDescriptor connectSocket(in BluetoothDevice device, int type, in ParcelUuid uuid, int port, int flag);
ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);
diff --git a/core/java/android/bluetooth/IBluetoothCallback.aidl b/core/java/android/bluetooth/IBluetoothCallback.aidl
index 8edb3f4..e280978 100644
--- a/core/java/android/bluetooth/IBluetoothCallback.aidl
+++ b/core/java/android/bluetooth/IBluetoothCallback.aidl
@@ -23,5 +23,6 @@
*/
interface IBluetoothCallback
{
- void onRfcommChannelFound(int channel);
+ //void onRfcommChannelFound(int channel);
+ void onBluetoothStateChange(int prevState, int newState);
}
diff --git a/services/java/com/android/server/BluetoothManagerService.java b/services/java/com/android/server/BluetoothManagerService.java
index 3c3b9db..32fddeb 100644
--- a/services/java/com/android/server/BluetoothManagerService.java
+++ b/services/java/com/android/server/BluetoothManagerService.java
@@ -6,6 +6,7 @@
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.IBluetooth;
+import android.bluetooth.IBluetoothCallback;
import android.bluetooth.IBluetoothManager;
import android.bluetooth.IBluetoothManagerCallback;
import android.bluetooth.IBluetoothStateChangeCallback;
@@ -49,8 +50,7 @@
private static final int MESSAGE_UNREGISTER_STATE_CHANGE_CALLBACK = 31;
private static final int MESSAGE_BLUETOOTH_SERVICE_CONNECTED = 40;
private static final int MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED = 41;
- private static final int MESSAGE_BLUETOOTH_ON = 50;
- private static final int MESSAGE_BLUETOOTH_OFF = 51;
+ private static final int MESSAGE_BLUETOOTH_STATE_CHANGE=60;
private static final int MESSAGE_TIMEOUT_BIND =100;
private static final int MESSAGE_TIMEOUT_UNBIND =101;
private static final int MESSAGE_GET_NAME_AND_ADDRESS=200;
@@ -80,20 +80,19 @@
}
}
- private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ private final IBluetoothCallback mBluetoothCallback = new IBluetoothCallback.Stub() {
+ @Override
+ public void onBluetoothStateChange(int prevState, int newState) throws RemoteException {
+ Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_STATE_CHANGE,prevState,newState);
+ mHandler.sendMessage(msg);
+ }
+ };
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
- int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
- if (state == BluetoothAdapter.STATE_OFF) {
- Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_OFF);
- mHandler.sendMessage(msg);
- } else if (state == BluetoothAdapter.STATE_ON) {
- Message msg = mHandler.obtainMessage(MESSAGE_BLUETOOTH_ON);
- mHandler.sendMessage(msg);
- }
- } else if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
+ if (BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED.equals(action)) {
String newName = intent.getStringExtra(BluetoothAdapter.EXTRA_LOCAL_NAME);
Log.d(TAG, "Bluetooth Adapter name changed to " + newName);
if (newName != null) {
@@ -332,6 +331,14 @@
if (mUnbinding) return;
mUnbinding = true;
if (isConnected()) {
+ if (!mConnection.isGetNameAddressOnly()) {
+ //Unregister callback object
+ try {
+ mBluetooth.unregisterCallback(mBluetoothCallback);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Unable to register BluetoothCallback",re);
+ }
+ }
if (DBG) Log.d(TAG, "Sending unbind request.");
mBluetooth = null;
//Unbind
@@ -343,7 +350,23 @@
}
}
- private void sendBluetoothServiceDownEvent() {
+ private void sendBluetoothStateCallback(boolean isUp) {
+ int n = mStateChangeCallbacks.beginBroadcast();
+ Log.d(TAG,"Broadcasting onBluetoothStateChange("+isUp+") to " + n + " receivers.");
+ for (int i=0; i <n;i++) {
+ try {
+ mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(isUp);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
+ }
+ }
+ mStateChangeCallbacks.finishBroadcast();
+ }
+
+ /**
+ * Inform BluetoothAdapter instances that Adapter service is down
+ */
+ private void sendBluetoothServiceDownCallback() {
if (!mConnection.isGetNameAddressOnly()) {
if (DBG) Log.d(TAG,"Calling onBluetoothServiceDown callbacks");
int n = mCallbacks.beginBroadcast();
@@ -463,7 +486,7 @@
i.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
i.putExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.STATE_OFF);
mContext.startService(i);
- sendBluetoothServiceDownEvent();
+ sendBluetoothServiceDownCallback();
unbindAndFinish();
} else {
if (msg.arg1 < MAX_SAVE_RETRIES) {
@@ -473,7 +496,7 @@
mHandler.sendMessageDelayed(retryMsg, TIMEOUT_SAVE_MS);
} else {
Log.w(TAG,"Maximum name/address remote retrieval retry exceeded");
- sendBluetoothServiceDownEvent();
+ sendBluetoothServiceDownCallback();
unbindAndFinish();
}
}
@@ -504,11 +527,14 @@
//Start bind timeout and bind
Message timeoutMsg=mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
mHandler.sendMessageDelayed(timeoutMsg,TIMEOUT_BIND_MS);
+ /*
Intent i = new Intent(IBluetooth.class.getName());
i.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
i.putExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.STATE_ON);
mContext.startService(i);
+ */
mConnection.setGetNameAddressOnly(false);
+ Intent i = new Intent(IBluetooth.class.getName());
if (!mContext.bindService(i, mConnection,Context.BIND_AUTO_CREATE)) {
mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
Log.e(TAG, "Fail to bind to: " + IBluetooth.class.getName());
@@ -603,17 +629,31 @@
mHandler.sendMessage(getMsg);
return;
}
- int n = mCallbacks.beginBroadcast();
- Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
- for (int i=0; i <n;i++) {
- try {
- mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
- }
- }
- mCallbacks.finishBroadcast();
+ //Register callback object
+ try {
+ mBluetooth.registerCallback(mBluetoothCallback);
+ } catch (RemoteException re) {
+ Log.e(TAG, "Unable to register BluetoothCallback",re);
+ }
+
+ //Inform BluetoothAdapter instances that service is up
+ int n = mCallbacks.beginBroadcast();
+ Log.d(TAG,"Broadcasting onBluetoothServiceUp() to " + n + " receivers.");
+ for (int i=0; i <n;i++) {
+ try {
+ mCallbacks.getBroadcastItem(i).onBluetoothServiceUp(mBluetooth);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to call onBluetoothServiceUp() on callback #" + i, e);
+ }
+ }
+ mCallbacks.finishBroadcast();
+
+ //Do enable request
+ Intent i = new Intent(IBluetooth.class.getName());
+ i.putExtra(EXTRA_ACTION, ACTION_SERVICE_STATE_CHANGED);
+ i.putExtra(BluetoothAdapter.EXTRA_STATE,BluetoothAdapter.STATE_ON);
+ mContext.startService(i);
}
break;
case MESSAGE_TIMEOUT_BIND: {
@@ -623,42 +663,38 @@
}
}
break;
- case MESSAGE_BLUETOOTH_ON:
+ case MESSAGE_BLUETOOTH_STATE_CHANGE:
{
- if (DBG) Log.d(TAG, "MESSAGE_BLUETOOTH_ON");
- int n = mStateChangeCallbacks.beginBroadcast();
- Log.d(TAG,"Broadcasting onBluetoothStateChange() to " + n + " receivers.");
- for (int i=0; i <n;i++) {
- try {
- mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(true);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
+ int prevState = msg.arg1;
+ int newState = msg.arg2;
+ if (DBG) Log.d(TAG, "MESSAGE_BLUETOOTH_STATE_CHANGE: prevState = " + prevState + ", newState=" + newState);
+ if (prevState != newState) {
+ //Notify all proxy objects first of adapter state change
+ if (newState == BluetoothAdapter.STATE_ON || newState == BluetoothAdapter.STATE_OFF) {
+ boolean isUp = (newState==BluetoothAdapter.STATE_ON);
+ sendBluetoothStateCallback(isUp);
+
+ //If Bluetooth is off, send service down event to proxy objects, and unbind
+ if (!isUp) {
+ sendBluetoothServiceDownCallback();
+ unbindAndFinish();
+ }
}
+
+ //Send broadcast message to everyone else
+ Intent intent = new Intent(BluetoothAdapter.ACTION_STATE_CHANGED);
+ intent.putExtra(BluetoothAdapter.EXTRA_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothAdapter.EXTRA_STATE, newState);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
+ if (DBG) Log.d(TAG,"Bluetooth State Change Intent: " + prevState + " -> " + newState);
+ mContext.sendBroadcast(intent,BLUETOOTH_PERM);
}
- mStateChangeCallbacks.finishBroadcast();
- }
- break;
- case MESSAGE_BLUETOOTH_OFF:
- {
- if (DBG) Log.d(TAG, "MESSAGE_BLUETOOTH_OFF");
- int n = mStateChangeCallbacks.beginBroadcast();
- Log.d(TAG,"Broadcasting onBluetoothStateChange() to " + n + " receivers.");
- for (int i=0; i <n;i++) {
- try {
- mStateChangeCallbacks.getBroadcastItem(i).onBluetoothStateChange(false);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to call onBluetoothStateChange() on callback #" + i , e);
- }
- }
- mStateChangeCallbacks.finishBroadcast();
- sendBluetoothServiceDownEvent();
- unbindAndFinish();
}
break;
case MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED:
{
if (DBG) Log.d(TAG, "MESSAGE_BLUETOOTH_SERVICE_DISCONNECTED");
- sendBluetoothServiceDownEvent();
+ sendBluetoothServiceDownCallback();
}
break;
case MESSAGE_TIMEOUT_UNBIND: