#include "ash/system/cast/media_cast_audio_selector_view.h"
#include <algorithm>
#include <utility>
#include "ash/system/audio/output_audio_sliders_view.h"
#include "ash/system/cast/media_cast_list_view.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/observer_list.h"
#include "base/strings/utf_string_conversions.h"
#include "components/global_media_controls/public/views/media_item_ui_view.h"
#include "components/vector_icons/vector_icons.h"
#include "media/audio/audio_device_description.h"
#include "media/base/media_switches.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/models/image_model.h"
#include "ui/views/background.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/box_layout_view.h"
namespace ash {
namespace {
constexpr int kSelectorViewWidth = 400;
}
MediaCastAudioSelectorView::MediaCastAudioSelectorView(
mojo::PendingRemote<global_media_controls::mojom::DeviceListHost>
device_list_host,
mojo::PendingReceiver<global_media_controls::mojom::DeviceListClient>
receiver,
base::RepeatingClosure stop_casting_callback,
bool show_devices)
: device_list_host_(std::move(device_list_host)) {
views::Builder<views::View>(this)
.SetBackground(views::CreateSolidBackground(SK_ColorTRANSPARENT))
.SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical))
.SetPreferredSize(
gfx::Size(kSelectorViewWidth, GetHeightForWidth(kSelectorViewWidth)))
.AddChildren(
views::Builder<views::BoxLayoutView>()
.CopyAddressTo(&list_view_container_)
.SetID(kListViewContainerId)
.SetOrientation(views::BoxLayout::Orientation::kVertical)
.SetVisible(false)
.AddChildren(
views::Builder<views::View>(
std::make_unique<OutputAudioSlidersView>(
base::BindRepeating(
&MediaCastAudioSelectorView::OnDevicesUpdated,
base::Unretained(this),
DeviceType::kAudioDevice)))
.SetID(kMediaAudioListViewId))
.AddChildren(
views::Builder<views::View>(
std::make_unique<MediaCastListView>(
std::move(stop_casting_callback),
base::BindRepeating(
&MediaCastAudioSelectorView::OnCastDeviceSelected,
base::Unretained(this)),
base::BindRepeating(
&MediaCastAudioSelectorView::OnDevicesUpdated,
base::Unretained(this), DeviceType::kCastDevice),
std::move(receiver)))
.SetID(kMediaCastListViewId)))
.BuildChildren();
if (show_devices) {
ShowDevices();
}
DeprecatedLayoutImmediately();
}
MediaCastAudioSelectorView::~MediaCastAudioSelectorView() = default;
void MediaCastAudioSelectorView::SetMediaItemUIView(
global_media_controls::MediaItemUIView* view) {
media_item_ui_ = view;
}
void MediaCastAudioSelectorView::OnColorsChanged(SkColor foreground_color,
SkColor background_color) {}
void MediaCastAudioSelectorView::UpdateCurrentAudioDevice(
const std::string& current_device_id) {}
void MediaCastAudioSelectorView::MediaCastAudioSelectorView::ShowDevices() {
DCHECK(!is_expanded_);
is_expanded_ = true;
NotifyAccessibilityEventDeprecated(ax::mojom::Event::kExpandedChanged, true);
list_view_container_->SetVisible(true);
if (const auto& children = list_view_container_->children();
!children.empty()) {
children[0]->RequestFocus();
}
}
void MediaCastAudioSelectorView::HideDevices() {
DCHECK(is_expanded_);
is_expanded_ = false;
NotifyAccessibilityEventDeprecated(ax::mojom::Event::kExpandedChanged, true);
list_view_container_->SetVisible(false);
PreferredSizeChanged();
}
bool MediaCastAudioSelectorView::IsDeviceSelectorExpanded() {
return is_expanded_;
}
void MediaCastAudioSelectorView::OnDevicesUpdated(DeviceType device_type,
bool has_devices) {
device_type_bits_[static_cast<int>(device_type)] = has_devices;
if (media_item_ui_) {
media_item_ui_->OnDeviceSelectorViewDevicesChanged(device_type_bits_.any());
}
}
void MediaCastAudioSelectorView::OnCastDeviceSelected(
const std::string& device_id) {
if (device_list_host_) {
device_list_host_->SelectDevice(device_id);
}
}
BEGIN_METADATA(MediaCastAudioSelectorView)
END_METADATA
}