[Audiosharing] Handle auto start intent from QS
When intent extra EXTRA_START_LE_AUDIO_SHARING is true, audio sharing page needs auto toggle on the main switch and start audio sharing. And if there are one active sink and one connected sink, auto add source to them without popping up dialog. Test: atest Flag: com.android.settingslib.flags.enable_le_audio_sharing Bug: 331892035 Change-Id: I0c677ea33c9e0e3eeb8495c8618bff685b13a8ed
This commit is contained in:
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.connecteddevice.audiosharing;
|
package com.android.settings.connecteddevice.audiosharing;
|
||||||
|
|
||||||
|
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_START_LE_AUDIO_SHARING;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
@@ -27,6 +29,7 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.util.FeatureFlagUtils;
|
import android.util.FeatureFlagUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.Pair;
|
import android.util.Pair;
|
||||||
@@ -44,6 +47,7 @@ import androidx.lifecycle.DefaultLifecycleObserver;
|
|||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.bluetooth.Utils;
|
import com.android.settings.bluetooth.Utils;
|
||||||
import com.android.settings.core.BasePreferenceController;
|
import com.android.settings.core.BasePreferenceController;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
@@ -66,11 +70,12 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
public class AudioSharingSwitchBarController extends BasePreferenceController
|
public class AudioSharingSwitchBarController extends BasePreferenceController
|
||||||
implements DefaultLifecycleObserver,
|
implements DefaultLifecycleObserver,
|
||||||
OnCheckedChangeListener,
|
OnCheckedChangeListener,
|
||||||
LocalBluetoothProfileManager.ServiceListener {
|
LocalBluetoothProfileManager.ServiceListener {
|
||||||
private static final String TAG = "AudioSharingSwitchCtlr";
|
private static final String TAG = "AudioSharingSwitchCtlr";
|
||||||
private static final String PREF_KEY = "audio_sharing_main_switch";
|
private static final String PREF_KEY = "audio_sharing_main_switch";
|
||||||
|
|
||||||
@@ -106,6 +111,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
private List<AudioSharingDeviceItem> mDeviceItemsForSharing = new ArrayList<>();
|
private List<AudioSharingDeviceItem> mDeviceItemsForSharing = new ArrayList<>();
|
||||||
@VisibleForTesting IntentFilter mIntentFilter;
|
@VisibleForTesting IntentFilter mIntentFilter;
|
||||||
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
|
private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
|
||||||
|
private AtomicInteger mIntentHandleStage =
|
||||||
|
new AtomicInteger(StartIntentHandleStage.TO_HANDLE.ordinal());
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
BroadcastReceiver mReceiver =
|
BroadcastReceiver mReceiver =
|
||||||
@@ -309,6 +316,12 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
registerCallbacks();
|
registerCallbacks();
|
||||||
|
if (mIntentHandleStage.compareAndSet(
|
||||||
|
StartIntentHandleStage.TO_HANDLE.ordinal(),
|
||||||
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal())) {
|
||||||
|
Log.d(TAG, "onStart: handleStartAudioSharingFromIntent");
|
||||||
|
handleStartAudioSharingFromIntent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -344,8 +357,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
// FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST is always true in
|
// FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST is always true in
|
||||||
// prod. We can turn off the flag for debug purpose.
|
// prod. We can turn off the flag for debug purpose.
|
||||||
if (FeatureFlagUtils.isEnabled(
|
if (FeatureFlagUtils.isEnabled(
|
||||||
mContext,
|
mContext,
|
||||||
FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST)
|
FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST)
|
||||||
&& mAssistant.getAllConnectedDevices().isEmpty()) {
|
&& mAssistant.getAllConnectedDevices().isEmpty()) {
|
||||||
// Pop up dialog to ask users to connect at least one lea buds before audio sharing.
|
// Pop up dialog to ask users to connect at least one lea buds before audio sharing.
|
||||||
AudioSharingUtils.postOnMainThread(
|
AudioSharingUtils.postOnMainThread(
|
||||||
@@ -386,6 +399,12 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
if (mProfileManager != null) {
|
if (mProfileManager != null) {
|
||||||
mProfileManager.removeServiceListener(this);
|
mProfileManager.removeServiceListener(this);
|
||||||
}
|
}
|
||||||
|
if (mIntentHandleStage.compareAndSet(
|
||||||
|
StartIntentHandleStage.TO_HANDLE.ordinal(),
|
||||||
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal())) {
|
||||||
|
Log.d(TAG, "onServiceConnected: handleStartAudioSharingFromIntent");
|
||||||
|
handleStartAudioSharingFromIntent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +508,7 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
boolean isStateReady =
|
boolean isStateReady =
|
||||||
isBluetoothOn()
|
isBluetoothOn()
|
||||||
&& AudioSharingUtils.isAudioSharingProfileReady(
|
&& AudioSharingUtils.isAudioSharingProfileReady(
|
||||||
mProfileManager);
|
mProfileManager);
|
||||||
AudioSharingUtils.postOnMainThread(
|
AudioSharingUtils.postOnMainThread(
|
||||||
mContext,
|
mContext,
|
||||||
() -> {
|
() -> {
|
||||||
@@ -526,7 +545,24 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
AudioSharingUtils.addSourceToTargetSinks(mTargetActiveSinks, mBtManager);
|
AudioSharingUtils.addSourceToTargetSinks(mTargetActiveSinks, mBtManager);
|
||||||
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING);
|
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING);
|
||||||
mTargetActiveSinks.clear();
|
mTargetActiveSinks.clear();
|
||||||
|
if (mIntentHandleStage.compareAndSet(
|
||||||
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||||
|
StartIntentHandleStage.HANDLED.ordinal())
|
||||||
|
&& mDeviceItemsForSharing.size() == 1) {
|
||||||
|
Log.d(TAG, "handleOnBroadcastReady: auto add source to the second device");
|
||||||
|
AudioSharingUtils.addSourceToTargetSinks(
|
||||||
|
mGroupedConnectedDevices.getOrDefault(
|
||||||
|
mDeviceItemsForSharing.get(0).getGroupId(), ImmutableList.of()),
|
||||||
|
mBtManager);
|
||||||
|
mGroupedConnectedDevices.clear();
|
||||||
|
mDeviceItemsForSharing.clear();
|
||||||
|
// TODO: Add metric for auto add by intent
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
mIntentHandleStage.compareAndSet(
|
||||||
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||||
|
StartIntentHandleStage.HANDLED.ordinal());
|
||||||
if (mFragment == null) {
|
if (mFragment == null) {
|
||||||
Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment.");
|
Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment.");
|
||||||
mGroupedConnectedDevices.clear();
|
mGroupedConnectedDevices.clear();
|
||||||
@@ -572,12 +608,58 @@ public class AudioSharingSwitchBarController extends BasePreferenceController
|
|||||||
@NonNull ViewGroup host, @NonNull View view, @NonNull AccessibilityEvent event) {
|
@NonNull ViewGroup host, @NonNull View view, @NonNull AccessibilityEvent event) {
|
||||||
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
|
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
|
||||||
&& (event.getContentChangeTypes()
|
&& (event.getContentChangeTypes()
|
||||||
& AccessibilityEvent.CONTENT_CHANGE_TYPE_ENABLED)
|
& AccessibilityEvent.CONTENT_CHANGE_TYPE_ENABLED)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
Log.d(TAG, "Skip accessibility event for CONTENT_CHANGE_TYPE_ENABLED");
|
Log.d(TAG, "Skip accessibility event for CONTENT_CHANGE_TYPE_ENABLED");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return super.onRequestSendAccessibilityEvent(host, view, event);
|
return super.onRequestSendAccessibilityEvent(host, view, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleStartAudioSharingFromIntent() {
|
||||||
|
var unused =
|
||||||
|
ThreadUtils.postOnBackgroundThread(
|
||||||
|
() -> {
|
||||||
|
if (mFragment == null
|
||||||
|
|| mFragment.getActivity() == null
|
||||||
|
|| mFragment.getActivity().getIntent() == null) {
|
||||||
|
Log.d(
|
||||||
|
TAG,
|
||||||
|
"Skip handleStartAudioSharingFromIntent, "
|
||||||
|
+ "fragment intent is null");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Intent intent = mFragment.getActivity().getIntent();
|
||||||
|
Bundle args =
|
||||||
|
intent.getBundleExtra(
|
||||||
|
SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS);
|
||||||
|
Boolean shouldStart =
|
||||||
|
args != null
|
||||||
|
&& args.getBoolean(EXTRA_START_LE_AUDIO_SHARING, false);
|
||||||
|
if (!shouldStart) {
|
||||||
|
Log.d(TAG, "Skip handleStartAudioSharingFromIntent, arg false");
|
||||||
|
mIntentHandleStage.compareAndSet(
|
||||||
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||||
|
StartIntentHandleStage.HANDLED.ordinal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (BluetoothUtils.isBroadcasting(mBtManager)) {
|
||||||
|
Log.d(TAG, "Skip handleStartAudioSharingFromIntent, in broadcast");
|
||||||
|
mIntentHandleStage.compareAndSet(
|
||||||
|
StartIntentHandleStage.HANDLE_AUTO_ADD.ordinal(),
|
||||||
|
StartIntentHandleStage.HANDLED.ordinal());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.d(TAG, "HandleStartAudioSharingFromIntent, start broadcast");
|
||||||
|
AudioSharingUtils.postOnMainThread(
|
||||||
|
mContext, () -> mSwitchBar.setChecked(true));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum StartIntentHandleStage {
|
||||||
|
TO_HANDLE,
|
||||||
|
HANDLE_AUTO_ADD,
|
||||||
|
HANDLED,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -18,6 +18,7 @@ package com.android.settings.connecteddevice.audiosharing;
|
|||||||
|
|
||||||
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
|
||||||
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
|
||||||
|
import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_START_LE_AUDIO_SHARING;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
@@ -33,6 +34,7 @@ import static org.mockito.Mockito.verify;
|
|||||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
import static org.robolectric.Shadows.shadowOf;
|
import static org.robolectric.Shadows.shadowOf;
|
||||||
|
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
@@ -47,6 +49,7 @@ import android.content.BroadcastReceiver;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.platform.test.flag.junit.SetFlagsRule;
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.util.FeatureFlagUtils;
|
import android.util.FeatureFlagUtils;
|
||||||
@@ -55,14 +58,18 @@ import android.view.View;
|
|||||||
import android.view.accessibility.AccessibilityEvent;
|
import android.view.accessibility.AccessibilityEvent;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.fragment.app.DialogFragment;
|
import androidx.fragment.app.DialogFragment;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentActivity;
|
import androidx.fragment.app.FragmentActivity;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.SettingsActivity;
|
||||||
import com.android.settings.bluetooth.Utils;
|
import com.android.settings.bluetooth.Utils;
|
||||||
import com.android.settings.testutils.FakeFeatureFactory;
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
|
||||||
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
|
||||||
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
import com.android.settings.testutils.shadow.ShadowThreadUtils;
|
||||||
@@ -105,6 +112,7 @@ import java.util.concurrent.Executor;
|
|||||||
ShadowBluetoothAdapter.class,
|
ShadowBluetoothAdapter.class,
|
||||||
ShadowBluetoothUtils.class,
|
ShadowBluetoothUtils.class,
|
||||||
ShadowThreadUtils.class,
|
ShadowThreadUtils.class,
|
||||||
|
ShadowAlertDialogCompat.class
|
||||||
})
|
})
|
||||||
public class AudioSharingSwitchBarControllerTest {
|
public class AudioSharingSwitchBarControllerTest {
|
||||||
private static final String TEST_DEVICE_NAME1 = "test1";
|
private static final String TEST_DEVICE_NAME1 = "test1";
|
||||||
@@ -129,6 +137,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
@Mock private LocalBluetoothLeBroadcast mBroadcast;
|
@Mock private LocalBluetoothLeBroadcast mBroadcast;
|
||||||
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
|
||||||
@Mock private VolumeControlProfile mVolumeControl;
|
@Mock private VolumeControlProfile mVolumeControl;
|
||||||
|
@Mock private BluetoothLeBroadcastMetadata mMetadata;
|
||||||
@Mock private CompoundButton mBtnView;
|
@Mock private CompoundButton mBtnView;
|
||||||
@Mock private CachedBluetoothDevice mCachedDevice1;
|
@Mock private CachedBluetoothDevice mCachedDevice1;
|
||||||
@Mock private CachedBluetoothDevice mCachedDevice2;
|
@Mock private CachedBluetoothDevice mCachedDevice2;
|
||||||
@@ -434,6 +443,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||||
when(mBtnView.isEnabled()).thenReturn(true);
|
when(mBtnView.isEnabled()).thenReturn(true);
|
||||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
mController =
|
mController =
|
||||||
new AudioSharingSwitchBarController(
|
new AudioSharingSwitchBarController(
|
||||||
@@ -466,6 +476,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
doNothing().when(mBroadcast).startPrivateBroadcast();
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
verify(mBroadcast).startPrivateBroadcast();
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
shadowOf(Looper.getMainLooper()).idle();
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
@@ -502,6 +513,58 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
1));
|
1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onPlaybackStarted_clickShareBtnOnDialog_addSource() {
|
||||||
|
FeatureFlagUtils.setEnabled(
|
||||||
|
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||||
|
when(mBtnView.isEnabled()).thenReturn(true);
|
||||||
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false);
|
||||||
|
|
||||||
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
|
assertThat(dialog).isNotNull();
|
||||||
|
View btnView = dialog.findViewById(R.id.positive_btn);
|
||||||
|
assertThat(btnView).isNotNull();
|
||||||
|
btnView.performClick();
|
||||||
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
|
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onPlaybackStarted_clickCancelBtnOnDialog_doNothing() {
|
||||||
|
FeatureFlagUtils.setEnabled(
|
||||||
|
mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true);
|
||||||
|
when(mBtnView.isEnabled()).thenReturn(true);
|
||||||
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
|
verify(mBroadcast).startPrivateBroadcast();
|
||||||
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false);
|
||||||
|
|
||||||
|
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
|
||||||
|
assertThat(dialog).isNotNull();
|
||||||
|
View btnView = dialog.findViewById(R.id.negative_btn);
|
||||||
|
assertThat(btnView).isNotNull();
|
||||||
|
btnView.performClick();
|
||||||
|
shadowMainLooper().idle();
|
||||||
|
|
||||||
|
verify(mAssistant, never()).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||||
|
assertThat(dialog.isShowing()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBluetoothLeBroadcastCallbacks_updateSwitch() {
|
public void testBluetoothLeBroadcastCallbacks_updateSwitch() {
|
||||||
mOnAudioSharingStateChanged = false;
|
mOnAudioSharingStateChanged = false;
|
||||||
@@ -543,8 +606,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBluetoothLeBroadcastCallbacks_doNothing() {
|
public void testBluetoothLeBroadcastCallbacks_doNothing() {
|
||||||
BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class);
|
mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata);
|
||||||
mController.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, metadata);
|
|
||||||
mController.mBroadcastCallback.onBroadcastUpdated(/* reason= */ 1, /* broadcastId= */ 1);
|
mController.mBroadcastCallback.onBroadcastUpdated(/* reason= */ 1, /* broadcastId= */ 1);
|
||||||
mController.mBroadcastCallback.onPlaybackStarted(/* reason= */ 1, /* broadcastId= */ 1);
|
mController.mBroadcastCallback.onPlaybackStarted(/* reason= */ 1, /* broadcastId= */ 1);
|
||||||
mController.mBroadcastCallback.onPlaybackStopped(/* reason= */ 1, /* broadcastId= */ 1);
|
mController.mBroadcastCallback.onPlaybackStopped(/* reason= */ 1, /* broadcastId= */ 1);
|
||||||
@@ -556,9 +618,8 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBluetoothLeBroadcastAssistantCallbacks_logAction() {
|
public void testBluetoothLeBroadcastAssistantCallbacks_logAction() {
|
||||||
BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class);
|
|
||||||
mController.mBroadcastAssistantCallback.onSourceAddFailed(
|
mController.mBroadcastAssistantCallback.onSourceAddFailed(
|
||||||
mDevice1, metadata, /* reason= */ 1);
|
mDevice1, mMetadata, /* reason= */ 1);
|
||||||
verify(mFeatureFactory.metricsFeatureProvider)
|
verify(mFeatureFactory.metricsFeatureProvider)
|
||||||
.action(
|
.action(
|
||||||
mContext,
|
mContext,
|
||||||
@@ -569,7 +630,6 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testBluetoothLeBroadcastAssistantCallbacks_doNothing() {
|
public void testBluetoothLeBroadcastAssistantCallbacks_doNothing() {
|
||||||
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class);
|
||||||
BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class);
|
|
||||||
|
|
||||||
// Do nothing
|
// Do nothing
|
||||||
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
|
mController.mBroadcastAssistantCallback.onReceiveStateChanged(
|
||||||
@@ -588,7 +648,7 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
mDevice1, /* sourceId= */ 1, /* reason= */ 1);
|
mDevice1, /* sourceId= */ 1, /* reason= */ 1);
|
||||||
mController.mBroadcastAssistantCallback.onSourceModifyFailed(
|
mController.mBroadcastAssistantCallback.onSourceModifyFailed(
|
||||||
mDevice1, /* sourceId= */ 1, /* reason= */ 1);
|
mDevice1, /* sourceId= */ 1, /* reason= */ 1);
|
||||||
mController.mBroadcastAssistantCallback.onSourceFound(metadata);
|
mController.mBroadcastAssistantCallback.onSourceFound(mMetadata);
|
||||||
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1);
|
mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1);
|
||||||
verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider);
|
verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider);
|
||||||
}
|
}
|
||||||
@@ -614,4 +674,74 @@ public class AudioSharingSwitchBarControllerTest {
|
|||||||
.onRequestSendAccessibilityEvent(mSwitchBar, view, event))
|
.onRequestSendAccessibilityEvent(mSwitchBar, view, event))
|
||||||
.isFalse();
|
.isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleStartAudioSharingFromIntent_flagOff_doNothing() {
|
||||||
|
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
setUpStartSharingIntent();
|
||||||
|
mController.onStart(mLifecycleOwner);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
verify(mSwitchBar, never()).setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleStartAudioSharingFromIntent_profileNotReady_doNothing() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
when(mAssistant.isProfileReady()).thenReturn(false);
|
||||||
|
setUpStartSharingIntent();
|
||||||
|
mController.onServiceConnected();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
verify(mSwitchBar, never()).setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleStartAudioSharingFromIntent_argFalse_doNothing() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
mController.onStart(mLifecycleOwner);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
verify(mSwitchBar, never()).setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleStartAudioSharingFromIntent_handle() {
|
||||||
|
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
|
||||||
|
when(mBtnView.isEnabled()).thenReturn(true);
|
||||||
|
when(mAssistant.getAllConnectedDevices()).thenReturn(ImmutableList.of(mDevice2, mDevice1));
|
||||||
|
when(mBroadcast.getLatestBluetoothLeBroadcastMetadata()).thenReturn(mMetadata);
|
||||||
|
setUpStartSharingIntent();
|
||||||
|
mController.onServiceConnected();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
verify(mSwitchBar).setChecked(true);
|
||||||
|
doNothing().when(mBroadcast).startPrivateBroadcast();
|
||||||
|
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
|
||||||
|
mController.mBroadcastCallback.onPlaybackStarted(0, 0);
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
|
||||||
|
verify(mFeatureFactory.metricsFeatureProvider)
|
||||||
|
.action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING));
|
||||||
|
verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false);
|
||||||
|
verify(mAssistant).addSource(mDevice2, mMetadata, /* isGroupOp= */ false);
|
||||||
|
List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
|
||||||
|
assertThat(childFragments).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpStartSharingIntent() {
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putBoolean(EXTRA_START_LE_AUDIO_SHARING, true);
|
||||||
|
Intent intent = new Intent();
|
||||||
|
intent.putExtra(SettingsActivity.EXTRA_SHOW_FRAGMENT_ARGUMENTS, args);
|
||||||
|
Fragment fragment = new Fragment();
|
||||||
|
FragmentController.of(fragment, intent)
|
||||||
|
.create(/* containerViewId= */ 0, /* bundle= */ null)
|
||||||
|
.start()
|
||||||
|
.resume()
|
||||||
|
.visible()
|
||||||
|
.get();
|
||||||
|
shadowOf(Looper.getMainLooper()).idle();
|
||||||
|
mController.init(fragment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user