Update bluetooth QS tile secondary text.
Only show detailed status when connected to exactly one device. Otherwise show "X devices". Also, listen for bluetooth profile service callbacks to initialize the bluetooth device state after systemui crashes. TODO: Update string to "X devices connected" after P Change-Id: I99a3484c3dfa7eb0d6d8836336ebb84cbdaadbe5 Fixes: 76102598 Fixes: 77498698 Test: manual
This commit is contained in:
@@ -51,6 +51,7 @@ import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/** Quick settings tile: Bluetooth **/
|
||||
public class BluetoothTile extends QSTileImpl<BooleanState> {
|
||||
@@ -137,7 +138,9 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
|
||||
if (enabled) {
|
||||
if (connected) {
|
||||
state.icon = new BluetoothConnectedTileIcon();
|
||||
state.label = mController.getLastDeviceName();
|
||||
if (!TextUtils.isEmpty(mController.getConnectedDeviceName())) {
|
||||
state.label = mController.getConnectedDeviceName();
|
||||
}
|
||||
state.contentDescription =
|
||||
mContext.getString(R.string.accessibility_bluetooth_name, state.label)
|
||||
+ ", " + state.secondaryLabel;
|
||||
@@ -177,9 +180,18 @@ public class BluetoothTile extends QSTileImpl<BooleanState> {
|
||||
if (isTransient) {
|
||||
return mContext.getString(R.string.quick_settings_bluetooth_secondary_label_transient);
|
||||
}
|
||||
final CachedBluetoothDevice lastDevice = mController.getLastDevice();
|
||||
|
||||
if (enabled && connected && lastDevice != null) {
|
||||
List<CachedBluetoothDevice> connectedDevices = mController.getConnectedDevices();
|
||||
if (enabled && connected && !connectedDevices.isEmpty()) {
|
||||
if (connectedDevices.size() > 1) {
|
||||
// TODO(b/76102598): add a new string for "X connected devices" after P
|
||||
return mContext.getResources().getQuantityString(
|
||||
R.plurals.quick_settings_hotspot_secondary_label_num_devices,
|
||||
connectedDevices.size(),
|
||||
connectedDevices.size());
|
||||
}
|
||||
|
||||
CachedBluetoothDevice lastDevice = connectedDevices.get(0);
|
||||
final int batteryLevel = lastDevice.getBatteryLevel();
|
||||
|
||||
if (batteryLevel != BluetoothDevice.BATTERY_LEVEL_UNKNOWN) {
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.android.systemui.Dumpable;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController.Callback;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public interface BluetoothController extends CallbackController<Callback>, Dumpable {
|
||||
boolean isBluetoothSupported();
|
||||
@@ -30,7 +31,7 @@ public interface BluetoothController extends CallbackController<Callback>, Dumpa
|
||||
|
||||
boolean isBluetoothConnected();
|
||||
boolean isBluetoothConnecting();
|
||||
String getLastDeviceName();
|
||||
String getConnectedDeviceName();
|
||||
void setBluetoothEnabled(boolean enabled);
|
||||
Collection<CachedBluetoothDevice> getDevices();
|
||||
void connect(CachedBluetoothDevice device);
|
||||
@@ -39,7 +40,7 @@ public interface BluetoothController extends CallbackController<Callback>, Dumpa
|
||||
|
||||
int getMaxConnectionState(CachedBluetoothDevice device);
|
||||
int getBondState(CachedBluetoothDevice device);
|
||||
CachedBluetoothDevice getLastDevice();
|
||||
List<CachedBluetoothDevice> getConnectedDevices();
|
||||
|
||||
public interface Callback {
|
||||
void onBluetoothStateChange(boolean enabled);
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.util.Log;
|
||||
import com.android.settingslib.bluetooth.BluetoothCallback;
|
||||
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothManager;
|
||||
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.systemui.Dependency;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
@@ -38,10 +39,11 @@ import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
public class BluetoothControllerImpl implements BluetoothController, BluetoothCallback,
|
||||
CachedBluetoothDevice.Callback {
|
||||
CachedBluetoothDevice.Callback, LocalBluetoothProfileManager.ServiceListener {
|
||||
private static final String TAG = "BluetoothController";
|
||||
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||||
|
||||
@@ -51,10 +53,10 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
private final WeakHashMap<CachedBluetoothDevice, ActuallyCachedState> mCachedState =
|
||||
new WeakHashMap<>();
|
||||
private final Handler mBgHandler;
|
||||
private final List<CachedBluetoothDevice> mConnectedDevices = new ArrayList<>();
|
||||
|
||||
private boolean mEnabled;
|
||||
private int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
|
||||
private CachedBluetoothDevice mLastDevice;
|
||||
|
||||
private final H mHandler = new H(Looper.getMainLooper());
|
||||
private int mState;
|
||||
@@ -65,6 +67,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
if (mLocalBluetoothManager != null) {
|
||||
mLocalBluetoothManager.getEventManager().setReceiverHandler(mBgHandler);
|
||||
mLocalBluetoothManager.getEventManager().registerCallback(this);
|
||||
mLocalBluetoothManager.getProfileManager().addServiceListener(this);
|
||||
onBluetoothStateChanged(
|
||||
mLocalBluetoothManager.getBluetoothAdapter().getBluetoothState());
|
||||
}
|
||||
@@ -88,11 +91,10 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
}
|
||||
pw.print(" mEnabled="); pw.println(mEnabled);
|
||||
pw.print(" mConnectionState="); pw.println(stateToString(mConnectionState));
|
||||
pw.print(" mLastDevice="); pw.println(mLastDevice);
|
||||
pw.print(" mConnectedDevices="); pw.println(mConnectedDevices);
|
||||
pw.print(" mCallbacks.size="); pw.println(mHandler.mCallbacks.size());
|
||||
pw.println(" Bluetooth Devices:");
|
||||
for (CachedBluetoothDevice device :
|
||||
mLocalBluetoothManager.getCachedDeviceManager().getCachedDevicesCopy()) {
|
||||
for (CachedBluetoothDevice device : getDevices()) {
|
||||
pw.println(" " + getDeviceString(device));
|
||||
}
|
||||
}
|
||||
@@ -121,8 +123,8 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedBluetoothDevice getLastDevice() {
|
||||
return mLastDevice;
|
||||
public List<CachedBluetoothDevice> getConnectedDevices() {
|
||||
return mConnectedDevices;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -186,8 +188,11 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastDeviceName() {
|
||||
return mLastDevice != null ? mLastDevice.getName() : null;
|
||||
public String getConnectedDeviceName() {
|
||||
if (mConnectedDevices.size() == 1) {
|
||||
return mConnectedDevices.get(0).getName();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -200,10 +205,7 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
private void updateConnected() {
|
||||
// Make sure our connection state is up to date.
|
||||
int state = mLocalBluetoothManager.getBluetoothAdapter().getConnectionState();
|
||||
if (mLastDevice != null && !mLastDevice.isConnected()) {
|
||||
// Clear out last device if no longer connected.
|
||||
mLastDevice = null;
|
||||
}
|
||||
mConnectedDevices.clear();
|
||||
// If any of the devices are in a higher state than the adapter, move the adapter into
|
||||
// that state.
|
||||
for (CachedBluetoothDevice device : getDevices()) {
|
||||
@@ -211,13 +213,12 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
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 (device.isConnected()) {
|
||||
mConnectedDevices.add(device);
|
||||
}
|
||||
}
|
||||
|
||||
if (mLastDevice == null && state == BluetoothAdapter.STATE_CONNECTED) {
|
||||
if (mConnectedDevices.isEmpty() && state == BluetoothAdapter.STATE_CONNECTED) {
|
||||
// If somehow we think we are connected, but have no connected devices, we aren't
|
||||
// connected.
|
||||
state = BluetoothAdapter.STATE_DISCONNECTED;
|
||||
@@ -271,7 +272,6 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
@Override
|
||||
public void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
|
||||
mCachedState.remove(cachedDevice);
|
||||
mLastDevice = cachedDevice;
|
||||
updateConnected();
|
||||
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
|
||||
}
|
||||
@@ -293,6 +293,15 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
|
||||
return state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceConnected() {
|
||||
updateConnected();
|
||||
mHandler.sendEmptyMessage(H.MSG_PAIRED_DEVICES_CHANGED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected() {}
|
||||
|
||||
private static class ActuallyCachedState implements Runnable {
|
||||
|
||||
private final WeakReference<CachedBluetoothDevice> mDevice;
|
||||
|
||||
@@ -35,6 +35,7 @@ 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.settingslib.bluetooth.LocalBluetoothProfileManager;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
|
||||
import org.junit.Before;
|
||||
@@ -68,6 +69,8 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
|
||||
mMockAdapter = mock(LocalBluetoothAdapter.class);
|
||||
when(mMockBluetoothManager.getBluetoothAdapter()).thenReturn(mMockAdapter);
|
||||
when(mMockBluetoothManager.getEventManager()).thenReturn(mock(BluetoothEventManager.class));
|
||||
when(mMockBluetoothManager.getProfileManager())
|
||||
.thenReturn(mock(LocalBluetoothProfileManager.class));
|
||||
|
||||
mBluetoothControllerImpl = new BluetoothControllerImpl(mContext,
|
||||
mTestableLooper.getLooper());
|
||||
|
||||
@@ -21,6 +21,8 @@ import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController.Callback;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class FakeBluetoothController extends BaseLeakChecker<Callback> implements
|
||||
BluetoothController {
|
||||
@@ -55,7 +57,7 @@ public class FakeBluetoothController extends BaseLeakChecker<Callback> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLastDeviceName() {
|
||||
public String getConnectedDeviceName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -95,7 +97,7 @@ public class FakeBluetoothController extends BaseLeakChecker<Callback> implement
|
||||
}
|
||||
|
||||
@Override
|
||||
public CachedBluetoothDevice getLastDevice() {
|
||||
return null;
|
||||
public List<CachedBluetoothDevice> getConnectedDevices() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user