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

Commit 3ea041fc authored by Yiyi Shen's avatar Yiyi Shen Committed by Android (Google) Code Review
Browse files

Merge changes from topic "audio_sharing_preview" into main

* changes:
  [Audiosharing] Enable audio sharing feature when preview option on.
  [Audiosharing] Add utils to check is audio sharing preview enabled
parents 8e0d56ea d7404e4f
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -224,7 +224,7 @@ public class BluetoothEventManager {
        // audio sharing is enabled.
        if (bluetoothProfile == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT
                && state == BluetoothAdapter.STATE_DISCONNECTED
                && BluetoothUtils.isAudioSharingEnabled()) {
                && BluetoothUtils.isAudioSharingUIAvailable(mContext)) {
            LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager();
            if (profileManager != null
                    && profileManager.getLeAudioBroadcastProfile() != null
+36 −1
Original line number Diff line number Diff line
@@ -64,6 +64,8 @@ public class BluetoothUtils {

    public static final int META_INT_ERROR = -1;
    public static final String BT_ADVANCED_HEADER_ENABLED = "bt_advanced_header_enabled";
    public static final String DEVELOPER_OPTION_PREVIEW_KEY =
            "bluetooth_le_audio_sharing_ui_preview_enabled";
    private static final int METADATA_FAST_PAIR_CUSTOMIZED_FIELDS = 25;
    private static final String KEY_HEARABLE_CONTROL_SLICE = "HEARABLE_CONTROL_SLICE_WITH_WIDTH";
    private static final Set<Integer> SA_PROFILES =
@@ -643,6 +645,12 @@ public class BluetoothUtils {
                && connectedGroupIds.contains(groupId);
    }

    /** Returns if the le audio sharing UI is available. */
    public static boolean isAudioSharingUIAvailable(@Nullable Context context) {
        return isAudioSharingEnabled() || (context != null && isAudioSharingPreviewEnabled(
                context.getContentResolver()));
    }

    /** Returns if the le audio sharing is enabled. */
    public static boolean isAudioSharingEnabled() {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -653,7 +661,23 @@ public class BluetoothUtils {
                    && adapter.isLeAudioBroadcastAssistantSupported()
                            == BluetoothStatusCodes.FEATURE_SUPPORTED;
        } catch (IllegalStateException e) {
            Log.d(TAG, "LE state is on, but there is no bluetooth service.", e);
            Log.d(TAG, "Fail to check isAudioSharingEnabled, e = ", e);
            return false;
        }
    }

    /** Returns if the le audio sharing preview is enabled in developer option. */
    public static boolean isAudioSharingPreviewEnabled(@Nullable ContentResolver contentResolver) {
        BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
        try {
            return Flags.audioSharingDeveloperOption()
                    && getAudioSharingPreviewValue(contentResolver)
                    && adapter.isLeAudioBroadcastSourceSupported()
                            == BluetoothStatusCodes.FEATURE_SUPPORTED
                    && adapter.isLeAudioBroadcastAssistantSupported()
                            == BluetoothStatusCodes.FEATURE_SUPPORTED;
        } catch (IllegalStateException e) {
            Log.d(TAG, "Fail to check isAudioSharingPreviewEnabled, e = ", e);
            return false;
        }
    }
@@ -996,6 +1020,17 @@ public class BluetoothUtils {
                BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
    }

    /** Get develop option value for audio sharing preview. */
    @WorkerThread
    private static boolean getAudioSharingPreviewValue(@Nullable ContentResolver contentResolver) {
        if (contentResolver == null) return false;
        return Settings.Global.getInt(
                contentResolver,
                DEVELOPER_OPTION_PREVIEW_KEY,
                0 // value off
        ) == 1;
    }

    /** Get secondary {@link CachedBluetoothDevice} in broadcast. */
    @Nullable
    @WorkerThread
+1 −1
Original line number Diff line number Diff line
@@ -1245,7 +1245,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
     */
    public String getConnectionSummary(boolean shortSummary) {
        CharSequence summary = null;
        if (BluetoothUtils.isAudioSharingEnabled()) {
        if (BluetoothUtils.isAudioSharingUIAvailable(mContext)) {
            if (mBluetoothManager == null) {
                mBluetoothManager = LocalBluetoothManager.getInstance(mContext, null);
            }
+8 −6
Original line number Diff line number Diff line
@@ -383,12 +383,8 @@ public class CsipDeviceManager {
                preferredMainDevice.refresh();
                hasChanged = true;
            }
            if (isWorkProfile()) {
                log("addMemberDevicesIntoMainDevice: skip sync source for work profile");
            } else {
            syncAudioSharingSourceIfNeeded(preferredMainDevice);
        }
        }
        if (hasChanged) {
            log("addMemberDevicesIntoMainDevice: After changed, CachedBluetoothDevice list: "
                    + mCachedDevices);
@@ -402,8 +398,12 @@ public class CsipDeviceManager {
    }

    private void syncAudioSharingSourceIfNeeded(CachedBluetoothDevice mainDevice) {
        boolean isAudioSharingEnabled = BluetoothUtils.isAudioSharingEnabled();
        boolean isAudioSharingEnabled = BluetoothUtils.isAudioSharingUIAvailable(mContext);
        if (isAudioSharingEnabled) {
            if (isWorkProfile()) {
                log("addMemberDevicesIntoMainDevice: skip sync source for work profile");
                return;
            }
            boolean hasBroadcastSource = BluetoothUtils.isBroadcasting(mBtManager)
                    && BluetoothUtils.hasConnectedBroadcastSource(
                    mainDevice, mBtManager);
@@ -433,6 +433,8 @@ public class CsipDeviceManager {
                    }
                }
            }
        } else {
            log("addMemberDevicesIntoMainDevice: skip sync source, flag disabled");
        }
    }

+133 −0
Original line number Diff line number Diff line
@@ -29,11 +29,13 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -48,6 +50,7 @@ import android.util.Pair;

import com.android.internal.R;
import com.android.settingslib.flags.Flags;
import com.android.settingslib.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.widget.AdaptiveIcon;

import com.google.common.collect.ImmutableList;
@@ -61,6 +64,8 @@ import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;

import java.util.ArrayList;
import java.util.Collections;
@@ -69,6 +74,7 @@ import java.util.List;
import java.util.Set;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class})
public class BluetoothUtilsTest {

    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
@@ -88,6 +94,7 @@ public class BluetoothUtilsTest {
    @Mock private BluetoothLeBroadcastReceiveState mLeBroadcastReceiveState;

    private Context mContext;
    private ShadowBluetoothAdapter mShadowBluetoothAdapter;
    private static final String STRING_METADATA = "string_metadata";
    private static final String BOOL_METADATA = "true";
    private static final String INT_METADATA = "25";
@@ -109,6 +116,7 @@ public class BluetoothUtilsTest {

        mContext = spy(RuntimeEnvironment.application);
        mSetFlagsRule.disableFlags(FLAG_ENABLE_DETERMINING_ADVANCED_DETAILS_HEADER_WITH_METADATA);
        mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
        when(mLocalBluetoothManager.getProfileManager()).thenReturn(mProfileManager);
        when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
        when(mProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
@@ -1123,4 +1131,129 @@ public class BluetoothUtilsTest {
                                AudioDeviceInfo.TYPE_HEARING_AID,
                                address));
    }

    @Test
    public void isAudioSharingEnabled_flagOff_returnsFalse() {
        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);

        assertThat(BluetoothUtils.isAudioSharingEnabled()).isFalse();
    }

    @Test
    public void isAudioSharingEnabled_featureNotSupported_returnsFalse() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);

        assertThat(BluetoothUtils.isAudioSharingEnabled()).isFalse();
    }

    @Test
    public void isAudioSharingEnabled_featureSupported_returnsTrue() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);

        assertThat(BluetoothUtils.isAudioSharingEnabled()).isTrue();
    }

    @Test
    public void isAudioSharingPreviewEnabled_flagOff_returnsFalse() {
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);

        assertThat(BluetoothUtils.isAudioSharingPreviewEnabled(
                mContext.getContentResolver())).isFalse();
    }

    @Test
    public void isAudioSharingPreviewEnabled_featureNotSupported_returnsFalse() {
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);

        assertThat(BluetoothUtils.isAudioSharingPreviewEnabled(
                mContext.getContentResolver())).isFalse();
    }

    @Test
    public void isAudioSharingPreviewEnabled_developerOptionOff_returnsFalse() {
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        Settings.Global.putInt(mContext.getContentResolver(),
                BluetoothUtils.DEVELOPER_OPTION_PREVIEW_KEY, 0);

        assertThat(BluetoothUtils.isAudioSharingPreviewEnabled(
                mContext.getContentResolver())).isFalse();
    }

    @Test
    public void isAudioSharingPreviewEnabled_developerOptionOn_returnsTrue() {
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        Settings.Global.putInt(mContext.getContentResolver(),
                BluetoothUtils.DEVELOPER_OPTION_PREVIEW_KEY, 1);

        assertThat(BluetoothUtils.isAudioSharingPreviewEnabled(
                mContext.getContentResolver())).isTrue();
    }

    @Test
    public void isAudioSharingUIAvailable_audioSharingAndPreviewFlagOff_returnsFalse() {
        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mSetFlagsRule.disableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);

        assertThat(BluetoothUtils.isAudioSharingUIAvailable(mContext)).isFalse();
    }

    @Test
    public void isAudioSharingUIAvailable_audioSharingAndPreviewDisabled_returnsFalse() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_NOT_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);

        assertThat(BluetoothUtils.isAudioSharingUIAvailable(mContext)).isFalse();
    }

    @Test
    public void isAudioSharingUIAvailable_audioSharingEnabled_returnsTrue() {
        mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);
        Settings.Global.putInt(mContext.getContentResolver(),
                BluetoothUtils.DEVELOPER_OPTION_PREVIEW_KEY, 0);

        assertThat(BluetoothUtils.isAudioSharingUIAvailable(mContext)).isTrue();
    }

    @Test
    public void isAudioSharingUIAvailable_audioSharingPreviewEnabled_returnsTrue() {
        mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
                BluetoothStatusCodes.FEATURE_SUPPORTED);
        mSetFlagsRule.enableFlags(Flags.FLAG_AUDIO_SHARING_DEVELOPER_OPTION);
        Settings.Global.putInt(mContext.getContentResolver(),
                BluetoothUtils.DEVELOPER_OPTION_PREVIEW_KEY, 1);

        assertThat(BluetoothUtils.isAudioSharingUIAvailable(mContext)).isTrue();
    }
}