Commit 75efc8f5 authored by Muyao Xu's avatar Muyao Xu Committed by Commit Bot

[Cast+Zenith] Show available cast devices in Global Media Controls

Global Media Controls can now show available cast devices along with
availblae audio devices for each active media session. This change is
visible when GlobalMediaControlsCastStartStop feature is enabled.

MediaNotificationAudioDeviceSelectorView implements
CastDialogController::Observer interface and owns a CastDialogController
object to listen to sink updates and update the UI.

Change-Id: Ie9488fee7183f10b4f6d71e41254223fc6d68c48
Bug: b/161610050, 1107162
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2353010
Commit-Queue: Muyao Xu <muyaoxu@google.com>
Reviewed-by: default avatarElly Fong-Jones <ellyjones@chromium.org>
Reviewed-by: default avatarTommy Steimel <steimel@chromium.org>
Reviewed-by: default avatarTakumi Fujimoto <takumif@chromium.org>
Cr-Commit-Position: refs/heads/master@{#806437}
parent c09ef60c
...@@ -3526,6 +3526,8 @@ static_library("ui") { ...@@ -3526,6 +3526,8 @@ static_library("ui") {
"views/global_media_controls/media_dialog_view_observer.h", "views/global_media_controls/media_dialog_view_observer.h",
"views/global_media_controls/media_notification_container_impl_view.cc", "views/global_media_controls/media_notification_container_impl_view.cc",
"views/global_media_controls/media_notification_container_impl_view.h", "views/global_media_controls/media_notification_container_impl_view.h",
"views/global_media_controls/media_notification_device_entry_ui.cc",
"views/global_media_controls/media_notification_device_entry_ui.h",
"views/global_media_controls/media_notification_device_selector_view.cc", "views/global_media_controls/media_notification_device_selector_view.cc",
"views/global_media_controls/media_notification_device_selector_view.h", "views/global_media_controls/media_notification_device_selector_view.h",
"views/global_media_controls/media_notification_device_selector_view_delegate.h", "views/global_media_controls/media_notification_device_selector_view_delegate.h",
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "chrome/browser/ui/global_media_controls/media_notification_device_provider_impl.h" #include "chrome/browser/ui/global_media_controls/media_notification_device_provider_impl.h"
#include "chrome/browser/ui/global_media_controls/media_notification_service_observer.h" #include "chrome/browser/ui/global_media_controls/media_notification_service_observer.h"
#include "chrome/browser/ui/global_media_controls/overlay_media_notification.h" #include "chrome/browser/ui/global_media_controls/overlay_media_notification.h"
#include "chrome/browser/ui/media_router/media_router_ui.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "components/media_message_center/media_notification_item.h" #include "components/media_message_center/media_notification_item.h"
#include "components/media_message_center/media_notification_util.h" #include "components/media_message_center/media_notification_util.h"
...@@ -790,6 +791,19 @@ void MediaNotificationService::set_device_provider_for_testing( ...@@ -790,6 +791,19 @@ void MediaNotificationService::set_device_provider_for_testing(
device_provider_ = std::move(device_provider); device_provider_ = std::move(device_provider);
} }
std::unique_ptr<media_router::CastDialogController>
MediaNotificationService::CreateCastDialogControllerForSession(
const std::string& session_id) {
auto it = sessions_.find(session_id);
if (it != sessions_.end()) {
auto ui = std::make_unique<media_router::MediaRouterUI>(
it->second.web_contents());
ui->InitWithDefaultMediaSource();
return ui;
}
return nullptr;
}
void MediaNotificationService::OnItemUnfrozen(const std::string& id) { void MediaNotificationService::OnItemUnfrozen(const std::string& id) {
frozen_session_ids_.erase(id); frozen_session_ids_.erase(id);
......
...@@ -39,6 +39,10 @@ namespace media_message_center { ...@@ -39,6 +39,10 @@ namespace media_message_center {
class MediaSessionNotificationItem; class MediaSessionNotificationItem;
} // namespace media_message_center } // namespace media_message_center
namespace media_router {
class CastDialogController;
}
class MediaDialogDelegate; class MediaDialogDelegate;
class MediaNotificationContainerImpl; class MediaNotificationContainerImpl;
class MediaNotificationServiceObserver; class MediaNotificationServiceObserver;
...@@ -131,6 +135,11 @@ class MediaNotificationService ...@@ -131,6 +135,11 @@ class MediaNotificationService
void set_device_provider_for_testing( void set_device_provider_for_testing(
std::unique_ptr<MediaNotificationDeviceProvider> device_provider); std::unique_ptr<MediaNotificationDeviceProvider> device_provider);
// Instantiates a MediaRouterViewsUI object associated with the Session with
// the given |session_id|.
std::unique_ptr<media_router::CastDialogController>
CreateCastDialogControllerForSession(const std::string& session_id);
private: private:
friend class MediaNotificationServiceTest; friend class MediaNotificationServiceTest;
friend class MediaToolbarButtonControllerTest; friend class MediaToolbarButtonControllerTest;
...@@ -261,7 +270,7 @@ class MediaNotificationService ...@@ -261,7 +270,7 @@ class MediaNotificationService
mojo::Receiver<media_session::mojom::MediaControllerObserver> mojo::Receiver<media_session::mojom::MediaControllerObserver>
observer_receiver_{this}; observer_receiver_{this};
// Used to request audio output be routed to a different device // Used to request audio output be routed to a different device.
mojo::Remote<media_session::mojom::MediaController> controller_; mojo::Remote<media_session::mojom::MediaController> controller_;
base::WeakPtr<media_router::WebContentsPresentationManager> base::WeakPtr<media_router::WebContentsPresentationManager>
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/metrics/field_trial_params.h" #include "base/metrics/field_trial_params.h"
#include "chrome/browser/media/router/media_router_feature.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"
#include "chrome/browser/ui/global_media_controls/media_notification_container_observer.h" #include "chrome/browser/ui/global_media_controls/media_notification_container_observer.h"
#include "chrome/browser/ui/global_media_controls/media_notification_service.h" #include "chrome/browser/ui/global_media_controls/media_notification_service.h"
...@@ -138,9 +139,14 @@ MediaNotificationContainerImplView::MediaNotificationContainerImplView( ...@@ -138,9 +139,14 @@ MediaNotificationContainerImplView::MediaNotificationContainerImplView(
if (base::FeatureList::IsEnabled( if (base::FeatureList::IsEnabled(
media::kGlobalMediaControlsSeamlessTransfer) && media::kGlobalMediaControlsSeamlessTransfer) &&
!is_cast_notification) { !is_cast_notification) {
auto cast_controller =
media_router::GlobalMediaControlsCastStartStopEnabled()
? service_->CreateCastDialogControllerForSession(id_)
: nullptr;
auto audio_device_selector_view = auto audio_device_selector_view =
std::make_unique<MediaNotificationDeviceSelectorView>( std::make_unique<MediaNotificationDeviceSelectorView>(
this, audio_sink_id_, foreground_color_, background_color_); this, std::move(cast_controller), audio_sink_id_, foreground_color_,
background_color_);
audio_device_selector_view_ = audio_device_selector_view_ =
AddChildView(std::move(audio_device_selector_view)); AddChildView(std::move(audio_device_selector_view));
view_->UpdateCornerRadius(message_center::kNotificationCornerRadius, 0); view_->UpdateCornerRadius(message_center::kNotificationCornerRadius, 0);
......
// Copyright 2020 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/global_media_controls/media_notification_device_entry_ui.h"
#include "base/strings/utf_string_conversions.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/layout/box_layout.h"
namespace {
constexpr gfx::Insets kIconContainerInsets{10, 15};
constexpr int kDeviceIconSize = 18;
constexpr gfx::Insets kLabelsContainerInsets{18, 0};
constexpr gfx::Size kDeviceEntryViewSize{400, 30};
constexpr int kEntryHighlightOpacity = 45;
} // namespace
DeviceEntryUI::DeviceEntryUI(SkColor foreground_color,
SkColor background_color,
const std::string& raw_device_id,
const std::string& device_name,
const gfx::VectorIcon* icon,
const std::string& subtext)
: foreground_color_(foreground_color),
background_color_(background_color),
raw_device_id_(raw_device_id),
device_name_(device_name),
icon_(icon) {}
std::string DeviceEntryUI::GetEntryLabelForTesting() {
return base::UTF16ToUTF8(device_name_label_->GetText());
}
AudioDeviceEntryView::AudioDeviceEntryView(SkColor foreground_color,
SkColor background_color,
const std::string& raw_device_id,
const std::string& device_name,
const std::string& subtext)
: DeviceEntryUI(foreground_color,
background_color,
raw_device_id,
device_name,
&vector_icons::kHeadsetIcon) {
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
icon_container_ = AddChildView(std::make_unique<views::View>());
auto* icon_container_layout =
icon_container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, kIconContainerInsets));
icon_container_layout->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kCenter);
icon_container_layout->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kCenter);
device_icon_ =
icon_container_->AddChildView(std::make_unique<views::ImageView>());
device_icon_->SetImage(
gfx::CreateVectorIcon(*icon_, kDeviceIconSize, foreground_color));
labels_container_ = AddChildView(std::make_unique<views::View>());
auto* labels_container_layout =
labels_container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, kLabelsContainerInsets));
labels_container_layout->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kCenter);
labels_container_layout->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kStart);
views::Label::CustomFont device_name_label_font{
views::Label::GetDefaultFontList().DeriveWithSizeDelta(1)};
device_name_label_ =
labels_container_->AddChildView(std::make_unique<views::Label>(
base::UTF8ToUTF16(device_name_), device_name_label_font));
device_name_label_->SetEnabledColor(foreground_color);
device_name_label_->SetBackgroundColor(background_color);
if (!subtext.empty()) {
device_subtext_label_ = labels_container_->AddChildView(
std::make_unique<views::Label>(base::UTF8ToUTF16(subtext)));
device_subtext_label_->SetTextStyle(
views::style::TextStyle::STYLE_SECONDARY);
device_subtext_label_->SetEnabledColor(foreground_color);
device_subtext_label_->SetBackgroundColor(background_color);
}
// Ensures that hovering over these items also hovers this view.
icon_container_->set_can_process_events_within_subtree(false);
labels_container_->set_can_process_events_within_subtree(false);
SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
SetInkDropMode(Button::InkDropMode::ON);
set_ink_drop_base_color(foreground_color);
set_has_ink_drop_action_on_click(true);
SetPreferredSize(kDeviceEntryViewSize);
}
void AudioDeviceEntryView::SetHighlighted(bool highlighted) {
is_highlighted_ = highlighted;
if (highlighted) {
SetInkDropMode(Button::InkDropMode::OFF);
set_has_ink_drop_action_on_click(false);
SetBackground(views::CreateSolidBackground(
SkColorSetA(GetInkDropBaseColor(), kEntryHighlightOpacity)));
} else {
SetInkDropMode(Button::InkDropMode::ON);
set_has_ink_drop_action_on_click(true);
SetBackground(nullptr);
}
}
void AudioDeviceEntryView::OnColorsChanged(SkColor foreground_color,
SkColor background_color) {
foreground_color_ = foreground_color;
background_color_ = background_color;
set_ink_drop_base_color(foreground_color_);
device_icon_->SetImage(
gfx::CreateVectorIcon(*icon_, kDeviceIconSize, foreground_color_));
device_name_label_->SetEnabledColor(foreground_color_);
device_name_label_->SetBackgroundColor(background_color_);
if (device_subtext_label_) {
device_subtext_label_->SetEnabledColor(foreground_color_);
device_subtext_label_->SetBackgroundColor(background_color_);
}
// Reapply highlight formatting as some effects rely on these colors.
SetHighlighted(is_highlighted_);
}
DeviceEntryUIType AudioDeviceEntryView::GetType() const {
return DeviceEntryUIType::kAudio;
}
CastDeviceEntryView::CastDeviceEntryView(SkColor foreground_color,
SkColor background_color,
const media_router::UIMediaSink& sink)
: DeviceEntryUI(foreground_color,
background_color,
sink.id,
base::UTF16ToUTF8(sink.friendly_name),
// TODO(muyaoxu): change device icon
&vector_icons::kHeadsetIcon),
CastDialogSinkButton(nullptr,
sink,
/* TODO(muyaoxu): change this to button_tag */ 0) {}
// TODO(muyaoxu): Implement this function
void CastDeviceEntryView::OnColorsChanged(SkColor foreground_color,
SkColor background_color) {}
DeviceEntryUIType CastDeviceEntryView::GetType() const {
return DeviceEntryUIType::kCast;
}
// Copyright 2020 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.
#ifndef CHROME_BROWSER_UI_VIEWS_GLOBAL_MEDIA_CONTROLS_MEDIA_NOTIFICATION_DEVICE_ENTRY_UI_H_
#define CHROME_BROWSER_UI_VIEWS_GLOBAL_MEDIA_CONTROLS_MEDIA_NOTIFICATION_DEVICE_ENTRY_UI_H_
#include "chrome/browser/ui/views/media_router/cast_dialog_sink_button.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/vector_icon_types.h"
#include "ui/views/controls/button/button.h"
namespace views {
class ImageView;
class Label;
} // namespace views
enum class DeviceEntryUIType {
kAudio = 0,
kCast = 1,
kMaxValue = kCast,
};
class DeviceEntryUI {
public:
DeviceEntryUI(SkColor foreground_color,
SkColor background_color,
const std::string& raw_device_id,
const std::string& device_name,
const gfx::VectorIcon* icon_,
const std::string& subtext = "");
DeviceEntryUI(const DeviceEntryUI&) = delete;
DeviceEntryUI& operator=(const DeviceEntryUI&) = delete;
virtual ~DeviceEntryUI() = default;
const std::string& raw_device_id() const { return raw_device_id_; }
const std::string& device_name() const { return device_name_; }
virtual void OnColorsChanged(SkColor foreground_color,
SkColor background_color) = 0;
virtual DeviceEntryUIType GetType() const = 0;
std::string GetEntryLabelForTesting();
bool GetEntryIsHighlightedForTesting() const { return is_highlighted_; }
protected:
SkColor foreground_color_, background_color_;
const std::string raw_device_id_;
const std::string device_name_;
bool is_highlighted_ = false;
const gfx::VectorIcon* const icon_;
views::Label* device_name_label_ = nullptr;
};
class AudioDeviceEntryView : public views::Button, public DeviceEntryUI {
public:
AudioDeviceEntryView(SkColor foreground_color,
SkColor background_color,
const std::string& raw_device_id,
const std::string& name,
const std::string& subtext = "");
~AudioDeviceEntryView() override = default;
void SetHighlighted(bool highlighted);
// DeviceEntryUI
void OnColorsChanged(SkColor foreground_color,
SkColor background_color) override;
DeviceEntryUIType GetType() const override;
private:
views::View* icon_container_ = nullptr;
views::ImageView* device_icon_ = nullptr;
views::View* labels_container_ = nullptr;
views::Label* device_subtext_label_ = nullptr;
};
class CastDeviceEntryView : public DeviceEntryUI,
public media_router::CastDialogSinkButton {
public:
CastDeviceEntryView(SkColor foreground_color,
SkColor background_color,
const media_router::UIMediaSink& sink);
~CastDeviceEntryView() override = default;
// DeviceEntryUI
void OnColorsChanged(SkColor foreground_color,
SkColor background_color) override;
DeviceEntryUIType GetType() const override;
};
#endif // CHROME_BROWSER_UI_VIEWS_GLOBAL_MEDIA_CONTROLS_MEDIA_NOTIFICATION_DEVICE_ENTRY_UI_H_
...@@ -8,167 +8,27 @@ ...@@ -8,167 +8,27 @@
#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"
#include "chrome/browser/ui/media_router/cast_dialog_model.h"
#include "chrome/browser/ui/views/global_media_controls/media_notification_device_selector_view_delegate.h" #include "chrome/browser/ui/views/global_media_controls/media_notification_device_selector_view_delegate.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "components/vector_icons/vector_icons.h"
#include "media/audio/audio_device_description.h" #include "media/audio/audio_device_description.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/bubble/bubble_border.h" #include "ui/views/bubble/bubble_border.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
#include "ui/views/style/typography.h"
namespace { namespace {
// Constants for the DeviceEntryView
constexpr gfx::Insets kIconContainerInsets{10, 15};
constexpr int kDeviceIconSize = 18;
constexpr gfx::Insets kLabelsContainerInsets{18, 0};
constexpr gfx::Size kDeviceEntryViewSize{400, 30};
constexpr int kEntryHighlightOpacity = 45;
// Constants for the MediaNotificationDeviceSelectorView // Constants for the MediaNotificationDeviceSelectorView
constexpr gfx::Insets kExpandButtonStripInsets{6, 15}; constexpr gfx::Insets kExpandButtonStripInsets{6, 15};
constexpr gfx::Size kExpandButtonStripSize{400, 30}; constexpr gfx::Size kExpandButtonStripSize{400, 30};
constexpr gfx::Insets kExpandButtonBorderInsets{4, 8}; constexpr gfx::Insets kExpandButtonBorderInsets{4, 8};
class DeviceEntryView : public views::Button {
public:
DeviceEntryView(const SkColor& foreground_color,
const SkColor& background_color,
const std::string& raw_device_id,
const std::string& name,
const std::string& subtext = "");
const std::string& GetDeviceId() { return raw_device_id_; }
const std::string& GetDeviceName() { return device_name_; }
void SetHighlighted(bool highlighted);
void OnColorsChanged(const SkColor& foreground_color,
const SkColor& background_color);
bool is_highlighted_for_testing() { return is_highlighted_; }
protected:
SkColor foreground_color_, background_color_;
const std::string raw_device_id_, device_name_;
bool is_highlighted_ = false;
views::View* icon_container_;
views::ImageView* device_icon_;
views::View* labels_container_;
views::Label* device_name_label_;
views::Label* device_subtext_label_ = nullptr;
};
// The maximum number of audio devices to count when recording the // The maximum number of audio devices to count when recording the
// Media.GlobalMediaControls.NumberOfAvailableAudioDevices histogram. 30 was // Media.GlobalMediaControls.NumberOfAvailableAudioDevices histogram. 30 was
// chosen because it would be very unlikely to see a user with 30+ audio // chosen because it would be very unlikely to see a user with 30+ audio
// devices. // devices.
const int kAudioDevicesCountHistogramMax = 30; const int kAudioDevicesCountHistogramMax = 30;
} // anonymous namespace
DeviceEntryView::DeviceEntryView(const SkColor& foreground_color,
const SkColor& background_color,
const std::string& raw_device_id,
const std::string& name,
const std::string& subtext)
: foreground_color_(foreground_color),
background_color_(background_color),
raw_device_id_(raw_device_id),
device_name_(name) {
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal));
icon_container_ = AddChildView(std::make_unique<views::View>());
auto* icon_container_layout =
icon_container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kHorizontal, kIconContainerInsets));
icon_container_layout->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kCenter);
icon_container_layout->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kCenter);
device_icon_ =
icon_container_->AddChildView(std::make_unique<views::ImageView>());
device_icon_->SetImage(gfx::CreateVectorIcon(
vector_icons::kHeadsetIcon, kDeviceIconSize, foreground_color));
labels_container_ = AddChildView(std::make_unique<views::View>());
auto* labels_container_layout_ =
labels_container_->SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, kLabelsContainerInsets));
labels_container_layout_->set_main_axis_alignment(
views::BoxLayout::MainAxisAlignment::kCenter);
labels_container_layout_->set_cross_axis_alignment(
views::BoxLayout::CrossAxisAlignment::kStart);
views::Label::CustomFont device_name_label_font{
views::Label::GetDefaultFontList().DeriveWithSizeDelta(1)};
device_name_label_ =
labels_container_->AddChildView(std::make_unique<views::Label>(
base::UTF8ToUTF16(device_name_), device_name_label_font));
device_name_label_->SetEnabledColor(foreground_color);
device_name_label_->SetBackgroundColor(background_color);
if (!subtext.empty()) {
device_subtext_label_ = labels_container_->AddChildView(
std::make_unique<views::Label>(base::UTF8ToUTF16(subtext)));
device_subtext_label_->SetTextStyle(
views::style::TextStyle::STYLE_SECONDARY);
device_subtext_label_->SetEnabledColor(foreground_color);
device_subtext_label_->SetBackgroundColor(background_color);
}
// Ensures that hovering over these items also hovers this view.
icon_container_->set_can_process_events_within_subtree(false);
labels_container_->set_can_process_events_within_subtree(false);
SetFocusBehavior(views::View::FocusBehavior::ALWAYS);
SetInkDropMode(Button::InkDropMode::ON);
set_ink_drop_base_color(foreground_color);
set_has_ink_drop_action_on_click(true);
SetPreferredSize(kDeviceEntryViewSize);
}
void DeviceEntryView::SetHighlighted(bool highlighted) {
is_highlighted_ = highlighted;
if (highlighted) {
SetInkDropMode(Button::InkDropMode::OFF);
set_has_ink_drop_action_on_click(false);
SetBackground(views::CreateSolidBackground(
SkColorSetA(GetInkDropBaseColor(), kEntryHighlightOpacity)));
} else {
SetInkDropMode(Button::InkDropMode::ON);
set_has_ink_drop_action_on_click(true);
SetBackground(nullptr);
}
}
void DeviceEntryView::OnColorsChanged(const SkColor& foreground_color,
const SkColor& background_color) {
foreground_color_ = foreground_color;
background_color_ = background_color;
set_ink_drop_base_color(foreground_color_);
device_icon_->SetImage(gfx::CreateVectorIcon(
vector_icons::kHeadsetIcon, kDeviceIconSize, foreground_color_));
device_name_label_->SetEnabledColor(foreground_color_);
device_name_label_->SetBackgroundColor(background_color_);
if (device_subtext_label_) {
device_subtext_label_->SetEnabledColor(foreground_color_);
device_subtext_label_->SetBackgroundColor(background_color_);
}
// Reapply highlight formatting as some effects rely on these colors.
SetHighlighted(is_highlighted_);
}
namespace {
class ExpandDeviceSelectorButton : public IconLabelBubbleView { class ExpandDeviceSelectorButton : public IconLabelBubbleView {
public: public:
explicit ExpandDeviceSelectorButton(IconLabelBubbleView::Delegate* delegate); explicit ExpandDeviceSelectorButton(IconLabelBubbleView::Delegate* delegate);
...@@ -218,6 +78,7 @@ void ExpandDeviceSelectorButton::OnColorsChanged() { ...@@ -218,6 +78,7 @@ void ExpandDeviceSelectorButton::OnColorsChanged() {
MediaNotificationDeviceSelectorView::MediaNotificationDeviceSelectorView( MediaNotificationDeviceSelectorView::MediaNotificationDeviceSelectorView(
MediaNotificationDeviceSelectorViewDelegate* delegate, MediaNotificationDeviceSelectorViewDelegate* delegate,
std::unique_ptr<media_router::CastDialogController> controller,
const std::string& current_device_id, const std::string& current_device_id,
const SkColor& foreground_color, const SkColor& foreground_color,
const SkColor& background_color) const SkColor& background_color)
...@@ -243,12 +104,11 @@ MediaNotificationDeviceSelectorView::MediaNotificationDeviceSelectorView( ...@@ -243,12 +104,11 @@ MediaNotificationDeviceSelectorView::MediaNotificationDeviceSelectorView(
std::make_unique<ExpandDeviceSelectorButton>(this)); std::make_unique<ExpandDeviceSelectorButton>(this));
expand_button_->set_listener(this); expand_button_->set_listener(this);
audio_device_entries_container_ = device_entry_views_container_ = AddChildView(std::make_unique<views::View>());
AddChildView(std::make_unique<views::View>()); device_entry_views_container_->SetLayoutManager(
audio_device_entries_container_->SetLayoutManager(
std::make_unique<views::BoxLayout>( std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical)); views::BoxLayout::Orientation::kVertical));
audio_device_entries_container_->SetVisible(false); device_entry_views_container_->SetVisible(false);
SetBackground(views::CreateSolidBackground(background_color_)); SetBackground(views::CreateSolidBackground(background_color_));
// Set the size of this view // Set the size of this view
...@@ -271,33 +131,36 @@ MediaNotificationDeviceSelectorView::MediaNotificationDeviceSelectorView( ...@@ -271,33 +131,36 @@ MediaNotificationDeviceSelectorView::MediaNotificationDeviceSelectorView(
base::BindRepeating(&MediaNotificationDeviceSelectorView:: base::BindRepeating(&MediaNotificationDeviceSelectorView::
UpdateIsAudioDeviceSwitchingEnabled, UpdateIsAudioDeviceSwitchingEnabled,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
if (controller) {
cast_controller_ = std::move(controller);
cast_controller_->AddObserver(this);
}
} }
void MediaNotificationDeviceSelectorView::UpdateCurrentAudioDevice( void MediaNotificationDeviceSelectorView::UpdateCurrentAudioDevice(
const std::string& current_device_id) { const std::string& current_device_id) {
if (current_device_entry_view_) if (current_audio_device_entry_view_)
current_device_entry_view_->SetHighlighted(false); current_audio_device_entry_view_->SetHighlighted(false);
// Find DeviceEntryView* from |device_entry_ui_map_| with |current_device_id|.
auto it = base::ranges::find_if( auto it = base::ranges::find_if(
audio_device_entries_container_->children(), device_entry_ui_map_, [&current_device_id](const auto& pair) {
[&current_device_id](auto& item) { return pair.second->raw_device_id() == current_device_id;
return static_cast<DeviceEntryView*>(item)->GetDeviceId() ==
current_device_id;
}); });
if (it == audio_device_entries_container_->children().end()) { if (it == device_entry_ui_map_.end()) {
current_device_entry_view_ = nullptr; current_audio_device_entry_view_ = nullptr;
current_device_id_ = ""; current_device_id_ = "";
return; return;
} }
current_device_id_ = current_device_id; current_device_id_ = current_device_id;
current_device_entry_view_ = static_cast<DeviceEntryView*>(*it); current_audio_device_entry_view_ =
current_device_entry_view_->SetHighlighted(true); static_cast<AudioDeviceEntryView*>(it->second);
audio_device_entries_container_->ReorderChildView(current_device_entry_view_, current_audio_device_entry_view_->SetHighlighted(true);
0); device_entry_views_container_->ReorderChildView(
current_audio_device_entry_view_, 0);
current_device_entry_view_->Layout(); current_audio_device_entry_view_->Layout();
} }
MediaNotificationDeviceSelectorView::~MediaNotificationDeviceSelectorView() { MediaNotificationDeviceSelectorView::~MediaNotificationDeviceSelectorView() {
...@@ -315,16 +178,18 @@ MediaNotificationDeviceSelectorView::~MediaNotificationDeviceSelectorView() { ...@@ -315,16 +178,18 @@ MediaNotificationDeviceSelectorView::~MediaNotificationDeviceSelectorView() {
void MediaNotificationDeviceSelectorView::UpdateAvailableAudioDevices( void MediaNotificationDeviceSelectorView::UpdateAvailableAudioDevices(
const media::AudioDeviceDescriptions& device_descriptions) { const media::AudioDeviceDescriptions& device_descriptions) {
audio_device_entries_container_->RemoveAllChildViews(true); RemoveDevicesOfType(DeviceEntryUIType::kAudio);
current_device_entry_view_ = nullptr; current_audio_device_entry_view_ = nullptr;
bool current_device_still_exists = false; bool current_device_still_exists = false;
for (auto description : device_descriptions) { for (auto description : device_descriptions) {
auto device_entry_view = std::make_unique<DeviceEntryView>( auto device_entry_view = std::make_unique<AudioDeviceEntryView>(
foreground_color_, background_color_, description.unique_id, foreground_color_, background_color_, description.unique_id,
description.device_name, ""); description.device_name, "");
device_entry_view->set_listener(this); device_entry_view->set_listener(this);
audio_device_entries_container_->AddChildView(std::move(device_entry_view)); device_entry_view->set_tag(next_tag_++);
device_entry_ui_map_[device_entry_view->tag()] = device_entry_view.get();
device_entry_views_container_->AddChildView(std::move(device_entry_view));
if (!current_device_still_exists && if (!current_device_still_exists &&
description.unique_id == current_device_id_) description.unique_id == current_device_id_)
current_device_still_exists = true; current_device_still_exists = true;
...@@ -346,10 +211,8 @@ void MediaNotificationDeviceSelectorView::OnColorsChanged( ...@@ -346,10 +211,8 @@ void MediaNotificationDeviceSelectorView::OnColorsChanged(
background_color_ = background_color; background_color_ = background_color;
SetBackground(views::CreateSolidBackground(background_color_)); SetBackground(views::CreateSolidBackground(background_color_));
for (auto it : device_entry_ui_map_) {
for (auto* view : audio_device_entries_container_->children()) { it.second->OnColorsChanged(foreground_color_, background_color_);
static_cast<DeviceEntryView*>(view)->OnColorsChanged(foreground_color_,
background_color_);
} }
expand_button_->OnColorsChanged(); expand_button_->OnColorsChanged();
...@@ -367,13 +230,8 @@ void MediaNotificationDeviceSelectorView::ButtonPressed( ...@@ -367,13 +230,8 @@ void MediaNotificationDeviceSelectorView::ButtonPressed(
ShowDevices(); ShowDevices();
delegate_->OnDeviceSelectorViewSizeChanged(); delegate_->OnDeviceSelectorViewSizeChanged();
} else { } else if (GetDeviceEntryUI(sender)->GetType() == DeviceEntryUIType::kAudio) {
DCHECK(std::find(audio_device_entries_container_->children().cbegin(), delegate_->OnAudioSinkChosen(GetDeviceEntryUI(sender)->raw_device_id());
audio_device_entries_container_->children().cend(),
sender) !=
audio_device_entries_container_->children().end());
delegate_->OnAudioSinkChosen(
static_cast<DeviceEntryView*>(sender)->GetDeviceId());
} }
} }
...@@ -388,21 +246,18 @@ SkColor MediaNotificationDeviceSelectorView::GetIconLabelBubbleBackgroundColor() ...@@ -388,21 +246,18 @@ SkColor MediaNotificationDeviceSelectorView::GetIconLabelBubbleBackgroundColor()
} }
views::Button* views::Button*
MediaNotificationDeviceSelectorView::get_expand_button_for_testing() { MediaNotificationDeviceSelectorView::GetExpandButtonForTesting() {
return expand_button_; return expand_button_;
} }
// static std::string MediaNotificationDeviceSelectorView::GetEntryLabelForTesting(
std::string MediaNotificationDeviceSelectorView::get_entry_label_for_testing(
views::View* entry_view) { views::View* entry_view) {
return static_cast<DeviceEntryView*>(entry_view)->GetDeviceName(); return GetDeviceEntryUI(entry_view)->device_name();
} }
// static bool MediaNotificationDeviceSelectorView::GetEntryIsHighlightedForTesting(
bool MediaNotificationDeviceSelectorView::get_entry_is_highlighted_for_testing(
views::View* entry_view) { views::View* entry_view) {
return static_cast<DeviceEntryView*>(entry_view) return GetDeviceEntryUI(entry_view)->GetEntryIsHighlightedForTesting();
->is_highlighted_for_testing();
} }
void MediaNotificationDeviceSelectorView::ShowDevices() { void MediaNotificationDeviceSelectorView::ShowDevices() {
...@@ -412,13 +267,13 @@ void MediaNotificationDeviceSelectorView::ShowDevices() { ...@@ -412,13 +267,13 @@ void MediaNotificationDeviceSelectorView::ShowDevices() {
if (!have_devices_been_shown_) { if (!have_devices_been_shown_) {
base::UmaHistogramExactLinear( base::UmaHistogramExactLinear(
kAudioDevicesCountHistogramName, kAudioDevicesCountHistogramName,
audio_device_entries_container_->children().size(), device_entry_views_container_->children().size(),
kAudioDevicesCountHistogramMax); kAudioDevicesCountHistogramMax);
base::UmaHistogramBoolean(kDeviceSelectorOpenedHistogramName, true); base::UmaHistogramBoolean(kDeviceSelectorOpenedHistogramName, true);
have_devices_been_shown_ = true; have_devices_been_shown_ = true;
} }
audio_device_entries_container_->SetVisible(true); device_entry_views_container_->SetVisible(true);
PreferredSizeChanged(); PreferredSizeChanged();
} }
...@@ -426,7 +281,7 @@ void MediaNotificationDeviceSelectorView::HideDevices() { ...@@ -426,7 +281,7 @@ void MediaNotificationDeviceSelectorView::HideDevices() {
DCHECK(is_expanded_); DCHECK(is_expanded_);
is_expanded_ = false; is_expanded_ = false;
audio_device_entries_container_->SetVisible(false); device_entry_views_container_->SetVisible(false);
PreferredSizeChanged(); PreferredSizeChanged();
} }
...@@ -441,26 +296,26 @@ void MediaNotificationDeviceSelectorView::UpdateVisibility() { ...@@ -441,26 +296,26 @@ void MediaNotificationDeviceSelectorView::UpdateVisibility() {
delegate_->OnDeviceSelectorViewSizeChanged(); delegate_->OnDeviceSelectorViewSizeChanged();
} }
// TODO(muyaoxu@):Change the logic to work with Cast devices
bool MediaNotificationDeviceSelectorView::ShouldBeVisible() { bool MediaNotificationDeviceSelectorView::ShouldBeVisible() {
if (!is_audio_device_switching_enabled_) if (!is_audio_device_switching_enabled_)
return false; return false;
// The UI should be visible if there are more than one unique devices. That is // The UI should be visible if there are more than one unique devices. That is
// when: // when:
// * There are at least three devices // * There are at least three devices
// * Or, there are two devices and one of them has the default ID but not the // * Or, there are two devices and one of them has the default ID but not the
// default name. // default name.
if (audio_device_entries_container_->children().size() == 2) { if (device_entry_views_container_->children().size() == 2) {
return base::ranges::any_of( return base::ranges::any_of(
audio_device_entries_container_->children(), [](views::View* view) { device_entry_views_container_->children(), [this](views::View* view) {
auto* entry = static_cast<DeviceEntryView*>(view); DeviceEntryUI* entry = GetDeviceEntryUI(view);
return entry->GetDeviceId() == return entry->raw_device_id() ==
media::AudioDeviceDescription::kDefaultDeviceId && media::AudioDeviceDescription::kDefaultDeviceId &&
entry->GetDeviceName() != entry->device_name() !=
media::AudioDeviceDescription::GetDefaultDeviceName(); media::AudioDeviceDescription::GetDefaultDeviceName();
}); });
} }
return audio_device_entries_container_->children().size() > 2; return device_entry_views_container_->children().size() > 2;
} }
void MediaNotificationDeviceSelectorView::UpdateIsAudioDeviceSwitchingEnabled( void MediaNotificationDeviceSelectorView::UpdateIsAudioDeviceSwitchingEnabled(
...@@ -471,3 +326,43 @@ void MediaNotificationDeviceSelectorView::UpdateIsAudioDeviceSwitchingEnabled( ...@@ -471,3 +326,43 @@ void MediaNotificationDeviceSelectorView::UpdateIsAudioDeviceSwitchingEnabled(
is_audio_device_switching_enabled_ = enabled; is_audio_device_switching_enabled_ = enabled;
UpdateVisibility(); UpdateVisibility();
} }
void MediaNotificationDeviceSelectorView::RemoveDevicesOfType(
DeviceEntryUIType type) {
std::vector<views::View*> views_to_remove;
for (auto* view : device_entry_views_container_->children()) {
if (GetDeviceEntryUI(view)->GetType() == type) {
views_to_remove.push_back(view);
}
}
for (auto* view : views_to_remove) {
device_entry_ui_map_.erase(static_cast<views::Button*>(view)->tag());
device_entry_views_container_->RemoveChildView(view);
delete view;
}
}
DeviceEntryUI* MediaNotificationDeviceSelectorView::GetDeviceEntryUI(
views::View* view) {
auto it = device_entry_ui_map_.find(static_cast<views::Button*>(view)->tag());
DCHECK(it != device_entry_ui_map_.end());
return it->second;
}
void MediaNotificationDeviceSelectorView::OnModelUpdated(
const media_router::CastDialogModel& model) {
RemoveDevicesOfType(DeviceEntryUIType::kCast);
for (auto sink : model.media_sinks()) {
auto device_entry_view = std::make_unique<CastDeviceEntryView>(
foreground_color_, background_color_, sink);
device_entry_view->set_tag(next_tag_++);
device_entry_ui_map_[device_entry_view->tag()] = device_entry_view.get();
device_entry_views_container_->AddChildView(std::move(device_entry_view));
}
SetVisible(true);
delegate_->OnDeviceSelectorViewSizeChanged();
}
void MediaNotificationDeviceSelectorView::OnControllerInvalidated() {
cast_controller_.reset();
}
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
#include "base/callback_list.h" #include "base/callback_list.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/media_router/cast_dialog_controller.h"
#include "chrome/browser/ui/views/global_media_controls/media_notification_device_entry_ui.h"
#include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h"
#include "media/audio/audio_device_description.h" #include "media/audio/audio_device_description.h"
#include "ui/views/controls/button/image_button.h" #include "ui/views/controls/button/image_button.h"
...@@ -14,7 +16,6 @@ ...@@ -14,7 +16,6 @@
#include "ui/views/layout/box_layout.h" #include "ui/views/layout/box_layout.h"
namespace { namespace {
class DeviceEntryView;
class ExpandDeviceSelectorButton; class ExpandDeviceSelectorButton;
const char kAudioDevicesCountHistogramName[] = const char kAudioDevicesCountHistogramName[] =
"Media.GlobalMediaControls.NumberOfAvailableAudioDevices"; "Media.GlobalMediaControls.NumberOfAvailableAudioDevices";
...@@ -29,10 +30,12 @@ class MediaNotificationDeviceSelectorViewDelegate; ...@@ -29,10 +30,12 @@ class MediaNotificationDeviceSelectorViewDelegate;
class MediaNotificationDeviceSelectorView class MediaNotificationDeviceSelectorView
: public views::View, : public views::View,
public views::ButtonListener, public views::ButtonListener,
public IconLabelBubbleView::Delegate { public IconLabelBubbleView::Delegate,
public media_router::CastDialogController::Observer {
public: public:
MediaNotificationDeviceSelectorView( MediaNotificationDeviceSelectorView(
MediaNotificationDeviceSelectorViewDelegate* delegate, MediaNotificationDeviceSelectorViewDelegate* delegate,
std::unique_ptr<media_router::CastDialogController> controller,
const std::string& current_device_id, const std::string& current_device_id,
const SkColor& foreground_color, const SkColor& foreground_color,
const SkColor& background_color); const SkColor& background_color);
...@@ -56,9 +59,13 @@ class MediaNotificationDeviceSelectorView ...@@ -56,9 +59,13 @@ class MediaNotificationDeviceSelectorView
SkColor GetIconLabelBubbleSurroundingForegroundColor() const override; SkColor GetIconLabelBubbleSurroundingForegroundColor() const override;
SkColor GetIconLabelBubbleBackgroundColor() const override; SkColor GetIconLabelBubbleBackgroundColor() const override;
views::Button* get_expand_button_for_testing(); // media_router::CastDialogController::Observer
static std::string get_entry_label_for_testing(views::View* entry_view); void OnModelUpdated(const media_router::CastDialogModel& model) override;
static bool get_entry_is_highlighted_for_testing(views::View* entry_view); void OnControllerInvalidated() override;
views::Button* GetExpandButtonForTesting();
std::string GetEntryLabelForTesting(views::View* entry_view);
bool GetEntryIsHighlightedForTesting(views::View* entry_view);
private: private:
FRIEND_TEST_ALL_PREFIXES(MediaNotificationDeviceSelectorViewTest, FRIEND_TEST_ALL_PREFIXES(MediaNotificationDeviceSelectorViewTest,
...@@ -84,6 +91,8 @@ class MediaNotificationDeviceSelectorView ...@@ -84,6 +91,8 @@ class MediaNotificationDeviceSelectorView
void ShowDevices(); void ShowDevices();
void HideDevices(); void HideDevices();
void RemoveDevicesOfType(DeviceEntryUIType type);
DeviceEntryUI* GetDeviceEntryUI(views::View* view);
bool has_expand_button_been_shown_ = false; bool has_expand_button_been_shown_ = false;
bool have_devices_been_shown_ = false; bool have_devices_been_shown_ = false;
...@@ -93,20 +102,26 @@ class MediaNotificationDeviceSelectorView ...@@ -93,20 +102,26 @@ class MediaNotificationDeviceSelectorView
MediaNotificationDeviceSelectorViewDelegate* const delegate_; MediaNotificationDeviceSelectorViewDelegate* const delegate_;
std::string current_device_id_; std::string current_device_id_;
SkColor foreground_color_, background_color_; SkColor foreground_color_, background_color_;
DeviceEntryView* current_device_entry_view_ = nullptr; AudioDeviceEntryView* current_audio_device_entry_view_ = nullptr;
// Child views // Child views
views::View* expand_button_strip_; views::View* expand_button_strip_ = nullptr;
ExpandDeviceSelectorButton* expand_button_; ExpandDeviceSelectorButton* expand_button_ = nullptr;
views::View* audio_device_entries_container_; views::View* device_entry_views_container_ = nullptr;
std::unique_ptr<MediaNotificationDeviceProvider:: std::unique_ptr<MediaNotificationDeviceProvider::
GetOutputDevicesCallbackList::Subscription> GetOutputDevicesCallbackList::Subscription>
audio_device_subscription_; audio_device_subscription_;
std::unique_ptr<base::RepeatingCallbackList<void(bool)>::Subscription> std::unique_ptr<base::RepeatingCallbackList<void(bool)>::Subscription>
is_device_switching_enabled_subscription_; is_device_switching_enabled_subscription_;
std::unique_ptr<media_router::CastDialogController> cast_controller_;
// Each button has a unique tag, which is used to look up DeviceEntryUI* in
// |device_entry_ui_map_|.
int next_tag_ = 0;
std::map<int, DeviceEntryUI*> device_entry_ui_map_;
base::WeakPtrFactory<MediaNotificationDeviceSelectorView> weak_ptr_factory_{ base::WeakPtrFactory<MediaNotificationDeviceSelectorView> weak_ptr_factory_{
this}; this};
}; };
......
...@@ -123,14 +123,12 @@ class MediaNotificationDeviceSelectorViewTest : public ChromeViewsTestBase { ...@@ -123,14 +123,12 @@ class MediaNotificationDeviceSelectorViewTest : public ChromeViewsTestBase {
ui::EventTimeForNow(), 0, 0)); ui::EventTimeForNow(), 0, 0));
} }
static std::string EntryLabelText(views::View* entry_view) { std::string EntryLabelText(views::View* entry_view) {
return MediaNotificationDeviceSelectorView::get_entry_label_for_testing( return view_->GetEntryLabelForTesting(entry_view);
entry_view);
} }
static bool IsHighlighted(views::View* entry_view) { bool IsHighlighted(views::View* entry_view) {
return MediaNotificationDeviceSelectorView:: return view_->GetEntryIsHighlightedForTesting(entry_view);
get_entry_is_highlighted_for_testing(entry_view);
} }
std::string GetButtonText(views::View* view) { std::string GetButtonText(views::View* view) {
...@@ -150,11 +148,12 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsCreated) { ...@@ -150,11 +148,12 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsCreated) {
provider->AddDevice("Earbuds", "3"); provider->AddDevice("Earbuds", "3");
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* media_router::CastDialogController*/ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
ASSERT_TRUE(view_->audio_device_entries_container_ != nullptr); ASSERT_TRUE(view_->device_entry_views_container_ != nullptr);
auto container_children = view_->audio_device_entries_container_->children(); auto container_children = view_->device_entry_views_container_->children();
ASSERT_EQ(container_children.size(), 3u); ASSERT_EQ(container_children.size(), 3u);
EXPECT_EQ(EntryLabelText(container_children.at(0)), "Speaker"); EXPECT_EQ(EntryLabelText(container_children.at(0)), "Speaker");
...@@ -171,12 +170,13 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -171,12 +170,13 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
provider->AddDevice("Earbuds", "3"); provider->AddDevice("Earbuds", "3");
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* media_router::CastDialogController*/ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
ASSERT_TRUE(view_->expand_button_); ASSERT_TRUE(view_->expand_button_);
EXPECT_FALSE(view_->audio_device_entries_container_->GetVisible()); EXPECT_FALSE(view_->device_entry_views_container_->GetVisible());
SimulateButtonClick(view_->get_expand_button_for_testing()); SimulateButtonClick(view_->GetExpandButtonForTesting());
EXPECT_TRUE(view_->audio_device_entries_container_->GetVisible()); EXPECT_TRUE(view_->device_entry_views_container_->GetVisible());
} }
TEST_F(MediaNotificationDeviceSelectorViewTest, TEST_F(MediaNotificationDeviceSelectorViewTest,
...@@ -190,14 +190,14 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -190,14 +190,14 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
provider->AddDevice("Earbuds", "3"); provider->AddDevice("Earbuds", "3");
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* media_router::CastDialogController*/ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
EXPECT_CALL(delegate, OnAudioSinkChosen("1")).Times(1); EXPECT_CALL(delegate, OnAudioSinkChosen("1")).Times(1);
EXPECT_CALL(delegate, OnAudioSinkChosen("2")).Times(1); EXPECT_CALL(delegate, OnAudioSinkChosen("2")).Times(1);
EXPECT_CALL(delegate, OnAudioSinkChosen("3")).Times(1); EXPECT_CALL(delegate, OnAudioSinkChosen("3")).Times(1);
for (views::View* child : for (views::View* child : view_->device_entry_views_container_->children()) {
view_->audio_device_entries_container_->children()) {
SimulateButtonClick(child); SimulateButtonClick(child);
} }
} }
...@@ -212,10 +212,10 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, CurrentDeviceHighlighted) { ...@@ -212,10 +212,10 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, CurrentDeviceHighlighted) {
provider->AddDevice("Earbuds", "3"); provider->AddDevice("Earbuds", "3");
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "3", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* media_router::CastDialogController*/ nullptr, "3",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
auto* first_entry = auto* first_entry = view_->device_entry_views_container_->children().front();
view_->audio_device_entries_container_->children().front();
EXPECT_EQ(EntryLabelText(first_entry), "Earbuds"); EXPECT_EQ(EntryLabelText(first_entry), "Earbuds");
EXPECT_TRUE(IsHighlighted(first_entry)); EXPECT_TRUE(IsHighlighted(first_entry));
} }
...@@ -229,14 +229,16 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceHighlightedOnChange) { ...@@ -229,14 +229,16 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceHighlightedOnChange) {
provider->AddDevice("Earbuds", "3"); provider->AddDevice("Earbuds", "3");
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* media_router::CastDialogController*/ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
auto& container_children = view_->audio_device_entries_container_->children(); auto& container_children = view_->device_entry_views_container_->children();
// There should be only one highlighted button. It should be the first button. // There should be only one highlighted button. It should be the first button.
// It's text should be "Speaker" // It's text should be "Speaker"
EXPECT_EQ(base::ranges::count_if(container_children, IsHighlighted), 1); auto highlight_pred = [this](views::View* v) { return IsHighlighted(v); };
EXPECT_EQ(base::ranges::find_if(container_children, IsHighlighted), EXPECT_EQ(base::ranges::count_if(container_children, highlight_pred), 1);
EXPECT_EQ(base::ranges::find_if(container_children, highlight_pred),
container_children.begin()); container_children.begin());
EXPECT_EQ(EntryLabelText(container_children.front()), "Speaker"); EXPECT_EQ(EntryLabelText(container_children.front()), "Speaker");
...@@ -244,8 +246,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceHighlightedOnChange) { ...@@ -244,8 +246,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceHighlightedOnChange) {
view_->UpdateCurrentAudioDevice("3"); view_->UpdateCurrentAudioDevice("3");
// The button for "Earbuds" should come before all others & be highlighted. // The button for "Earbuds" should come before all others & be highlighted.
EXPECT_EQ(base::ranges::count_if(container_children, IsHighlighted), 1); EXPECT_EQ(base::ranges::count_if(container_children, highlight_pred), 1);
EXPECT_EQ(base::ranges::find_if(container_children, IsHighlighted), EXPECT_EQ(base::ranges::find_if(container_children, highlight_pred),
container_children.begin()); container_children.begin());
EXPECT_EQ(EntryLabelText(container_children.front()), "Earbuds"); EXPECT_EQ(EntryLabelText(container_children.front()), "Earbuds");
} }
...@@ -260,7 +262,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsChange) { ...@@ -260,7 +262,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsChange) {
provider->AddDevice("Earbuds", "3"); provider->AddDevice("Earbuds", "3");
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* media_router::CastDialogController*/ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
provider->ResetDevices(); provider->ResetDevices();
// Make "Monitor" the default device. // Make "Monitor" the default device.
...@@ -269,8 +272,7 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsChange) { ...@@ -269,8 +272,7 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsChange) {
provider->RunUICallback(); provider->RunUICallback();
{ {
auto& container_children = auto& container_children = view_->device_entry_views_container_->children();
view_->audio_device_entries_container_->children();
EXPECT_EQ(container_children.size(), 1u); EXPECT_EQ(container_children.size(), 1u);
ASSERT_FALSE(container_children.empty()); ASSERT_FALSE(container_children.empty());
EXPECT_EQ(EntryLabelText(container_children.front()), "Monitor"); EXPECT_EQ(EntryLabelText(container_children.front()), "Monitor");
...@@ -287,8 +289,7 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsChange) { ...@@ -287,8 +289,7 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceButtonsChange) {
provider->RunUICallback(); provider->RunUICallback();
{ {
auto& container_children = auto& container_children = view_->device_entry_views_container_->children();
view_->audio_device_entries_container_->children();
EXPECT_EQ(container_children.size(), 3u); EXPECT_EQ(container_children.size(), 3u);
ASSERT_FALSE(container_children.empty()); ASSERT_FALSE(container_children.empty());
...@@ -311,8 +312,9 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, VisibilityChanges) { ...@@ -311,8 +312,9 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, VisibilityChanges) {
EXPECT_CALL(delegate, OnDeviceSelectorViewSizeChanged).Times(2); EXPECT_CALL(delegate, OnDeviceSelectorViewSizeChanged).Times(2);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, media::AudioDeviceDescription::kDefaultDeviceId, &delegate, /* CastDialogController */ nullptr,
gfx::kPlaceholderColor, gfx::kPlaceholderColor); media::AudioDeviceDescription::kDefaultDeviceId, gfx::kPlaceholderColor,
gfx::kPlaceholderColor);
EXPECT_FALSE(view_->GetVisible()); EXPECT_FALSE(view_->GetVisible());
testing::Mock::VerifyAndClearExpectations(&delegate); testing::Mock::VerifyAndClearExpectations(&delegate);
...@@ -346,7 +348,9 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceChangeIsNotSupported) { ...@@ -346,7 +348,9 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, DeviceChangeIsNotSupported) {
delegate.supports_switching = false; delegate.supports_switching = false;
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* CastDialogController */ nullptr,
media::AudioDeviceDescription::kDefaultDeviceId, gfx::kPlaceholderColor,
gfx::kPlaceholderColor);
EXPECT_FALSE(view_->GetVisible()); EXPECT_FALSE(view_->GetVisible());
delegate.supports_switching = true; delegate.supports_switching = true;
...@@ -365,7 +369,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -365,7 +369,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
histogram_tester_.ExpectTotalCount(kAudioDevicesCountHistogramName, 0); histogram_tester_.ExpectTotalCount(kAudioDevicesCountHistogramName, 0);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* CastDialogController */ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
view_->ShowDevices(); view_->ShowDevices();
histogram_tester_.ExpectTotalCount(kAudioDevicesCountHistogramName, 1); histogram_tester_.ExpectTotalCount(kAudioDevicesCountHistogramName, 1);
...@@ -389,7 +394,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -389,7 +394,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 0); histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 0);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* CastDialogController */ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
EXPECT_FALSE(view_->GetVisible()); EXPECT_FALSE(view_->GetVisible());
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 0); histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 0);
...@@ -407,7 +413,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -407,7 +413,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
delegate.supports_switching = true; delegate.supports_switching = true;
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* CastDialogController */ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
EXPECT_TRUE(view_->GetVisible()); EXPECT_TRUE(view_->GetVisible());
histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 2); histogram_tester_.ExpectTotalCount(kDeviceSelectorAvailableHistogramName, 2);
...@@ -431,7 +438,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -431,7 +438,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 0); histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 0);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* CastDialogController */ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
EXPECT_FALSE(view_->GetVisible()); EXPECT_FALSE(view_->GetVisible());
view_.reset(); view_.reset();
...@@ -441,7 +449,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -441,7 +449,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
delegate.supports_switching = true; delegate.supports_switching = true;
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* CastDialogController */ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
view_.reset(); view_.reset();
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 1); histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 1);
...@@ -449,7 +458,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest, ...@@ -449,7 +458,8 @@ TEST_F(MediaNotificationDeviceSelectorViewTest,
1); 1);
view_ = std::make_unique<MediaNotificationDeviceSelectorView>( view_ = std::make_unique<MediaNotificationDeviceSelectorView>(
&delegate, "1", gfx::kPlaceholderColor, gfx::kPlaceholderColor); &delegate, /* CastDialogController */ nullptr, "1",
gfx::kPlaceholderColor, gfx::kPlaceholderColor);
view_->ShowDevices(); view_->ShowDevices();
histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 2); histogram_tester_.ExpectTotalCount(kDeviceSelectorOpenedHistogramName, 2);
......
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