DO NOT MERGE - Do not show Bluetooth icon when headset is not active

Do not show Bluetooth icon when A2DP, HFP and Hearing
aid profiles are connected but not active.
Other Bluetooth profile will retain the same behavior.

Bug: 144061558
Test: atest com.android.systemui.statusbar
Change-Id: Id0fab356f041e90a7654c8e18185c6aa15e2d4df
This commit is contained in:
Ugo Yu
2019-11-18 14:30:14 +08:00
parent 3ea014ca6d
commit 91182f3507
5 changed files with 109 additions and 2 deletions

View File

@@ -379,8 +379,11 @@ public class PhoneStatusBarPolicy
mContext.getString(R.string.accessibility_quick_settings_bluetooth_on);
boolean bluetoothVisible = false;
if (mBluetooth != null) {
if (mBluetooth.isBluetoothConnected()) {
contentDescription = mContext.getString(R.string.accessibility_bluetooth_connected);
if (mBluetooth.isBluetoothConnected()
&& (mBluetooth.isBluetoothAudioActive()
|| !mBluetooth.isBluetoothAudioProfileOnly())) {
contentDescription = mContext.getString(
R.string.accessibility_bluetooth_connected);
bluetoothVisible = mBluetooth.isBluetoothEnabled();
}
}

View File

@@ -31,6 +31,8 @@ public interface BluetoothController extends CallbackController<Callback>, Dumpa
boolean isBluetoothConnected();
boolean isBluetoothConnecting();
boolean isBluetoothAudioProfileOnly();
boolean isBluetoothAudioActive();
String getConnectedDeviceName();
void setBluetoothEnabled(boolean enabled);
Collection<CachedBluetoothDevice> getDevices();

View File

@@ -34,6 +34,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.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import java.io.FileDescriptor;
@@ -66,6 +67,8 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
private boolean mEnabled;
private int mConnectionState = BluetoothAdapter.STATE_DISCONNECTED;
private boolean mAudioProfileOnly;
private boolean mIsActive;
private final H mHandler = new H(Looper.getMainLooper());
private int mState;
@@ -103,6 +106,8 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
}
pw.print(" mEnabled="); pw.println(mEnabled);
pw.print(" mConnectionState="); pw.println(stateToString(mConnectionState));
pw.print(" mAudioProfileOnly="); pw.println(mAudioProfileOnly);
pw.print(" mIsActive="); pw.println(mIsActive);
pw.print(" mConnectedDevices="); pw.println(mConnectedDevices);
pw.print(" mCallbacks.size="); pw.println(mHandler.mCallbacks.size());
pw.println(" Bluetooth Devices:");
@@ -175,6 +180,16 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
return mConnectionState == BluetoothAdapter.STATE_CONNECTING;
}
@Override
public boolean isBluetoothAudioProfileOnly() {
return mAudioProfileOnly;
}
@Override
public boolean isBluetoothAudioActive() {
return mIsActive;
}
@Override
public void setBluetoothEnabled(boolean enabled) {
if (mLocalBluetoothManager != null) {
@@ -239,6 +254,48 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
mConnectionState = state;
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
updateAudioProfile();
}
private void updateActive() {
boolean isActive = false;
for (CachedBluetoothDevice device : getDevices()) {
isActive |= device.isActiveDevice(BluetoothProfile.HEADSET)
|| device.isActiveDevice(BluetoothProfile.A2DP)
|| device.isActiveDevice(BluetoothProfile.HEARING_AID);
}
if (mIsActive != isActive) {
mIsActive = isActive;
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
}
private void updateAudioProfile() {
boolean audioProfileConnected = false;
boolean otherProfileConnected = false;
for (CachedBluetoothDevice device : getDevices()) {
for (LocalBluetoothProfile profile : device.getProfiles()) {
int profileId = profile.getProfileId();
boolean isConnected = device.isConnectedProfile(profile);
if (profileId == BluetoothProfile.HEADSET
|| profileId == BluetoothProfile.A2DP
|| profileId == BluetoothProfile.HEARING_AID) {
audioProfileConnected |= isConnected;
} else {
otherProfileConnected |= isConnected;
}
}
}
boolean audioProfileOnly = (audioProfileConnected && !otherProfileConnected);
if (audioProfileOnly != mAudioProfileOnly) {
mAudioProfileOnly = audioProfileOnly;
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
}
@Override
@@ -293,6 +350,16 @@ public class BluetoothControllerImpl implements BluetoothController, BluetoothCa
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
@Override
public void onActiveDeviceChanged(CachedBluetoothDevice activeDevice, int bluetoothProfile) {
if (DEBUG) {
Log.d(TAG, "ActiveDeviceChanged=" + activeDevice.getAddress()
+ " profileId=" + bluetoothProfile);
}
updateActive();
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
@Override
public void onAclConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state) {
if (DEBUG) {

View File

@@ -39,6 +39,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.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.SysuiTestCase;
@@ -229,4 +230,28 @@ public class BluetoothControllerImplTest extends SysuiTestCase {
assertTrue(mBluetoothControllerImpl.isBluetoothConnected());
verify(callback, atLeastOnce()).onBluetoothStateChange(anyBoolean());
}
@Test
public void testOnActiveDeviceChanged_updatesAudioActive() {
assertFalse(mBluetoothControllerImpl.isBluetoothAudioActive());
assertFalse(mBluetoothControllerImpl.isBluetoothAudioProfileOnly());
CachedBluetoothDevice device = mock(CachedBluetoothDevice.class);
mDevices.add(device);
when(device.isActiveDevice(BluetoothProfile.HEADSET)).thenReturn(true);
List<LocalBluetoothProfile> profiles = new ArrayList<>();
LocalBluetoothProfile profile = mock(LocalBluetoothProfile.class);
profiles.add(profile);
when(profile.getProfileId()).thenReturn(BluetoothProfile.HEADSET);
when(device.getProfiles()).thenReturn(profiles);
when(device.isConnectedProfile(profile)).thenReturn(true);
mBluetoothControllerImpl.onAclConnectionStateChanged(device,
BluetoothProfile.STATE_CONNECTED);
mBluetoothControllerImpl.onActiveDeviceChanged(device, BluetoothProfile.HEADSET);
assertTrue(mBluetoothControllerImpl.isBluetoothAudioActive());
assertTrue(mBluetoothControllerImpl.isBluetoothAudioProfileOnly());
}
}

View File

@@ -56,6 +56,16 @@ public class FakeBluetoothController extends BaseLeakChecker<Callback> implement
return false;
}
@Override
public boolean isBluetoothAudioProfileOnly() {
return false;
}
@Override
public boolean isBluetoothAudioActive() {
return false;
}
@Override
public String getConnectedDeviceName() {
return null;