Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbe5a7f6 authored by Ze Li's avatar Ze Li
Browse files

[Temp bonding] Summary for guest devices

Test: com.android.settingslib.bluetooth.CachedBluetoothDeviceTest
Bug: 362859132
Flag: com.android.settingslib.flags.enable_temporary_bond_devices_ui
Change-Id: I28d10ddf9994bfc4576491179730022f3fb1c926
parent 7dc3dcde
Loading
Loading
Loading
Loading
+68 −29
Original line number Diff line number Diff line
@@ -16,8 +16,7 @@

package com.android.settingslib.bluetooth;

import static com.android.settingslib.flags.Flags.enableSetPreferredTransportForLeAudioDevice;
import static com.android.settingslib.flags.Flags.ignoreA2dpDisconnectionForAndroidAuto;
import static com.android.settingslib.media.flags.Flags.enableTvMediaOutputDialog;

import android.annotation.CallbackExecutor;
import android.annotation.StringRes;
@@ -53,7 +52,7 @@ import androidx.annotation.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.R;
import com.android.settingslib.Utils;
import com.android.settingslib.media.flags.Flags;
import com.android.settingslib.flags.Flags;
import com.android.settingslib.utils.ThreadUtils;
import com.android.settingslib.widget.AdaptiveOutlineDrawable;

@@ -264,7 +263,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                            mHandler.removeMessages(profile.getProfileId());
                            if (profile.getConnectionPolicy(mDevice) >
                                    BluetoothProfile.CONNECTION_POLICY_FORBIDDEN) {
                                if (ignoreA2dpDisconnectionForAndroidAuto()
                                if (Flags.ignoreA2dpDisconnectionForAndroidAuto()
                                        && profile instanceof A2dpProfile && isAndroidAuto()) {
                                    Log.w(TAG,
                                            "onProfileStateChanged(): Skip setting A2DP "
@@ -306,7 +305,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                        mLocalNapRoleConnected = true;
                    }
                }
                if (enableSetPreferredTransportForLeAudioDevice()
                if (Flags.enableSetPreferredTransportForLeAudioDevice()
                        && profile instanceof HidProfile) {
                    updatePreferredTransport();
                }
@@ -322,7 +321,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                mLocalNapRoleConnected = false;
            }

            if (enableSetPreferredTransportForLeAudioDevice()
            if (Flags.enableSetPreferredTransportForLeAudioDevice()
                    && profile instanceof LeAudioProfile) {
                updatePreferredTransport();
            }
@@ -1345,6 +1344,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
        if (mBluetoothManager == null) {
            mBluetoothManager = LocalBluetoothManager.getInstance(mContext, null);
        }
        boolean isTempBond = Flags.enableTemporaryBondDevicesUi()
                && BluetoothUtils.isTemporaryBondDevice(getDevice());
        if (BluetoothUtils.hasConnectedBroadcastSource(this, mBluetoothManager)) {
            // Gets summary for the buds which are in the audio sharing.
            int groupId = BluetoothUtils.getGroupId(this);
@@ -1363,7 +1364,16 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                        shortSummary);
            } else {
                // The buds are not primary buds
                return getSummaryWithBatteryInfo(
                return isTempBond
                        ? getSummaryWithBatteryInfo(
                                R.string.bluetooth_guest_media_only_battery_level_untethered,
                                R.string.bluetooth_guest_media_only_battery_level,
                                R.string.bluetooth_guest_media_only_no_battery_level,
                                leftBattery,
                                rightBattery,
                                batteryLevelPercentageString,
                                shortSummary)
                        : getSummaryWithBatteryInfo(
                                R.string.bluetooth_active_media_only_battery_level_untethered,
                                R.string.bluetooth_active_media_only_battery_level,
                                R.string.bluetooth_active_media_only_no_battery_level,
@@ -1381,7 +1391,16 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                                            && profile.isEnabled(getDevice()))) {
                // The buds support le audio.
                if (isConnected()) {
                    return getSummaryWithBatteryInfo(
                    return isTempBond
                            ? getSummaryWithBatteryInfo(
                                    R.string.bluetooth_guest_battery_level_untethered_lea_support,
                                    R.string.bluetooth_guest_battery_level_lea_support,
                                    R.string.bluetooth_guest_no_battery_level_lea_support,
                                    leftBattery,
                                    rightBattery,
                                    batteryLevelPercentageString,
                                    shortSummary)
                            : getSummaryWithBatteryInfo(
                                    R.string.bluetooth_battery_level_untethered_lea_support,
                                    R.string.bluetooth_battery_level_lea_support,
                                    R.string.bluetooth_no_battery_level_lea_support,
@@ -1390,7 +1409,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                                    batteryLevelPercentageString,
                                    shortSummary);
                } else {
                    return mContext.getString(R.string.bluetooth_saved_device_lea_support);
                    return isTempBond
                            ? mContext.getString(
                                    R.string.bluetooth_guest_saved_device_lea_support)
                            : mContext.getString(R.string.bluetooth_saved_device_lea_support);
                }
            }
        }
@@ -1509,11 +1531,19 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
            leftBattery = getLeftBatteryLevel();
            rightBattery = getRightBatteryLevel();

            boolean isTempBond = Flags.enableTemporaryBondDevicesUi()
                    && BluetoothUtils.isTemporaryBondDevice(getDevice());
            // Set default string with battery level in device connected situation.
            if (isTwsBatteryAvailable(leftBattery, rightBattery)) {
                stringRes = R.string.bluetooth_battery_level_untethered;
                stringRes =
                        isTempBond
                                ? R.string.bluetooth_guest_battery_level_untethered
                                : R.string.bluetooth_battery_level_untethered;
            } else if (batteryLevelPercentageString != null && !shortSummary) {
                stringRes = R.string.bluetooth_battery_level;
                stringRes =
                        isTempBond
                                ? R.string.bluetooth_guest_battery_level
                                : R.string.bluetooth_battery_level;
            }

            // Set active string in following device connected situation, also show battery
@@ -1529,11 +1559,20 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                        || (mIsActiveDeviceA2dp && !isOnCall)
                        || mIsActiveDeviceLeAudio) {
                    if (isTwsBatteryAvailable(leftBattery, rightBattery) && !shortSummary) {
                        stringRes = R.string.bluetooth_active_battery_level_untethered;
                        stringRes =
                                isTempBond
                                        ? R.string.bluetooth_guest_battery_level_untethered
                                        : R.string.bluetooth_active_battery_level_untethered;
                    } else if (batteryLevelPercentageString != null && !shortSummary) {
                        stringRes = R.string.bluetooth_active_battery_level;
                        stringRes =
                                isTempBond
                                        ? R.string.bluetooth_guest_battery_level
                                        : R.string.bluetooth_active_battery_level;
                    } else {
                        stringRes = R.string.bluetooth_active_no_battery_level;
                        stringRes =
                                isTempBond
                                        ? R.string.bluetooth_guest_no_battery_level
                                        : R.string.bluetooth_active_no_battery_level;
                    }
                }

@@ -1559,7 +1598,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
                || stringRes == R.string.bluetooth_active_battery_level_untethered_left
                || stringRes == R.string.bluetooth_active_battery_level_untethered_right
                || stringRes == R.string.bluetooth_battery_level_untethered;
        if (isTvSummary && summaryIncludesBatteryLevel && Flags.enableTvMediaOutputDialog()) {
        if (isTvSummary && summaryIncludesBatteryLevel && enableTvMediaOutputDialog()) {
            return getTvBatterySummary(
                    getMinBatteryLevelWithMemberDevices(),
                    leftBattery,
+86 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.settingslib.bluetooth;

import static com.android.settingslib.flags.Flags.FLAG_ENABLE_LE_AUDIO_SHARING;
import static com.android.settingslib.flags.Flags.FLAG_ENABLE_SET_PREFERRED_TRANSPORT_FOR_LE_AUDIO_DEVICE;
import static com.android.settingslib.flags.Flags.FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI;

import static com.google.common.truth.Truth.assertThat;

@@ -78,11 +79,14 @@ public class CachedBluetoothDeviceTest {
    private static final String TWS_BATTERY_RIGHT = "25";
    private static final String TWS_LOW_BATTERY_THRESHOLD_LOW = "10";
    private static final String TWS_LOW_BATTERY_THRESHOLD_HIGH = "25";
    private static final String TEMP_BOND_METADATA =
            "<TEMP_BOND_TYPE>le_audio_sharing</TEMP_BOND_TYPE>";
    private static final short RSSI_1 = 10;
    private static final short RSSI_2 = 11;
    private static final boolean JUSTDISCOVERED_1 = true;
    private static final boolean JUSTDISCOVERED_2 = false;
    private static final int LOW_BATTERY_COLOR = android.R.color.holo_red_dark;
    private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
    @Mock
    private LocalBluetoothProfileManager mProfileManager;
    @Mock
@@ -128,6 +132,7 @@ public class CachedBluetoothDeviceTest {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TV_MEDIA_OUTPUT_DIALOG);
        mSetFlagsRule.enableFlags(FLAG_ENABLE_SET_PREFERRED_TRANSPORT_FOR_LE_AUDIO_DEVICE);
        mSetFlagsRule.enableFlags(FLAG_ENABLE_LE_AUDIO_SHARING);
        mSetFlagsRule.enableFlags(FLAG_ENABLE_TEMPORARY_BOND_DEVICES_UI);
        mContext = RuntimeEnvironment.application;
        mAudioManager = mContext.getSystemService(AudioManager.class);
        mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
@@ -2074,6 +2079,87 @@ public class CachedBluetoothDeviceTest {
        assertThat(mCachedDevice.getConnectionSummary(false)).isNull();
    }

    @Test
    public void getConnectionSummary_GuestDeviceBroadcastPrimary_activeDevice_returnActive() {
        when(mBroadcast.isEnabled(any())).thenReturn(true);
        when(mCachedDevice.getDevice()).thenReturn(mDevice);
        Settings.Secure.putInt(
                mContext.getContentResolver(),
                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
                BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
        when(mDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
                .thenReturn(TEMP_BOND_METADATA.getBytes());

        List<Long> bisSyncState = new ArrayList<>();
        bisSyncState.add(1L);
        when(mLeBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);
        List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
        sourceList.add(mLeBroadcastReceiveState);
        when(mAssistant.getAllSources(any())).thenReturn(sourceList);

        when(mCachedDevice.getGroupId()).thenReturn(1);
        when(mCachedDevice.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true);

        assertThat(mCachedDevice.getConnectionSummary(false))
                .isEqualTo(mContext.getString(R.string.bluetooth_active_no_battery_level));
    }

    @Test
    public void getConnectionSummary_GuestDeviceBroadcastSecondary_activeDevice_returnGuestMedia() {
        when(mBroadcast.isEnabled(any())).thenReturn(true);
        when(mCachedDevice.getDevice()).thenReturn(mDevice);
        Settings.Secure.putInt(
                mContext.getContentResolver(),
                BluetoothUtils.getPrimaryGroupIdUriForBroadcast(),
                1);
        when(mDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
                .thenReturn(TEMP_BOND_METADATA.getBytes());

        List<Long> bisSyncState = new ArrayList<>();
        bisSyncState.add(1L);
        when(mLeBroadcastReceiveState.getBisSyncState()).thenReturn(bisSyncState);
        List<BluetoothLeBroadcastReceiveState> sourceList = new ArrayList<>();
        sourceList.add(mLeBroadcastReceiveState);
        when(mAssistant.getAllSources(any())).thenReturn(sourceList);

        when(mCachedDevice.getGroupId()).thenReturn(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);

        assertThat(mCachedDevice.getConnectionSummary(false))
                .isEqualTo(
                        mContext.getString(R.string.bluetooth_guest_media_only_no_battery_level));
    }

    @Test
    public void getConnectionSummary_GuestDeviceSupportsBroadcastConnected_returnGuestSupportLe() {
        when(mBroadcast.isEnabled(any())).thenReturn(true);
        when(mCachedDevice.getDevice()).thenReturn(mDevice);
        when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true);
        when(mDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
                .thenReturn(TEMP_BOND_METADATA.getBytes());

        when(mCachedDevice.getProfiles()).thenReturn(ImmutableList.of(mLeAudioProfile));
        when(mCachedDevice.isConnected()).thenReturn(true);

        assertThat(mCachedDevice.getConnectionSummary(false))
                .isEqualTo(
                        mContext.getString(R.string.bluetooth_guest_no_battery_level_lea_support));
    }

    @Test
    public void getConnectionSummary_GuestDeviceSupportsBroadcastNotConnected_returnSavedGuest() {
        when(mBroadcast.isEnabled(any())).thenReturn(true);
        when(mCachedDevice.getDevice()).thenReturn(mDevice);
        when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true);
        when(mDevice.getMetadata(METADATA_FAST_PAIR_CUSTOMIZED_FIELDS))
                .thenReturn(TEMP_BOND_METADATA.getBytes());

        when(mCachedDevice.getProfiles()).thenReturn(ImmutableList.of(mLeAudioProfile));
        when(mCachedDevice.isConnected()).thenReturn(false);

        assertThat(mCachedDevice.getConnectionSummary(false))
                .isEqualTo(mContext.getString(R.string.bluetooth_guest_saved_device_lea_support));
    }

    @Test
    public void isHearingDevice_supportHearingRelatedProfiles_returnTrue() {
        when(mCachedDevice.getProfiles()).thenReturn(