[Audiosharing] Revert ag/31626042 (exclude utils)

FP will handle set temp for manual pair in Settings

Test: atest
Flag: com.android.settingslib.flags.enable_temporary_bond_devices_ui
Bug: 392004799
Change-Id: I3afae523ef0d5a6c236a482127a714f422a6e000
This commit is contained in:
Yiyi Shen
2025-02-14 16:35:30 +08:00
parent 9fb0e28bf7
commit 2c5f451b3a
2 changed files with 28 additions and 202 deletions

View File

@@ -46,7 +46,6 @@ import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.HearingAidStatsLogUtils;
import com.android.settingslib.flags.Flags;
import com.android.settingslib.utils.ThreadUtils;
import com.google.common.collect.ImmutableList;
@@ -63,7 +62,6 @@ import java.util.concurrent.TimeUnit;
public abstract class BluetoothDevicePairingDetailBase extends DeviceListPreferenceFragment {
private static final long AUTO_DISMISS_TIME_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(15);
private static final int AUTO_DISMISS_MESSAGE_ID = 1001;
private static final int AUTO_FINISH_MESSAGE_ID = 1002;
private static final ImmutableList<Integer> AUDIO_SHARING_PROFILES = ImmutableList.of(
BluetoothProfile.LE_AUDIO,
BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT, BluetoothProfile.VOLUME_CONTROL);
@@ -91,8 +89,8 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
// onDeviceBondStateChanged(BOND_BONDED), BluetoothDevicePreference's summary has already
// change from "Pairing..." to empty since it listens to metadata changes happens earlier.
//
// In pairing flow during audio sharing, we have to wait on this page till the device is
// connected to check the device type and handle extra logic for audio sharing.
// In share then pair flow, we have to wait on this page till the device is connected to check
// the device type and handle extra logic for audio sharing.
// The BluetoothDevicePreference summary will be blank for seconds between "Pairing..." and
// "Connecting..." To help users better understand the process, we listen to metadata change
// as well and show a progress dialog with "Connecting to ...." once BluetoothDevice.getState()
@@ -103,11 +101,10 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
public void onMetadataChanged(@NonNull BluetoothDevice device, int key,
@Nullable byte[] value) {
Log.d(getLogTag(), "onMetadataChanged device = " + device + ", key = " + key);
if ((mShouldTriggerShareThenPairFlow || shouldSetTempBondMetadata())
&& mProgressDialog == null
if (mShouldTriggerShareThenPairFlow && mProgressDialog == null
&& device.getBondState() == BluetoothDevice.BOND_BONDED
&& mSelectedList.contains(device)) {
handleDeviceBondedInAudioSharing(device);
handleShareThenPair(device);
// Once device is bonded, remove the listener
removeOnMetadataChangedListener(device);
}
@@ -181,12 +178,11 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
@Override
public void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState) {
boolean shouldSetTempBond = shouldSetTempBondMetadata();
if (bondState == BluetoothDevice.BOND_BONDED) {
if (cachedDevice != null && (mShouldTriggerShareThenPairFlow || shouldSetTempBond)) {
if (cachedDevice != null && mShouldTriggerShareThenPairFlow) {
BluetoothDevice device = cachedDevice.getDevice();
if (device != null && mSelectedList.contains(device)) {
handleDeviceBondedInAudioSharing(device);
handleShareThenPair(device);
removeOnMetadataChangedListener(device);
return;
}
@@ -195,7 +191,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
finish();
return;
} else if (bondState == BluetoothDevice.BOND_BONDING) {
if ((mShouldTriggerShareThenPairFlow || shouldSetTempBond) && cachedDevice != null) {
if (mShouldTriggerShareThenPairFlow && cachedDevice != null) {
BluetoothDevice device = cachedDevice.getDevice();
if (device != null && mSelectedList.contains(device)) {
addOnMetadataChangedListener(device);
@@ -208,7 +204,7 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
pageId);
HearingAidStatsLogUtils.setBondEntryForDevice(bondEntry, cachedDevice);
} else if (bondState == BluetoothDevice.BOND_NONE) {
if ((mShouldTriggerShareThenPairFlow || shouldSetTempBond) && cachedDevice != null) {
if (mShouldTriggerShareThenPairFlow && cachedDevice != null) {
BluetoothDevice device = cachedDevice.getDevice();
if (device != null && mSelectedList.contains(device)) {
removeOnMetadataChangedListener(device);
@@ -240,22 +236,15 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
&& mSelectedList.contains(device)) {
var unused = ThreadUtils.postOnBackgroundThread(() -> {
if (BluetoothUtils.isAudioSharingUIAvailable(getContext())) {
if ((mShouldTriggerShareThenPairFlow || shouldSetTempBondMetadata())
if (mShouldTriggerShareThenPairFlow
&& state == BluetoothAdapter.STATE_CONNECTED
&& device.equals(mJustBonded)
&& AUDIO_SHARING_PROFILES.contains(bluetoothProfile)
&& isReadyForAudioSharing(cachedDevice, bluetoothProfile)) {
Log.d(getLogTag(), "onProfileConnectionStateChanged, lea eligible");
dismissConnectingDialog();
BluetoothUtils.setTemporaryBondMetadata(device);
if (mShouldTriggerShareThenPairFlow) {
mHandler.removeMessages(AUTO_DISMISS_MESSAGE_ID);
postOnMainThread(() ->
finishFragmentWithResultForAudioSharing(device));
} else {
mHandler.removeMessages(AUTO_FINISH_MESSAGE_ID);
postOnMainThread(() -> finish());
}
postOnMainThread(() -> finishFragmentWithResultForAudioSharing(device));
}
} else {
postOnMainThread(() -> finish());
@@ -341,16 +330,6 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
return false;
}
private boolean shouldSetTempBondMetadata() {
return Flags.enableTemporaryBondDevicesUi()
&& BluetoothUtils.isAudioSharingUIAvailable(getContext())
&& BluetoothUtils.isBroadcasting(mLocalManager)
&& mLocalManager != null
&& mLocalManager.getCachedDeviceManager() != null
&& mLocalManager.getProfileManager().getLeAudioBroadcastAssistantProfile() != null
&& !Utils.shouldBlockPairingInAudioSharing(mLocalManager);
}
private boolean isReadyForAudioSharing(@NonNull CachedBluetoothDevice cachedDevice,
int justConnectedProfile) {
for (int profile : AUDIO_SHARING_PROFILES) {
@@ -405,10 +384,10 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
});
}
private void handleDeviceBondedInAudioSharing(@Nullable BluetoothDevice device) {
private void handleShareThenPair(@Nullable BluetoothDevice device) {
var unused = ThreadUtils.postOnBackgroundThread(() -> {
if (mJustBonded != null) {
Log.d(getLogTag(), "Skip handleDeviceBondedInAudioSharing, already done");
Log.d(getLogTag(), "Skip handleShareThenPair, already done");
return;
}
mJustBonded = device;
@@ -417,7 +396,6 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
String deviceName = TextUtils.isEmpty(aliasName) ? device.getAddress()
: aliasName;
showConnectingDialog(deviceName);
if (mShouldTriggerShareThenPairFlow) {
// For share then pair flow, we have strong signal that users wish to pair new
// device to join sharing.
// So we wait for AUTO_DISMISS_TIME_THRESHOLD_MS, if we find that the bonded device
@@ -428,28 +406,12 @@ public abstract class BluetoothDevicePairingDetailBase extends DeviceListPrefere
mHandler.postDelayed(() ->
postOnMainThread(
() -> {
Log.d(getLogTag(),
"Show incompatible dialog when timeout");
Log.d(getLogTag(), "Show incompatible dialog when timeout");
dismissConnectingDialog();
AudioSharingIncompatibleDialogFragment.show(this,
deviceName,
AudioSharingIncompatibleDialogFragment.show(this, deviceName,
() -> finish());
}), AUTO_DISMISS_MESSAGE_ID, AUTO_DISMISS_TIME_THRESHOLD_MS);
}
} else {
// For other pairing request during audio sharing with sinks < 2, we wait for
// AUTO_DISMISS_TIME_THRESHOLD_MS, if we find that the bonded device is lea in
// onProfileConnectionStateChanged, we finish the activity and set the device as
// temp bond; otherwise, we just finish the activity.
if (!mHandler.hasMessages(AUTO_FINISH_MESSAGE_ID)) {
mHandler.postDelayed(() ->
postOnMainThread(
() -> {
Log.d(getLogTag(), "Finish activity when timeout");
finish();
}), AUTO_FINISH_MESSAGE_ID, AUTO_DISMISS_TIME_THRESHOLD_MS);
}
}
});
}

View File

@@ -18,7 +18,6 @@ package com.android.settings.bluetooth;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_BT_DEVICE_TO_AUTO_ADD_SOURCE;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_PAIR_AND_JOIN_SHARING;
import static com.android.settingslib.bluetooth.devicesettings.data.repository.DeviceSettingServiceConnection.METADATA_FAST_PAIR_CUSTOMIZED_FIELDS;
import static com.google.common.truth.Truth.assertThat;
@@ -37,7 +36,6 @@ import static org.robolectric.Shadows.shadowOf;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
@@ -66,15 +64,9 @@ import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowFragment;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.CachedBluetoothDeviceManager;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.flags.Flags;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -122,14 +114,6 @@ public class BluetoothDevicePairingDetailBaseTest {
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private LocalBluetoothManager mLocalManager;
@Mock
private CachedBluetoothDeviceManager mDeviceManager;
@Mock
private LocalBluetoothProfileManager mProfileManager;
@Mock
private LocalBluetoothLeBroadcast mBroadcast;
@Mock
private LocalBluetoothLeBroadcastAssistant mAssistant;
@Mock
private CachedBluetoothDevice mCachedBluetoothDevice;
@Mock
private Drawable mDrawable;
@@ -221,7 +205,6 @@ public class BluetoothDevicePairingDetailBaseTest {
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(false);
setUpAudioSharingStates(/* enabled = */ false, /* needSetTempBondMetadata = */ false);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDED);
verify(mFragment).finish();
@@ -236,31 +219,6 @@ public class BluetoothDevicePairingDetailBaseTest {
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(true);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ false);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDED);
shadowOf(Looper.getMainLooper()).idle();
ProgressDialogFragment progressDialog = mFragment.mProgressDialog;
assertThat(progressDialog).isNotNull();
assertThat(progressDialog.getMessage()).isEqualTo(
mContext.getString(R.string.progress_dialog_connect_device_content,
TEST_DEVICE_ADDRESS));
assertThat(
ShadowDialogFragment.isIsShowing(ProgressDialogFragment.class.getName())).isTrue();
verify(mFragment, never()).finish();
ShadowDialogFragment.reset();
}
@Test
@Config(shadows = ShadowDialogFragment.class)
@EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI})
public void onDeviceBondStateChanged_bonded_pairAfterShare_handle() {
ShadowDialogFragment.reset();
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(false);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ true);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDED);
shadowOf(Looper.getMainLooper()).idle();
@@ -283,7 +241,6 @@ public class BluetoothDevicePairingDetailBaseTest {
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(false);
setUpAudioSharingStates(/* enabled = */ false, /* needSetTempBondMetadata = */ false);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDING);
verify(mBluetoothAdapter, never()).addOnMetadataChangedListener(any(BluetoothDevice.class),
@@ -297,21 +254,6 @@ public class BluetoothDevicePairingDetailBaseTest {
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(true);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ false);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDING);
verify(mBluetoothAdapter).addOnMetadataChangedListener(eq(mBluetoothDevice),
any(Executor.class),
any(BluetoothAdapter.OnMetadataChangedListener.class));
}
@Test
@EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI})
public void onDeviceBondStateChanged_bonding_pairAfterShare_addListener() {
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(false);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ true);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDING);
verify(mBluetoothAdapter).addOnMetadataChangedListener(eq(mBluetoothDevice),
@@ -337,21 +279,6 @@ public class BluetoothDevicePairingDetailBaseTest {
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(true);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ false);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDING);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_NONE);
verify(mBluetoothAdapter).removeOnMetadataChangedListener(eq(mBluetoothDevice),
any(BluetoothAdapter.OnMetadataChangedListener.class));
}
@Test
@EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI})
public void onDeviceBondStateChanged_unbonded_pairAfterShare_removeListener() {
when(mCachedBluetoothDevice.getDevice()).thenReturn(mBluetoothDevice);
mFragment.mSelectedList.add(mBluetoothDevice);
setUpFragmentWithShareThenPairIntent(false);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ true);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDING);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_NONE);
@@ -387,7 +314,6 @@ public class BluetoothDevicePairingDetailBaseTest {
when(mCachedBluetoothDevice.getDevice()).thenReturn(device);
mFragment.mSelectedList.add(device);
setUpFragmentWithShareThenPairIntent(true);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ false);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDED);
shadowOf(Looper.getMainLooper()).idle();
@@ -400,7 +326,6 @@ public class BluetoothDevicePairingDetailBaseTest {
BluetoothAdapter.STATE_CONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT);
shadowOf(Looper.getMainLooper()).idle();
verify(device).setMetadata(eq(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS), any());
ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
verify(mFragment.getActivity()).setResult(eq(Activity.RESULT_OK), captor.capture());
Intent intent = captor.getValue();
@@ -416,35 +341,6 @@ public class BluetoothDevicePairingDetailBaseTest {
ShadowDialogFragment.reset();
}
@Test
@Config(shadows = ShadowDialogFragment.class)
@EnableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI})
public void
onProfileConnectionStateChanged_inSelectedListAndConnected_pairAfterShare_handle() {
ShadowDialogFragment.reset();
BluetoothDevice device = spy(mBluetoothDevice);
when(mCachedBluetoothDevice.getDevice()).thenReturn(device);
mFragment.mSelectedList.add(device);
setUpFragmentWithShareThenPairIntent(false);
setUpAudioSharingStates(/* enabled = */ true, /* needSetTempBondMetadata = */ true);
mFragment.onDeviceBondStateChanged(mCachedBluetoothDevice, BluetoothDevice.BOND_BONDED);
shadowOf(Looper.getMainLooper()).idle();
when(mCachedBluetoothDevice.isConnected()).thenReturn(true);
when(mCachedBluetoothDevice.isConnectedLeAudioDevice()).thenReturn(true);
when(mCachedBluetoothDevice.isConnectedLeAudioBroadcastAssistantDevice()).thenReturn(true);
when(mCachedBluetoothDevice.isConnectedVolumeControlDevice()).thenReturn(true);
mFragment.onProfileConnectionStateChanged(mCachedBluetoothDevice,
BluetoothAdapter.STATE_CONNECTED, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT);
shadowOf(Looper.getMainLooper()).idle();
verify(device).setMetadata(eq(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS), any());
verify(mFragment).finish();
ShadowDialogFragment.reset();
}
@Test
@DisableFlags({Flags.FLAG_ENABLE_LE_AUDIO_SHARING, Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI})
public void onProfileConnectionStateChanged_deviceNotInSelectedList_doNothing() {
@@ -537,38 +433,6 @@ public class BluetoothDevicePairingDetailBaseTest {
mFragment.mShouldTriggerShareThenPairFlow = mFragment.shouldTriggerShareThenPairFlow();
}
private void setUpAudioSharingStates(boolean enabled, boolean needSetTempBondMetadata) {
when(mLocalManager.getProfileManager()).thenReturn(mProfileManager);
when(mProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
when(mProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant);
when(mLocalManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
if (!enabled) {
when(mBroadcast.isEnabled(null)).thenReturn(false);
} else {
when(mBroadcast.isEnabled(null)).thenReturn(true);
when(mBroadcast.getLatestBroadcastId()).thenReturn(1);
BluetoothDevice device1 = mock(BluetoothDevice.class);
CachedBluetoothDevice cachedDevice1 = mock(CachedBluetoothDevice.class);
when(mDeviceManager.findDevice(device1)).thenReturn(cachedDevice1);
when(cachedDevice1.getGroupId()).thenReturn(1);
when(cachedDevice1.getDevice()).thenReturn(device1);
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
when(state.getBroadcastId()).thenReturn(1);
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(state));
if (needSetTempBondMetadata) {
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(device1));
} else {
BluetoothDevice device2 = mock(BluetoothDevice.class);
CachedBluetoothDevice cachedDevice2 = mock(CachedBluetoothDevice.class);
when(mDeviceManager.findDevice(device2)).thenReturn(cachedDevice2);
when(cachedDevice2.getGroupId()).thenReturn(2);
when(cachedDevice2.getDevice()).thenReturn(device2);
when(mAssistant.getAllConnectedDevices()).thenReturn(
ImmutableList.of(device1, device2));
}
}
}
private static class TestBluetoothDevicePairingDetailBase extends
BluetoothDevicePairingDetailBase {