Commit d37f3a32 authored by Takumi Fujimoto's avatar Takumi Fujimoto Committed by Commit Bot

Implement sink list button for Harmony Cast dialog

- Add CastDialogSinkButton, which will be used for sink list items in
  the Harmony Cast dialog. It's a subclass of HoverButton that shows a
  device icon and an optional status indicator (checkmark or throbber).
- Add UIMediaSink, a struct containing data used to populate the button
- Add Skia icons used by the button: Cast for EDU, input, speaker,
  speaker group, and TV

Screenshot of the button (two of them) in a WIP dialog:
https://drive.google.com/file/d/1M1R9jO-VHEO18aA3pTpoQBI4FHMU5MEf/view?usp=sharing

Dimensions and colors are subject to change in later CLs.

Bug: 826089, 826393
Change-Id: I0eef58e1c0b9bf2cff3b3d146e911d3a18c7d23c
Reviewed-on: https://chromium-review.googlesource.com/996458
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Reviewed-by: default avatarBret Sepulveda <bsep@chromium.org>
Reviewed-by: default avatarEvan Stade <estade@chromium.org>
Reviewed-by: default avatarAdam Parker <amp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#550722}
parent c249e29d
...@@ -35,6 +35,7 @@ aggregate_vector_icons("chrome_vector_icons") { ...@@ -35,6 +35,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"browser_tools_error_touch.icon", "browser_tools_error_touch.icon",
"browser_tools_touch.icon", "browser_tools_touch.icon",
"browser_tools_update_touch.icon", "browser_tools_update_touch.icon",
"cast_for_education.icon",
"content_paste.icon", "content_paste.icon",
"cookie.icon", "cookie.icon",
"crashed_tab.icon", "crashed_tab.icon",
...@@ -54,6 +55,7 @@ aggregate_vector_icons("chrome_vector_icons") { ...@@ -54,6 +55,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"google_pay_logo_with_vertical_separator.icon", "google_pay_logo_with_vertical_separator.icon",
"horizontal_menu.icon", "horizontal_menu.icon",
"incognito.icon", "incognito.icon",
"input.icon",
"key.icon", "key.icon",
"laptop.icon", "laptop.icon",
"launch.icon", "launch.icon",
...@@ -80,6 +82,8 @@ aggregate_vector_icons("chrome_vector_icons") { ...@@ -80,6 +82,8 @@ aggregate_vector_icons("chrome_vector_icons") {
"settings.icon", "settings.icon",
"signin_button_drop_down_arrow.icon", "signin_button_drop_down_arrow.icon",
"smartphone.icon", "smartphone.icon",
"speaker.icon",
"speaker_group.icon",
"supervisor_account.icon", "supervisor_account.icon",
"supervisor_account_circle.icon", "supervisor_account_circle.icon",
"sync.icon", "sync.icon",
...@@ -107,6 +111,7 @@ aggregate_vector_icons("chrome_vector_icons") { ...@@ -107,6 +111,7 @@ aggregate_vector_icons("chrome_vector_icons") {
"tablet.icon", "tablet.icon",
"translate.icon", "translate.icon",
"trash_can.icon", "trash_can.icon",
"tv.icon",
"usb_security_key.icon", "usb_security_key.icon",
"user_account_avatar.icon", "user_account_avatar.icon",
"user_menu_guest.icon", "user_menu_guest.icon",
......
// 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.
MOVE_TO, 42, 6,
H_LINE_TO, 6,
R_CUBIC_TO, -2.2f, 0, -4, 1.8f, -4, 4,
R_V_LINE_TO, 6,
R_H_LINE_TO, 4,
R_V_LINE_TO, -6,
R_H_LINE_TO, 36,
R_V_LINE_TO, 28,
H_LINE_TO, 28,
R_V_LINE_TO, 4,
R_H_LINE_TO, 14,
R_CUBIC_TO, 2.2f, 0, 4, -1.8f, 4, -4,
V_LINE_TO, 10,
R_CUBIC_TO, 0, -2.2f, -1.8f, -4, -4, -4,
CLOSE,
MOVE_TO, 2, 36,
R_V_LINE_TO, 6,
R_H_LINE_TO, 6,
R_CUBIC_TO, 0, -3.32f, -2.68f, -6, -6, -6,
CLOSE,
R_MOVE_TO, 0, -8,
R_V_LINE_TO, 4,
R_CUBIC_TO, 5.52f, 0, 10, 4.48f, 10, 10,
R_H_LINE_TO, 4,
R_CUBIC_TO, 0, -7.74f, -6.26f, -14, -14, -14,
CLOSE,
R_MOVE_TO, 0, -8,
R_V_LINE_TO, 4,
R_CUBIC_TO, 9.94f, 0, 18, 8.06f, 18, 18,
R_H_LINE_TO, 4,
R_CUBIC_TO, 0, -12.16f, -9.86f, -22, -22, -22,
CLOSE,
R_MOVE_TO, 20, 2.18f,
R_V_LINE_TO, 4,
LINE_TO, 29, 30,
R_LINE_TO, 7, -3.82f,
R_V_LINE_TO, -4,
LINE_TO, 29, 26,
R_LINE_TO, -7, -3.82f,
CLOSE,
MOVE_TO, 29, 12,
R_LINE_TO, -11, 6,
R_LINE_TO, 11, 6,
R_LINE_TO, 11, -6,
R_LINE_TO, -11, -6,
CLOSE
\ No newline at end of file
// 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 21, 3.01f,
H_LINE_TO, 3,
R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
V_LINE_TO, 9,
R_H_LINE_TO, 2,
V_LINE_TO, 4.99f,
R_H_LINE_TO, 18,
R_V_LINE_TO, 14.03f,
H_LINE_TO, 3,
V_LINE_TO, 15,
H_LINE_TO, 1,
R_V_LINE_TO, 4.01f,
R_CUBIC_TO, 0, 1.1f, 0.9f, 1.98f, 2, 1.98f,
R_H_LINE_TO, 18,
R_CUBIC_TO, 1.1f, 0, 2, -0.88f, 2, -1.98f,
R_V_LINE_TO, -14,
R_ARC_TO, 2, 2, 0, 0, 0, -2, -2,
CLOSE,
MOVE_TO, 11, 16,
R_LINE_TO, 4, -4,
R_LINE_TO, -4, -4,
R_V_LINE_TO, 3,
H_LINE_TO, 1,
R_V_LINE_TO, 2,
R_H_LINE_TO, 10,
R_V_LINE_TO, 3,
CLOSE
// 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 17, 2,
H_LINE_TO, 7,
R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
R_V_LINE_TO, 16,
R_CUBIC_TO, 0, 1.1f, 0.9f, 1.99f, 2, 1.99f,
LINE_TO, 17, 22,
R_CUBIC_TO, 1.1f, 0, 2, -0.9f, 2, -2,
V_LINE_TO, 4,
R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2,
CLOSE,
R_MOVE_TO, -5, 2,
R_CUBIC_TO, 1.1f, 0, 2, 0.9f, 2, 2,
R_CUBIC_TO, 0, 1.1f, -0.9f, 2, -2, 2,
R_ARC_TO, 2, 2, 0, 1, 1, 0, -4,
CLOSE,
R_MOVE_TO, 0, 16,
R_CUBIC_TO, -2.76f, 0, -5, -2.24f, -5, -5,
R_CUBIC_TO, 0, -2.76f, 2.24f, -5, 5, -5,
R_CUBIC_TO, 2.76f, 0, 5, 2.24f, 5, 5,
R_CUBIC_TO, 0, 2.76f, -2.24f, 5, -5, 5,
CLOSE,
R_MOVE_TO, 0, -8,
R_CUBIC_TO, -1.66f, 0, -3, 1.34f, -3, 3,
R_CUBIC_TO, 0, 1.66f, 1.34f, 3, 3, 3,
R_CUBIC_TO, 1.66f, 0, 3, -1.34f, 3, -3,
R_CUBIC_TO, 0, -1.66f, -1.34f, -3, -3, -3,
CLOSE
// 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 18.2f, 1,
H_LINE_TO, 9.8f,
CUBIC_TO, 8.81f, 1, 8, 1.81f, 8, 2.8f,
R_V_LINE_TO, 14.4f,
R_CUBIC_TO, 0, 0.99f, 0.81f, 1.79f, 1.8f, 1.79f,
R_LINE_TO, 8.4f, 0.01f,
R_CUBIC_TO, 0.99f, 0, 1.8f, -0.81f, 1.8f, -1.8f,
V_LINE_TO, 2.8f,
R_CUBIC_TO, 0, -0.99f, -0.81f, -1.8f, -1.8f, -1.8f,
CLOSE,
MOVE_TO, 14, 3,
R_CUBIC_TO, 1.1f, 0, 2, 0.89f, 2, 2,
R_CUBIC_TO, 0, 1.11f, -0.9f, 2, -2, 2,
R_CUBIC_TO, -1.1f, 0, -2, -0.89f, -2, -2,
R_CUBIC_TO, 0, -1.11f, 0.9f, -2, 2, -2,
CLOSE,
R_MOVE_TO, 0, 13.5f,
R_CUBIC_TO, -2.21f, 0, -4, -1.79f, -4, -4,
R_CUBIC_TO, 0, -2.21f, 1.79f, -4, 4, -4,
R_CUBIC_TO, 2.21f, 0, 4, 1.79f, 4, 4,
R_CUBIC_TO, 0, 2.21f, -1.79f, 4, -4, 4,
CLOSE,
CIRCLE, 14, 12.5, 2.5,
MOVE_TO, 6, 5,
H_LINE_TO, 4,
R_V_LINE_TO, 16,
R_ARC_TO, 2, 2, 0, 0, 0, 2, 2,
R_H_LINE_TO, 10,
R_V_LINE_TO, -2,
H_LINE_TO, 6,
V_LINE_TO, 5,
CLOSE
// 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.
CANVAS_DIMENSIONS, 24,
MOVE_TO, 21, 3,
H_LINE_TO, 3,
R_CUBIC_TO, -1.1f, 0, -2, 0.9f, -2, 2,
R_V_LINE_TO, 12,
R_CUBIC_TO, 0, 1.1f, 0.9f, 2, 2, 2,
R_H_LINE_TO, 5,
R_V_LINE_TO, 2,
R_H_LINE_TO, 8,
R_V_LINE_TO, -2,
R_H_LINE_TO, 5,
R_CUBIC_TO, 1.1f, 0, 1.99f, -0.9f, 1.99f, -2,
LINE_TO, 23, 5,
R_CUBIC_TO, 0, -1.1f, -0.9f, -2, -2, -2,
CLOSE,
R_MOVE_TO, 0, 14,
H_LINE_TO, 3,
V_LINE_TO, 5,
R_H_LINE_TO, 18,
R_V_LINE_TO, 12,
CLOSE
...@@ -1404,6 +1404,8 @@ split_static_library("ui") { ...@@ -1404,6 +1404,8 @@ split_static_library("ui") {
"media_router/presentation_receiver_window_factory_mac.cc", "media_router/presentation_receiver_window_factory_mac.cc",
"media_router/query_result_manager.cc", "media_router/query_result_manager.cc",
"media_router/query_result_manager.h", "media_router/query_result_manager.h",
"media_router/ui_media_sink.cc",
"media_router/ui_media_sink.h",
"native_window_tracker.h", "native_window_tracker.h",
"omnibox/alternate_nav_infobar_delegate.cc", "omnibox/alternate_nav_infobar_delegate.cc",
"omnibox/alternate_nav_infobar_delegate.h", "omnibox/alternate_nav_infobar_delegate.h",
...@@ -3177,6 +3179,8 @@ split_static_library("ui") { ...@@ -3177,6 +3179,8 @@ split_static_library("ui") {
"views/location_bar/star_view.h", "views/location_bar/star_view.h",
"views/location_bar/zoom_view.cc", "views/location_bar/zoom_view.cc",
"views/location_bar/zoom_view.h", "views/location_bar/zoom_view.h",
"views/media_router/cast_dialog_sink_button.cc",
"views/media_router/cast_dialog_sink_button.h",
"views/media_router/media_router_dialog_controller_views.cc", "views/media_router/media_router_dialog_controller_views.cc",
"views/media_router/media_router_dialog_controller_views.h", "views/media_router/media_router_dialog_controller_views.h",
"views/media_router/presentation_receiver_window_factory.cc", "views/media_router/presentation_receiver_window_factory.cc",
...@@ -3395,6 +3399,10 @@ split_static_library("ui") { ...@@ -3395,6 +3399,10 @@ split_static_library("ui") {
] ]
} }
} }
if (is_chrome_branded) {
deps += [ "//chrome/browser/ui/media_router/internal/vector_icons" ]
}
} }
if (use_aura) { if (use_aura) {
......
// 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/media_router/ui_media_sink.h"
namespace media_router {
UIMediaSink::UIMediaSink() = default;
UIMediaSink::UIMediaSink(const UIMediaSink& other) = default;
UIMediaSink::~UIMediaSink() = default;
} // namespace media_router
// 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.
#ifndef CHROME_BROWSER_UI_MEDIA_ROUTER_UI_MEDIA_SINK_H_
#define CHROME_BROWSER_UI_MEDIA_ROUTER_UI_MEDIA_SINK_H_
#include "base/strings/string16.h"
#include "chrome/common/media_router/media_sink.h"
#include "url/gurl.h"
namespace media_router {
enum class UIMediaSinkState {
// Sink is available to be Cast to.
AVAILABLE,
// Sink is starting a new Casting activity. A sink temporarily enters this
// state when transitioning from AVAILABLE to CONNECTED (or to ERROR_STATE).
CONNECTING,
// Sink has a media route.
CONNECTED,
// Sink is disconnected/cached (not available right now).
UNAVAILABLE,
// Sink is in an error state.
ERROR_STATE
};
// A bitmask of this enum is used to indicate what actions can be performed on a
// sink.
enum class UICastAction {
// Start Casting the presentation for the current tab or the tab itself.
CAST_TAB = 1 << 1,
// Start Casting the entire desktop.
CAST_DESKTOP = 1 << 2,
// Stop Casting.
STOP = 1 << 3,
};
struct UIMediaSink {
public:
UIMediaSink();
UIMediaSink(const UIMediaSink& other);
~UIMediaSink();
// The unique ID for the media sink.
std::string id;
// Name that can be used by the user to identify the sink.
base::string16 friendly_name;
// Normally the sink status text is set from |state|. This field allows it
// to be overridden for error states or to show route descriptions.
base::string16 status_text;
// Presentation URL to use when initiating a new casting activity for this
// sink. For sites that integrate with the Presentation API, this is the
// top frame presentation URL. Mirroring, Cast apps, and DIAL apps use a
// non-https scheme.
GURL presentation_url;
// Active route ID, or empty string if none.
std::string route_id;
// The ID of the tab associated with the media route specified by |route_id|.
// This is a nullopt if the route is not associated with a tab (e.g. because
// it is for desktop Casting) or there is no route.
base::Optional<int> tab_id;
// The icon to use for the sink.
SinkIconType icon_type;
// The current state of the media sink.
UIMediaSinkState state;
// If non-zero, a help center article ID for troubleshooting.
// This will show an info bubble with a tooltip for the article.
// Otherwise, 0.
int tooltip_article_id;
// Bitmask of UICastAction values that determine which actions are supported
// by this sink.
int allowed_actions;
};
} // namespace media_router
#endif // CHROME_BROWSER_UI_MEDIA_ROUTER_UI_MEDIA_SINK_H_
// 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_sink_button.h"
#include "chrome/app/vector_icons/vector_icons.h"
#include "chrome/grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_types.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/throbber.h"
#include "ui/views/vector_icons.h"
#if defined(GOOGLE_CHROME_BUILD)
#include "chrome/browser/ui/media_router/internal/vector_icons/vector_icons.h"
#endif
namespace media_router {
namespace {
gfx::ImageSkia CreateSinkIcon(SinkIconType icon_type) {
const gfx::VectorIcon* vector_icon;
switch (icon_type) {
case SinkIconType::CAST_AUDIO_GROUP:
vector_icon = &kSpeakerGroupIcon;
break;
case SinkIconType::CAST_AUDIO:
vector_icon = &kSpeakerIcon;
break;
case SinkIconType::EDUCATION:
vector_icon = &kCastForEducationIcon;
break;
case SinkIconType::WIRED_DISPLAY:
vector_icon = &kInputIcon;
break;
// Use proprietary icons only in Chrome builds. The default TV icon is used
// instead for these sink types in Chromium builds.
#if defined(GOOGLE_CHROME_BUILD)
case SinkIconType::MEETING:
vector_icon = &vector_icons::kMeetIcon;
break;
case SinkIconType::HANGOUT:
vector_icon = &vector_icons::kHangoutIcon;
break;
#endif // defined(GOOGLE_CHROME_BUILD)
case SinkIconType::CAST:
case SinkIconType::GENERIC:
default:
vector_icon = &kTvIcon;
break;
}
constexpr int kPrimaryIconSize = 24;
return gfx::CreateVectorIcon(*vector_icon, kPrimaryIconSize,
gfx::kChromeIconGrey);
}
std::unique_ptr<views::View> CreatePrimaryIconForSink(const UIMediaSink& sink) {
auto icon_view = std::make_unique<views::ImageView>();
icon_view->SetImage(CreateSinkIcon(sink.icon_type));
return icon_view;
}
std::unique_ptr<views::View> CreateSecondaryIconForSink(
const UIMediaSink& sink) {
if (sink.state == UIMediaSinkState::CONNECTED) {
constexpr int kSecondaryIconSize = 16;
auto icon_view = std::make_unique<views::ImageView>();
icon_view->SetImage(gfx::CreateVectorIcon(
views::kMenuCheckIcon, kSecondaryIconSize, gfx::kChromeIconGrey));
return icon_view;
} else if (sink.state == UIMediaSinkState::CONNECTING) {
auto throbber_view = std::make_unique<views::Throbber>();
throbber_view->Start();
return throbber_view;
}
return nullptr;
}
} // namespace
CastDialogSinkButton::CastDialogSinkButton(
views::ButtonListener* button_listener,
const UIMediaSink& sink)
: HoverButton(button_listener,
CreatePrimaryIconForSink(sink),
sink.friendly_name,
sink.status_text,
CreateSecondaryIconForSink(sink)),
sink_(sink) {}
CastDialogSinkButton::~CastDialogSinkButton() {}
void CastDialogSinkButton::SetSelected(bool is_selected) {
is_selected_ = is_selected;
if (!is_selected_) {
GetInkDrop()->SnapToHidden();
GetInkDrop()->SetHovered(false);
}
}
bool CastDialogSinkButton::OnMousePressed(const ui::MouseEvent& event) {
// TODO(crbug.com/826089): Show a context menu on right click.
if (event.IsRightMouseButton())
return true;
return HoverButton::OnMousePressed(event);
}
void CastDialogSinkButton::OnBlur() {
Button::OnBlur();
if (is_selected_)
SnapInkDropToActivated();
}
base::string16 CastDialogSinkButton::GetActionText() const {
return l10n_util::GetStringUTF16(sink_.state == UIMediaSinkState::CONNECTED
? IDS_MEDIA_ROUTER_STOP_CASTING_BUTTON
: IDS_MEDIA_ROUTER_START_CASTING_BUTTON);
}
void CastDialogSinkButton::SnapInkDropToActivated() {
GetInkDrop()->SnapToActivated();
}
} // namespace media_router
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_MEDIA_ROUTER_CAST_DIALOG_SINK_BUTTON_H_
#define CHROME_BROWSER_UI_VIEWS_MEDIA_ROUTER_CAST_DIALOG_SINK_BUTTON_H_
#include "chrome/browser/ui/media_router/ui_media_sink.h"
#include "chrome/browser/ui/views/hover_button.h"
namespace ui {
class MouseEvent;
}
namespace media_router {
// A button representing a sink in the Cast dialog. It is highlighted when
// hovered or selected.
class CastDialogSinkButton : public HoverButton {
public:
CastDialogSinkButton(views::ButtonListener* button_listener,
const UIMediaSink& sink);
~CastDialogSinkButton() override;
// Sets |is_selected_| and updates the button's ink drop accordingly.
void SetSelected(bool is_selected);
// views::View:
bool OnMousePressed(const ui::MouseEvent& event) override;
void OnBlur() override;
// Returns the text that should be shown on the main action button of the Cast
// dialog when this button is selected.
base::string16 GetActionText() const;
// Changes the ink drop to the pressed state without animation.
void SnapInkDropToActivated();
const UIMediaSink& sink() const { return sink_; }
private:
UIMediaSink sink_;
bool is_selected_ = false;
DISALLOW_COPY_AND_ASSIGN(CastDialogSinkButton);
};
} // namespace media_router
#endif // CHROME_BROWSER_UI_VIEWS_MEDIA_ROUTER_CAST_DIALOG_SINK_BUTTON_H_
// 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_sink_button.h"
#include "chrome/browser/ui/media_router/ui_media_sink.h"
#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/button/button.h"
namespace media_router {
namespace {
class MockButtonListener : public views::ButtonListener {
public:
MockButtonListener() = default;
~MockButtonListener() = default;
MOCK_METHOD2(ButtonPressed,
void(views::Button* sender, const ui::Event& event));
private:
DISALLOW_COPY_AND_ASSIGN(MockButtonListener);
};
class CastDialogSinkButtonTest : public ChromeViewsTestBase {
public:
CastDialogSinkButtonTest() = default;
~CastDialogSinkButtonTest() override = default;
private:
DISALLOW_COPY_AND_ASSIGN(CastDialogSinkButtonTest);
};
void CheckActionTextForState(UIMediaSinkState state,
base::string16 expected_text) {
UIMediaSink sink;
sink.state = state;
CastDialogSinkButton button(nullptr, sink);
EXPECT_EQ(expected_text, button.GetActionText());
}
} // namespace
TEST_F(CastDialogSinkButtonTest, GetActionText) {
// TODO(crbug.com/826089): Determine what the text should be for other states.
CheckActionTextForState(
UIMediaSinkState::AVAILABLE,
l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_START_CASTING_BUTTON));
CheckActionTextForState(
UIMediaSinkState::CONNECTED,
l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_STOP_CASTING_BUTTON));
}
} // namespace media_router
...@@ -4226,6 +4226,7 @@ test("unit_tests") { ...@@ -4226,6 +4226,7 @@ test("unit_tests") {
"../browser/ui/views/global_error_bubble_view_unittest.cc", "../browser/ui/views/global_error_bubble_view_unittest.cc",
"../browser/ui/views/harmony/layout_provider_unittest.cc", "../browser/ui/views/harmony/layout_provider_unittest.cc",
"../browser/ui/views/hover_button_unittest.cc", "../browser/ui/views/hover_button_unittest.cc",
"../browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc",
"../browser/ui/views/page_info/page_info_bubble_view_unittest.cc", "../browser/ui/views/page_info/page_info_bubble_view_unittest.cc",
"../browser/ui/views/payments/payment_request_item_list_unittest.cc", "../browser/ui/views/payments/payment_request_item_list_unittest.cc",
"../browser/ui/views/payments/validating_textfield_unittest.cc", "../browser/ui/views/payments/validating_textfield_unittest.cc",
......
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