Commit f5e796e7 authored by Noah Rose Ledesma's avatar Noah Rose Ledesma Committed by Commit Bot

GMC: Add metrics for seamless transfer

This change adds several metrics for the device picker in the Global
Media Controls dialog:

Media.GlobalMediaControls.NumberOfAvailableAudioDevices tracks the
number of audio devices displayed in the device picker UI each time it
is opened.

Media.GlobalMediaControls.DeviceSelectorAvailable tracks if the device
selector was available.

Media.GlobalMediaControls.DeviceSelectorOpened tracks if the device
selector was opened.

For details see the entries in histograms.xml

Bug: 1096257
Change-Id: Ia67b919ee63330239ed5e4cd38c694142896417d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2393256
Commit-Queue: Noah Rose Ledesma <noahrose@google.com>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Reviewed-by: default avatarBrian White <bcwhite@chromium.org>
Auto-Submit: Noah Rose Ledesma <noahrose@google.com>
Cr-Commit-Position: refs/heads/master@{#806286}
parent 8e72b56f
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/ui/views/global_media_controls/media_notification_device_selector_view.h" #include "chrome/browser/ui/views/global_media_controls/media_notification_device_selector_view.h"
#include "base/metrics/histogram_functions.h"
#include "base/ranges/algorithm.h" #include "base/ranges/algorithm.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/global_media_controls/media_notification_container_impl.h" #include "chrome/browser/ui/global_media_controls/media_notification_container_impl.h"
...@@ -61,6 +62,12 @@ class DeviceEntryView : public views::Button { ...@@ -61,6 +62,12 @@ class DeviceEntryView : public views::Button {
views::Label* device_subtext_label_ = nullptr; views::Label* device_subtext_label_ = nullptr;
}; };
// The maximum number of audio devices to count when recording the
// Media.GlobalMediaControls.NumberOfAvailableAudioDevices histogram. 30 was
// chosen because it would be very unlikely to see a user with 30+ audio
// devices.
const int kAudioDevicesCountHistogramMax = 30;
} // anonymous namespace } // anonymous namespace
DeviceEntryView::DeviceEntryView(const SkColor& foreground_color, DeviceEntryView::DeviceEntryView(const SkColor& foreground_color,
...@@ -295,6 +302,15 @@ void MediaNotificationDeviceSelectorView::UpdateCurrentAudioDevice( ...@@ -295,6 +302,15 @@ void MediaNotificationDeviceSelectorView::UpdateCurrentAudioDevice(
MediaNotificationDeviceSelectorView::~MediaNotificationDeviceSelectorView() { MediaNotificationDeviceSelectorView::~MediaNotificationDeviceSelectorView() {
audio_device_subscription_.release(); audio_device_subscription_.release();
// If this metric has not been recorded during the lifetime of this view, it
// means that the device selector was never made available.
if (!has_expand_button_been_shown_) {
base::UmaHistogramBoolean(kDeviceSelectorAvailableHistogramName, false);
} else if (!have_devices_been_shown_) {
// Record if the device selector was available but never opened
base::UmaHistogramBoolean(kDeviceSelectorOpenedHistogramName, false);
}
} }
void MediaNotificationDeviceSelectorView::UpdateAvailableAudioDevices( void MediaNotificationDeviceSelectorView::UpdateAvailableAudioDevices(
...@@ -393,6 +409,15 @@ void MediaNotificationDeviceSelectorView::ShowDevices() { ...@@ -393,6 +409,15 @@ void MediaNotificationDeviceSelectorView::ShowDevices() {
DCHECK(!is_expanded_); DCHECK(!is_expanded_);
is_expanded_ = true; is_expanded_ = true;
if (!have_devices_been_shown_) {
base::UmaHistogramExactLinear(
kAudioDevicesCountHistogramName,
audio_device_entries_container_->children().size(),
kAudioDevicesCountHistogramMax);
base::UmaHistogramBoolean(kDeviceSelectorOpenedHistogramName, true);
have_devices_been_shown_ = true;
}
audio_device_entries_container_->SetVisible(true); audio_device_entries_container_->SetVisible(true);
PreferredSizeChanged(); PreferredSizeChanged();
} }
...@@ -407,6 +432,12 @@ void MediaNotificationDeviceSelectorView::HideDevices() { ...@@ -407,6 +432,12 @@ void MediaNotificationDeviceSelectorView::HideDevices() {
void MediaNotificationDeviceSelectorView::UpdateVisibility() { void MediaNotificationDeviceSelectorView::UpdateVisibility() {
SetVisible(ShouldBeVisible()); SetVisible(ShouldBeVisible());
if (!has_expand_button_been_shown_ && GetVisible()) {
base::UmaHistogramBoolean(kDeviceSelectorAvailableHistogramName, true);
has_expand_button_been_shown_ = true;
}
delegate_->OnDeviceSelectorViewSizeChanged(); delegate_->OnDeviceSelectorViewSizeChanged();
} }
......
...@@ -16,6 +16,12 @@ ...@@ -16,6 +16,12 @@
namespace { namespace {
class DeviceEntryView; class DeviceEntryView;
class ExpandDeviceSelectorButton; class ExpandDeviceSelectorButton;
const char kAudioDevicesCountHistogramName[] =
"Media.GlobalMediaControls.NumberOfAvailableAudioDevices";
const char kDeviceSelectorAvailableHistogramName[] =
"Media.GlobalMediaControls.DeviceSelectorAvailable";
const char kDeviceSelectorOpenedHistogramName[] =
"Media.GlobalMediaControls.DeviceSelectorOpened";
} // anonymous namespace } // anonymous namespace
class MediaNotificationDeviceSelectorViewDelegate; class MediaNotificationDeviceSelectorViewDelegate;
...@@ -67,6 +73,10 @@ class MediaNotificationDeviceSelectorView ...@@ -67,6 +73,10 @@ class MediaNotificationDeviceSelectorView
DeviceHighlightedOnChange); DeviceHighlightedOnChange);
FRIEND_TEST_ALL_PREFIXES(MediaNotificationDeviceSelectorViewTest, FRIEND_TEST_ALL_PREFIXES(MediaNotificationDeviceSelectorViewTest,
DeviceButtonsChange); DeviceButtonsChange);
FRIEND_TEST_ALL_PREFIXES(MediaNotificationDeviceSelectorViewTest,
AudioDevicesCountHistogramRecorded);
FRIEND_TEST_ALL_PREFIXES(MediaNotificationDeviceSelectorViewTest,
DeviceSelectorOpenedHistogramRecorded);
void UpdateVisibility(); void UpdateVisibility();
...@@ -75,6 +85,9 @@ class MediaNotificationDeviceSelectorView ...@@ -75,6 +85,9 @@ class MediaNotificationDeviceSelectorView
void ShowDevices(); void ShowDevices();
void HideDevices(); void HideDevices();
bool has_expand_button_been_shown_ = false;
bool have_devices_been_shown_ = false;
bool is_expanded_ = false; bool is_expanded_ = false;
bool is_audio_device_switching_enabled_ = false; bool is_audio_device_switching_enabled_ = false;
MediaNotificationDeviceSelectorViewDelegate* const delegate_; MediaNotificationDeviceSelectorViewDelegate* const delegate_;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include "base/callback_list.h" #include "base/callback_list.h"
#include "base/ranges/algorithm.h" #include "base/ranges/algorithm.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "chrome/browser/ui/global_media_controls/media_notification_device_provider.h" #include "chrome/browser/ui/global_media_controls/media_notification_device_provider.h"
#include "chrome/browser/ui/global_media_controls/media_notification_service.h" #include "chrome/browser/ui/global_media_controls/media_notification_service.h"
...@@ -137,6 +138,7 @@ class MediaNotificationDeviceSelectorViewTest : public ChromeViewsTestBase { ...@@ -137,6 +138,7 @@ class MediaNotificationDeviceSelectorViewTest : public ChromeViewsTestBase {
} }
std::unique_ptr<MediaNotificationDeviceSelectorView> view_; std::unique_ptr<MediaNotificationDeviceSelectorView> view_;
base::HistogramTester histogram_tester_;
}; };
TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsCreated) { TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsCreated) {
...@@ -351,3 +353,110 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceChangeIsNotSupported) { ...@@ -351,3 +353,110 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceChangeIsNotSupported) {
delegate.RunSupportsDeviceSwitchingCallback(); delegate.RunSupportsDeviceSwitchingCallback();
EXPECT_TRUE(view_->GetVisible()); EXPECT_TRUE(view_->GetVisible());
} }
TEST_F(MediaNotificationDeviceSelectorViewTest,
AudioDevicesCountHistogramRecorded) {
MockMediaNotificationDeviceSelectorViewDelegate delegate;
auto* provider = delegate.GetProvider();
provider->AddDevice("Speaker", "1");
provider->AddDevice("Headphones", "2");
provider->AddDevice("Earbuds", "3");
histogram_tester_.ExpectTotalCount(kAudioDevicesCountHistogramName, 0);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor);
view_->ShowDevices();
histogram_tester_.ExpectTotalCount(kAudioDevicesCountHistogramName, 1);
histogram_tester_.ExpectBucketCount(kAudioDevicesCountHistogramName, 3, 1);
provider->AddDevice("Monitor", "4");
provider->RunUICallback();
histogram_tester_.ExpectTotalCount(kAudioDevicesCountHistogramName, 1);
histogram_tester_.ExpectBucketCount(kAudioDevicesCountHistogramName, 3, 1);
}
TEST_F(MediaNotificationDeviceSelectorViewTest,
DeviceSelectorAvailableHistogramRecorded) {
MockMediaNotificationDeviceSelectorViewDelegate delegate;
auto* provider = delegate.GetProvider();
provider->AddDevice("Speaker",
media::AudioDeviceDescription::kDefaultDeviceId);
delegate.supports_switching = false;
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 0);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor);
EXPECT_FALSE(view_->GetVisible());
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 0);
provider->AddDevice("Headphones", "2");
provider->RunUICallback();
EXPECT_FALSE(view_->GetVisible());
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 0);
view_.reset();
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 1);
histogram_tester_.ExpectBucketCount(kDeviceSelectorAvailableHistogramName,
false, 1);
delegate.supports_switching = true;
view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor);
EXPECT_TRUE(view_->GetVisible());
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 2);
histogram_tester_.ExpectBucketCount(kDeviceSelectorAvailableHistogramName,
true, 1);
view_.reset();
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 2);
}
TEST_F(MediaNotificationDeviceSelectorViewTest,
DeviceSelectorOpenedHistogramRecorded) {
MockMediaNotificationDeviceSelectorViewDelegate delegate;
auto* provider = delegate.GetProvider();
provider->AddDevice("Speaker",
media::AudioDeviceDescription::kDefaultDeviceId);
provider->AddDevice("Headphones", "2");
delegate.supports_switching = false;
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 0);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor);
EXPECT_FALSE(view_->GetVisible());
view_.reset();
// The histrogram should not be recorded when the device selector is not
// available.
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 0);
delegate.supports_switching = true;
view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor);
view_.reset();
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 1);
histogram_tester_.ExpectBucketCount(kDeviceSelectorOpenedHistogramName, false,
1);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor);
view_->ShowDevices();
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 2);
histogram_tester_.ExpectBucketCount(kDeviceSelectorOpenedHistogramName, true,
1);
view_.reset();
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 2);
}
...@@ -81643,6 +81643,29 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -81643,6 +81643,29 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary> </summary>
</histogram> </histogram>
<histogram name="Media.GlobalMediaControls.DeviceSelectorAvailable"
enum="Boolean" expires_after="2021-09-08">
<owner>steimel@chromium.org</owner>
<owner>media-dev@chromium.org</owner>
<summary>
Records if the Global Media Controls device selector was available. Recorded
once per notification either when the device selector was shown or when the
notification disappears.
</summary>
</histogram>
<histogram name="Media.GlobalMediaControls.DeviceSelectorOpened" enum="Boolean"
expires_after="2021-09-08">
<owner>steimel@chromium.org</owner>
<owner>media-dev@chromium.org</owner>
<summary>
Records if the Global Media Controls device selector was opened. Recorded
once per notification either when the device selector was opened or when the
notification disappears. This histogram is only recorded if the device
selector was available.
</summary>
</histogram>
<histogram name="Media.GlobalMediaControls.DismissReason" <histogram name="Media.GlobalMediaControls.DismissReason"
enum="GlobalMediaControlsDismissReason" expires_after="2021-02-14"> enum="GlobalMediaControlsDismissReason" expires_after="2021-02-14">
<owner>steimel@chromium.org</owner> <owner>steimel@chromium.org</owner>
...@@ -81666,6 +81689,17 @@ reviews. Googlers can read more about this at go/gwsq-gerrit. ...@@ -81666,6 +81689,17 @@ reviews. Googlers can read more about this at go/gwsq-gerrit.
</summary> </summary>
</histogram> </histogram>
<histogram name="Media.GlobalMediaControls.NumberOfAvailableAudioDevices"
units="devices" expires_after="2021-09-08">
<owner>steimel@chromium.org</owner>
<owner>media-dev@chromium.org</owner>
<summary>
Recorded each time the Global Media Controls Device picker dialog is opened
and is populated with devices. Records the number of device options
displayed, possibly including the default fallback device.
</summary>
</histogram>
<histogram name="Media.GlobalMediaControls.RepeatUsage" enum="BooleanIsRepeat" <histogram name="Media.GlobalMediaControls.RepeatUsage" enum="BooleanIsRepeat"
expires_after="2021-02-14"> expires_after="2021-02-14">
<owner>steimel@chromium.org</owner> <owner>steimel@chromium.org</owner>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment