Merge "Listen for bluetooth audio changes in system ui." into pi-dev
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 34a099c..00ee575 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -195,8 +195,10 @@
                 if (DEBUG) Log.d(TAG, "Adding local HEADSET profile");
                 mHeadsetProfile = new HeadsetProfile(mContext, mLocalAdapter,
                         mDeviceManager, this);
-                addProfile(mHeadsetProfile, HeadsetProfile.NAME,
-                        BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
+                addHeadsetProfile(mHeadsetProfile, HeadsetProfile.NAME,
+                        BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
+                        BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED,
+                        BluetoothHeadset.STATE_AUDIO_DISCONNECTED);
             }
         } else if (mHeadsetProfile != null) {
             Log.w(TAG, "Warning: HEADSET profile was previously added but the UUID is now missing.");
@@ -208,8 +210,10 @@
                 if(DEBUG) Log.d(TAG, "Adding local HfpClient profile");
                 mHfpClientProfile =
                     new HfpClientProfile(mContext, mLocalAdapter, mDeviceManager, this);
-                addProfile(mHfpClientProfile, HfpClientProfile.NAME,
-                        BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED);
+                addHeadsetProfile(mHfpClientProfile, HfpClientProfile.NAME,
+                        BluetoothHeadsetClient.ACTION_CONNECTION_STATE_CHANGED,
+                        BluetoothHeadsetClient.ACTION_AUDIO_STATE_CHANGED,
+                        BluetoothHeadsetClient.STATE_AUDIO_DISCONNECTED);
             }
         } else if (mHfpClientProfile != null) {
             Log.w(TAG,
@@ -277,6 +281,15 @@
         // There is no local SDP record for HID and Settings app doesn't control PBAP Server.
     }
 
+    private void addHeadsetProfile(LocalBluetoothProfile profile, String profileName,
+            String stateChangedAction, String audioStateChangedAction, int audioDisconnectedState) {
+        BluetoothEventManager.Handler handler = new HeadsetStateChangeHandler(
+                profile, audioStateChangedAction, audioDisconnectedState);
+        mEventManager.addProfileHandler(stateChangedAction, handler);
+        mEventManager.addProfileHandler(audioStateChangedAction, handler);
+        mProfileNameMap.put(profileName, profile);
+    }
+
     private final Collection<ServiceListener> mServiceListeners =
             new ArrayList<ServiceListener>();
 
@@ -323,18 +336,47 @@
                 cachedDevice = mDeviceManager.addDevice(mLocalAdapter,
                         LocalBluetoothProfileManager.this, device);
             }
+            onReceiveInternal(intent, cachedDevice);
+        }
+
+        protected void onReceiveInternal(Intent intent, CachedBluetoothDevice cachedDevice) {
             int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
             int oldState = intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
             if (newState == BluetoothProfile.STATE_DISCONNECTED &&
                     oldState == BluetoothProfile.STATE_CONNECTING) {
                 Log.i(TAG, "Failed to connect " + mProfile + " device");
             }
-
             cachedDevice.onProfileStateChanged(mProfile, newState);
             cachedDevice.refresh();
         }
     }
 
+    /** Connectivity and audio state change handler for headset profiles. */
+    private class HeadsetStateChangeHandler extends StateChangedHandler {
+        private final String mAudioChangeAction;
+        private final int mAudioDisconnectedState;
+
+        HeadsetStateChangeHandler(LocalBluetoothProfile profile, String audioChangeAction,
+                int audioDisconnectedState) {
+            super(profile);
+            mAudioChangeAction = audioChangeAction;
+            mAudioDisconnectedState = audioDisconnectedState;
+        }
+
+        @Override
+        public void onReceiveInternal(Intent intent, CachedBluetoothDevice cachedDevice) {
+            if (mAudioChangeAction.equals(intent.getAction())) {
+                int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
+                if (newState != mAudioDisconnectedState) {
+                    cachedDevice.onProfileStateChanged(mProfile, BluetoothProfile.STATE_CONNECTED);
+                }
+                cachedDevice.refresh();
+            } else {
+                super.onReceiveInternal(intent, cachedDevice);
+            }
+        }
+    }
+
     /** State change handler for NAP and PANU profiles. */
     private class PanStateChangedHandler extends StateChangedHandler {