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:
Amin Shaikh
2018-04-18 14:14:38 -04:00
parent e3a34816dc
commit 45fb7a75cf
5 changed files with 53 additions and 26 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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;

View File

@@ -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());

View File

@@ -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();
}
}