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

Commit 3cfd4cf7 authored by Yiyi Shen's avatar Yiyi Shen
Browse files

[Audiosharing] Route to audio sharing page to start broadcast.

Since we already support auto start sharing and add source from QS pill
click. We can reuse the intent when user click on the second LEA headset
to start audio sharing from Connected devices page.

Test: atest
Bug: 331892035
Flag: com.android.settingslib.flags.enable_le_audio_sharing
Change-Id: I83f7ae25ed96bbddb3c631b69b409f09577f421b
parent 2a01b356
Loading
Loading
Loading
Loading
+18 −32
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.settings.connecteddevice.audiosharing;

import static java.util.stream.Collectors.toList;
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_START_LE_AUDIO_SHARING;

import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothCsipSetCoordinator;
@@ -25,6 +25,7 @@ import android.bluetooth.BluetoothLeBroadcast;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.util.Pair;

@@ -34,6 +35,7 @@ import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;

import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
@@ -63,8 +65,6 @@ public class AudioSharingDialogHandler {
    @Nullable private final LocalBluetoothLeBroadcast mBroadcast;
    @Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant;
    private final MetricsFeatureProvider mMetricsFeatureProvider;
    // The target sinks to join broadcast onPlaybackStarted
    @Nullable private List<BluetoothDevice> mTargetSinks;
    private boolean mIsStoppingBroadcast = false;

    @VisibleForTesting
@@ -83,15 +83,6 @@ public class AudioSharingDialogHandler {
                @Override
                public void onBroadcastStartFailed(int reason) {
                    Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
                    if (mTargetSinks != null) {
                        mMetricsFeatureProvider.action(
                                mContext,
                                SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED,
                                SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY);
                        AudioSharingUtils.toastMessage(
                                mContext, "Fail to start broadcast, reason " + reason);
                        mTargetSinks = null;
                    }
                }

                @Override
@@ -113,6 +104,9 @@ public class AudioSharingDialogHandler {
                                    + reason
                                    + ", broadcastId = "
                                    + broadcastId);
                    AudioSharingUtils.toastMessage(
                            mContext,
                            mContext.getString(R.string.audio_sharing_sharing_stopped_label));
                    mIsStoppingBroadcast = false;
                }

@@ -144,18 +138,6 @@ public class AudioSharingDialogHandler {
                                    + reason
                                    + ", broadcastId = "
                                    + broadcastId);
                    if (mTargetSinks != null) {
                        AudioSharingUtils.addSourceToTargetSinks(mTargetSinks, mLocalBtManager);
                        new SubSettingLauncher(mContext)
                                .setDestination(AudioSharingDashboardFragment.class.getName())
                                .setSourceMetricsCategory(
                                        (mHostFragment instanceof DashboardFragment)
                                                ? ((DashboardFragment) mHostFragment)
                                                        .getMetricsCategory()
                                                : SettingsEnums.PAGE_UNKNOWN)
                                .launch();
                        mTargetSinks = null;
                    }
                }

                @Override
@@ -375,14 +357,18 @@ public class AudioSharingDialogHandler {
                        new AudioSharingJoinDialogFragment.DialogEventListener() {
                            @Override
                            public void onShareClick() {
                                mTargetSinks =
                                        groupedDevices.values().stream()
                                                .flatMap(items -> items.stream())
                                                .collect(toList());
                                Log.d(TAG, "Start broadcast with sinks = " + mTargetSinks.size());
                                if (mBroadcast != null) {
                                    mBroadcast.startPrivateBroadcast();
                                }
                                Bundle args = new Bundle();
                                args.putBoolean(EXTRA_START_LE_AUDIO_SHARING, true);
                                new SubSettingLauncher(mContext)
                                        .setDestination(
                                                AudioSharingDashboardFragment.class.getName())
                                        .setSourceMetricsCategory(
                                                (mHostFragment instanceof DashboardFragment)
                                                        ? ((DashboardFragment) mHostFragment)
                                                                .getMetricsCategory()
                                                        : SettingsEnums.PAGE_UNKNOWN)
                                        .setArguments(args)
                                        .launch();
                            }

                            @Override
+29 −55
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@@ -37,6 +38,8 @@ import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.bluetooth.BluetoothStatusCodes;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.Pair;
@@ -45,6 +48,7 @@ import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.android.settings.SettingsActivity;
import com.android.settings.bluetooth.Utils;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
@@ -67,6 +71,7 @@ import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -132,7 +137,7 @@ public class AudioSharingDialogHandlerTest {
                FragmentActivity.class,
                0 /* containerViewId */,
                null /* bundle */);
        mContext = mParentFragment.getContext();
        mContext = spy(mParentFragment.getContext());
        ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
        mLocalBtManager = Utils.getLocalBtManager(mContext);
        ShadowBluetoothAdapter shadowBluetoothAdapter =
@@ -294,7 +299,17 @@ public class AudioSharingDialogHandlerTest {
        AudioSharingJoinDialogFragment.DialogEventListener listener = fragment.getListener();
        assertThat(listener).isNotNull();
        listener.onShareClick();
        verify(mBroadcast).startPrivateBroadcast();
        ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext).startActivity(argumentCaptor.capture());
        Intent intent = argumentCaptor.getValue();
        assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
                .isEqualTo(AudioSharingDashboardFragment.class.getName());
        assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS))
                .isNotNull();
        Bundle args = intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
        assertThat(args).isNotNull();
        assertThat(args.getBoolean(LocalBluetoothLeBroadcast.EXTRA_START_LE_AUDIO_SHARING))
                .isTrue();
        listener.onCancelClick();
        verify(mCachedDevice1).setActive();
    }
@@ -500,7 +515,17 @@ public class AudioSharingDialogHandlerTest {
        AudioSharingJoinDialogFragment.DialogEventListener listener = fragment.getListener();
        assertThat(listener).isNotNull();
        listener.onShareClick();
        verify(mBroadcast).startPrivateBroadcast();
        ArgumentCaptor<Intent> argumentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext).startActivity(argumentCaptor.capture());
        Intent intent = argumentCaptor.getValue();
        assertThat(intent.getStringExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT))
                .isEqualTo(AudioSharingDashboardFragment.class.getName());
        assertThat(intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS))
                .isNotNull();
        Bundle args = intent.getBundleExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
        assertThat(args).isNotNull();
        assertThat(args.getBoolean(LocalBluetoothLeBroadcast.EXTRA_START_LE_AUDIO_SHARING))
                .isTrue();
        listener.onCancelClick();
        verify(mCachedDevice1, never()).setActive();
    }
@@ -726,58 +751,6 @@ public class AudioSharingDialogHandlerTest {
        verify(mBroadcast).unregisterServiceCallBack(any(BluetoothLeBroadcast.Callback.class));
    }

    @Test
    public void onBroadcastStartFailed_logAction() {
        setUpBroadcast(false);
        ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
        when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
        when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
        mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
        shadowOf(Looper.getMainLooper()).idle();
        List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
        assertThat(childFragments)
                .comparingElementsUsing(TAG_EQUALS)
                .containsExactly(AudioSharingJoinDialogFragment.tag());
        AudioSharingJoinDialogFragment fragment =
                (AudioSharingJoinDialogFragment) Iterables.getOnlyElement(childFragments);
        AudioSharingJoinDialogFragment.DialogEventListener listener = fragment.getListener();
        assertThat(listener).isNotNull();
        listener.onShareClick();

        mHandler.mBroadcastCallback.onBroadcastStartFailed(/* reason= */ 1);
        verify(mFeatureFactory.metricsFeatureProvider)
                .action(
                        mContext,
                        SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED,
                        SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY);
    }

    @Test
    public void onPlaybackStarted_addSource() {
        setUpBroadcast(false);
        ImmutableList<BluetoothDevice> deviceList = ImmutableList.of(mDevice1, mDevice3);
        when(mAssistant.getAllConnectedDevices()).thenReturn(deviceList);
        when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
        mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
        shadowOf(Looper.getMainLooper()).idle();
        List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
        assertThat(childFragments)
                .comparingElementsUsing(TAG_EQUALS)
                .containsExactly(AudioSharingJoinDialogFragment.tag());
        AudioSharingJoinDialogFragment fragment =
                (AudioSharingJoinDialogFragment) Iterables.getOnlyElement(childFragments);
        AudioSharingJoinDialogFragment.DialogEventListener listener = fragment.getListener();
        assertThat(listener).isNotNull();
        listener.onShareClick();

        setUpBroadcast(true);
        mHandler.mBroadcastCallback.onPlaybackStarted(/* reason= */ 1, /* broadcastId= */ 1);
        shadowOf(Looper.getMainLooper()).idle();

        verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
        verify(mAssistant).addSource(mDevice3, mMetadata, /* isGroupOp= */ false);
    }

    @Test
    public void onBroadcastStopFailed_logAction() {
        setUpBroadcast(true);
@@ -808,6 +781,7 @@ public class AudioSharingDialogHandlerTest {
    @Test
    public void testBluetoothLeBroadcastCallbacks_doNothing() {
        mHandler.mBroadcastCallback.onBroadcastStarted(/* reason= */ 1, /* broadcastId= */ 1);
        mHandler.mBroadcastCallback.onBroadcastStartFailed(/* reason= */ 1);
        mHandler.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata);
        mHandler.mBroadcastCallback.onBroadcastUpdated(/* reason= */ 1, /* broadcastId= */ 1);
        mHandler.mBroadcastCallback.onPlaybackStarted(/* reason= */ 1, /* broadcastId= */ 1);