Merge "Fix QS/status bar BT state"
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 4dfaf45..374086d 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -25,6 +25,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.NightDisplayController;
import com.android.internal.util.Preconditions;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.plugins.ActivityStarter;
@@ -248,6 +249,9 @@
mProviders.put(PluginDependencyProvider.class, () ->
new PluginDependencyProvider(get(PluginManager.class)));
+ mProviders.put(LocalBluetoothManager.class, () ->
+ LocalBluetoothManager.getInstance(mContext, null));
+
// Put all dependencies above here so the factory can override them if it wants.
SystemUIFactory.getInstance().injectDependencies(mProviders, mContext);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 15c4afe..36d24b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -29,6 +29,7 @@
import com.android.settingslib.bluetooth.BluetoothCallback;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.systemui.Dependency;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -52,7 +53,7 @@
private int mState;
public BluetoothControllerImpl(Context context, Looper bgLooper) {
- mLocalBluetoothManager = LocalBluetoothManager.getInstance(context, null);
+ mLocalBluetoothManager = Dependency.get(LocalBluetoothManager.class);
if (mLocalBluetoothManager != null) {
mLocalBluetoothManager.getEventManager().setReceiverHandler(new Handler(bgLooper));
mLocalBluetoothManager.getEventManager().registerCallback(this);
@@ -174,24 +175,30 @@
private void updateConnected() {
// Make sure our connection state is up to date.
int state = mLocalBluetoothManager.getBluetoothAdapter().getConnectionState();
- if (state != mConnectionState) {
- mConnectionState = state;
- mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
+ if (mLastDevice != null && !mLastDevice.isConnected()) {
+ // Clear out last device if no longer connected.
+ mLastDevice = null;
}
- if (mLastDevice != null && mLastDevice.isConnected()) {
- // Our current device is still valid.
- return;
- }
- mLastDevice = null;
+ // If any of the devices are in a higher state than the adapter, move the adapter into
+ // that state.
for (CachedBluetoothDevice device : getDevices()) {
- if (device.isConnected()) {
+ int maxDeviceState = device.getMaxConnectionState();
+ if (maxDeviceState > state) {
+ state = maxDeviceState;
+ }
+ if (mLastDevice == null && device.isConnected()) {
+ // Set as last connected device only if we don't have one.
mLastDevice = device;
}
}
- if (mLastDevice == null && mConnectionState == BluetoothAdapter.STATE_CONNECTED) {
+
+ if (mLastDevice == null && state == BluetoothAdapter.STATE_CONNECTED) {
// If somehow we think we are connected, but have no connected devices, we aren't
// connected.
- mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
+ state = BluetoothAdapter.STATE_DISCONNECTED;
+ }
+ if (state != mConnectionState) {
+ mConnectionState = state;
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
}
@@ -238,7 +245,6 @@
public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
mLastDevice = cachedDevice;
updateConnected();
- mConnectionState = state;
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
new file mode 100644
index 0000000..8808988
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BluetoothControllerImplTest.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package com.android.systemui.statusbar.policy;
+
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothProfile;
+import android.testing.TestableLooper;
+
+import com.android.settingslib.bluetooth.BluetoothEventManager;
+import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
+import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
+import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.systemui.SysuiTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BluetoothControllerImplTest extends SysuiTestCase {
+
+ private LocalBluetoothManager mMockBluetoothManager;
+ private CachedBluetoothDeviceManager mMockDeviceManager;
+ private LocalBluetoothAdapter mMockAdapter;
+ private TestableLooper mTestableLooper;
+ private BluetoothControllerImpl mBluetoothControllerImpl;
+
+ private List<CachedBluetoothDevice> mDevices;
+
+ @Before
+ public void setup() throws Exception {
+ mTestableLooper = new TestableLooper();
+ mMockBluetoothManager = mDependency.injectMockDependency(LocalBluetoothManager.class);
+ mDevices = new ArrayList<>();
+ mMockDeviceManager = mock(CachedBluetoothDeviceManager.class);
+ when(mMockDeviceManager.getCachedDevicesCopy()).thenReturn(mDevices);
+ when(mMockBluetoothManager.getCachedDeviceManager()).thenReturn(mMockDeviceManager);
+ mMockAdapter = mock(LocalBluetoothAdapter.class);
+ when(mMockBluetoothManager.getBluetoothAdapter()).thenReturn(mMockAdapter);
+ when(mMockBluetoothManager.getEventManager()).thenReturn(mock(BluetoothEventManager.class));
+
+ mBluetoothControllerImpl = new BluetoothControllerImpl(mContext,
+ mTestableLooper.getLooper());
+ }
+
+ @Test
+ public void testNoConnectionWithDevices() {
+ CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
+ when(device.isConnected()).thenReturn(true);
+ when(device.getMaxConnectionState()).thenReturn(BluetoothProfile.STATE_CONNECTED);
+ mDevices.add(device);
+ when(mMockAdapter.getConnectionState()).thenReturn(BluetoothAdapter.STATE_DISCONNECTED);
+
+ mBluetoothControllerImpl.onConnectionStateChanged(null,
+ BluetoothAdapter.STATE_DISCONNECTED);
+ assertTrue(mBluetoothControllerImpl.isBluetoothConnected());
+ }
+}