summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorimcheng <imcheng@google.com>2015-06-16 15:18:47 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-16 22:19:24 +0000
commitb3ec4d4af16df1575e36cc80b784db5ed7f9f6cc (patch)
tree5ca4cc745a45e6a7cb4c1233c1dcb60e465c7878 /chrome
parente6fabf10ffdd14af952a9fc0182a8ffef3cd5825 (diff)
downloadchromium_src-b3ec4d4af16df1575e36cc80b784db5ed7f9f6cc.zip
chromium_src-b3ec4d4af16df1575e36cc80b784db5ed7f9f6cc.tar.gz
chromium_src-b3ec4d4af16df1575e36cc80b784db5ed7f9f6cc.tar.bz2
[Media Router] Add Issues handling in WebUI Message Handler.
This patch consists of: - new string resources for Issues action button labels. - convert IssuesObserver from interface to a base class to be consistent with Media{Sinks,Routes}Observer classes. - rename {Add,Remove}IssuesObserver to [Un]RegisterIssuesObserver. - add initiator WebContents field to MediaRouterUI. Note that this will be set to a non-null value during InitCommon() (crrev.com/1156373014). - add Issue handling (OnActOnIssue) in WebUI MessageHandler. For the "Learn more" action, open a Chromecast help page with the supplied page ID (which comes from WebUI). - various cleanup/renaming of the function names in WebUI/C++ interfaces for consistency. BUG=464216 Review URL: https://codereview.chromium.org/1161113003 Cr-Commit-Position: refs/heads/master@{#334713}
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/media_router_strings.grdp14
-rw-r--r--chrome/browser/media/router/issues_observer.cc21
-rw-r--r--chrome/browser/media/router/issues_observer.h20
-rw-r--r--chrome/browser/media/router/media_router.gypi1
-rw-r--r--chrome/browser/media/router/media_router.h4
-rw-r--r--chrome/browser/media/router/media_router_mojo_impl.cc4
-rw-r--r--chrome/browser/media/router/media_router_mojo_impl.h4
-rw-r--r--chrome/browser/media/router/mock_media_router.h4
-rw-r--r--chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html4
-rw-r--r--chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js25
-rw-r--r--chrome/browser/resources/media_router/media_router.js3
-rw-r--r--chrome/browser/resources/media_router/media_router_ui_interface.js20
-rw-r--r--chrome/browser/ui/webui/media_router/media_cast_mode.h1
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc11
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_ui.cc7
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_ui.h1
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc2
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h1
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc173
-rw-r--r--chrome/chrome_tests_unit.gypi1
20 files changed, 299 insertions, 22 deletions
diff --git a/chrome/app/media_router_strings.grdp b/chrome/app/media_router_strings.grdp
index cfe94d1..48ed0ab 100644
--- a/chrome/app/media_router_strings.grdp
+++ b/chrome/app/media_router_strings.grdp
@@ -37,6 +37,20 @@
Select cast mode
</message>
+ <!-- Issue Actions -->
+ <message name="IDS_MEDIA_ROUTER_CANCEL_BUTTON" desc="Text of Cancel button.">
+ Cancel
+ </message>
+ <message name="IDS_MEDIA_ROUTER_DISMISS_BUTTON" desc="Text of Dismiss button.">
+ Dismiss
+ </message>
+ <message name="IDS_MEDIA_ROUTER_LEARN_MORE_BUTTON" desc="Text of Learn More button.">
+ Learn More
+ </message>
+ <message name="IDS_MEDIA_ROUTER_OK_BUTTON" desc="Text of Ok button.">
+ Ok
+ </message>
+
<!-- Route Details -->
<message name="IDS_MEDIA_ROUTER_BACK_TO_SINK_PICKER" desc="Label of back to sink picker button.">
Back to device list
diff --git a/chrome/browser/media/router/issues_observer.cc b/chrome/browser/media/router/issues_observer.cc
new file mode 100644
index 0000000..0d496d8
--- /dev/null
+++ b/chrome/browser/media/router/issues_observer.cc
@@ -0,0 +1,21 @@
+// Copyright 2015 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/media/router/issues_observer.h"
+
+#include "base/logging.h"
+#include "chrome/browser/media/router/media_router.h"
+
+namespace media_router {
+
+IssuesObserver::IssuesObserver(MediaRouter* router) : router_(router) {
+ DCHECK(router_);
+ router_->RegisterIssuesObserver(this);
+}
+
+IssuesObserver::~IssuesObserver() {
+ router_->UnregisterIssuesObserver(this);
+}
+
+} // namespace media_router
diff --git a/chrome/browser/media/router/issues_observer.h b/chrome/browser/media/router/issues_observer.h
index 33443dd..d8b4258 100644
--- a/chrome/browser/media/router/issues_observer.h
+++ b/chrome/browser/media/router/issues_observer.h
@@ -9,15 +9,23 @@
namespace media_router {
-// Interface for observing when issues have been updated.
-// TODO(imcheng): Implement automatic register/unregister from MediaRouter.
+class MediaRouter;
+
+// Base class for observing Media Router Issue. There is at most one Issue
+// at any given time.
class IssuesObserver {
public:
- virtual ~IssuesObserver() {}
+ explicit IssuesObserver(MediaRouter* router);
+ virtual ~IssuesObserver();
+
+ // Called when there is an updated Media Router Issue.
+ // If |issue| is nullptr, then there is currently no issue.
+ virtual void OnIssueUpdated(const Issue* issue) {}
+
+ private:
+ MediaRouter* router_;
- // Called when there is a new highest priority issue.
- // |issue| can be nullptr.
- virtual void OnIssueUpdated(const Issue* issue) = 0;
+ DISALLOW_COPY_AND_ASSIGN(IssuesObserver);
};
} // namespace media_router
diff --git a/chrome/browser/media/router/media_router.gypi b/chrome/browser/media/router/media_router.gypi
index 4851a43..460c38e 100644
--- a/chrome/browser/media/router/media_router.gypi
+++ b/chrome/browser/media/router/media_router.gypi
@@ -13,6 +13,7 @@
'issue_manager.cc',
'issue_manager.h',
'issues_observer.h',
+ 'issues_observer.cc',
'media_route.cc',
'media_route.h',
'media_route_id.h',
diff --git a/chrome/browser/media/router/media_router.h b/chrome/browser/media/router/media_router.h
index 3280798..071f55b 100644
--- a/chrome/browser/media/router/media_router.h
+++ b/chrome/browser/media/router/media_router.h
@@ -132,10 +132,10 @@ class MediaRouter {
// Adds the IssuesObserver |observer|.
// It is invalid to register the same observer more than once and will result
// in undefined behavior.
- virtual void AddIssuesObserver(IssuesObserver* observer) = 0;
+ virtual void RegisterIssuesObserver(IssuesObserver* observer) = 0;
// Removes the IssuesObserver |observer|.
- virtual void RemoveIssuesObserver(IssuesObserver* observer) = 0;
+ virtual void UnregisterIssuesObserver(IssuesObserver* observer) = 0;
};
} // namespace media_router
diff --git a/chrome/browser/media/router/media_router_mojo_impl.cc b/chrome/browser/media/router/media_router_mojo_impl.cc
index 0528a9f..d8c81e8 100644
--- a/chrome/browser/media/router/media_router_mojo_impl.cc
+++ b/chrome/browser/media/router/media_router_mojo_impl.cc
@@ -285,12 +285,12 @@ void MediaRouterMojoImpl::UnregisterMediaRoutesObserver(
}
}
-void MediaRouterMojoImpl::AddIssuesObserver(IssuesObserver* observer) {
+void MediaRouterMojoImpl::RegisterIssuesObserver(IssuesObserver* observer) {
// TODO(imcheng): Implement. (crbug.com/461815)
NOTIMPLEMENTED();
}
-void MediaRouterMojoImpl::RemoveIssuesObserver(IssuesObserver* observer) {
+void MediaRouterMojoImpl::UnregisterIssuesObserver(IssuesObserver* observer) {
// TODO(imcheng): Implement. (crbug.com/461815)
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/media/router/media_router_mojo_impl.h b/chrome/browser/media/router/media_router_mojo_impl.h
index febd0d5..a1be573 100644
--- a/chrome/browser/media/router/media_router_mojo_impl.h
+++ b/chrome/browser/media/router/media_router_mojo_impl.h
@@ -78,8 +78,8 @@ class MediaRouterMojoImpl : public MediaRouter,
void UnregisterMediaSinksObserver(MediaSinksObserver* observer) override;
void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) override;
void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) override;
- void AddIssuesObserver(IssuesObserver* observer) override;
- void RemoveIssuesObserver(IssuesObserver* observer) override;
+ void RegisterIssuesObserver(IssuesObserver* observer) override;
+ void UnregisterIssuesObserver(IssuesObserver* observer) override;
void set_instance_id_for_test(const std::string& instance_id) {
instance_id_ = instance_id;
diff --git a/chrome/browser/media/router/mock_media_router.h b/chrome/browser/media/router/mock_media_router.h
index 74cdb70..8eadf62 100644
--- a/chrome/browser/media/router/mock_media_router.h
+++ b/chrome/browser/media/router/mock_media_router.h
@@ -41,8 +41,8 @@ class MockMediaRouter : public MediaRouter {
const std::string& message,
const SendRouteMessageCallback& callback));
MOCK_METHOD1(ClearIssue, void(const Issue::Id& issue_id));
- MOCK_METHOD1(AddIssuesObserver, void(IssuesObserver* observer));
- MOCK_METHOD1(RemoveIssuesObserver, void(IssuesObserver* observer));
+ MOCK_METHOD1(RegisterIssuesObserver, void(IssuesObserver* observer));
+ MOCK_METHOD1(UnregisterIssuesObserver, void(IssuesObserver* observer));
MOCK_METHOD1(RegisterMediaSinksObserver, void(MediaSinksObserver* observer));
MOCK_METHOD1(UnregisterMediaSinksObserver,
diff --git a/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html b/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
index bdc2ae3..835f83f 100644
--- a/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
+++ b/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
@@ -19,7 +19,7 @@
</paper-button>
<paper-button raised class="button action"
on-click="onClickDefaultAction_">
- <span>[[issue.defaultActionText]]</span>
+ <span>[[defaultActionButtonText_]]</span>
</paper-button>
</div>
</div>
@@ -34,7 +34,7 @@
<span>[[issue.optActionText]]</span>
</span>
<span class="issue-action" on-click="onClickDefaultAction_">
- <span>[[issue.defaultActionText]]</span>
+ <span>[[defaultActionButtonText_]]</span>
</span>
</div>
</template>
diff --git a/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js b/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js
index 9cde810..ec1ded8 100644
--- a/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js
+++ b/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.js
@@ -4,6 +4,16 @@
// This Polymer element is used to show information about issues related
// to casting.
+(function() {
+
+/**
+ * Maps an issue action type to the resource identifier of the text shown
+ * in the action button.
+ * @type {!Array<string>}
+ */
+var issueActionTypeToButtonTextResource = [
+ 'okButton', 'cancelButton', 'dismissButton', 'learnMoreButton'];
+
Polymer({
is: 'issue-banner',
@@ -16,6 +26,18 @@ Polymer({
type: Object,
value: null,
},
+
+ /**
+ * The text shown in the default action button.
+ * @private {string}
+ */
+ defaultActionButtonText_: {
+ type: String,
+ value: function() {
+ return loadTimeData.getString(
+ issueActionTypeToButtonTextResource[issue.defaultActionType]);
+ },
+ },
},
/**
@@ -56,7 +78,7 @@ Polymer({
this.fire('issue-action-click', {
id: this.issue.id,
actionType: actionType,
- helpPageId: this.issue.helpPageId,
+ helpPageId: this.issue.helpPageId
});
},
@@ -80,3 +102,4 @@ Polymer({
this.fireIssueActionClick_(this.issue.optActionType);
},
});
+})();
diff --git a/chrome/browser/resources/media_router/media_router.js b/chrome/browser/resources/media_router/media_router.js
index f567ce2..4773a16 100644
--- a/chrome/browser/resources/media_router/media_router.js
+++ b/chrome/browser/resources/media_router/media_router.js
@@ -40,7 +40,8 @@ cr.define('media_router', function() {
* Acts on an issue and dismisses it from the UI.
* Called when the user performs an action on an issue.
*
- * @param {{detail: {id: string, actionType: number}}} data
+ * @param {{detail: {id: string, actionType: number, helpPageId: number}}}
+ * data
* Parameters in |data|.detail:
* id - issue ID.
* actionType - type of action performed by the user.
diff --git a/chrome/browser/resources/media_router/media_router_ui_interface.js b/chrome/browser/resources/media_router/media_router_ui_interface.js
index f9437116..aa8680e 100644
--- a/chrome/browser/resources/media_router/media_router_ui_interface.js
+++ b/chrome/browser/resources/media_router/media_router_ui_interface.js
@@ -11,6 +11,26 @@ cr.define('media_router.ui', function() {
var container = null;
/**
+ * Populates the WebUI with data obtained from Media Router.
+ *
+ * @param {{headerText: string,
+ * sinks: !Array<!media_router.Sink>,
+ * routes: !Array<!media_router.Route>,
+ * castModes: !Array<!media_router.CastMode>}} data
+ * Parameters in data:
+ * headerText - text to be displayed in the header of the WebUI.
+ * sinks - list of sinks to be displayed.
+ * routes - list of routes that are associated with the sinks.
+ * castModes - list of available cast modes.
+ */
+ function setInitialData(data) {
+ container.headerText = data['headerText'];
+ container.sinkList = data['sinks'];
+ container.routeList = data['routes'];
+ container.castModeList = data['castModes'];
+ }
+
+ /**
* Adds a new route.
*
* @param {!media_router.Route} route
diff --git a/chrome/browser/ui/webui/media_router/media_cast_mode.h b/chrome/browser/ui/webui/media_router/media_cast_mode.h
index 7c9e069..80af5d4 100644
--- a/chrome/browser/ui/webui/media_router/media_cast_mode.h
+++ b/chrome/browser/ui/webui/media_router/media_cast_mode.h
@@ -32,6 +32,7 @@ enum MediaCastMode {
using CastModeSet = std::set<MediaCastMode>;
+// TODO(imcheng): Move localization logic to WebUI.
// Returns a localized title string for |mode| and |host| (e.g. google.com).
std::string MediaCastModeToTitle(MediaCastMode mode, const std::string& host);
diff --git a/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc b/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc
index d8693b3..90cdd0f 100644
--- a/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_localized_strings_provider.cc
@@ -28,6 +28,16 @@ void AddRouteDetailsStrings(content::WebUIDataSource* html_source) {
IDS_MEDIA_ROUTER_STOP_CASTING_BUTTON);
}
+void AddIssuesActionsStrings(content::WebUIDataSource* html_source) {
+ html_source->AddLocalizedString("cancelButton",
+ IDS_MEDIA_ROUTER_CANCEL_BUTTON);
+ html_source->AddLocalizedString("dismissButton",
+ IDS_MEDIA_ROUTER_DISMISS_BUTTON);
+ html_source->AddLocalizedString("learnMoreButton",
+ IDS_MEDIA_ROUTER_LEARN_MORE_BUTTON);
+ html_source->AddLocalizedString("okButton", IDS_MEDIA_ROUTER_OK_BUTTON);
+}
+
} // namespace
namespace media_router {
@@ -35,6 +45,7 @@ namespace media_router {
void AddLocalizedStrings(content::WebUIDataSource* html_source) {
AddMediaRouterStrings(html_source);
AddRouteDetailsStrings(html_source);
+ AddIssuesActionsStrings(html_source);
html_source->SetJsonPath(kLocalizedStringsFile);
}
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.cc b/chrome/browser/ui/webui/media_router/media_router_ui.cc
index 752c006..2b2b54a 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -50,7 +50,10 @@ std::string GetHostFromURL(const GURL& gurl) {
// updated.
class MediaRouterUI::UIIssuesObserver : public IssuesObserver {
public:
- explicit UIIssuesObserver(MediaRouterUI* ui) : ui_(ui) { DCHECK(ui); }
+ UIIssuesObserver(MediaRouter* router, MediaRouterUI* ui)
+ : IssuesObserver(router), ui_(ui) {
+ DCHECK(ui);
+ }
~UIIssuesObserver() override {}
@@ -151,7 +154,7 @@ void MediaRouterUI::InitCommon(const content::WebContents* initiator,
DCHECK(initiator);
// Register for Issue and MediaRoute updates.
- issues_observer_.reset(new UIIssuesObserver(this));
+ issues_observer_.reset(new UIIssuesObserver(router_, this));
routes_observer_.reset(new UIMediaRoutesObserver(router_, this));
query_result_manager_.reset(new QueryResultManager(router_));
diff --git a/chrome/browser/ui/webui/media_router/media_router_ui.h b/chrome/browser/ui/webui/media_router/media_router_ui.h
index bec84a8..e3e4a21 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui.h
+++ b/chrome/browser/ui/webui/media_router/media_router_ui.h
@@ -105,7 +105,6 @@ class MediaRouterUI
const std::vector<MediaSinkWithCastModes>& sinks() const { return sinks_; }
const std::vector<MediaRoute>& routes() const { return routes_; }
const std::set<MediaCastMode>& cast_modes() const { return cast_modes_; }
-
const content::WebContents* initiator() const { return initiator_; }
private:
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
index b27a8c4..03e9eca 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.cc
@@ -309,7 +309,7 @@ void MediaRouterWebUIMessageHandler::OnCloseRoute(
const base::DictionaryValue* args_dict = nullptr;
std::string route_id;
if (!args->GetDictionary(0, &args_dict) ||
- !args_dict->GetString(0, &route_id)) {
+ !args_dict->GetString("routeId", &route_id)) {
DVLOG(1) << "Unable to extract args.";
return;
}
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h
index 8193358..0fbfbee 100644
--- a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler.h
@@ -14,6 +14,7 @@
#include "content/public/browser/web_ui_message_handler.h"
namespace base {
+class DictionaryValue;
class ListValue;
} // namespace base
diff --git a/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
new file mode 100644
index 0000000..105d0a1
--- /dev/null
+++ b/chrome/browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc
@@ -0,0 +1,173 @@
+// Copyright 2015 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/webui/media_router/media_router_webui_message_handler.h"
+#include "content/public/test/test_web_ui.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media_router {
+
+class TestingMediaRouterWebUIMessageHandler
+ : public MediaRouterWebUIMessageHandler {
+ public:
+ explicit TestingMediaRouterWebUIMessageHandler(content::WebUI* web_ui) {
+ set_web_ui(web_ui);
+ }
+
+ ~TestingMediaRouterWebUIMessageHandler() override { set_web_ui(nullptr); }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TestingMediaRouterWebUIMessageHandler);
+};
+
+class MediaRouterWebUIMessageHandlerTest : public testing::Test {
+ public:
+ MediaRouterWebUIMessageHandlerTest() : web_ui_(), handler_(&web_ui_) {}
+ ~MediaRouterWebUIMessageHandlerTest() override {}
+
+ protected:
+ content::TestWebUI web_ui_;
+ TestingMediaRouterWebUIMessageHandler handler_;
+};
+
+TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateSinks) {
+ MediaSink::Id sink_id("sinkId123");
+ std::string sink_name("The sink");
+ std::vector<MediaSinkWithCastModes> media_sink_with_cast_modes_list;
+ MediaSinkWithCastModes media_sink_with_cast_modes(
+ MediaSink(sink_id, sink_name));
+ media_sink_with_cast_modes.cast_modes.insert(MediaCastMode::TAB_MIRROR);
+ media_sink_with_cast_modes_list.push_back(media_sink_with_cast_modes);
+
+ handler_.UpdateSinks(media_sink_with_cast_modes_list);
+ EXPECT_EQ(1u, web_ui_.call_data().size());
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data()[0];
+ EXPECT_EQ("media_router.ui.setSinkList", call_data.function_name());
+ const base::Value* arg1 = call_data.arg1();
+ const base::ListValue* sinks_list_value = nullptr;
+ EXPECT_TRUE(arg1->GetAsList(&sinks_list_value));
+ const base::DictionaryValue* sink_value = nullptr;
+ EXPECT_TRUE(sinks_list_value->GetDictionary(0, &sink_value));
+
+ std::string value;
+ EXPECT_TRUE(sink_value->GetString("id", &value));
+ EXPECT_EQ(sink_id, value);
+
+ EXPECT_TRUE(sink_value->GetString("name", &value));
+ EXPECT_EQ(sink_name, value);
+
+ const base::ListValue* cast_modes_value = nullptr;
+ EXPECT_TRUE(sink_value->GetList("castModes", &cast_modes_value));
+ int cast_mode = -1;
+ EXPECT_TRUE(cast_modes_value->GetInteger(0, &cast_mode));
+ EXPECT_EQ(static_cast<int>(MediaCastMode::TAB_MIRROR), cast_mode);
+}
+
+TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateRoutes) {
+ MediaRoute::Id route_id("routeId123");
+ MediaSink::Id sink_id("sinkId123");
+ MediaSink sink(sink_id, "The sink");
+ std::string description("This is a route");
+ bool is_local = true;
+ std::vector<MediaRoute> routes;
+ routes.push_back(MediaRoute(route_id, MediaSource("mediaSource"),
+ MediaSink(sink_id, "The sink"), description,
+ is_local));
+
+ handler_.UpdateRoutes(routes);
+ EXPECT_EQ(1u, web_ui_.call_data().size());
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data()[0];
+ EXPECT_EQ("media_router.ui.setRouteList", call_data.function_name());
+ const base::Value* arg1 = call_data.arg1();
+ const base::ListValue* routes_list_value = nullptr;
+ EXPECT_TRUE(arg1->GetAsList(&routes_list_value));
+ const base::DictionaryValue* route_value = nullptr;
+ EXPECT_TRUE(routes_list_value->GetDictionary(0, &route_value));
+
+ std::string value;
+ EXPECT_TRUE(route_value->GetString("id", &value));
+ EXPECT_EQ(route_id, value);
+ EXPECT_TRUE(route_value->GetString("sinkId", &value));
+ EXPECT_EQ(sink_id, value);
+ EXPECT_TRUE(route_value->GetString("title", &value));
+ EXPECT_EQ(description, value);
+
+ bool actual_is_local = false;
+ EXPECT_TRUE(route_value->GetBoolean("isLocal", &actual_is_local));
+ EXPECT_EQ(is_local, actual_is_local);
+}
+
+TEST_F(MediaRouterWebUIMessageHandlerTest, AddRoute) {
+ MediaRoute::Id route_id("routeId123");
+ MediaSink::Id sink_id("sinkId123");
+ MediaSink sink(sink_id, "The sink");
+ std::string description("This is a route");
+ bool is_local = true;
+ MediaRoute route(route_id, MediaSource("mediaSource"),
+ MediaSink(sink_id, "The sink"), description, is_local);
+
+ handler_.AddRoute(route);
+ EXPECT_EQ(1u, web_ui_.call_data().size());
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data()[0];
+ EXPECT_EQ("media_router.ui.addRoute", call_data.function_name());
+ const base::Value* arg1 = call_data.arg1();
+ const base::DictionaryValue* route_value = nullptr;
+ EXPECT_TRUE(arg1->GetAsDictionary(&route_value));
+
+ std::string value;
+ EXPECT_TRUE(route_value->GetString("id", &value));
+ EXPECT_EQ(route_id, value);
+ EXPECT_TRUE(route_value->GetString("sinkId", &value));
+ EXPECT_EQ(sink_id, value);
+ EXPECT_TRUE(route_value->GetString("title", &value));
+ EXPECT_EQ(description, value);
+
+ bool actual_is_local = false;
+ EXPECT_TRUE(route_value->GetBoolean("isLocal", &actual_is_local));
+ EXPECT_EQ(is_local, actual_is_local);
+}
+
+TEST_F(MediaRouterWebUIMessageHandlerTest, UpdateIssue) {
+ std::string issue_title("An issue");
+ std::string issue_message("This is an issue");
+ IssueAction default_action(IssueAction::TYPE_OK);
+ std::vector<IssueAction> secondary_actions;
+ secondary_actions.push_back(IssueAction(IssueAction::TYPE_DISMISS));
+ MediaRoute::Id route_id("routeId123");
+ bool is_blocking = true;
+ Issue issue(issue_title, issue_message, default_action, secondary_actions,
+ route_id, Issue::FATAL, is_blocking, "helpUrl");
+ const Issue::Id& issue_id = issue.id();
+
+ handler_.UpdateIssue(&issue);
+ EXPECT_EQ(1u, web_ui_.call_data().size());
+ const content::TestWebUI::CallData& call_data = *web_ui_.call_data()[0];
+ EXPECT_EQ("media_router.ui.setIssue", call_data.function_name());
+ const base::Value* arg1 = call_data.arg1();
+ const base::DictionaryValue* issue_value = nullptr;
+ EXPECT_TRUE(arg1->GetAsDictionary(&issue_value));
+
+ std::string value;
+ EXPECT_TRUE(issue_value->GetString("id", &value));
+ EXPECT_EQ(issue_id, value);
+ EXPECT_TRUE(issue_value->GetString("title", &value));
+ EXPECT_EQ(issue_title, value);
+ EXPECT_TRUE(issue_value->GetString("message", &value));
+ EXPECT_EQ(issue_message, value);
+
+ int action_type_num = -1;
+ EXPECT_TRUE(issue_value->GetInteger("defaultActionType", &action_type_num));
+ EXPECT_EQ(default_action.type(), action_type_num);
+ EXPECT_TRUE(issue_value->GetInteger("secondaryActionType", &action_type_num));
+ EXPECT_EQ(secondary_actions[0].type(), action_type_num);
+
+ EXPECT_TRUE(issue_value->GetString("routeId", &value));
+ EXPECT_EQ(route_id, value);
+
+ bool actual_is_blocking = false;
+ EXPECT_TRUE(issue_value->GetBoolean("isBlocking", &actual_is_blocking));
+ EXPECT_EQ(is_blocking, actual_is_blocking);
+}
+
+} // namespace media_router
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 9895d64..cfa9dbf 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1456,6 +1456,7 @@
'browser/ui/webui/media_router/media_router_dialog_controller_unittest.cc',
'browser/ui/webui/media_router/media_router_test.cc',
'browser/ui/webui/media_router/media_router_test.h',
+ 'browser/ui/webui/media_router/media_router_webui_message_handler_unittest.cc',
'browser/ui/webui/media_router/query_result_manager_unittest.cc',
],
# Everything but Android and iOS (iOS is handled separately).