Merge "[Audiosharing] Handle auto start intent from QS" into main
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