blob: 98476b7ad126afc7f69e9cf74e9cc30bbd016719 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/views/media_router/cast_dialog_metrics.h"
#include "base/metrics/histogram_macros.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/media_router/ui_media_sink.h"
#include "chrome/common/pref_names.h"
#include "components/media_router/common/mojom/media_route_provider_id.mojom-shared.h"
#include "components/media_router/common/pref_names.h"
#include "components/prefs/pref_service.h"
namespace media_router {
using mojom::MediaRouteProviderId;
namespace {
DialogActivationLocationAndCastMode GetActivationLocationAndCastMode(
MediaRouterDialogOpenOrigin activation_location,
MediaCastMode cast_mode,
bool is_icon_pinned) {
switch (activation_location) {
case MediaRouterDialogOpenOrigin::TOOLBAR:
if (is_icon_pinned) {
switch (cast_mode) {
case MediaCastMode::PRESENTATION:
return DialogActivationLocationAndCastMode::
kPinnedIconAndPresentation;
case MediaCastMode::TAB_MIRROR:
return DialogActivationLocationAndCastMode::kPinnedIconAndTabMirror;
case MediaCastMode::DESKTOP_MIRROR:
return DialogActivationLocationAndCastMode::
kPinnedIconAndDesktopMirror;
}
} else {
switch (cast_mode) {
case MediaCastMode::PRESENTATION:
return DialogActivationLocationAndCastMode::
kEphemeralIconAndPresentation;
case MediaCastMode::TAB_MIRROR:
return DialogActivationLocationAndCastMode::
kEphemeralIconAndTabMirror;
case MediaCastMode::DESKTOP_MIRROR:
return DialogActivationLocationAndCastMode::
kEphemeralIconAndDesktopMirror;
}
}
break;
case MediaRouterDialogOpenOrigin::CONTEXTUAL_MENU:
switch (cast_mode) {
case MediaCastMode::PRESENTATION:
return DialogActivationLocationAndCastMode::
kContextMenuAndPresentation;
case MediaCastMode::TAB_MIRROR:
return DialogActivationLocationAndCastMode::kContextMenuAndTabMirror;
case MediaCastMode::DESKTOP_MIRROR:
return DialogActivationLocationAndCastMode::
kContextMenuAndDesktopMirror;
}
break;
case MediaRouterDialogOpenOrigin::PAGE:
switch (cast_mode) {
case MediaCastMode::PRESENTATION:
return DialogActivationLocationAndCastMode::kPageAndPresentation;
case MediaCastMode::TAB_MIRROR:
return DialogActivationLocationAndCastMode::kPageAndTabMirror;
case MediaCastMode::DESKTOP_MIRROR:
return DialogActivationLocationAndCastMode::kPageAndDesktopMirror;
}
break;
case MediaRouterDialogOpenOrigin::APP_MENU:
switch (cast_mode) {
case MediaCastMode::PRESENTATION:
return DialogActivationLocationAndCastMode::kAppMenuAndPresentation;
case MediaCastMode::TAB_MIRROR:
return DialogActivationLocationAndCastMode::kAppMenuAndTabMirror;
case MediaCastMode::DESKTOP_MIRROR:
return DialogActivationLocationAndCastMode::kAppMenuAndDesktopMirror;
}
break;
// |OVERFLOW_MENU| refers to extension icons hidden in the app menu. That
// mode is no longer available for the Cast toolbar icon.
case MediaRouterDialogOpenOrigin::OVERFLOW_MENU:
case MediaRouterDialogOpenOrigin::SYSTEM_TRAY:
case MediaRouterDialogOpenOrigin::TOTAL_COUNT:
break;
}
NOTREACHED();
return DialogActivationLocationAndCastMode::kMaxValue;
}
} // namespace
CastDialogMetrics::CastDialogMetrics(
const base::Time& initialization_time,
MediaRouterDialogOpenOrigin activation_location,
Profile* profile)
: initialization_time_(initialization_time),
activation_location_(activation_location),
is_icon_pinned_(
profile->GetPrefs()->GetBoolean(::prefs::kShowCastIconInToolbar)) {
MediaRouterMetrics::RecordIconStateAtDialogOpen(is_icon_pinned_);
MediaRouterMetrics::RecordCloudPrefAtDialogOpen(
profile->GetPrefs()->GetBoolean(prefs::kMediaRouterEnableCloudServices));
}
CastDialogMetrics::~CastDialogMetrics() = default;
void CastDialogMetrics::OnSinksLoaded(const base::Time& sinks_load_time) {
if (!sinks_load_time_.is_null())
return;
MediaRouterMetrics::RecordMediaRouterDialogLoaded(sinks_load_time -
initialization_time_);
sinks_load_time_ = sinks_load_time;
}
void CastDialogMetrics::OnPaint(const base::Time& paint_time) {
if (!paint_time_.is_null())
return;
MediaRouterMetrics::RecordMediaRouterDialogPaint(paint_time -
initialization_time_);
paint_time_ = paint_time;
}
void CastDialogMetrics::OnStartCasting(const base::Time& start_time,
int selected_sink_index,
MediaCastMode cast_mode,
SinkIconType icon_type,
bool has_cast_and_dial) {
DCHECK(!sinks_load_time_.is_null());
MediaRouterMetrics::RecordStartRouteDeviceIndex(selected_sink_index);
if (!first_action_recorded_) {
MediaRouterMetrics::RecordStartLocalSessionLatency(start_time -
sinks_load_time_);
}
MaybeRecordFirstAction(MediaRouterUserAction::START_LOCAL);
MaybeRecordActivationLocationAndCastMode(cast_mode);
MediaRouterMetrics::RecordMediaSinkTypeForCastDialog(icon_type);
if (has_cast_and_dial) {
MediaRouterMetrics::RecordMediaSinkTypeWhenCastAndDialPresent(
icon_type, UiType::kCastDialog);
}
}
void CastDialogMetrics::OnStopCasting(bool is_local_route) {
if (is_local_route) {
MediaRouterMetrics::RecordStopLocalRoute();
MaybeRecordFirstAction(MediaRouterUserAction::STOP_LOCAL);
} else {
MediaRouterMetrics::RecordStopRemoteRoute();
MaybeRecordFirstAction(MediaRouterUserAction::STOP_REMOTE);
}
}
void CastDialogMetrics::OnCastModeSelected() {
MaybeRecordFirstAction(MediaRouterUserAction::CHANGE_MODE);
}
void CastDialogMetrics::OnCloseDialog(const base::Time& close_time) {
if (!first_action_recorded_ && !paint_time_.is_null())
MediaRouterMetrics::RecordCloseDialogLatency(close_time - paint_time_);
MaybeRecordFirstAction(MediaRouterUserAction::CLOSE);
}
void CastDialogMetrics::OnRecordSinkCount(
const std::vector<CastDialogSinkButton*>& sink_buttons) {
media_router::MediaRouterMetrics::RecordDeviceCount(sink_buttons.size());
std::map<MediaRouteProviderId, std::map<bool, int>> counts = {
{MediaRouteProviderId::CAST, {{true, 0}, {false, 0}}},
{MediaRouteProviderId::DIAL, {{true, 0}, {false, 0}}},
{MediaRouteProviderId::WIRED_DISPLAY, {{true, 0}, {false, 0}}}};
for (const CastDialogSinkButton* sink_button : sink_buttons) {
if (sink_button->sink().provider != MediaRouteProviderId::TEST) {
counts.at(sink_button->sink().provider).at(sink_button->GetEnabled())++;
}
}
for (auto provider : {MediaRouteProviderId::CAST, MediaRouteProviderId::DIAL,
MediaRouteProviderId::WIRED_DISPLAY}) {
for (bool is_available : {true, false}) {
int count = counts.at(provider).at(is_available);
media_router::MediaRouterMetrics::RecordCastDialogDeviceCount(
activation_location_, provider, is_available, count);
}
}
}
void CastDialogMetrics::MaybeRecordFirstAction(MediaRouterUserAction action) {
if (first_action_recorded_)
return;
MediaRouterMetrics::RecordMediaRouterInitialUserAction(action);
first_action_recorded_ = true;
}
void CastDialogMetrics::MaybeRecordActivationLocationAndCastMode(
MediaCastMode cast_mode) {
if (activation_location_and_cast_mode_recorded_)
return;
UMA_HISTOGRAM_ENUMERATION(
"MediaRouter.Ui.Dialog.ActivationLocationAndCastMode",
GetActivationLocationAndCastMode(activation_location_, cast_mode,
is_icon_pinned_));
activation_location_and_cast_mode_recorded_ = true;
}
} // namespace media_router