[Audiosharing] Log action in audio sharing dialogs
P3 for add audio sharing loggings
Bug: 331515891
Test: atest
Change-Id: Iea29e74e00c239e8cb8cddee6eae71ba902add01
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
index 6f7de8c..3d111fd 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragment.java
@@ -20,9 +20,11 @@
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@@ -48,13 +50,17 @@
* @param item The device item clicked.
*/
void onItemClick(AudioSharingDeviceItem item);
+
+ /** Called when users click the cancel button in the dialog. */
+ void onCancelClick();
}
@Nullable private static DialogEventListener sListener;
+ private static Pair<Integer, Object>[] sEventData = new Pair[0];
@Override
public int getMetricsCategory() {
- return SettingsEnums.DIALOG_START_AUDIO_SHARING;
+ return SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE;
}
/**
@@ -63,14 +69,17 @@
* @param host The Fragment this dialog will be hosted.
* @param deviceItems The connected device items eligible for audio sharing.
* @param listener The callback to handle the user action on this dialog.
+ * @param eventData The eventData to log with for dialog onClick events.
*/
public static void show(
@NonNull Fragment host,
@NonNull List<AudioSharingDeviceItem> deviceItems,
- @NonNull DialogEventListener listener) {
+ @NonNull DialogEventListener listener,
+ @NonNull Pair<Integer, Object>[] eventData) {
if (!AudioSharingUtils.isFeatureEnabled()) return;
final FragmentManager manager = host.getChildFragmentManager();
sListener = listener;
+ sEventData = eventData;
AlertDialog dialog = AudioSharingDialogHelper.getDialogIfShowing(manager, TAG);
if (dialog != null) {
Log.d(TAG, "Dialog is showing, return.");
@@ -84,7 +93,19 @@
dialogFrag.show(manager, TAG);
}
+ /** Return the tag of {@link AudioSharingDialogFragment} dialog. */
+ public static @NonNull String tag() {
+ return TAG;
+ }
+
+ /** Test only: get the event data passed to the dialog. */
+ @VisibleForTesting
+ protected @NonNull Pair<Integer, Object>[] getEventData() {
+ return sEventData;
+ }
+
@Override
+ @NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
Bundle arguments = requireArguments();
List<AudioSharingDeviceItem> deviceItems =
@@ -93,12 +114,17 @@
AudioSharingDialogFactory.newBuilder(getActivity())
.setTitleIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
.setIsCustomBodyEnabled(true);
+ if (deviceItems == null) {
+ Log.d(TAG, "Create dialog error: null deviceItems");
+ return builder.build();
+ }
if (deviceItems.isEmpty()) {
builder.setTitle(R.string.audio_sharing_share_dialog_title)
.setCustomImage(R.drawable.audio_sharing_guidance)
.setCustomMessage(R.string.audio_sharing_dialog_connect_device_content)
.setNegativeButton(
- R.string.audio_sharing_close_button_label, (dig, which) -> dismiss());
+ R.string.audio_sharing_close_button_label,
+ (dig, which) -> onCancelClick());
} else if (deviceItems.size() == 1) {
AudioSharingDeviceItem deviceItem = Iterables.getOnlyElement(deviceItems);
builder.setTitle(
@@ -111,11 +137,16 @@
v -> {
if (sListener != null) {
sListener.onItemClick(deviceItem);
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
+ sEventData);
}
dismiss();
})
.setCustomNegativeButton(
- R.string.audio_sharing_no_thanks_button_label, v -> dismiss());
+ R.string.audio_sharing_no_thanks_button_label, v -> onCancelClick());
} else {
builder.setTitle(R.string.audio_sharing_share_with_more_dialog_title)
.setCustomMessage(R.string.audio_sharing_dialog_share_more_content)
@@ -130,8 +161,20 @@
dismiss();
},
AudioSharingDeviceAdapter.ActionType.SHARE))
- .setCustomNegativeButton(com.android.settings.R.string.cancel, v -> dismiss());
+ .setCustomNegativeButton(
+ com.android.settings.R.string.cancel, v -> onCancelClick());
}
return builder.build();
}
+
+ private void onCancelClick() {
+ if (sListener != null) {
+ sListener.onCancelClick();
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
+ sEventData);
+ }
+ dismiss();
+ }
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
index c329e82..5458a9f 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandler.java
@@ -24,6 +24,7 @@
import android.bluetooth.BluetoothLeBroadcastReceiveState;
import android.content.Context;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -33,15 +34,21 @@
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.bluetooth.BluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+import com.android.settingslib.utils.ThreadUtils;
+
+import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Executor;
public class AudioSharingDialogHandler {
@@ -51,6 +58,7 @@
@Nullable private final LocalBluetoothManager mLocalBtManager;
@Nullable private final LocalBluetoothLeBroadcast mBroadcast;
@Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant;
+ private final MetricsFeatureProvider mMetricsFeatureProvider;
private List<BluetoothDevice> mTargetSinks = new ArrayList<>();
private final BluetoothLeBroadcast.Callback mBroadcastCallback =
@@ -119,9 +127,7 @@
new SubSettingLauncher(mContext)
.setDestination(AudioSharingDashboardFragment.class.getName())
.setSourceMetricsCategory(
- (mHostFragment != null
- && mHostFragment
- instanceof DashboardFragment)
+ (mHostFragment instanceof DashboardFragment)
? ((DashboardFragment) mHostFragment)
.getMetricsCategory()
: SettingsEnums.PAGE_UNKNOWN)
@@ -146,6 +152,7 @@
mLocalBtManager != null
? mLocalBtManager.getProfileManager().getLeAudioBroadcastAssistantProfile()
: null;
+ mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
}
/** Register callbacks for dialog handler */
@@ -191,6 +198,18 @@
List<AudioSharingDeviceItem> deviceItemsInSharingSession =
AudioSharingUtils.buildOrderedConnectedLeadAudioSharingDeviceItem(
mLocalBtManager, groupedDevices, /* filterByInSharing= */ true);
+ AudioSharingStopDialogFragment.DialogEventListener listener =
+ () -> {
+ cachedDevice.setActive();
+ AudioSharingUtils.stopBroadcasting(mLocalBtManager);
+ };
+ Pair<Integer, Object>[] eventData =
+ AudioSharingUtils.buildAudioSharingDialogEventData(
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY,
+ SettingsEnums.DIALOG_STOP_AUDIO_SHARING,
+ userTriggered,
+ deviceItemsInSharingSession.size(),
+ /* candidateDeviceCount= */ 0);
postOnMainThread(
() -> {
closeOpeningDialogsOtherThan(AudioSharingStopDialogFragment.tag());
@@ -198,10 +217,8 @@
mHostFragment,
deviceItemsInSharingSession,
cachedDevice,
- () -> {
- cachedDevice.setActive();
- AudioSharingUtils.stopBroadcasting(mLocalBtManager);
- });
+ listener,
+ eventData);
});
} else {
if (userTriggered) {
@@ -252,6 +269,20 @@
// Show audio sharing switch dialog when the third eligible (LE audio) remote device
// connected during a sharing session.
if (deviceItemsInSharingSession.size() >= 2) {
+ AudioSharingDisconnectDialogFragment.DialogEventListener listener =
+ (AudioSharingDeviceItem item) -> {
+ // Remove all sources from the device user clicked
+ removeSourceForGroup(item.getGroupId(), groupedDevices);
+ // Add current broadcast to the latest connected device
+ addSourceForGroup(groupId, groupedDevices);
+ };
+ Pair<Integer, Object>[] eventData =
+ AudioSharingUtils.buildAudioSharingDialogEventData(
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY,
+ SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE,
+ userTriggered,
+ deviceItemsInSharingSession.size(),
+ /* candidateDeviceCount= */ 1);
postOnMainThread(
() -> {
closeOpeningDialogsOtherThan(
@@ -260,16 +291,29 @@
mHostFragment,
deviceItemsInSharingSession,
cachedDevice,
- (AudioSharingDeviceItem item) -> {
- // Remove all sources from the device user clicked
- removeSourceForGroup(item.getGroupId(), groupedDevices);
- // Add current broadcast to the latest connected device
- addSourceForGroup(groupId, groupedDevices);
- });
+ listener,
+ eventData);
});
} else {
// Show audio sharing join dialog when the first or second eligible (LE audio)
// remote device connected during a sharing session.
+ AudioSharingJoinDialogFragment.DialogEventListener listener =
+ new AudioSharingJoinDialogFragment.DialogEventListener() {
+ @Override
+ public void onShareClick() {
+ addSourceForGroup(groupId, groupedDevices);
+ }
+
+ @Override
+ public void onCancelClick() {}
+ };
+ Pair<Integer, Object>[] eventData =
+ AudioSharingUtils.buildAudioSharingDialogEventData(
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY,
+ SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE,
+ userTriggered,
+ deviceItemsInSharingSession.size(),
+ /* candidateDeviceCount= */ 1);
postOnMainThread(
() -> {
closeOpeningDialogsOtherThan(AudioSharingJoinDialogFragment.tag());
@@ -277,15 +321,8 @@
mHostFragment,
deviceItemsInSharingSession,
cachedDevice,
- new AudioSharingJoinDialogFragment.DialogEventListener() {
- @Override
- public void onShareClick() {
- addSourceForGroup(groupId, groupedDevices);
- }
-
- @Override
- public void onCancelClick() {}
- });
+ listener,
+ eventData);
});
}
} else {
@@ -302,39 +339,43 @@
// Show audio sharing join dialog when the second eligible (LE audio) remote
// device connect and no sharing session.
if (deviceItems.size() == 1) {
+ AudioSharingJoinDialogFragment.DialogEventListener listener =
+ new AudioSharingJoinDialogFragment.DialogEventListener() {
+ @Override
+ public void onShareClick() {
+ mTargetSinks = new ArrayList<>();
+ for (List<CachedBluetoothDevice> devices :
+ groupedDevices.values()) {
+ for (CachedBluetoothDevice device : devices) {
+ mTargetSinks.add(device.getDevice());
+ }
+ }
+ Log.d(TAG, "Start broadcast with sinks = " + mTargetSinks.size());
+ if (mBroadcast != null) {
+ mBroadcast.startPrivateBroadcast();
+ }
+ }
+
+ @Override
+ public void onCancelClick() {
+ if (userTriggered) {
+ cachedDevice.setActive();
+ }
+ }
+ };
+
+ Pair<Integer, Object>[] eventData =
+ AudioSharingUtils.buildAudioSharingDialogEventData(
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY,
+ SettingsEnums.DIALOG_START_AUDIO_SHARING,
+ userTriggered,
+ /* deviceCountInSharing= */ 0,
+ /* candidateDeviceCount= */ 2);
postOnMainThread(
() -> {
closeOpeningDialogsOtherThan(AudioSharingJoinDialogFragment.tag());
AudioSharingJoinDialogFragment.show(
- mHostFragment,
- deviceItems,
- cachedDevice,
- new AudioSharingJoinDialogFragment.DialogEventListener() {
- @Override
- public void onShareClick() {
- mTargetSinks = new ArrayList<>();
- for (List<CachedBluetoothDevice> devices :
- groupedDevices.values()) {
- for (CachedBluetoothDevice device : devices) {
- mTargetSinks.add(device.getDevice());
- }
- }
- Log.d(
- TAG,
- "Start broadcast with sinks: "
- + mTargetSinks.size());
- if (mBroadcast != null) {
- mBroadcast.startPrivateBroadcast();
- }
- }
-
- @Override
- public void onCancelClick() {
- if (userTriggered) {
- cachedDevice.setActive();
- }
- }
- });
+ mHostFragment, deviceItems, cachedDevice, listener, eventData);
});
} else if (userTriggered) {
cachedDevice.setActive();
@@ -346,9 +387,12 @@
if (mHostFragment == null) return;
List<Fragment> fragments = mHostFragment.getChildFragmentManager().getFragments();
for (Fragment fragment : fragments) {
- if (fragment instanceof DialogFragment && !fragment.getTag().equals(tag)) {
+ if (fragment instanceof DialogFragment
+ && fragment.getTag() != null
+ && !fragment.getTag().equals(tag)) {
Log.d(TAG, "Remove staled opening dialog " + fragment.getTag());
((DialogFragment) fragment).dismiss();
+ logDialogDismissEvent(fragment);
}
}
}
@@ -365,6 +409,7 @@
&& AudioSharingUtils.getGroupId(device) == groupId) {
Log.d(TAG, "Remove staled opening dialog for group " + groupId);
((DialogFragment) fragment).dismiss();
+ logDialogDismissEvent(fragment);
}
}
}
@@ -382,6 +427,7 @@
"Remove staled opening dialog for device "
+ cachedDevice.getDevice().getAnonymizedAddress());
((DialogFragment) fragment).dismiss();
+ logDialogDismissEvent(fragment);
}
}
}
@@ -409,9 +455,9 @@
Log.d(TAG, "Fail to remove source for group " + groupId);
return;
}
- groupedDevices.get(groupId).stream()
+ groupedDevices.getOrDefault(groupId, ImmutableList.of()).stream()
.map(CachedBluetoothDevice::getDevice)
- .filter(device -> device != null)
+ .filter(Objects::nonNull)
.forEach(
device -> {
for (BluetoothLeBroadcastReceiveState source :
@@ -431,9 +477,9 @@
Log.d(TAG, "Fail to add source due to invalid group id, group = " + groupId);
return;
}
- groupedDevices.get(groupId).stream()
+ groupedDevices.getOrDefault(groupId, ImmutableList.of()).stream()
.map(CachedBluetoothDevice::getDevice)
- .filter(device -> device != null)
+ .filter(Objects::nonNull)
.forEach(
device ->
mAssistant.addSource(
@@ -449,4 +495,29 @@
private boolean isBroadcasting() {
return mBroadcast != null && mBroadcast.isEnabled(null);
}
+
+ private void logDialogDismissEvent(Fragment fragment) {
+ var unused =
+ ThreadUtils.postOnBackgroundThread(
+ () -> {
+ int pageId = SettingsEnums.PAGE_UNKNOWN;
+ if (fragment instanceof AudioSharingJoinDialogFragment) {
+ pageId =
+ ((AudioSharingJoinDialogFragment) fragment)
+ .getMetricsCategory();
+ } else if (fragment instanceof AudioSharingStopDialogFragment) {
+ pageId =
+ ((AudioSharingStopDialogFragment) fragment)
+ .getMetricsCategory();
+ } else if (fragment instanceof AudioSharingDisconnectDialogFragment) {
+ pageId =
+ ((AudioSharingDisconnectDialogFragment) fragment)
+ .getMetricsCategory();
+ }
+ mMetricsFeatureProvider.action(
+ mContext,
+ SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS,
+ pageId);
+ });
+ }
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
index e859693..5f6d84a 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragment.java
@@ -20,16 +20,20 @@
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.utils.ThreadUtils;
import java.util.List;
import java.util.Locale;
@@ -55,6 +59,7 @@
@Nullable private static DialogEventListener sListener;
@Nullable private static CachedBluetoothDevice sNewDevice;
+ private static Pair<Integer, Object>[] sEventData = new Pair[0];
@Override
public int getMetricsCategory() {
@@ -70,12 +75,14 @@
* @param deviceItems The existing connected device items in audio sharing session.
* @param newDevice The latest connected device triggered this dialog.
* @param listener The callback to handle the user action on this dialog.
+ * @param eventData The eventData to log with for dialog onClick events.
*/
public static void show(
@NonNull Fragment host,
@NonNull List<AudioSharingDeviceItem> deviceItems,
@NonNull CachedBluetoothDevice newDevice,
- @NonNull DialogEventListener listener) {
+ @NonNull DialogEventListener listener,
+ @NonNull Pair<Integer, Object>[] eventData) {
if (!AudioSharingUtils.isFeatureEnabled()) return;
FragmentManager manager = host.getChildFragmentManager();
AlertDialog dialog = AudioSharingDialogHelper.getDialogIfShowing(manager, TAG);
@@ -91,6 +98,7 @@
newGroupId));
sListener = listener;
sNewDevice = newDevice;
+ sEventData = eventData;
return;
} else {
Log.d(
@@ -101,10 +109,22 @@
+ "dismiss current dialog.",
newGroupId));
dialog.dismiss();
+ var unused =
+ ThreadUtils.postOnBackgroundThread(
+ () ->
+ FeatureFactory.getFeatureFactory()
+ .getMetricsFeatureProvider()
+ .action(
+ dialog.getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS,
+ SettingsEnums
+ .DIALOG_AUDIO_SHARING_SWITCH_DEVICE));
}
}
sListener = listener;
sNewDevice = newDevice;
+ sEventData = eventData;
Log.d(TAG, "Show up the dialog.");
final Bundle bundle = new Bundle();
bundle.putParcelableList(BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS, deviceItems);
@@ -125,28 +145,54 @@
return sNewDevice;
}
+ /** Test only: get the event data passed to the dialog. */
+ @VisibleForTesting
+ protected @NonNull Pair<Integer, Object>[] getEventData() {
+ return sEventData;
+ }
+
@Override
+ @NonNull
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Bundle arguments = requireArguments();
List<AudioSharingDeviceItem> deviceItems =
arguments.getParcelable(BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS, List.class);
- return AudioSharingDialogFactory.newBuilder(getActivity())
- .setTitle(R.string.audio_sharing_disconnect_dialog_title)
- .setTitleIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
- .setIsCustomBodyEnabled(true)
- .setCustomMessage(R.string.audio_sharing_dialog_disconnect_content)
- .setCustomDeviceActions(
- new AudioSharingDeviceAdapter(
- getContext(),
- deviceItems,
- (AudioSharingDeviceItem item) -> {
- if (sListener != null) {
- sListener.onItemClick(item);
- }
+ AudioSharingDialogFactory.DialogBuilder builder =
+ AudioSharingDialogFactory.newBuilder(getActivity())
+ .setTitle(R.string.audio_sharing_disconnect_dialog_title)
+ .setTitleIcon(com.android.settingslib.R.drawable.ic_bt_le_audio_sharing)
+ .setIsCustomBodyEnabled(true)
+ .setCustomMessage(R.string.audio_sharing_dialog_disconnect_content)
+ .setCustomNegativeButton(
+ com.android.settings.R.string.cancel,
+ v -> {
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
+ sEventData);
dismiss();
- },
- AudioSharingDeviceAdapter.ActionType.REMOVE))
- .setCustomNegativeButton(com.android.settings.R.string.cancel, v -> dismiss())
- .build();
+ });
+ if (deviceItems == null) {
+ Log.d(TAG, "Create dialog error: null deviceItems");
+ return builder.build();
+ }
+ builder.setCustomDeviceActions(
+ new AudioSharingDeviceAdapter(
+ getContext(),
+ deviceItems,
+ (AudioSharingDeviceItem item) -> {
+ if (sListener != null) {
+ sListener.onItemClick(item);
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
+ sEventData);
+ }
+ dismiss();
+ },
+ AudioSharingDeviceAdapter.ActionType.REMOVE));
+ return builder.build();
}
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
index 4982179..7eebbcb 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragment.java
@@ -20,9 +20,11 @@
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
@@ -52,6 +54,7 @@
@Nullable private static DialogEventListener sListener;
@Nullable private static CachedBluetoothDevice sNewDevice;
+ private static Pair<Integer, Object>[] sEventData = new Pair[0];
@Override
public int getMetricsCategory() {
@@ -69,16 +72,19 @@
* @param deviceItems The existing connected device items eligible for audio sharing.
* @param newDevice The latest connected device triggered this dialog.
* @param listener The callback to handle the user action on this dialog.
+ * @param eventData The eventData to log with for dialog onClick events.
*/
public static void show(
@NonNull Fragment host,
@NonNull List<AudioSharingDeviceItem> deviceItems,
@NonNull CachedBluetoothDevice newDevice,
- @NonNull DialogEventListener listener) {
+ @NonNull DialogEventListener listener,
+ @NonNull Pair<Integer, Object>[] eventData) {
if (!AudioSharingUtils.isFeatureEnabled()) return;
final FragmentManager manager = host.getChildFragmentManager();
sListener = listener;
sNewDevice = newDevice;
+ sEventData = eventData;
AlertDialog dialog = AudioSharingDialogHelper.getDialogIfShowing(manager, TAG);
if (dialog != null) {
Log.d(TAG, "Dialog is showing, update the content.");
@@ -104,7 +110,14 @@
return sNewDevice;
}
+ /** Test only: get the event data passed to the dialog. */
+ @VisibleForTesting
+ protected @NonNull Pair<Integer, Object>[] getEventData() {
+ return sEventData;
+ }
+
@Override
+ @NonNull
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Bundle arguments = requireArguments();
List<AudioSharingDeviceItem> deviceItems =
@@ -121,6 +134,11 @@
v -> {
if (sListener != null) {
sListener.onShareClick();
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
+ sEventData);
}
dismiss();
})
@@ -129,11 +147,20 @@
v -> {
if (sListener != null) {
sListener.onCancelClick();
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
+ sEventData);
}
dismiss();
})
.build();
- updateDialog(deviceItems, newDeviceName, dialog);
+ if (deviceItems == null) {
+ Log.d(TAG, "Fail to create dialog: null deviceItems");
+ } else {
+ updateDialog(deviceItems, newDeviceName, dialog);
+ }
dialog.show();
AudioSharingDialogHelper.updateMessageStyle(dialog);
return dialog;
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
index affd54a..beac4b0 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragment.java
@@ -20,16 +20,20 @@
import android.app.settings.SettingsEnums;
import android.os.Bundle;
import android.util.Log;
+import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import com.android.settings.R;
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.utils.ThreadUtils;
import com.google.common.collect.Iterables;
@@ -52,6 +56,7 @@
@Nullable private static DialogEventListener sListener;
@Nullable private static CachedBluetoothDevice sCachedDevice;
+ private static Pair<Integer, Object>[] sEventData = new Pair[0];
@Override
public int getMetricsCategory() {
@@ -67,12 +72,14 @@
* @param deviceItems The existing connected device items in audio sharing session.
* @param newDevice The latest connected device triggered this dialog.
* @param listener The callback to handle the user action on this dialog.
+ * @param eventData The eventData to log with for dialog onClick events.
*/
public static void show(
@NonNull Fragment host,
@NonNull List<AudioSharingDeviceItem> deviceItems,
@NonNull CachedBluetoothDevice newDevice,
- @NonNull DialogEventListener listener) {
+ @NonNull DialogEventListener listener,
+ @NonNull Pair<Integer, Object>[] eventData) {
if (!AudioSharingUtils.isFeatureEnabled()) return;
final FragmentManager manager = host.getChildFragmentManager();
AlertDialog dialog = AudioSharingDialogHelper.getDialogIfShowing(manager, TAG);
@@ -88,6 +95,7 @@
newGroupId));
sListener = listener;
sCachedDevice = newDevice;
+ sEventData = eventData;
return;
} else {
Log.d(
@@ -98,10 +106,21 @@
+ "dismiss current dialog.",
newGroupId));
dialog.dismiss();
+ var unused =
+ ThreadUtils.postOnBackgroundThread(
+ () ->
+ FeatureFactory.getFeatureFactory()
+ .getMetricsFeatureProvider()
+ .action(
+ dialog.getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS,
+ SettingsEnums.DIALOG_STOP_AUDIO_SHARING));
}
}
sListener = listener;
sCachedDevice = newDevice;
+ sEventData = eventData;
Log.d(TAG, "Show up the dialog.");
final Bundle bundle = new Bundle();
bundle.putParcelableList(BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS, deviceItems);
@@ -121,23 +140,34 @@
return sCachedDevice;
}
+ /** Test only: get the event data passed to the dialog. */
+ @VisibleForTesting
+ protected @NonNull Pair<Integer, Object>[] getEventData() {
+ return sEventData;
+ }
+
@Override
+ @NonNull
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
Bundle arguments = requireArguments();
List<AudioSharingDeviceItem> deviceItems =
arguments.getParcelable(BUNDLE_KEY_DEVICE_TO_DISCONNECT_ITEMS, List.class);
String newDeviceName = arguments.getString(BUNDLE_KEY_NEW_DEVICE_NAME);
- String customMessage =
- deviceItems.size() == 1
- ? getString(
- R.string.audio_sharing_stop_dialog_content,
- Iterables.getOnlyElement(deviceItems).getName())
- : (deviceItems.size() == 2
- ? getString(
- R.string.audio_sharing_stop_dialog_with_two_content,
- deviceItems.get(0).getName(),
- deviceItems.get(1).getName())
- : getString(R.string.audio_sharing_stop_dialog_with_more_content));
+ String customMessage = "";
+ if (deviceItems != null) {
+ customMessage =
+ deviceItems.size() == 1
+ ? getString(
+ R.string.audio_sharing_stop_dialog_content,
+ Iterables.getOnlyElement(deviceItems).getName())
+ : (deviceItems.size() == 2
+ ? getString(
+ R.string.audio_sharing_stop_dialog_with_two_content,
+ deviceItems.get(0).getName(),
+ deviceItems.get(1).getName())
+ : getString(
+ R.string.audio_sharing_stop_dialog_with_more_content));
+ }
AlertDialog dialog =
AudioSharingDialogFactory.newBuilder(getActivity())
.setTitle(
@@ -150,10 +180,21 @@
(dlg, which) -> {
if (sListener != null) {
sListener.onStopSharingClick();
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED,
+ sEventData);
}
})
.setNegativeButton(
- com.android.settings.R.string.cancel, (dlg, which) -> dismiss())
+ com.android.settings.R.string.cancel,
+ (dlg, which) ->
+ mMetricsFeatureProvider.action(
+ getContext(),
+ SettingsEnums
+ .ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED,
+ sEventData))
.build();
dialog.show();
AudioSharingDialogHelper.updateMessageStyle(dialog);
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
index 475be85..5022579 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarController.java
@@ -16,6 +16,7 @@
package com.android.settings.connecteddevice.audiosharing;
+import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeBroadcast;
@@ -29,24 +30,27 @@
import android.content.IntentFilter;
import android.util.FeatureFlagUtils;
import android.util.Log;
+import android.util.Pair;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.fragment.app.Fragment;
import androidx.lifecycle.DefaultLifecycleObserver;
import androidx.lifecycle.LifecycleOwner;
import com.android.settings.bluetooth.Utils;
import com.android.settings.core.BasePreferenceController;
-import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.SettingsMainSwitchBar;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
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 com.android.settingslib.utils.ThreadUtils;
import com.google.common.collect.ImmutableList;
@@ -56,6 +60,7 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -91,14 +96,15 @@
@Nullable private final LocalBluetoothProfileManager mProfileManager;
@Nullable private final LocalBluetoothLeBroadcast mBroadcast;
@Nullable private final LocalBluetoothLeBroadcastAssistant mAssistant;
- @Nullable private DashboardFragment mFragment;
+ @Nullable private Fragment mFragment;
private final Executor mExecutor;
+ private final MetricsFeatureProvider mMetricsFeatureProvider;
private final OnAudioSharingStateChangedListener mListener;
private Map<Integer, List<CachedBluetoothDevice>> mGroupedConnectedDevices = new HashMap<>();
private List<BluetoothDevice> mTargetActiveSinks = new ArrayList<>();
private List<AudioSharingDeviceItem> mDeviceItemsForSharing = new ArrayList<>();
@VisibleForTesting IntentFilter mIntentFilter;
- private AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
+ private final AtomicBoolean mCallbacksRegistered = new AtomicBoolean(false);
@VisibleForTesting
BroadcastReceiver mReceiver =
@@ -110,7 +116,8 @@
}
};
- private final BluetoothLeBroadcast.Callback mBroadcastCallback =
+ @VisibleForTesting
+ protected final BluetoothLeBroadcast.Callback mBroadcastCallback =
new BluetoothLeBroadcast.Callback() {
@Override
public void onBroadcastStarted(int reason, int broadcastId) {
@@ -182,7 +189,7 @@
public void onPlaybackStopped(int reason, int broadcastId) {}
};
- private BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
+ private final BluetoothLeBroadcastAssistant.Callback mBroadcastAssistantCallback =
new BluetoothLeBroadcastAssistant.Callback() {
@Override
public void onSearchStarted(int reason) {}
@@ -251,9 +258,9 @@
@Override
public void onReceiveStateChanged(
- BluetoothDevice sink,
+ @NonNull BluetoothDevice sink,
int sourceId,
- BluetoothLeBroadcastReceiveState state) {}
+ @NonNull BluetoothLeBroadcastReceiveState state) {}
};
AudioSharingSwitchBarController(
@@ -273,6 +280,7 @@
? null
: mProfileManager.getLeAudioBroadcastAssistantProfile();
mExecutor = Executors.newSingleThreadExecutor();
+ mMetricsFeatureProvider = FeatureFactory.getFeatureFactory().getMetricsFeatureProvider();
}
@Override
@@ -378,7 +386,7 @@
*
* @param fragment The fragment to host the {@link AudioSharingSwitchBarController} dialog.
*/
- public void init(DashboardFragment fragment) {
+ public void init(@NonNull Fragment fragment) {
this.mFragment = fragment;
}
@@ -494,34 +502,58 @@
}
private void handleOnBroadcastReady() {
- AudioSharingUtils.addSourceToTargetSinks(mTargetActiveSinks, mBtManager);
- mTargetActiveSinks.clear();
+ Pair<Integer, Object>[] eventData =
+ AudioSharingUtils.buildAudioSharingDialogEventData(
+ SettingsEnums.AUDIO_SHARING_SETTINGS,
+ SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE,
+ /* userTriggered= */ false,
+ /* deviceCountInSharing= */ mTargetActiveSinks.isEmpty() ? 0 : 1,
+ /* candidateDeviceCount= */ mDeviceItemsForSharing.size());
+ if (!mTargetActiveSinks.isEmpty()) {
+ Log.d(TAG, "handleOnBroadcastReady: automatically add source to active sinks.");
+ AudioSharingUtils.addSourceToTargetSinks(mTargetActiveSinks, mBtManager);
+ mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_AUTO_JOIN_AUDIO_SHARING);
+ mTargetActiveSinks.clear();
+ }
if (mFragment == null) {
- Log.w(TAG, "Dialog fail to show due to null fragment.");
+ Log.d(TAG, "handleOnBroadcastReady: dialog fail to show due to null fragment.");
mGroupedConnectedDevices.clear();
mDeviceItemsForSharing.clear();
return;
}
+ showDialog(eventData);
+ }
+
+ private void showDialog(Pair<Integer, Object>[] eventData) {
+ AudioSharingDialogFragment.DialogEventListener listener =
+ new AudioSharingDialogFragment.DialogEventListener() {
+ @Override
+ public void onItemClick(@NonNull AudioSharingDeviceItem item) {
+ AudioSharingUtils.addSourceToTargetSinks(
+ mGroupedConnectedDevices
+ .getOrDefault(item.getGroupId(), ImmutableList.of())
+ .stream()
+ .map(CachedBluetoothDevice::getDevice)
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList()),
+ mBtManager);
+ mGroupedConnectedDevices.clear();
+ mDeviceItemsForSharing.clear();
+ }
+
+ @Override
+ public void onCancelClick() {
+ mGroupedConnectedDevices.clear();
+ mDeviceItemsForSharing.clear();
+ }
+ };
AudioSharingUtils.postOnMainThread(
mContext,
() -> {
// Check nullability to pass NullAway check
if (mFragment != null) {
AudioSharingDialogFragment.show(
- mFragment,
- mDeviceItemsForSharing,
- item -> {
- AudioSharingUtils.addSourceToTargetSinks(
- mGroupedConnectedDevices
- .getOrDefault(
- item.getGroupId(), ImmutableList.of())
- .stream()
- .map(CachedBluetoothDevice::getDevice)
- .collect(Collectors.toList()),
- mBtManager);
- mGroupedConnectedDevices.clear();
- mDeviceItemsForSharing.clear();
- });
+ mFragment, mDeviceItemsForSharing, listener, eventData);
}
});
}
diff --git a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
index f63717e..29f605c 100644
--- a/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
+++ b/src/com/android/settings/connecteddevice/audiosharing/AudioSharingUtils.java
@@ -16,6 +16,12 @@
package com.android.settings.connecteddevice.audiosharing;
+import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT;
+import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING;
+import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID;
+import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID;
+import static com.android.settings.connecteddevice.audiosharing.AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED;
+
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
@@ -25,6 +31,7 @@
import android.content.Context;
import android.provider.Settings;
import android.util.Log;
+import android.util.Pair;
import android.widget.Toast;
import androidx.annotation.NonNull;
@@ -54,6 +61,14 @@
private static final String TAG = "AudioSharingUtils";
private static final boolean DEBUG = BluetoothUtils.D;
+ public enum MetricKey {
+ METRIC_KEY_SOURCE_PAGE_ID,
+ METRIC_KEY_PAGE_ID,
+ METRIC_KEY_USER_TRIGGERED,
+ METRIC_KEY_DEVICE_COUNT_IN_SHARING,
+ METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ }
+
/**
* Fetch {@link CachedBluetoothDevice}s connected to the broadcast assistant. The devices are
* grouped by CSIP group id.
@@ -121,7 +136,7 @@
boolean filterByInSharing) {
List<CachedBluetoothDevice> orderedDevices = new ArrayList<>();
for (List<CachedBluetoothDevice> devices : groupedConnectedDevices.values()) {
- @Nullable CachedBluetoothDevice leadDevice = getLeadDevice(devices);
+ CachedBluetoothDevice leadDevice = getLeadDevice(devices);
if (leadDevice == null) {
Log.d(TAG, "Skip due to no lead device");
continue;
@@ -206,7 +221,7 @@
return buildOrderedConnectedLeadDevices(
localBtManager, groupedConnectedDevices, filterByInSharing)
.stream()
- .map(device -> buildAudioSharingDeviceItem(device))
+ .map(AudioSharingUtils::buildAudioSharingDeviceItem)
.collect(Collectors.toList());
}
@@ -315,8 +330,9 @@
manager.getProfileManager().getLeAudioBroadcastProfile();
if (broadcast == null) {
Log.d(TAG, "Skip stop broadcasting due to broadcast profile is null");
+ } else {
+ broadcast.stopBroadcast(broadcast.getLatestBroadcastId());
}
- broadcast.stopBroadcast(broadcast.getLatestBroadcastId());
}
/**
@@ -378,9 +394,32 @@
return false;
}
VolumeControlProfile vc = profileManager.getVolumeControlProfile();
- if (vc == null || !vc.isProfileReady()) {
- return false;
- }
- return true;
+ return vc != null && vc.isProfileReady();
+ }
+
+ /**
+ * Build audio sharing dialog log event data
+ *
+ * @param sourcePageId The source page id on which the dialog is shown. *
+ * @param pageId The page id of the dialog.
+ * @param userTriggered Indicates whether the dialog is triggered by user click.
+ * @param deviceCountInSharing The count of the devices joining the audio sharing.
+ * @param candidateDeviceCount The count of the eligible devices to join the audio sharing.
+ * @return The event data to be attached to the audio sharing action logs.
+ */
+ @NonNull
+ public static Pair<Integer, Object>[] buildAudioSharingDialogEventData(
+ int sourcePageId,
+ int pageId,
+ boolean userTriggered,
+ int deviceCountInSharing,
+ int candidateDeviceCount) {
+ return new Pair[] {
+ Pair.create(METRIC_KEY_SOURCE_PAGE_ID.ordinal(), sourcePageId),
+ Pair.create(METRIC_KEY_PAGE_ID.ordinal(), pageId),
+ Pair.create(METRIC_KEY_USER_TRIGGERED.ordinal(), userTriggered ? 1 : 0),
+ Pair.create(METRIC_KEY_DEVICE_COUNT_IN_SHARING.ordinal(), deviceCountInSharing),
+ Pair.create(METRIC_KEY_CANDIDATE_DEVICE_COUNT.ordinal(), candidateDeviceCount)
+ };
}
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
index 4336e77..c63a1a9 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogFragmentTest.java
@@ -18,11 +18,17 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
+import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothStatusCodes;
+import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.util.Pair;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
@@ -34,6 +40,7 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.flags.Flags;
@@ -72,20 +79,33 @@
new AudioSharingDeviceItem(TEST_DEVICE_NAME2, /* groupId= */ 2, /* isActive= */ false);
private static final AudioSharingDeviceItem TEST_DEVICE_ITEM3 =
new AudioSharingDeviceItem(TEST_DEVICE_NAME3, /* groupId= */ 3, /* isActive= */ false);
+ private static final AudioSharingDialogFragment.DialogEventListener EMPTY_EVENT_LISTENER =
+ new AudioSharingDialogFragment.DialogEventListener() {
+ @Override
+ public void onItemClick(AudioSharingDeviceItem item) {}
+
+ @Override
+ public void onCancelClick() {}
+ };
+ private static final Pair<Integer, Object> TEST_EVENT_DATA = Pair.create(1, 1);
+ private static final Pair<Integer, Object>[] TEST_EVENT_DATA_LIST =
+ new Pair[] {TEST_EVENT_DATA};
private Fragment mParent;
private AudioSharingDialogFragment mFragment;
- private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+ private FakeFeatureFactory mFeatureFactory;
@Before
public void setUp() {
ShadowAlertDialogCompat.reset();
- mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- mShadowBluetoothAdapter.setEnabled(true);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
+ ShadowBluetoothAdapter shadowBluetoothAdapter =
+ Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ shadowBluetoothAdapter.setEnabled(true);
+ shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
+ shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
mFragment = new AudioSharingDialogFragment();
mParent = new Fragment();
FragmentController.setupFragment(
@@ -93,9 +113,16 @@
}
@Test
+ public void getMetricsCategory_correctValue() {
+ assertThat(mFragment.getMetricsCategory())
+ .isEqualTo(SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE);
+ }
+
+ @Test
public void onCreateDialog_flagOff_dialogNotExist() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, new ArrayList<>(), (item) -> {});
+ AudioSharingDialogFragment.show(
+ mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
@@ -105,14 +132,20 @@
@Test
public void onCreateDialog_flagOn_noConnectedDevice() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, new ArrayList<>(), (item) -> {});
+ AudioSharingDialogFragment.show(
+ mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+ assertThat(dialog).isNotNull();
TextView description = dialog.findViewById(R.id.description_text);
+ assertThat(description).isNotNull();
ImageView image = dialog.findViewById(R.id.description_image);
+ assertThat(image).isNotNull();
Button shareBtn = dialog.findViewById(R.id.positive_btn);
+ assertThat(shareBtn).isNotNull();
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
+ assertThat(cancelBtn).isNotNull();
assertThat(dialog.isShowing()).isTrue();
assertThat(description.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(description.getText().toString())
@@ -125,13 +158,22 @@
@Test
public void onCreateDialog_noConnectedDevice_dialogDismiss() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, new ArrayList<>(), (item) -> {});
+ AudioSharingDialogFragment.show(
+ mParent, new ArrayList<>(), EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(android.R.id.button2).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(android.R.id.button2);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
shadowMainLooper().idle();
assertThat(dialog.isShowing()).isFalse();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
@@ -139,15 +181,21 @@
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
list.add(TEST_DEVICE_ITEM1);
- mFragment.show(mParent, list, (item) -> {});
+ AudioSharingDialogFragment.show(mParent, list, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+ assertThat(dialog).isNotNull();
TextView title = dialog.findViewById(R.id.title_text);
+ assertThat(title).isNotNull();
TextView description = dialog.findViewById(R.id.description_text);
+ assertThat(description).isNotNull();
ImageView image = dialog.findViewById(R.id.description_image);
+ assertThat(image).isNotNull();
Button shareBtn = dialog.findViewById(R.id.positive_btn);
+ assertThat(shareBtn).isNotNull();
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
+ assertThat(cancelBtn).isNotNull();
assertThat(dialog.isShowing()).isTrue();
assertThat(title.getText().toString())
.isEqualTo(
@@ -166,12 +214,22 @@
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
list.add(TEST_DEVICE_ITEM1);
- mFragment.show(mParent, list, (item) -> {});
+ AudioSharingDialogFragment.show(mParent, list, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(R.id.negative_btn).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(R.id.negative_btn);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
+ shadowMainLooper().idle();
+
assertThat(dialog.isShowing()).isFalse();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
@@ -180,13 +238,35 @@
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
list.add(TEST_DEVICE_ITEM1);
AtomicBoolean isShareBtnClicked = new AtomicBoolean(false);
- mFragment.show(mParent, list, (item) -> isShareBtnClicked.set(true));
+ AudioSharingDialogFragment.show(
+ mParent,
+ list,
+ new AudioSharingDialogFragment.DialogEventListener() {
+ @Override
+ public void onItemClick(AudioSharingDeviceItem item) {
+ isShareBtnClicked.set(true);
+ }
+
+ @Override
+ public void onCancelClick() {}
+ },
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(R.id.positive_btn).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(R.id.positive_btn);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
+ shadowMainLooper().idle();
+
assertThat(dialog.isShowing()).isFalse();
assertThat(isShareBtnClicked.get()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
@@ -196,15 +276,21 @@
list.add(TEST_DEVICE_ITEM1);
list.add(TEST_DEVICE_ITEM2);
list.add(TEST_DEVICE_ITEM3);
- mFragment.show(mParent, list, (item) -> {});
+ AudioSharingDialogFragment.show(mParent, list, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+ assertThat(dialog).isNotNull();
TextView description = dialog.findViewById(R.id.description_text);
+ assertThat(description).isNotNull();
ImageView image = dialog.findViewById(R.id.description_image);
+ assertThat(image).isNotNull();
Button shareBtn = dialog.findViewById(R.id.positive_btn);
+ assertThat(shareBtn).isNotNull();
Button cancelBtn = dialog.findViewById(R.id.negative_btn);
+ assertThat(cancelBtn).isNotNull();
RecyclerView recyclerView = dialog.findViewById(R.id.device_btn_list);
+ assertThat(recyclerView).isNotNull();
assertThat(dialog.isShowing()).isTrue();
assertThat(description.getVisibility()).isEqualTo(View.VISIBLE);
assertThat(description.getText().toString())
@@ -223,11 +309,35 @@
list.add(TEST_DEVICE_ITEM1);
list.add(TEST_DEVICE_ITEM2);
list.add(TEST_DEVICE_ITEM3);
- mFragment.show(mParent, list, (item) -> {});
+ AtomicBoolean isCancelBtnClicked = new AtomicBoolean(false);
+ AudioSharingDialogFragment.show(
+ mParent,
+ list,
+ new AudioSharingDialogFragment.DialogEventListener() {
+ @Override
+ public void onItemClick(AudioSharingDeviceItem item) {}
+
+ @Override
+ public void onCancelClick() {
+ isCancelBtnClicked.set(true);
+ }
+ },
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(R.id.negative_btn).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(R.id.negative_btn);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
+ shadowMainLooper().idle();
+
assertThat(dialog.isShowing()).isFalse();
+ assertThat(isCancelBtnClicked.get()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
}
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 570af1f..633bc06 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDialogHandlerTest.java
@@ -24,6 +24,7 @@
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.BluetoothLeBroadcastReceiveState;
@@ -32,6 +33,7 @@
import android.content.Context;
import android.os.Looper;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.util.Pair;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
@@ -39,6 +41,7 @@
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.bluetooth.Utils;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settings.testutils.shadow.ShadowBluetoothUtils;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -51,6 +54,7 @@
import com.android.settingslib.flags.Flags;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
import com.google.common.truth.Correspondence;
import org.junit.Before;
@@ -87,6 +91,7 @@
Correspondence.from(
(Fragment fragment, String tag) ->
fragment instanceof DialogFragment
+ && ((DialogFragment) fragment).getTag() != null
&& ((DialogFragment) fragment).getTag().equals(tag),
"is equal to");
@@ -107,20 +112,22 @@
private Fragment mParentFragment;
@Mock private BluetoothLeBroadcastReceiveState mState;
private Context mContext;
- private ShadowBluetoothAdapter mShadowBluetoothAdapter;
private AudioSharingDialogHandler mHandler;
+ private FakeFeatureFactory mFeatureFactory;
@Before
public void setup() {
mContext = ApplicationProvider.getApplicationContext();
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
mLocalBtManager = Utils.getLocalBtManager(mContext);
- mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- mShadowBluetoothAdapter.setEnabled(true);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
+ ShadowBluetoothAdapter shadowBluetoothAdapter =
+ Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ shadowBluetoothAdapter.setEnabled(true);
+ shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
+ shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
when(mLocalBtManager.getProfileManager()).thenReturn(mLocalBtProfileManager);
when(mLocalBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
@@ -183,9 +190,33 @@
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingStopDialogFragment.tag());
+
+ AudioSharingStopDialogFragment fragment =
+ (AudioSharingStopDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_STOP_AUDIO_SHARING),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 0));
}
@Test
@@ -211,9 +242,33 @@
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingJoinDialogFragment.tag());
+
+ AudioSharingJoinDialogFragment fragment =
+ (AudioSharingJoinDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_START_AUDIO_SHARING),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 0),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 2));
}
@Test
@@ -227,9 +282,33 @@
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingJoinDialogFragment.tag());
+
+ AudioSharingJoinDialogFragment fragment =
+ (AudioSharingJoinDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 1));
}
@Test
@@ -245,9 +324,33 @@
when(mAssistant.getAllSources(mDevice4)).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ true);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingDisconnectDialogFragment.tag());
+
+ AudioSharingDisconnectDialogFragment fragment =
+ (AudioSharingDisconnectDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 2),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 1));
}
@Test
@@ -273,9 +376,33 @@
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice2, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingStopDialogFragment.tag());
+
+ AudioSharingStopDialogFragment fragment =
+ (AudioSharingStopDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_STOP_AUDIO_SHARING),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 0),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 0));
}
@Test
@@ -301,9 +428,33 @@
when(mAssistant.getAllSources(any())).thenReturn(ImmutableList.of());
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingJoinDialogFragment.tag());
+
+ AudioSharingJoinDialogFragment fragment =
+ (AudioSharingJoinDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_START_AUDIO_SHARING),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 0),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 0),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 2));
}
@Test
@@ -317,9 +468,33 @@
when(mAssistant.getAllSources(mDevice3)).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingJoinDialogFragment.tag());
+
+ AudioSharingJoinDialogFragment fragment =
+ (AudioSharingJoinDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 0),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 1));
}
@Test
@@ -334,9 +509,33 @@
when(mAssistant.getAllSources(mDevice4)).thenReturn(ImmutableList.of(mState));
mHandler.handleDeviceConnected(mCachedDevice1, /* userTriggered= */ false);
shadowOf(Looper.getMainLooper()).idle();
- assertThat(mParentFragment.getChildFragmentManager().getFragments())
+ List<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
.comparingElementsUsing(TAG_EQUALS)
.containsExactly(AudioSharingDisconnectDialogFragment.tag());
+
+ AudioSharingDisconnectDialogFragment fragment =
+ (AudioSharingDisconnectDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.SETTINGS_CONNECTED_DEVICE_CATEGORY),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 0),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 2),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 1));
}
@Test
@@ -357,6 +556,11 @@
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_START_AUDIO_SHARING);
}
@Test
@@ -377,6 +581,11 @@
mHandler.closeOpeningDialogsForNonLeaDevice(mCachedDevice2);
shadowOf(Looper.getMainLooper()).idle();
assertThat(mParentFragment.getChildFragmentManager().getFragments()).isEmpty();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ mContext,
+ SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS,
+ SettingsEnums.DIALOG_STOP_AUDIO_SHARING);
}
private void setUpBroadcast(boolean isBroadcasting) {
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
index 348efbe..481c78d 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingDisconnectDialogFragmentTest.java
@@ -18,13 +18,21 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
+import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothStatusCodes;
+import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.util.Pair;
+import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AlertDialog;
@@ -33,6 +41,7 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -78,15 +87,19 @@
new AudioSharingDeviceItem(TEST_DEVICE_NAME2, TEST_GROUP_ID2, /* isActive= */ false);
private static final AudioSharingDeviceItem TEST_DEVICE_ITEM3 =
new AudioSharingDeviceItem(TEST_DEVICE_NAME3, TEST_GROUP_ID3, /* isActive= */ false);
+ private static final AudioSharingDisconnectDialogFragment.DialogEventListener
+ EMPTY_EVENT_LISTENER = (AudioSharingDeviceItem item) -> {};
+ private static final Pair<Integer, Object> TEST_EVENT_DATA = Pair.create(1, 1);
+ private static final Pair<Integer, Object>[] TEST_EVENT_DATA_LIST =
+ new Pair[] {TEST_EVENT_DATA};
@Mock private BluetoothDevice mDevice1;
@Mock private BluetoothDevice mDevice3;
-
@Mock private CachedBluetoothDevice mCachedDevice1;
@Mock private CachedBluetoothDevice mCachedDevice3;
+ private FakeFeatureFactory mFeatureFactory;
private Fragment mParent;
private AudioSharingDisconnectDialogFragment mFragment;
- private ShadowBluetoothAdapter mShadowBluetoothAdapter;
private ArrayList<AudioSharingDeviceItem> mDeviceItems = new ArrayList<>();
@Before
@@ -96,12 +109,14 @@
latestAlertDialog.dismiss();
ShadowAlertDialogCompat.reset();
}
- mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- mShadowBluetoothAdapter.setEnabled(true);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
+ ShadowBluetoothAdapter shadowBluetoothAdapter =
+ Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ shadowBluetoothAdapter.setEnabled(true);
+ shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
+ shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mDevice1.getAnonymizedAddress()).thenReturn(TEST_ADDRESS1);
when(mDevice3.getAnonymizedAddress()).thenReturn(TEST_ADDRESS3);
when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
@@ -117,12 +132,19 @@
}
@Test
+ public void getMetricsCategory_correctValue() {
+ assertThat(mFragment.getMetricsCategory())
+ .isEqualTo(SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE);
+ }
+
+ @Test
public void onCreateDialog_flagOff_dialogNotExist() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mDeviceItems = new ArrayList<>();
mDeviceItems.add(TEST_DEVICE_ITEM1);
mDeviceItems.add(TEST_DEVICE_ITEM2);
- mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> {});
+ AudioSharingDisconnectDialogFragment.show(
+ mParent, mDeviceItems, mCachedDevice3, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
@@ -135,12 +157,15 @@
mDeviceItems = new ArrayList<>();
mDeviceItems.add(TEST_DEVICE_ITEM1);
mDeviceItems.add(TEST_DEVICE_ITEM2);
- mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> {});
+ AudioSharingDisconnectDialogFragment.show(
+ mParent, mDeviceItems, mCachedDevice3, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+ assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
RecyclerView view = dialog.findViewById(R.id.device_btn_list);
+ assertThat(view).isNotNull();
assertThat(view.getAdapter().getItemCount()).isEqualTo(2);
}
@@ -150,12 +175,14 @@
mDeviceItems = new ArrayList<>();
mDeviceItems.add(TEST_DEVICE_ITEM1);
mDeviceItems.add(TEST_DEVICE_ITEM2);
- mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> {});
+ AudioSharingDisconnectDialogFragment.show(
+ mParent, mDeviceItems, mCachedDevice3, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
- AtomicBoolean isItemBtnClicked = new AtomicBoolean(false);
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+ assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
RecyclerView view = dialog.findViewById(R.id.device_btn_list);
+ assertThat(view).isNotNull();
assertThat(view.getAdapter().getItemCount()).isEqualTo(2);
Button btn1 =
view.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.device_button);
@@ -173,37 +200,71 @@
TEST_DEVICE_NAME2));
// Update dialog content for device with same group
- mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> isItemBtnClicked.set(true));
+ AtomicBoolean isItemBtnClicked = new AtomicBoolean(false);
+ AudioSharingDisconnectDialogFragment.show(
+ mParent,
+ mDeviceItems,
+ mCachedDevice3,
+ (AudioSharingDeviceItem item) -> isItemBtnClicked.set(true),
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog.isShowing()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider, times(0))
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS),
+ eq(SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE));
+
btn1 = view.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.device_button);
btn1.performClick();
+ shadowMainLooper().idle();
+ assertThat(dialog.isShowing()).isFalse();
assertThat(isItemBtnClicked.get()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
- public void onCreateDialog_dialogIsShowingForNewGroup_updateDialog() {
+ public void onCreateDialog_dialogIsShowingForNewGroup_showNewDialog() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
mDeviceItems = new ArrayList<>();
mDeviceItems.add(TEST_DEVICE_ITEM1);
mDeviceItems.add(TEST_DEVICE_ITEM2);
- mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> {});
+ AudioSharingDisconnectDialogFragment.show(
+ mParent, mDeviceItems, mCachedDevice3, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+ assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
RecyclerView view = dialog.findViewById(R.id.device_btn_list);
+ assertThat(view).isNotNull();
assertThat(view.getAdapter().getItemCount()).isEqualTo(2);
// Show new dialog for device with new group
ArrayList<AudioSharingDeviceItem> newDeviceItems = new ArrayList<>();
newDeviceItems.add(TEST_DEVICE_ITEM2);
newDeviceItems.add(TEST_DEVICE_ITEM3);
- mFragment.show(mParent, newDeviceItems, mCachedDevice1, (item) -> {});
+ AudioSharingDisconnectDialogFragment.show(
+ mParent,
+ newDeviceItems,
+ mCachedDevice1,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog.isShowing()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS),
+ eq(SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE));
+
view = dialog.findViewById(R.id.device_btn_list);
+ assertThat(view).isNotNull();
assertThat(view.getAdapter().getItemCount()).isEqualTo(2);
Button btn1 =
view.findViewHolderForAdapterPosition(0).itemView.findViewById(R.id.device_button);
@@ -227,12 +288,27 @@
mDeviceItems = new ArrayList<>();
mDeviceItems.add(TEST_DEVICE_ITEM1);
mDeviceItems.add(TEST_DEVICE_ITEM2);
- mFragment.show(mParent, mDeviceItems, mCachedDevice3, (item) -> {});
+ AudioSharingDisconnectDialogFragment.show(
+ mParent, mDeviceItems, mCachedDevice3, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
+ shadowMainLooper().idle();
+ AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
+ assertThat(dialog).isNotNull();
+ assertThat(dialog.isShowing()).isTrue();
+ View btnView = dialog.findViewById(R.id.negative_btn);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
shadowMainLooper().idle();
- AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- assertThat(dialog.isShowing()).isTrue();
- dialog.findViewById(R.id.negative_btn).performClick();
assertThat(dialog.isShowing()).isFalse();
+ verify(mFeatureFactory.metricsFeatureProvider, times(0))
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS),
+ eq(SettingsEnums.DIALOG_AUDIO_SHARING_SWITCH_DEVICE));
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
index 2d55d97..c7b21ad 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingJoinDialogFragmentTest.java
@@ -18,13 +18,19 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothStatusCodes;
+import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.util.Pair;
+import android.view.View;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
@@ -32,6 +38,7 @@
import com.android.settings.R;
import com.android.settings.bluetooth.Utils;
+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.ShadowBluetoothUtils;
@@ -82,6 +89,9 @@
@Override
public void onCancelClick() {}
};
+ private static final Pair<Integer, Object> TEST_EVENT_DATA = Pair.create(1, 1);
+ private static final Pair<Integer, Object>[] TEST_EVENT_DATA_LIST =
+ new Pair[] {TEST_EVENT_DATA};
@Mock private CachedBluetoothDevice mCachedDevice1;
@Mock private CachedBluetoothDevice mCachedDevice2;
@@ -90,7 +100,7 @@
@Mock private LocalBluetoothLeBroadcast mBroadcast;
private Fragment mParent;
private AudioSharingJoinDialogFragment mFragment;
- private ShadowBluetoothAdapter mShadowBluetoothAdapter;
+ private FakeFeatureFactory mFeatureFactory;
@Before
public void setUp() {
@@ -99,12 +109,14 @@
latestAlertDialog.dismiss();
ShadowAlertDialogCompat.reset();
}
- mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- mShadowBluetoothAdapter.setEnabled(true);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
+ ShadowBluetoothAdapter shadowBluetoothAdapter =
+ Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ shadowBluetoothAdapter.setEnabled(true);
+ shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
+ shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME2);
mFragment = new AudioSharingJoinDialogFragment();
@@ -137,7 +149,12 @@
@Test
public void onCreateDialog_flagOff_dialogNotExist() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, new ArrayList<>(), mCachedDevice2, EMPTY_EVENT_LISTENER);
+ AudioSharingJoinDialogFragment.show(
+ mParent,
+ new ArrayList<>(),
+ mCachedDevice2,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNull();
@@ -146,7 +163,12 @@
@Test
public void onCreateDialog_flagOn_dialogShowTextForSingleDevice() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, new ArrayList<>(), mCachedDevice2, EMPTY_EVENT_LISTENER);
+ AudioSharingJoinDialogFragment.show(
+ mParent,
+ new ArrayList<>(),
+ mCachedDevice2,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
@@ -160,7 +182,8 @@
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
list.add(TEST_DEVICE_ITEM1);
- mFragment.show(mParent, list, mCachedDevice2, EMPTY_EVENT_LISTENER);
+ AudioSharingJoinDialogFragment.show(
+ mParent, list, mCachedDevice2, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
@@ -179,7 +202,8 @@
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
ArrayList<AudioSharingDeviceItem> list = new ArrayList<>();
list.add(TEST_DEVICE_ITEM1);
- mFragment.show(mParent, list, mCachedDevice2, EMPTY_EVENT_LISTENER);
+ AudioSharingJoinDialogFragment.show(
+ mParent, list, mCachedDevice2, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
@@ -188,7 +212,8 @@
// Update the content
ArrayList<AudioSharingDeviceItem> list2 = new ArrayList<>();
list2.add(TEST_DEVICE_ITEM2);
- mFragment.show(mParent, list2, mCachedDevice1, EMPTY_EVENT_LISTENER);
+ AudioSharingJoinDialogFragment.show(
+ mParent, list2, mCachedDevice1, EMPTY_EVENT_LISTENER, TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
@@ -205,11 +230,25 @@
@Test
public void onCreateDialog_clickCancel_dialogDismiss() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, new ArrayList<>(), mCachedDevice2, EMPTY_EVENT_LISTENER);
+ AudioSharingJoinDialogFragment.show(
+ mParent,
+ new ArrayList<>(),
+ mCachedDevice2,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(R.id.negative_btn).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(R.id.negative_btn);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
+ shadowMainLooper().idle();
assertThat(dialog.isShowing()).isFalse();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
@@ -228,12 +267,22 @@
@Override
public void onCancelClick() {}
- });
+ },
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(R.id.positive_btn).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(R.id.positive_btn);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
+ shadowMainLooper().idle();
assertThat(dialog.isShowing()).isFalse();
assertThat(isShareBtnClicked.get()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
@@ -252,11 +301,21 @@
public void onCancelClick() {
isCancelBtnClicked.set(true);
}
- });
+ },
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(R.id.negative_btn).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(R.id.negative_btn);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
+ shadowMainLooper().idle();
assertThat(dialog.isShowing()).isFalse();
assertThat(isCancelBtnClicked.get()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
}
diff --git a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
index 84d7a31..7d46a18 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingStopDialogFragmentTest.java
@@ -18,13 +18,21 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
+import android.app.settings.SettingsEnums;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothStatusCodes;
+import android.content.Context;
import android.platform.test.flag.junit.SetFlagsRule;
+import android.util.Pair;
+import android.view.View;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
@@ -32,6 +40,7 @@
import androidx.fragment.app.FragmentActivity;
import com.android.settings.R;
+import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
import com.android.settings.testutils.shadow.ShadowBluetoothAdapter;
import com.android.settingslib.bluetooth.CachedBluetoothDevice;
@@ -76,14 +85,19 @@
private static final AudioSharingDeviceItem TEST_DEVICE_ITEM3 =
new AudioSharingDeviceItem(
TEST_DEVICE_NAME3, TEST_DEVICE_GROUP_ID3, /* isActive= */ false);
+ private static final AudioSharingStopDialogFragment.DialogEventListener EMPTY_EVENT_LISTENER =
+ () -> {};
+ private static final Pair<Integer, Object> TEST_EVENT_DATA = Pair.create(1, 1);
+ private static final Pair<Integer, Object>[] TEST_EVENT_DATA_LIST =
+ new Pair[] {TEST_EVENT_DATA};
@Mock private CachedBluetoothDevice mCachedDevice1;
@Mock private CachedBluetoothDevice mCachedDevice2;
@Mock private BluetoothDevice mDevice1;
@Mock private BluetoothDevice mDevice2;
+ private FakeFeatureFactory mFeatureFactory;
private Fragment mParent;
private AudioSharingStopDialogFragment mFragment;
- private ShadowBluetoothAdapter mShadowBluetoothAdapter;
@Before
public void setUp() {
@@ -92,12 +106,14 @@
latestAlertDialog.dismiss();
ShadowAlertDialogCompat.reset();
}
- mShadowBluetoothAdapter = Shadow.extract(BluetoothAdapter.getDefaultAdapter());
- mShadowBluetoothAdapter.setEnabled(true);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
+ ShadowBluetoothAdapter shadowBluetoothAdapter =
+ Shadow.extract(BluetoothAdapter.getDefaultAdapter());
+ shadowBluetoothAdapter.setEnabled(true);
+ shadowBluetoothAdapter.setIsLeAudioBroadcastSourceSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
- mShadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
+ shadowBluetoothAdapter.setIsLeAudioBroadcastAssistantSupported(
BluetoothStatusCodes.FEATURE_SUPPORTED);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1);
when(mCachedDevice1.getDevice()).thenReturn(mDevice1);
@@ -111,9 +127,20 @@
}
@Test
+ public void getMetricsCategory_correctValue() {
+ assertThat(mFragment.getMetricsCategory())
+ .isEqualTo(SettingsEnums.DIALOG_STOP_AUDIO_SHARING);
+ }
+
+ @Test
public void onCreateDialog_flagOff_dialogNotExist() {
mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, ImmutableList.of(), mCachedDevice1, () -> {});
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(),
+ mCachedDevice1,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNull();
@@ -122,12 +149,18 @@
@Test
public void onCreateDialog_oneDeviceInSharing_showDialogWithCorrectMessage() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, ImmutableList.of(TEST_DEVICE_ITEM2), mCachedDevice1, () -> {});
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(TEST_DEVICE_ITEM2),
+ mCachedDevice1,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
TextView view = dialog.findViewById(R.id.description_text);
+ assertThat(view).isNotNull();
assertThat(view.getText().toString())
.isEqualTo(
mParent.getString(
@@ -137,16 +170,18 @@
@Test
public void onCreateDialog_twoDeviceInSharing_showDialogWithCorrectMessage() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(
+ AudioSharingStopDialogFragment.show(
mParent,
ImmutableList.of(TEST_DEVICE_ITEM2, TEST_DEVICE_ITEM3),
mCachedDevice1,
- () -> {});
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
TextView view = dialog.findViewById(R.id.description_text);
+ assertThat(view).isNotNull();
assertThat(view.getText().toString())
.isEqualTo(
mParent.getString(
@@ -158,57 +193,99 @@
@Test
public void onCreateDialog_dialogIsShowingForSameDevice_updateDialog() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, ImmutableList.of(), mCachedDevice1, () -> {});
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(),
+ mCachedDevice1,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
TextView view = dialog.findViewById(R.id.description_text);
+ assertThat(view).isNotNull();
assertThat(view.getText().toString())
.isEqualTo(mParent.getString(R.string.audio_sharing_stop_dialog_with_more_content));
// Update the content
AtomicBoolean isStopBtnClicked = new AtomicBoolean(false);
- mFragment.show(
- mParent, ImmutableList.of(), mCachedDevice1, () -> isStopBtnClicked.set(true));
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(),
+ mCachedDevice1,
+ () -> isStopBtnClicked.set(true),
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider, times(0))
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS),
+ eq(SettingsEnums.DIALOG_STOP_AUDIO_SHARING));
- dialog.findViewById(android.R.id.button1).performClick();
+ View btnView = dialog.findViewById(android.R.id.button1);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
shadowMainLooper().idle();
assertThat(dialog.isShowing()).isFalse();
assertThat(isStopBtnClicked.get()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
public void onCreateDialog_dialogIsShowingForNewDevice_showNewDialog() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, ImmutableList.of(), mCachedDevice1, () -> {});
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(),
+ mCachedDevice1,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
TextView view = dialog.findViewById(R.id.description_text);
+ assertThat(view).isNotNull();
assertThat(view.getText().toString())
.isEqualTo(mParent.getString(R.string.audio_sharing_stop_dialog_with_more_content));
TextView title = dialog.findViewById(R.id.title_text);
+ assertThat(title).isNotNull();
assertThat(title.getText().toString())
.isEqualTo(
mParent.getString(
R.string.audio_sharing_stop_dialog_title, TEST_DEVICE_NAME1));
// Show new dialog
- mFragment.show(mParent, ImmutableList.of(), mCachedDevice2, () -> {});
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(),
+ mCachedDevice2,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
assertThat(dialog).isNotNull();
assertThat(dialog.isShowing()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS),
+ eq(SettingsEnums.DIALOG_STOP_AUDIO_SHARING));
+
view = dialog.findViewById(R.id.description_text);
+ assertThat(view).isNotNull();
assertThat(view.getText().toString())
.isEqualTo(mParent.getString(R.string.audio_sharing_stop_dialog_with_more_content));
title = dialog.findViewById(R.id.title_text);
+ assertThat(title).isNotNull();
assertThat(title.getText().toString())
.isEqualTo(
mParent.getString(
@@ -218,25 +295,60 @@
@Test
public void onCreateDialog_clickCancel_dialogDismiss() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
- mFragment.show(mParent, ImmutableList.of(), mCachedDevice1, () -> {});
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(),
+ mCachedDevice1,
+ EMPTY_EVENT_LISTENER,
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(android.R.id.button2).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(android.R.id.button2);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
shadowMainLooper().idle();
assertThat(dialog.isShowing()).isFalse();
+ verify(mFeatureFactory.metricsFeatureProvider, times(0))
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS),
+ eq(SettingsEnums.DIALOG_STOP_AUDIO_SHARING));
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_NEGATIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
@Test
public void onCreateDialog_clickShare_callbackTriggered() {
mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LE_AUDIO_SHARING);
AtomicBoolean isStopBtnClicked = new AtomicBoolean(false);
- mFragment.show(
- mParent, ImmutableList.of(), mCachedDevice1, () -> isStopBtnClicked.set(true));
+ AudioSharingStopDialogFragment.show(
+ mParent,
+ ImmutableList.of(),
+ mCachedDevice1,
+ () -> isStopBtnClicked.set(true),
+ TEST_EVENT_DATA_LIST);
shadowMainLooper().idle();
AlertDialog dialog = ShadowAlertDialogCompat.getLatestAlertDialog();
- dialog.findViewById(android.R.id.button1).performClick();
+ assertThat(dialog).isNotNull();
+ View btnView = dialog.findViewById(android.R.id.button1);
+ assertThat(btnView).isNotNull();
+ btnView.performClick();
shadowMainLooper().idle();
assertThat(dialog.isShowing()).isFalse();
assertThat(isStopBtnClicked.get()).isTrue();
+ verify(mFeatureFactory.metricsFeatureProvider, times(0))
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_AUTO_DISMISS),
+ eq(SettingsEnums.DIALOG_STOP_AUDIO_SHARING));
+ verify(mFeatureFactory.metricsFeatureProvider)
+ .action(
+ any(Context.class),
+ eq(SettingsEnums.ACTION_AUDIO_SHARING_DIALOG_POSITIVE_BTN_CLICKED),
+ eq(TEST_EVENT_DATA));
}
}
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 0ead2d5..8f85feb8 100644
--- a/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
+++ b/tests/robotests/src/com/android/settings/connecteddevice/audiosharing/AudioSharingSwitchBarControllerTest.java
@@ -23,6 +23,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -30,6 +31,7 @@
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.BluetoothLeBroadcast;
@@ -43,12 +45,17 @@
import android.os.Looper;
import android.platform.test.flag.junit.SetFlagsRule;
import android.util.FeatureFlagUtils;
+import android.util.Pair;
import android.widget.CompoundButton;
+import androidx.fragment.app.DialogFragment;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LifecycleOwner;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.bluetooth.Utils;
+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.ShadowThreadUtils;
@@ -65,6 +72,8 @@
import com.android.settingslib.flags.Flags;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.truth.Correspondence;
import org.junit.Before;
import org.junit.Rule;
@@ -77,7 +86,9 @@
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
+import org.robolectric.shadows.androidx.fragment.FragmentController;
+import java.util.List;
import java.util.concurrent.Executor;
@RunWith(RobolectricTestRunner.class)
@@ -88,6 +99,18 @@
ShadowThreadUtils.class,
})
public class AudioSharingSwitchBarControllerTest {
+ private static final String TEST_DEVICE_NAME1 = "test1";
+ private static final String TEST_DEVICE_NAME2 = "test2";
+ private static final int TEST_DEVICE_GROUP_ID1 = 1;
+ private static final int TEST_DEVICE_GROUP_ID2 = 2;
+ private static final Correspondence<Fragment, String> TAG_EQUALS =
+ Correspondence.from(
+ (Fragment fragment, String tag) ->
+ fragment instanceof DialogFragment
+ && ((DialogFragment) fragment).getTag() != null
+ && ((DialogFragment) fragment).getTag().equals(tag),
+ "is equal to");
+
@Rule public final MockitoRule mMockitoRule = MockitoJUnit.rule();
@Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
@@ -99,17 +122,19 @@
@Mock private LocalBluetoothLeBroadcastAssistant mAssistant;
@Mock private VolumeControlProfile mVolumeControl;
@Mock private CompoundButton mBtnView;
- @Mock private CachedBluetoothDevice mCachedDevice;
- @Mock private BluetoothDevice mDevice;
+ @Mock private CachedBluetoothDevice mCachedDevice1;
+ @Mock private CachedBluetoothDevice mCachedDevice2;
+ @Mock private BluetoothDevice mDevice1;
+ @Mock private BluetoothDevice mDevice2;
private SettingsMainSwitchBar mSwitchBar;
private AudioSharingSwitchBarController mController;
- private AudioSharingSwitchBarController.OnAudioSharingStateChangedListener mListener;
+ private FakeFeatureFactory mFeatureFactory;
private Lifecycle mLifecycle;
private LifecycleOwner mLifecycleOwner;
private boolean mOnAudioSharingStateChanged;
private boolean mOnAudioSharingServiceConnected;
private ShadowBluetoothAdapter mShadowBluetoothAdapter;
- private LocalBluetoothManager mLocalBluetoothManager;
+ private Fragment mParentFragment;
@Before
public void setUp() {
@@ -122,13 +147,20 @@
mLifecycleOwner = () -> mLifecycle;
mLifecycle = new Lifecycle(mLifecycleOwner);
ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBtManager;
- mLocalBluetoothManager = Utils.getLocalBtManager(mContext);
- when(mLocalBluetoothManager.getProfileManager()).thenReturn(mBtProfileManager);
- when(mLocalBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
- when(mDeviceManager.findDevice(mDevice)).thenReturn(mCachedDevice);
- when(mCachedDevice.getDevice()).thenReturn(mDevice);
- when(mCachedDevice.getGroupId()).thenReturn(1);
- when(mCachedDevice.getName()).thenReturn("test");
+ LocalBluetoothManager localBluetoothManager = Utils.getLocalBtManager(mContext);
+ mFeatureFactory = FakeFeatureFactory.setupForTest();
+ when(localBluetoothManager.getProfileManager()).thenReturn(mBtProfileManager);
+ when(localBluetoothManager.getCachedDeviceManager()).thenReturn(mDeviceManager);
+ when(mDeviceManager.findDevice(mDevice1)).thenReturn(mCachedDevice1);
+ when(mCachedDevice1.getDevice()).thenReturn(mDevice1);
+ when(mCachedDevice1.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID1);
+ when(mCachedDevice1.getName()).thenReturn(TEST_DEVICE_NAME1);
+ when(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(false);
+ when(mDeviceManager.findDevice(mDevice2)).thenReturn(mCachedDevice2);
+ when(mCachedDevice2.getDevice()).thenReturn(mDevice2);
+ when(mCachedDevice2.getGroupId()).thenReturn(TEST_DEVICE_GROUP_ID2);
+ when(mCachedDevice2.getName()).thenReturn(TEST_DEVICE_NAME2);
+ when(mCachedDevice2.isActiveDevice(BluetoothProfile.LE_AUDIO)).thenReturn(true);
when(mBtProfileManager.getLeAudioBroadcastProfile()).thenReturn(mBroadcast);
when(mBtProfileManager.getLeAudioBroadcastAssistantProfile()).thenReturn(mAssistant);
when(mBtProfileManager.getVolumeControlProfile()).thenReturn(mVolumeControl);
@@ -153,7 +185,7 @@
mSwitchBar.setDisabledByAdmin(mock(RestrictedLockUtils.EnforcedAdmin.class));
mOnAudioSharingStateChanged = false;
mOnAudioSharingServiceConnected = false;
- mListener =
+ AudioSharingSwitchBarController.OnAudioSharingStateChangedListener listener =
new AudioSharingSwitchBarController.OnAudioSharingStateChangedListener() {
@Override
public void onAudioSharingStateChanged() {
@@ -165,7 +197,14 @@
mOnAudioSharingServiceConnected = true;
}
};
- mController = new AudioSharingSwitchBarController(mContext, mSwitchBar, mListener);
+ mController = new AudioSharingSwitchBarController(mContext, mSwitchBar, listener);
+ mParentFragment = new Fragment();
+ FragmentController.setupFragment(
+ mParentFragment,
+ FragmentActivity.class,
+ 0 /* containerViewId */,
+ null /* bundle */);
+ mController.init(mParentFragment);
}
@Test
@@ -356,7 +395,7 @@
when(mBtnView.isEnabled()).thenReturn(true);
when(mAssistant.getDevicesMatchingConnectionStates(
new int[] {BluetoothProfile.STATE_CONNECTED}))
- .thenReturn(ImmutableList.of(mDevice));
+ .thenReturn(ImmutableList.of(mDevice1));
doNothing().when(mBroadcast).startPrivateBroadcast();
mController.onCheckedChanged(mBtnView, /* isChecked= */ true);
verify(mBroadcast).startPrivateBroadcast();
@@ -380,4 +419,50 @@
mController.onCheckedChanged(mBtnView, /* isChecked= */ false);
verify(mBroadcast).stopBroadcast(1);
}
+
+ @Test
+ public void onPlaybackStarted_showJoinAudioSharingDialog() {
+ 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.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<Fragment> childFragments = mParentFragment.getChildFragmentManager().getFragments();
+ assertThat(childFragments)
+ .comparingElementsUsing(TAG_EQUALS)
+ .containsExactly(AudioSharingDialogFragment.tag());
+
+ AudioSharingDialogFragment fragment =
+ (AudioSharingDialogFragment) Iterables.getOnlyElement(childFragments);
+ Pair<Integer, Object>[] eventData = fragment.getEventData();
+ assertThat(eventData)
+ .asList()
+ .containsExactly(
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_SOURCE_PAGE_ID.ordinal(),
+ SettingsEnums.AUDIO_SHARING_SETTINGS),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_PAGE_ID.ordinal(),
+ SettingsEnums.DIALOG_AUDIO_SHARING_ADD_DEVICE),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_USER_TRIGGERED.ordinal(), 0),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_DEVICE_COUNT_IN_SHARING
+ .ordinal(),
+ 1),
+ Pair.create(
+ AudioSharingUtils.MetricKey.METRIC_KEY_CANDIDATE_DEVICE_COUNT
+ .ordinal(),
+ 1));
+ }
}