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

Add a dialog for enabling cloud services for Cast

This CL adds a dialog that allows users to enable cloud services in Cast
(Hangouts/Meet, Cast for EDU), and notifies that those services are
governed by the Google Privacy Policy.

The dialog is shown when the user tries to enable cloud services via the
context menu of the Cast toolbar icon ("Enable cloud services") if
the user has not previously acknowledged this dialog or the first run
flow of the old WebUI dialog.

If the user clicks on the "Enable" button in the dialog, we enable the
preferences kMediaRouterEnableCloudServices and
kMediaRouterCloudServicesPrefSet. If the dialog is closed in another
way, we make no pref changes.

Screenshot:
https://drive.google.com/open?id=1MSonPoMLYt0lfLeq9NfP5yoH15EeVZ6c

Bug: 848891

Change-Id: I9f565e328ea0fbc84131eef5e0fa3cb179284886
Reviewed-on: https://chromium-review.googlesource.com/1096403
Commit-Queue: Takumi Fujimoto <takumif@chromium.org>
Reviewed-by: default avatarBret Sepulveda <bsep@chromium.org>
Reviewed-by: default avatarmark a. foltz <mfoltz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570179}
parent 1aecdebf
...@@ -1382,6 +1382,7 @@ split_static_library("ui") { ...@@ -1382,6 +1382,7 @@ split_static_library("ui") {
"media_router/cast_dialog_model.h", "media_router/cast_dialog_model.h",
"media_router/cast_modes_with_media_sources.cc", "media_router/cast_modes_with_media_sources.cc",
"media_router/cast_modes_with_media_sources.h", "media_router/cast_modes_with_media_sources.h",
"media_router/cloud_services_dialog.h",
"media_router/media_cast_mode.cc", "media_router/media_cast_mode.cc",
"media_router/media_cast_mode.h", "media_router/media_cast_mode.h",
"media_router/media_router_dialog_controller_impl_base.cc", "media_router/media_router_dialog_controller_impl_base.cc",
...@@ -1747,6 +1748,10 @@ split_static_library("ui") { ...@@ -1747,6 +1748,10 @@ split_static_library("ui") {
"//third_party/libaddressinput:strings", "//third_party/libaddressinput:strings",
"//ui/events", "//ui/events",
] ]
if (!toolkit_views) {
sources += [ "media_router/cloud_services_dialog.cc" ]
}
} }
if (is_chromeos) { if (is_chromeos) {
...@@ -3200,6 +3205,8 @@ split_static_library("ui") { ...@@ -3200,6 +3205,8 @@ split_static_library("ui") {
"views/media_router/cast_dialog_sink_button.h", "views/media_router/cast_dialog_sink_button.h",
"views/media_router/cast_dialog_view.cc", "views/media_router/cast_dialog_view.cc",
"views/media_router/cast_dialog_view.h", "views/media_router/cast_dialog_view.h",
"views/media_router/cloud_services_dialog_view.cc",
"views/media_router/cloud_services_dialog_view.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/media_router_views_ui.cc", "views/media_router/media_router_views_ui.cc",
......
// 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/cloud_services_dialog.h"
namespace media_router {
void ShowCloudServicesDialog(Browser* browser) {}
} // 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_CLOUD_SERVICES_DIALOG_H_
#define CHROME_BROWSER_UI_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_H_
class Browser;
namespace media_router {
// Shows a dialog asking whether the user wants to enable casting to cloud
// services.
// The Views implementation of this is in cloud_services_dialog_view.cc.
// The non-Views implementation (no-op) is in cloud_services_dialog.cc.
void ShowCloudServicesDialog(Browser* browser);
} // namespace media_router
#endif // CHROME_BROWSER_UI_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_H_
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/signin_manager_factory.h" #include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/media_router/cloud_services_dialog.h"
#include "chrome/browser/ui/singleton_tabs.h" #include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h" #include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
#include "chrome/browser/ui/toolbar/media_router_action_controller.h" #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
...@@ -142,7 +143,6 @@ void MediaRouterContextualMenu::ExecuteCommand(int command_id, ...@@ -142,7 +143,6 @@ void MediaRouterContextualMenu::ExecuteCommand(int command_id,
const char kCastLearnMorePageUrl[] = const char kCastLearnMorePageUrl[] =
"https://support.google.com/chromecast/answer/2998338"; "https://support.google.com/chromecast/answer/2998338";
PrefService* pref_service;
switch (command_id) { switch (command_id) {
case IDC_MEDIA_ROUTER_ABOUT: case IDC_MEDIA_ROUTER_ABOUT:
ShowSingletonTab(browser_, GURL(kAboutPageUrl)); ShowSingletonTab(browser_, GURL(kAboutPageUrl));
...@@ -151,12 +151,7 @@ void MediaRouterContextualMenu::ExecuteCommand(int command_id, ...@@ -151,12 +151,7 @@ void MediaRouterContextualMenu::ExecuteCommand(int command_id,
SetAlwaysShowActionPref(!GetAlwaysShowActionPref()); SetAlwaysShowActionPref(!GetAlwaysShowActionPref());
break; break;
case IDC_MEDIA_ROUTER_CLOUD_SERVICES_TOGGLE: case IDC_MEDIA_ROUTER_CLOUD_SERVICES_TOGGLE:
pref_service = browser_->profile()->GetPrefs(); ToggleCloudServices();
pref_service->SetBoolean(prefs::kMediaRouterEnableCloudServices,
!pref_service->GetBoolean(prefs::kMediaRouterEnableCloudServices));
// If this has been set before, this is a no-op.
pref_service->SetBoolean(prefs::kMediaRouterCloudServicesPrefSet, true);
break; break;
case IDC_MEDIA_ROUTER_HELP: case IDC_MEDIA_ROUTER_HELP:
ShowSingletonTab(browser_, GURL(kCastHelpCenterPageUrl)); ShowSingletonTab(browser_, GURL(kCastHelpCenterPageUrl));
...@@ -185,6 +180,18 @@ void MediaRouterContextualMenu::ExecuteCommand(int command_id, ...@@ -185,6 +180,18 @@ void MediaRouterContextualMenu::ExecuteCommand(int command_id,
} }
} }
void MediaRouterContextualMenu::ToggleCloudServices() {
PrefService* pref_service = browser_->profile()->GetPrefs();
if (pref_service->GetBoolean(prefs::kMediaRouterCloudServicesPrefSet)) {
pref_service->SetBoolean(
prefs::kMediaRouterEnableCloudServices,
!pref_service->GetBoolean(prefs::kMediaRouterEnableCloudServices));
} else {
// If the user hasn't enabled cloud services before, show the opt-in dialog.
media_router::ShowCloudServicesDialog(browser_);
}
}
void MediaRouterContextualMenu::ReportIssue() { void MediaRouterContextualMenu::ReportIssue() {
// Opens feedback page loaded from the media router extension. // Opens feedback page loaded from the media router extension.
// This is temporary until feedback UI is redesigned. // This is temporary until feedback UI is redesigned.
......
...@@ -33,6 +33,8 @@ class MediaRouterContextualMenu : public ui::SimpleMenuModel::Delegate { ...@@ -33,6 +33,8 @@ class MediaRouterContextualMenu : public ui::SimpleMenuModel::Delegate {
private: private:
FRIEND_TEST_ALL_PREFIXES(MediaRouterContextualMenuUnitTest, FRIEND_TEST_ALL_PREFIXES(MediaRouterContextualMenuUnitTest,
ToggleCloudServicesItem); ToggleCloudServicesItem);
FRIEND_TEST_ALL_PREFIXES(MediaRouterContextualMenuUnitTest,
ShowCloudServicesDialog);
FRIEND_TEST_ALL_PREFIXES(MediaRouterContextualMenuUnitTest, FRIEND_TEST_ALL_PREFIXES(MediaRouterContextualMenuUnitTest,
ToggleAlwaysShowIconItem); ToggleAlwaysShowIconItem);
FRIEND_TEST_ALL_PREFIXES(MediaRouterContextualMenuUnitTest, FRIEND_TEST_ALL_PREFIXES(MediaRouterContextualMenuUnitTest,
...@@ -48,6 +50,11 @@ class MediaRouterContextualMenu : public ui::SimpleMenuModel::Delegate { ...@@ -48,6 +50,11 @@ class MediaRouterContextualMenu : public ui::SimpleMenuModel::Delegate {
bool IsCommandIdVisible(int command_id) const override; bool IsCommandIdVisible(int command_id) const override;
void ExecuteCommand(int command_id, int event_flags) override; void ExecuteCommand(int command_id, int event_flags) override;
// Toggles the enabled/disabled state of cloud services. This may show a
// dialog asking the user to acknowledge the Google Privacy Policy before
// enabling the services.
void ToggleCloudServices();
// Opens feedback page loaded from the media router extension. // Opens feedback page loaded from the media router extension.
void ReportIssue(); void ReportIssue();
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "chrome/browser/ui/toolbar/media_router_action.h" #include "chrome/browser/ui/toolbar/media_router_action.h"
#include "chrome/browser/ui/toolbar/media_router_action_controller.h" #include "chrome/browser/ui/toolbar/media_router_action_controller.h"
#include "chrome/browser/ui/toolbar/media_router_contextual_menu.h" #include "chrome/browser/ui/toolbar/media_router_contextual_menu.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/chromium_strings.h" #include "chrome/grit/chromium_strings.h"
#include "chrome/grit/generated_resources.h" #include "chrome/grit/generated_resources.h"
#include "chrome/test/base/browser_with_test_window_test.h" #include "chrome/test/base/browser_with_test_window_test.h"
...@@ -166,6 +167,8 @@ TEST_F(MediaRouterContextualMenuUnitTest, EnableAndDisableReportIssue) { ...@@ -166,6 +167,8 @@ TEST_F(MediaRouterContextualMenuUnitTest, EnableAndDisableReportIssue) {
// Tests whether the cloud services item is correctly toggled. This menu item // Tests whether the cloud services item is correctly toggled. This menu item
// is only availble on official Chrome builds. // is only availble on official Chrome builds.
// TODO(takumif): Add a test case that checks that the cloud services dialog is
// shown when the services are enabled for the first time.
TEST_F(MediaRouterContextualMenuUnitTest, ToggleCloudServicesItem) { TEST_F(MediaRouterContextualMenuUnitTest, ToggleCloudServicesItem) {
// The Media Router Action has a getter for the model, but not the delegate. // The Media Router Action has a getter for the model, but not the delegate.
// Create the MediaRouterContextualMenu ui::SimpleMenuModel::Delegate here. // Create the MediaRouterContextualMenu ui::SimpleMenuModel::Delegate here.
...@@ -175,6 +178,11 @@ TEST_F(MediaRouterContextualMenuUnitTest, ToggleCloudServicesItem) { ...@@ -175,6 +178,11 @@ TEST_F(MediaRouterContextualMenuUnitTest, ToggleCloudServicesItem) {
// surfaced. Whether or not it is surfaced is tested in the "Basic" test. // surfaced. Whether or not it is surfaced is tested in the "Basic" test.
signin_manager_->SetAuthenticatedAccountInfo("foo@bar.com", "password"); signin_manager_->SetAuthenticatedAccountInfo("foo@bar.com", "password");
// Set this preference so that the cloud services can be enabled without
// showing the opt-in dialog.
browser()->profile()->GetPrefs()->SetBoolean(
prefs::kMediaRouterCloudServicesPrefSet, true);
// By default, the command is not checked. // By default, the command is not checked.
EXPECT_FALSE(menu.IsCommandIdChecked( EXPECT_FALSE(menu.IsCommandIdChecked(
IDC_MEDIA_ROUTER_CLOUD_SERVICES_TOGGLE)); IDC_MEDIA_ROUTER_CLOUD_SERVICES_TOGGLE));
......
// 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/cloud_services_dialog_view.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/media_router/cloud_services_dialog.h"
#include "chrome/browser/ui/toolbar/component_toolbar_actions_factory.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/harmony/chrome_layout_provider.h"
#include "chrome/browser/ui/views/toolbar/browser_actions_container.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/grit/generated_resources.h"
#include "components/prefs/pref_service.h"
#include "components/strings/grit/components_strings.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/page_transition_types.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/controls/styled_label.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view.h"
#include "url/gurl.h"
namespace media_router {
void ShowCloudServicesDialog(Browser* browser) {
views::View* action_view =
BrowserView::GetBrowserViewForBrowser(browser)
->toolbar()
->browser_actions()
->GetViewForId(ComponentToolbarActionsFactory::kMediaRouterActionId);
CloudServicesDialogView::ShowDialog(action_view, browser);
}
// static
void CloudServicesDialogView::ShowDialog(views::View* anchor_view,
Browser* browser) {
if (CloudServicesDialogView::IsShowing())
HideDialog();
instance_ = new CloudServicesDialogView(anchor_view, browser);
views::Widget* widget =
views::BubbleDialogDelegateView::CreateBubble(instance_);
widget->Show();
}
// static
void CloudServicesDialogView::HideDialog() {
if (IsShowing())
instance_->GetWidget()->Close();
// We also set |instance_| to nullptr in WindowClosing() which is called
// asynchronously, because not all paths to close the dialog go through
// HideDialog(). We set it here because IsShowing() should be false after
// HideDialog() is called.
instance_ = nullptr;
}
// static
bool CloudServicesDialogView::IsShowing() {
return instance_ != nullptr;
}
// static
CloudServicesDialogView* CloudServicesDialogView::GetDialogForTest() {
return instance_;
}
bool CloudServicesDialogView::ShouldShowCloseButton() const {
return true;
}
base::string16 CloudServicesDialogView::GetWindowTitle() const {
return l10n_util::GetStringUTF16(
IDS_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_TITLE);
}
base::string16 CloudServicesDialogView::GetDialogButtonLabel(
ui::DialogButton button) const {
return l10n_util::GetStringUTF16(
button == ui::DIALOG_BUTTON_OK
? IDS_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_ENABLE
: IDS_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_CANCEL);
}
int CloudServicesDialogView::GetDialogButtons() const {
return ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL;
}
bool CloudServicesDialogView::Accept() {
PrefService* pref_service = browser_->profile()->GetPrefs();
pref_service->SetBoolean(prefs::kMediaRouterEnableCloudServices, true);
pref_service->SetBoolean(prefs::kMediaRouterCloudServicesPrefSet, true);
return true; // Close the dialog.
}
bool CloudServicesDialogView::Cancel() {
// No need to set the preference to disable cloud services, because this
// dialog is shown only when the services are disabled.
return true; // Close the dialog.
}
gfx::Size CloudServicesDialogView::CalculatePreferredSize() const {
const int width = ChromeLayoutProvider::Get()->GetDistanceMetric(
DISTANCE_BUBBLE_PREFERRED_WIDTH);
return gfx::Size(width, GetHeightForWidth(width));
}
CloudServicesDialogView::CloudServicesDialogView(views::View* anchor_view,
Browser* browser)
: BubbleDialogDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
browser_(browser) {
set_close_on_deactivate(false);
SetLayoutManager(std::make_unique<views::FillLayout>());
}
CloudServicesDialogView::~CloudServicesDialogView() = default;
void CloudServicesDialogView::Init() {
std::vector<base::string16> substrings;
substrings.push_back(
l10n_util::GetStringUTF16(IDS_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_BODY));
substrings.push_back(l10n_util::GetStringUTF16(IDS_LEARN_MORE));
std::vector<size_t> offsets;
base::string16 text = base::ReplaceStringPlaceholders(
base::ASCIIToUTF16("$1 $2"), substrings, &offsets);
gfx::Range learn_more_range(offsets[1], text.length());
views::StyledLabel::RangeStyleInfo link_style =
views::StyledLabel::RangeStyleInfo::CreateForLink();
link_style.disable_line_wrapping = false;
views::StyledLabel* body_text = new views::StyledLabel(text, this);
body_text->SetHorizontalAlignment(gfx::ALIGN_LEFT);
body_text->AddStyleRange(learn_more_range, link_style);
AddChildView(body_text);
}
void CloudServicesDialogView::WindowClosing() {
if (instance_ == this)
instance_ = nullptr;
}
void CloudServicesDialogView::StyledLabelLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
int event_flags) {
const GURL url = GURL(chrome::kCastCloudServicesHelpURL);
chrome::AddSelectedTabWithURL(browser_, url, ui::PAGE_TRANSITION_LINK);
}
// static
CloudServicesDialogView* CloudServicesDialogView::instance_ = nullptr;
} // 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_CLOUD_SERVICES_DIALOG_VIEW_H_
#define CHROME_BROWSER_UI_VIEWS_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_VIEW_H_
#include "base/strings/string16.h"
#include "ui/views/bubble/bubble_dialog_delegate.h"
#include "ui/views/controls/styled_label_listener.h"
class Browser;
namespace media_router {
// Dialog that asks the user whether they want to enable cloud services for the
// Cast feature.
class CloudServicesDialogView : public views::BubbleDialogDelegateView,
public views::StyledLabelListener {
public:
// Instantiates and shows the singleton dialog.
static void ShowDialog(views::View* anchor_view, Browser* browser);
// No-op if the dialog is currently not shown.
static void HideDialog();
static bool IsShowing();
// Called by tests. Returns the singleton dialog instance.
static CloudServicesDialogView* GetDialogForTest();
// views::WidgetDelegateView:
bool ShouldShowCloseButton() const override;
// views::WidgetDelegate:
base::string16 GetWindowTitle() const override;
// ui::DialogModel:
base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
int GetDialogButtons() const override;
// views::DialogDelegate:
bool Accept() override;
bool Cancel() override;
// views::View:
gfx::Size CalculatePreferredSize() const override;
private:
CloudServicesDialogView(views::View* anchor_view, Browser* browser);
~CloudServicesDialogView() override;
// views::BubbleDialogDelegateView:
void Init() override;
void WindowClosing() override;
// views::StyledLabelListener:
void StyledLabelLinkClicked(views::StyledLabel* label,
const gfx::Range& range,
int event_flags) override;
// The singleton dialog instance. This is a nullptr when a dialog is not
// shown.
static CloudServicesDialogView* instance_;
// Browser window that this dialog is attached to.
Browser* const browser_;
DISALLOW_COPY_AND_ASSIGN(CloudServicesDialogView);
};
} // namespace media_router
#endif // CHROME_BROWSER_UI_VIEWS_MEDIA_ROUTER_CLOUD_SERVICES_DIALOG_VIEW_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/cloud_services_dialog_view.h"
#include "base/run_loop.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/test_browser_window.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/views/chrome_views_test_base.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/views/widget/widget.h"
namespace media_router {
class CloudServicesDialogViewTest : public ChromeViewsTestBase {
public:
CloudServicesDialogViewTest() = default;
~CloudServicesDialogViewTest() override = default;
void SetUp() override {
ChromeViewsTestBase::SetUp();
window_ = std::make_unique<TestBrowserWindow>();
Browser::CreateParams browser_params(&profile_, true);
browser_params.window = window_.get();
browser_ = std::make_unique<Browser>(browser_params);
views::Widget::InitParams widget_params =
CreateParams(views::Widget::InitParams::TYPE_WINDOW);
widget_params.ownership =
views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
anchor_widget_ = std::make_unique<views::Widget>();
anchor_widget_->Init(widget_params);
anchor_widget_->Show();
}
void TearDown() override {
anchor_widget_.reset();
browser_.reset();
window_.reset();
ChromeViewsTestBase::TearDown();
}
protected:
void ShowDialog() {
CloudServicesDialogView::ShowDialog(anchor_widget_->GetContentsView(),
browser_.get());
EXPECT_TRUE(CloudServicesDialogView::IsShowing());
}
CloudServicesDialogView* GetDialog() {
return CloudServicesDialogView::GetDialogForTest();
}
void ExpectPrefsToBe(bool value) {
PrefService* pref_service = browser_->profile()->GetPrefs();
EXPECT_EQ(value,
pref_service->GetBoolean(prefs::kMediaRouterEnableCloudServices));
EXPECT_EQ(value, pref_service->GetBoolean(
prefs::kMediaRouterCloudServicesPrefSet));
}
content::TestBrowserThreadBundle thread_bundle_;
std::unique_ptr<BrowserWindow> window_;
std::unique_ptr<Browser> browser_;
std::unique_ptr<views::Widget> anchor_widget_;
TestingProfile profile_;
};
TEST_F(CloudServicesDialogViewTest, Enable) {
ExpectPrefsToBe(false);
ShowDialog();
GetDialog()->Accept();
// Clicking on the "Enable" button should set the pref values to true.
ExpectPrefsToBe(true);
}
TEST_F(CloudServicesDialogViewTest, Cancel) {
ExpectPrefsToBe(false);
ShowDialog();
GetDialog()->Cancel();
// Clicking on the "Cancel" button should result in no pref changes.
ExpectPrefsToBe(false);
}
TEST_F(CloudServicesDialogViewTest, Close) {
ExpectPrefsToBe(false);
ShowDialog();
GetDialog()->Close();
// Closing the dialog via the close button should result in no pref changes.
ExpectPrefsToBe(false);
}
} // namespace media_router
...@@ -16,6 +16,11 @@ const char kBluetoothAdapterOffHelpURL[] = ...@@ -16,6 +16,11 @@ const char kBluetoothAdapterOffHelpURL[] =
"https://support.google.com/chrome?p=bluetooth"; "https://support.google.com/chrome?p=bluetooth";
#endif #endif
// TODO(https://crbug.com/852139): Replace this numbered link with a P-link once
// we have one.
const char kCastCloudServicesHelpURL[] =
"https://support.google.com/chromecast/answer/6320939";
// TODO(https://crbug.com/852139): Replace this numbered link with a P-link once // TODO(https://crbug.com/852139): Replace this numbered link with a P-link once
// we have one. // we have one.
const char kCastNoDestinationFoundURL[] = const char kCastNoDestinationFoundURL[] =
......
...@@ -32,6 +32,9 @@ extern const char kAutomaticSettingsResetLearnMoreURL[]; ...@@ -32,6 +32,9 @@ extern const char kAutomaticSettingsResetLearnMoreURL[];
// The URL for providing help when the Bluetooth adapter is off. // The URL for providing help when the Bluetooth adapter is off.
extern const char kBluetoothAdapterOffHelpURL[]; extern const char kBluetoothAdapterOffHelpURL[];
// "Learn more" URL shown in the dialog to enable cloud services for Cast.
extern const char kCastCloudServicesHelpURL[];
// The URL for the help center article to show when no Cast destination has been // The URL for the help center article to show when no Cast destination has been
// found. // found.
extern const char kCastNoDestinationFoundURL[]; extern const char kCastNoDestinationFoundURL[];
......
...@@ -4322,6 +4322,7 @@ test("unit_tests") { ...@@ -4322,6 +4322,7 @@ test("unit_tests") {
"../browser/ui/views/media_router/cast_dialog_no_sinks_view_unittest.cc", "../browser/ui/views/media_router/cast_dialog_no_sinks_view_unittest.cc",
"../browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc", "../browser/ui/views/media_router/cast_dialog_sink_button_unittest.cc",
"../browser/ui/views/media_router/cast_dialog_view_unittest.cc", "../browser/ui/views/media_router/cast_dialog_view_unittest.cc",
"../browser/ui/views/media_router/cloud_services_dialog_view_unittest.cc",
"../browser/ui/views/media_router/media_router_views_ui_unittest.cc", "../browser/ui/views/media_router/media_router_views_ui_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",
......
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