From 18c4317b93fce47109017efdab089dec4b01f790 Mon Sep 17 00:00:00 2001 From: Jake Hamby Date: Fri, 26 Apr 2013 14:38:15 -0700 Subject: [PATCH] Show correct A2DP connection status in Bluetooth settings. When BluetoothSettings is entered via QuickSettings while an A2DP device is connected, we aren't showing the device connection status in the UI, because the device list is created before we've connected to the A2DP and Headset profile services, and we weren't refreshing the device list UI after getting the callback for onServiceConnected() and retrieving the list of connected devices. Add a line to HeadsetServiceListener.onServiceConnected() to call device.refresh() after we call device.onProfileStateChanged() to refresh the device list UI. Also copy the logic into A2dpProfile's onServiceConnected() callback so it will refresh the UI for any connected A2DP devices. The reason this bug doesn't show up when entering BT settings from the main Settings screen is because the onServiceConnected() callbacks happen before the device list is initialized, so the UI items are created with the correct connection status. For the same reason, the bug doesn't occur if the Settings app is already running and we re-enter it via Bluetooth QuickSettings. Bug: 8724247 Change-Id: I1a993636ecab18dd6e980e3b4d2485bbed256d74 --- .../settings/bluetooth/A2dpProfile.java | 26 ++++++++++++++++--- .../settings/bluetooth/HeadsetProfile.java | 14 +++++----- .../settings/bluetooth/HidProfile.java | 24 ++++++++++++++++- .../LocalBluetoothProfileManager.java | 4 +-- 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/src/com/android/settings/bluetooth/A2dpProfile.java b/src/com/android/settings/bluetooth/A2dpProfile.java index fbf24c9b22a..435a659de63 100755 --- a/src/com/android/settings/bluetooth/A2dpProfile.java +++ b/src/com/android/settings/bluetooth/A2dpProfile.java @@ -38,6 +38,9 @@ final class A2dpProfile implements LocalBluetoothProfile { private BluetoothA2dp mService; private boolean mIsProfileReady; + private final LocalBluetoothAdapter mLocalAdapter; + private final CachedBluetoothDeviceManager mDeviceManager; + static final ParcelUuid[] SINK_UUIDS = { BluetoothUuid.AudioSink, BluetoothUuid.AdvAudioDist, @@ -56,6 +59,19 @@ final class A2dpProfile implements LocalBluetoothProfile { public void onServiceConnected(int profile, BluetoothProfile proxy) { if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothA2dp) proxy; + // We just bound to the service, so refresh the UI for any connected A2DP devices. + List deviceList = mService.getConnectedDevices(); + while (!deviceList.isEmpty()) { + BluetoothDevice nextDevice = deviceList.remove(0); + CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice); + // we may add a new device here, but generally this should not happen + if (device == null) { + Log.w(TAG, "A2dpProfile found new device: " + nextDevice); + device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice); + } + device.onProfileStateChanged(A2dpProfile.this, BluetoothProfile.STATE_CONNECTED); + device.refresh(); + } mIsProfileReady=true; } @@ -68,10 +84,14 @@ final class A2dpProfile implements LocalBluetoothProfile { public boolean isProfileReady() { return mIsProfileReady; } - A2dpProfile(Context context, LocalBluetoothProfileManager profileManager) { + + A2dpProfile(Context context, LocalBluetoothAdapter adapter, + CachedBluetoothDeviceManager deviceManager, + LocalBluetoothProfileManager profileManager) { + mLocalAdapter = adapter; + mDeviceManager = deviceManager; mProfileManager = profileManager; - BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); - adapter.getProfileProxy(context, new A2dpServiceListener(), + mLocalAdapter.getProfileProxy(context, new A2dpServiceListener(), BluetoothProfile.A2DP); } diff --git a/src/com/android/settings/bluetooth/HeadsetProfile.java b/src/com/android/settings/bluetooth/HeadsetProfile.java index 83c8e8e35de..1caeb65422c 100755 --- a/src/com/android/settings/bluetooth/HeadsetProfile.java +++ b/src/com/android/settings/bluetooth/HeadsetProfile.java @@ -62,19 +62,19 @@ final class HeadsetProfile implements LocalBluetoothProfile { public void onServiceConnected(int profile, BluetoothProfile proxy) { if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothHeadset) proxy; - // We just bound to the service, so refresh the UI of the - // headset device. + // We just bound to the service, so refresh the UI for any connected HFP devices. List deviceList = mService.getConnectedDevices(); - if (!deviceList.isEmpty()) { - BluetoothDevice firstDevice = deviceList.get(0); - CachedBluetoothDevice device = mDeviceManager.findDevice(firstDevice); + while (!deviceList.isEmpty()) { + BluetoothDevice nextDevice = deviceList.remove(0); + CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice); // we may add a new device here, but generally this should not happen if (device == null) { - Log.w(TAG, "HeadsetProfile found new device: " + firstDevice); - device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, firstDevice); + Log.w(TAG, "HeadsetProfile found new device: " + nextDevice); + device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice); } device.onProfileStateChanged(HeadsetProfile.this, BluetoothProfile.STATE_CONNECTED); + device.refresh(); } mProfileManager.callServiceConnectedListeners(); diff --git a/src/com/android/settings/bluetooth/HidProfile.java b/src/com/android/settings/bluetooth/HidProfile.java index c502850ca2c..8df2845cb3a 100755 --- a/src/com/android/settings/bluetooth/HidProfile.java +++ b/src/com/android/settings/bluetooth/HidProfile.java @@ -38,6 +38,10 @@ final class HidProfile implements LocalBluetoothProfile { private BluetoothInputDevice mService; private boolean mIsProfileReady; + private final LocalBluetoothAdapter mLocalAdapter; + private final CachedBluetoothDeviceManager mDeviceManager; + private final LocalBluetoothProfileManager mProfileManager; + static final String NAME = "HID"; // Order of this profile in device profiles list @@ -50,6 +54,19 @@ final class HidProfile implements LocalBluetoothProfile { public void onServiceConnected(int profile, BluetoothProfile proxy) { if (V) Log.d(TAG,"Bluetooth service connected"); mService = (BluetoothInputDevice) proxy; + // We just bound to the service, so refresh the UI for any connected HID devices. + List deviceList = mService.getConnectedDevices(); + while (!deviceList.isEmpty()) { + BluetoothDevice nextDevice = deviceList.remove(0); + CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice); + // we may add a new device here, but generally this should not happen + if (device == null) { + Log.w(TAG, "HidProfile found new device: " + nextDevice); + device = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, nextDevice); + } + device.onProfileStateChanged(HidProfile.this, BluetoothProfile.STATE_CONNECTED); + device.refresh(); + } mIsProfileReady=true; } @@ -63,7 +80,12 @@ final class HidProfile implements LocalBluetoothProfile { return mIsProfileReady; } - HidProfile(Context context, LocalBluetoothAdapter adapter) { + HidProfile(Context context, LocalBluetoothAdapter adapter, + CachedBluetoothDeviceManager deviceManager, + LocalBluetoothProfileManager profileManager) { + mLocalAdapter = adapter; + mDeviceManager = deviceManager; + mProfileManager = profileManager; adapter.getProfileProxy(context, new InputDeviceServiceListener(), BluetoothProfile.INPUT_DEVICE); } diff --git a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java index 916ef9e146b..5d254aec6b8 100755 --- a/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java +++ b/src/com/android/settings/bluetooth/LocalBluetoothProfileManager.java @@ -111,7 +111,7 @@ final class LocalBluetoothProfileManager { } // Always add HID and PAN profiles - mHidProfile = new HidProfile(context, mLocalAdapter); + mHidProfile = new HidProfile(context, mLocalAdapter, mDeviceManager, this); addProfile(mHidProfile, HidProfile.NAME, BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED); @@ -138,7 +138,7 @@ final class LocalBluetoothProfileManager { if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.AudioSource)) { if (mA2dpProfile == null) { Log.d(TAG, "Adding local A2DP profile"); - mA2dpProfile = new A2dpProfile(mContext, this); + mA2dpProfile = new A2dpProfile(mContext, mLocalAdapter, mDeviceManager, this); addProfile(mA2dpProfile, A2dpProfile.NAME, BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED); }