From 52cbe2156973794f8e09965e7a062a50ffd9768f Mon Sep 17 00:00:00 2001 From: Yiyi Shen Date: Mon, 17 Jun 2024 16:00:49 +0800 Subject: [PATCH] [Audiosharing] Add audio sharing loggings (P4) Bug: 331515891 Test: atest Change-Id: I05e1c138f9cc32c4e873852f93bac65d3d0dc3ca --- ...udioSharingDevicePreferenceController.java | 13 +++ .../AudioSharingDialogHandler.java | 32 ++++-- .../AudioSharingStopDialogFragment.java | 7 ++ .../AudioSharingSwitchBarController.java | 62 ++++++----- ...SharingDevicePreferenceControllerTest.java | 32 +++++- .../AudioSharingDialogHandlerTest.java | 101 +++++++++++++++++- .../AudioSharingSwitchBarControllerTest.java | 83 ++++++++++++++ 7 files changed, 287 insertions(+), 43 deletions(-) diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java index b932a7e28ef..cc883fe57c1 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceController.java @@ -18,6 +18,7 @@ package com.android.settings.connecteddevice.audiosharing; import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast.EXTRA_BLUETOOTH_DEVICE; +import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastAssistant; @@ -44,6 +45,7 @@ import com.android.settings.bluetooth.Utils; import com.android.settings.connecteddevice.DevicePreferenceCallback; import com.android.settings.core.BasePreferenceController; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.overlay.FeatureFactory; import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.BluetoothCallback; import com.android.settingslib.bluetooth.BluetoothEventManager; @@ -56,6 +58,7 @@ import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.Locale; import java.util.concurrent.Executor; @@ -80,6 +83,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @Nullable private final LocalBluetoothProfileManager mProfileManager; @Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant; private final Executor mExecutor; + private final MetricsFeatureProvider mMetricsFeatureProvider; @Nullable private PreferenceGroup mPreferenceGroup; @Nullable private Preference mAudioSharingSettingsPreference; @Nullable private BluetoothDeviceUpdater mBluetoothDeviceUpdater; @@ -114,6 +118,10 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @NonNull BluetoothDevice sink, @NonNull BluetoothLeBroadcastMetadata source, int reason) { + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED, + SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY); AudioSharingUtils.toastMessage( mContext, String.format( @@ -143,6 +151,10 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro @Override public void onSourceRemoveFailed( @NonNull BluetoothDevice sink, int sourceId, int reason) { + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_LEAVE_FAILED, + SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY); AudioSharingUtils.toastMessage( mContext, String.format( @@ -183,6 +195,7 @@ public class AudioSharingDevicePreferenceController extends BasePreferenceContro ? null : mProfileManager.getLeAudioBroadcastAssistantProfile(); mExecutor = Executors.newSingleThreadExecutor(); + mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider(); } @Override diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java index 8d69cf6232c..15e3de90e7a 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java @@ -60,7 +60,9 @@ public class AudioSharingDialogHandler { @Nullable private final LocalBluetoothLeBroadcast mBroadcast; @Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant; private final MetricsFeatureProvider mMetricsFeatureProvider; - private List mTargetSinks = new ArrayList<>(); + // The target sinks to join broadcast onPlaybackStarted + @Nullable private List mTargetSinks; + private boolean mIsStoppingBroadcast = false; @VisibleForTesting final BluetoothLeBroadcast.Callback mBroadcastCallback = @@ -78,8 +80,15 @@ public class AudioSharingDialogHandler { @Override public void onBroadcastStartFailed(int reason) { Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason); - AudioSharingUtils.toastMessage( - mContext, "Fail to start broadcast, 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 @@ -101,13 +110,21 @@ public class AudioSharingDialogHandler { + reason + ", broadcastId = " + broadcastId); + mIsStoppingBroadcast = false; } @Override public void onBroadcastStopFailed(int reason) { Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason); - AudioSharingUtils.toastMessage( - mContext, "Fail to stop broadcast, reason " + reason); + if (mIsStoppingBroadcast) { + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_STOP_FAILED, + SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY); + AudioSharingUtils.toastMessage( + mContext, "Fail to stop broadcast, reason " + reason); + mIsStoppingBroadcast = false; + } } @Override @@ -124,7 +141,7 @@ public class AudioSharingDialogHandler { + reason + ", broadcastId = " + broadcastId); - if (!mTargetSinks.isEmpty()) { + if (mTargetSinks != null) { AudioSharingUtils.addSourceToTargetSinks(mTargetSinks, mLocalBtManager); new SubSettingLauncher(mContext) .setDestination(AudioSharingDashboardFragment.class.getName()) @@ -134,7 +151,7 @@ public class AudioSharingDialogHandler { .getMetricsCategory() : SettingsEnums.PAGE_UNKNOWN) .launch(); - mTargetSinks = new ArrayList<>(); + mTargetSinks = null; } } @@ -203,6 +220,7 @@ public class AudioSharingDialogHandler { AudioSharingStopDialogFragment.DialogEventListener listener = () -> { cachedDevice.setActive(); + mIsStoppingBroadcast = true; AudioSharingUtils.stopBroadcasting(mLocalBtManager); }; Pair[] eventData = diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java index 59593ba340f..b8da290f6e5 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java @@ -140,6 +140,13 @@ public class AudioSharingStopDialogFragment extends InstrumentedDialogFragment { return sCachedDevice; } + /** Test only: get the {@link DialogEventListener} passed to the dialog. */ + @VisibleForTesting + @Nullable + DialogEventListener getListener() { + return sListener; + } + /** Test only: get the event data passed to the dialog. */ @VisibleForTesting @NonNull diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java index 89d2c953a57..97055661686 100644 --- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java +++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java @@ -134,8 +134,11 @@ public class AudioSharingSwitchBarController extends BasePreferenceController @Override public void onBroadcastStartFailed(int reason) { Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason); - // TODO: handle broadcast start fail updateSwitch(); + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED, + SettingsEnums.AUDIO_SHARING_SETTINGS); } @Override @@ -164,8 +167,11 @@ public class AudioSharingSwitchBarController extends BasePreferenceController @Override public void onBroadcastStopFailed(int reason) { Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason); - // TODO: handle broadcast stop fail updateSwitch(); + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_STOP_FAILED, + SettingsEnums.AUDIO_SHARING_SETTINGS); } @Override @@ -189,7 +195,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController public void onPlaybackStopped(int reason, int broadcastId) {} }; - private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = + @VisibleForTesting + final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback = new BluetoothLeBroadcastAssistant.Callback() { @Override public void onSearchStarted(int reason) {} @@ -207,16 +214,8 @@ public class AudioSharingSwitchBarController extends BasePreferenceController public void onSourceFound(@NonNull BluetoothLeBroadcastMetadata source) {} @Override - public void onSourceAdded(@NonNull BluetoothDevice sink, int sourceId, int reason) { - Log.d( - TAG, - "onSourceAdded(), sink = " - + sink - + ", sourceId = " - + sourceId - + ", reason = " - + reason); - } + public void onSourceAdded( + @NonNull BluetoothDevice sink, int sourceId, int reason) {} @Override public void onSourceAddFailed( @@ -231,6 +230,10 @@ public class AudioSharingSwitchBarController extends BasePreferenceController + source + ", reason = " + reason); + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED, + SettingsEnums.AUDIO_SHARING_SETTINGS); AudioSharingUtils.toastMessage( mContext, String.format( @@ -318,15 +321,17 @@ public class AudioSharingSwitchBarController extends BasePreferenceController public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // Filter out unnecessary callbacks when switch is disabled. if (!buttonView.isEnabled()) return; + if (mBroadcast == null || mAssistant == null) { + mSwitchBar.setChecked(false); + Log.d(TAG, "Skip onCheckedChanged, profile not support."); + return; + } + mSwitchBar.setEnabled(false); + boolean isBroadcasting = AudioSharingUtils.isBroadcasting(mBtManager); if (isChecked) { - mSwitchBar.setEnabled(false); - boolean isBroadcasting = AudioSharingUtils.isBroadcasting(mBtManager); - if (mAssistant == null || mBroadcast == null || isBroadcasting) { - Log.d(TAG, "Skip startAudioSharing, already broadcasting or not support."); + if (isBroadcasting) { + Log.d(TAG, "Skip startAudioSharing, already broadcasting."); mSwitchBar.setEnabled(true); - if (!isBroadcasting) { - mSwitchBar.setChecked(false); - } return; } // FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST is always true in @@ -352,6 +357,11 @@ public class AudioSharingSwitchBarController extends BasePreferenceController } startAudioSharing(); } else { + if (!isBroadcasting) { + Log.d(TAG, "Skip stopAudioSharing, already not broadcasting."); + mSwitchBar.setEnabled(true); + return; + } stopAudioSharing(); } } @@ -454,18 +464,18 @@ public class AudioSharingSwitchBarController extends BasePreferenceController } if (mBroadcast != null) { mBroadcast.startPrivateBroadcast(); + mMetricsFeatureProvider.action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_ON, + deviceItems.size()); } } private void stopAudioSharing() { - mSwitchBar.setEnabled(false); - if (!AudioSharingUtils.isBroadcasting(mBtManager)) { - Log.d(TAG, "Skip stopAudioSharing, already not broadcasting or broadcast not support."); - mSwitchBar.setEnabled(true); - return; - } if (mBroadcast != null) { mBroadcast.stopBroadcast(mBroadcast.getLatestBroadcastId()); + mMetricsFeatureProvider.action( + mContext, SettingsEnums.ACTION_AUDIO_SHARING_MAIN_SWITCH_OFF); } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java index 18f75ba2b85..f3f32ae4e31 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDevicePreferenceControllerTest.java @@ -30,9 +30,11 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; +import android.app.settings.SettingsEnums; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcastAssistant; @@ -57,6 +59,7 @@ import androidx.test.core.app.ApplicationProvider; import com.android.settings.SettingsActivity; import com.android.settings.bluetooth.Utils; import com.android.settings.dashboard.DashboardFragment; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; import com.android.settings.testutils.shadow.ShadowFragment; @@ -136,6 +139,7 @@ public class AudioSharingDevicePreferenceControllerTest { private LifecycleOwner mLifecycleOwner; private PreferenceCategory mPreferenceGroup; private Preference mAudioSharingPreference; + private FakeFeatureFactory mFeatureFactory; @Before public void setUp() { @@ -148,6 +152,7 @@ public class AudioSharingDevicePreferenceControllerTest { BluetoothStatusCodes.FEATURE_SUPPORTED); mLifecycleOwner = () -> mLifecycle; mLifecycle = new Lifecycle(mLifecycleOwner); + mFeatureFactory = FakeFeatureFactory.setupForTest(); ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager; mLocalBtManager = Utils.getLocalBtManager(mContext); when(mLocalBtManager.getEventManager()).thenReturn(mEventManager); @@ -175,6 +180,7 @@ public class AudioSharingDevicePreferenceControllerTest { .thenReturn(mAudioSharingPreference); when(mScreen.findPreference(KEY)).thenReturn(mPreferenceGroup); mController = new AudioSharingDevicePreferenceController(mContext); + mController.init(mFragment); mController.setBluetoothDeviceUpdater(mBluetoothDeviceUpdater); mController.setDialogHandler(mDialogHandler); doReturn(mActivity).when(mFragment).getActivity(); @@ -526,6 +532,25 @@ public class AudioSharingDevicePreferenceControllerTest { verify(mBluetoothDeviceUpdater, times(2)).forceUpdate(); } + @Test + public void testBluetoothLeBroadcastAssistantCallbacks_logAction() { + mController.mBroadcastAssistantCallback.onSourceAddFailed( + mDevice, mSource, /* reason= */ 1); + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED, + SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY); + + mController.mBroadcastAssistantCallback.onSourceRemoveFailed( + mDevice, /* sourceId= */ 1, /* reason= */ 1); + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_LEAVE_FAILED, + SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY); + } + @Test public void testBluetoothLeBroadcastAssistantCallbacks_doNothing() { mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1); @@ -534,10 +559,6 @@ public class AudioSharingDevicePreferenceControllerTest { mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceAdded( mDevice, /* sourceId= */ 1, /* reason= */ 1); - mController.mBroadcastAssistantCallback.onSourceAddFailed( - mDevice, mSource, /* reason= */ 1); - mController.mBroadcastAssistantCallback.onSourceRemoveFailed( - mDevice, /* sourceId= */ 1, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceModified( mDevice, /* sourceId= */ 1, /* reason= */ 1); mController.mBroadcastAssistantCallback.onSourceModifyFailed( @@ -546,7 +567,8 @@ public class AudioSharingDevicePreferenceControllerTest { mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1); shadowOf(Looper.getMainLooper()).idle(); - // Above callbacks won't update group preference + // Above callbacks won't update group preference and log actions verify(mBluetoothDeviceUpdater, never()).forceUpdate(); + verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider); } } diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java index 4c060d4356d..a7e6f5698d2 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java @@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; import static org.robolectric.Shadows.shadowOf; @@ -288,6 +289,8 @@ public class AudioSharingDialogHandlerTest { assertThat(listener).isNotNull(); listener.onShareClick(); verify(mBroadcast).startPrivateBroadcast(); + listener.onCancelClick(); + verify(mCachedDevice1).setActive(); } @Test @@ -330,6 +333,8 @@ public class AudioSharingDialogHandlerTest { 1)); AudioSharingJoinDialogFragment.DialogEventListener listener = fragment.getListener(); assertThat(listener).isNotNull(); + listener.onCancelClick(); + verify(mAssistant, never()).addSource(mDevice1, mMetadata, /* isGroupOp= */ false); listener.onShareClick(); verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false); } @@ -397,7 +402,7 @@ public class AudioSharingDialogHandlerTest { @Test public void handleNonLeaDeviceConnected_sharing_showStopDialog() { setUpBroadcast(true); - ImmutableList deviceList = ImmutableList.of(mDevice2); + ImmutableList deviceList = ImmutableList.of(mDevice1); when(mAssistant.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED})) .thenReturn(deviceList); @@ -487,6 +492,8 @@ public class AudioSharingDialogHandlerTest { assertThat(listener).isNotNull(); listener.onShareClick(); verify(mBroadcast).startPrivateBroadcast(); + listener.onCancelClick(); + verify(mCachedDevice1, never()).setActive(); } @Test @@ -529,6 +536,8 @@ public class AudioSharingDialogHandlerTest { 1)); AudioSharingJoinDialogFragment.DialogEventListener listener = fragment.getListener(); assertThat(listener).isNotNull(); + listener.onCancelClick(); + verify(mAssistant, never()).addSource(mDevice1, mMetadata, /* isGroupOp= */ false); listener.onShareClick(); verify(mAssistant).addSource(mDevice1, mMetadata, /* isGroupOp= */ false); } @@ -604,11 +613,38 @@ public class AudioSharingDialogHandlerTest { SettingsEnums.DIALOG_START_AUDIO_SHARING); } + @Test + public void closeOpeningDialogsForLeaDevice_closeDisconnectDialog() { + // Show disconnect dialog + setUpBroadcast(true); + ImmutableList deviceList = ImmutableList.of(mDevice1, mDevice3, mDevice4); + when(mAssistant.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED})) + .thenReturn(deviceList); + when(mAssistant.getAllSources(mDevice1)).thenReturn(ImmutableList.of()); + when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState)); + when(mAssistant.getAllSources(mDevice4)).thenReturn(ImmutableList.of(mState)); + mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false); + shadowOf(Looper.getMainLooper()).idle(); + assertThat(mParentFragment.getChildFragmentManager().getFragments()) + .comparingElementsUsing(TAG_EQUALS) + .containsExactly(AudioSharingDisconnectDialogFragment.tag()); + // Close opening dialogs + mHandler.closeOpeningDialogsForLeaDevice(mCachedDevice1); + shadowOf(Looper.getMainLooper()).idle(); + assertThat(mParentFragment.getChildFragmentManager().getFragments()).isEmpty(); + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS, + SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE); + } + @Test public void closeOpeningDialogsForNonLeaDevice_closeStopDialog() { // Show stop dialog setUpBroadcast(true); - ImmutableList deviceList = ImmutableList.of(mDevice2); + ImmutableList deviceList = ImmutableList.of(mDevice1); when(mAssistant.getDevicesMatchingConnectionStates( new int[] {BluetoothProfile.STATE_CONNECTED})) .thenReturn(deviceList); @@ -677,6 +713,34 @@ public class AudioSharingDialogHandlerTest { verify(mBroadcast).unregisterServiceCallBack(any(BluetoothLeBroadcast.Callback.class)); } + @Test + public void onBroadcastStartFailed_logAction() { + setUpBroadcast(false); + ImmutableList deviceList = ImmutableList.of(mDevice1, mDevice3); + when(mAssistant.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED})) + .thenReturn(deviceList); + when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of()); + mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false); + shadowOf(Looper.getMainLooper()).idle(); + List 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); @@ -705,16 +769,42 @@ public class AudioSharingDialogHandlerTest { verify(mAssistant).addSource(mDevice3, mMetadata, /* isGroupOp= */ false); } + @Test + public void onBroadcastStopFailed_logAction() { + setUpBroadcast(true); + ImmutableList deviceList = ImmutableList.of(mDevice1); + when(mAssistant.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED})) + .thenReturn(deviceList); + when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState)); + mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ false); + shadowOf(Looper.getMainLooper()).idle(); + List childFragments = mParentFragment.getChildFragmentManager().getFragments(); + assertThat(childFragments) + .comparingElementsUsing(TAG_EQUALS) + .containsExactly(AudioSharingStopDialogFragment.tag()); + + AudioSharingStopDialogFragment fragment = + (AudioSharingStopDialogFragment) Iterables.getOnlyElement(childFragments); + AudioSharingStopDialogFragment.DialogEventListener listener = fragment.getListener(); + assertThat(listener).isNotNull(); + listener.onStopSharingClick(); + + mHandler.mBroadcastCallback.onBroadcastStopFailed(/* reason= */ 1); + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_STOP_FAILED, + SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY); + } + @Test public void testBluetoothLeBroadcastCallbacks_doNothing() { mHandler.mBroadcastCallback.onBroadcastStarted(/* reason= */ 1, /* broadcastId= */ 1); - mHandler.mBroadcastCallback.onBroadcastStopped(/* reason= */ 1, /* broadcastId= */ 1); mHandler.mBroadcastCallback.onBroadcastMetadataChanged(/* reason= */ 1, mMetadata); mHandler.mBroadcastCallback.onBroadcastUpdated(/* reason= */ 1, /* broadcastId= */ 1); mHandler.mBroadcastCallback.onPlaybackStarted(/* reason= */ 1, /* broadcastId= */ 1); mHandler.mBroadcastCallback.onPlaybackStopped(/* reason= */ 1, /* broadcastId= */ 1); - mHandler.mBroadcastCallback.onBroadcastStartFailed(/* reason= */ 1); - mHandler.mBroadcastCallback.onBroadcastStopFailed(/* reason= */ 1); mHandler.mBroadcastCallback.onBroadcastUpdateFailed(/* reason= */ 1, /* broadcastId= */ 1); verify(mAssistant, never()) @@ -723,6 +813,7 @@ public class AudioSharingDialogHandlerTest { any(BluetoothLeBroadcastMetadata.class), anyBoolean()); verify(mAssistant, never()).removeSource(any(BluetoothDevice.class), anyInt()); + verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider); } private void setUpBroadcast(boolean isBroadcasting) { diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java index 45d99c7adde..d68b68bcc78 100644 --- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java +++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java @@ -30,6 +30,7 @@ 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; import static org.robolectric.Shadows.shadowOf; @@ -39,6 +40,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothLeBroadcast; import android.bluetooth.BluetoothLeBroadcastAssistant; import android.bluetooth.BluetoothLeBroadcastMetadata; +import android.bluetooth.BluetoothLeBroadcastReceiveState; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothStatusCodes; import android.content.BroadcastReceiver; @@ -430,6 +432,38 @@ public class AudioSharingSwitchBarControllerTest { verify(mBroadcast).stopBroadcast(1); } + @Test + public void onPlaybackStarted_notInit_noDialog() { + FeatureFlagUtils.setEnabled( + mContext, FeatureFlagUtils.SETTINGS_NEED_CONNECTED_BLE_DEVICE_FOR_BROADCAST, true); + when(mBtnView.isEnabled()).thenReturn(true); + when(mAssistant.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED})) + .thenReturn(ImmutableList.of(mDevice2, mDevice1)); + doNothing().when(mBroadcast).startPrivateBroadcast(); + mController = + new AudioSharingSwitchBarController( + mContext, + mSwitchBar, + new AudioSharingSwitchBarController.OnAudioSharingStateChangedListener() { + @Override + public void onAudioSharingStateChanged() {} + + @Override + public void onAudioSharingProfilesConnected() {} + }); + mController.onCheckedChanged(mBtnView, /* isChecked= */ true); + verify(mBroadcast).startPrivateBroadcast(); + mController.mBroadcastCallback.onPlaybackStarted(0, 0); + shadowOf(Looper.getMainLooper()).idle(); + + verify(mFeatureFactory.metricsFeatureProvider) + .action(any(Context.class), eq(SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING)); + + List childFragments = mParentFragment.getChildFragmentManager().getFragments(); + assertThat(childFragments).isEmpty(); + } + @Test public void onPlaybackStarted_showJoinAudioSharingDialog() { FeatureFlagUtils.setEnabled( @@ -485,6 +519,11 @@ public class AudioSharingSwitchBarControllerTest { shadowOf(Looper.getMainLooper()).idle(); assertThat(mSwitchBar.isChecked()).isFalse(); assertThat(mOnAudioSharingStateChanged).isFalse(); + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_START_FAILED, + SettingsEnums.AUDIO_SHARING_SETTINGS); when(mBroadcast.isEnabled(any())).thenReturn(true); mController.mBroadcastCallback.onBroadcastStarted(/* reason= */ 1, /* broadcastId= */ 1); @@ -497,6 +536,11 @@ public class AudioSharingSwitchBarControllerTest { shadowOf(Looper.getMainLooper()).idle(); assertThat(mSwitchBar.isChecked()).isTrue(); assertThat(mOnAudioSharingStateChanged).isFalse(); + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_STOP_FAILED, + SettingsEnums.AUDIO_SHARING_SETTINGS); when(mBroadcast.isEnabled(any())).thenReturn(false); mController.mBroadcastCallback.onBroadcastStopped(/* reason= */ 1, /* broadcastId= */ 1); @@ -517,4 +561,43 @@ public class AudioSharingSwitchBarControllerTest { verify(mSwitchBar, never()).setChecked(anyBoolean()); assertThat(mOnAudioSharingStateChanged).isFalse(); } + + @Test + public void testBluetoothLeBroadcastAssistantCallbacks_logAction() { + BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class); + mController.mBroadcastAssistantCallback.onSourceAddFailed( + mDevice1, metadata, /* reason= */ 1); + verify(mFeatureFactory.metricsFeatureProvider) + .action( + mContext, + SettingsEnums.ACTION_AUDIO_SHARING_JOIN_FAILED, + SettingsEnums.AUDIO_SHARING_SETTINGS); + } + + @Test + public void testBluetoothLeBroadcastAssistantCallbacks_doNothing() { + BluetoothLeBroadcastReceiveState state = mock(BluetoothLeBroadcastReceiveState.class); + BluetoothLeBroadcastMetadata metadata = mock(BluetoothLeBroadcastMetadata.class); + + // Do nothing + mController.mBroadcastAssistantCallback.onReceiveStateChanged( + mDevice1, /* sourceId= */ 1, state); + mController.mBroadcastAssistantCallback.onSearchStarted(/* reason= */ 1); + mController.mBroadcastAssistantCallback.onSearchStartFailed(/* reason= */ 1); + mController.mBroadcastAssistantCallback.onSearchStopped(/* reason= */ 1); + mController.mBroadcastAssistantCallback.onSearchStopFailed(/* reason= */ 1); + mController.mBroadcastAssistantCallback.onSourceAdded( + mDevice1, /* sourceId= */ 1, /* reason= */ 1); + mController.mBroadcastAssistantCallback.onSourceRemoved( + mDevice1, /* sourceId= */ 1, /* reason= */ 1); + mController.mBroadcastAssistantCallback.onSourceRemoveFailed( + mDevice1, /* sourceId= */ 1, /* reason= */ 1); + mController.mBroadcastAssistantCallback.onSourceModified( + mDevice1, /* sourceId= */ 1, /* reason= */ 1); + mController.mBroadcastAssistantCallback.onSourceModifyFailed( + mDevice1, /* sourceId= */ 1, /* reason= */ 1); + mController.mBroadcastAssistantCallback.onSourceFound(metadata); + mController.mBroadcastAssistantCallback.onSourceLost(/* broadcastId= */ 1); + verifyNoMoreInteractions(mFeatureFactory.metricsFeatureProvider); + } }