| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/webui/media_router/media_router_ui.h" | 5 #include "chrome/browser/ui/webui/media_router/media_router_ui.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| 11 #include "base/strings/utf_string_conversions.h" | 11 #include "base/strings/utf_string_conversions.h" |
| 12 #include "chrome/browser/media/router/create_presentation_connection_request.h" | 12 #include "chrome/browser/media/router/create_presentation_connection_request.h" |
| 13 #include "chrome/browser/media/router/media_route.h" | 13 #include "chrome/browser/media/router/media_route.h" |
| 14 #include "chrome/browser/media/router/media_source_helper.h" | 14 #include "chrome/browser/media/router/media_source_helper.h" |
| 15 #include "chrome/browser/media/router/mock_media_router.h" | 15 #include "chrome/browser/media/router/mock_media_router.h" |
| 16 #include "chrome/browser/media/router/route_request_result.h" | 16 #include "chrome/browser/media/router/route_request_result.h" |
| 17 #include "chrome/browser/media/router/test_helper.h" | 17 #include "chrome/browser/media/router/test_helper.h" |
| 18 #include "chrome/browser/sessions/session_tab_helper.h" | 18 #include "chrome/browser/sessions/session_tab_helper.h" |
| 19 #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handle
r.h" | 19 #include "chrome/browser/ui/webui/media_router/media_router_webui_message_handle
r.h" |
| 20 #include "chrome/grit/generated_resources.h" | 20 #include "chrome/grit/generated_resources.h" |
| 21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
| 21 #include "chrome/test/base/testing_profile.h" | 22 #include "chrome/test/base/testing_profile.h" |
| 22 #include "content/public/test/test_browser_thread_bundle.h" | |
| 23 #include "content/public/test/test_web_ui.h" | 23 #include "content/public/test/test_web_ui.h" |
| 24 #include "extensions/browser/extension_registry.h" | 24 #include "extensions/browser/extension_registry.h" |
| 25 #include "extensions/common/extension.h" | 25 #include "extensions/common/extension.h" |
| 26 #include "extensions/common/extension_builder.h" | 26 #include "extensions/common/extension_builder.h" |
| 27 #include "extensions/common/test_util.h" | 27 #include "extensions/common/test_util.h" |
| 28 #include "extensions/common/value_builder.h" | 28 #include "extensions/common/value_builder.h" |
| 29 #include "testing/gmock/include/gmock/gmock.h" | 29 #include "testing/gmock/include/gmock/gmock.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 31 #include "ui/base/l10n/l10n_util.h" | 31 #include "ui/base/l10n/l10n_util.h" |
| 32 | 32 |
| 33 using content::WebContents; |
| 33 using testing::_; | 34 using testing::_; |
| 34 using testing::AnyNumber; | 35 using testing::AnyNumber; |
| 35 using testing::Invoke; | 36 using testing::Invoke; |
| 37 using testing::Return; |
| 36 using testing::SaveArg; | 38 using testing::SaveArg; |
| 37 using testing::Return; | |
| 38 | 39 |
| 39 namespace media_router { | 40 namespace media_router { |
| 40 | 41 |
| 41 class PresentationRequestCallbacks { | 42 class PresentationRequestCallbacks { |
| 42 public: | 43 public: |
| 43 explicit PresentationRequestCallbacks( | 44 explicit PresentationRequestCallbacks( |
| 44 const content::PresentationError& expected_error) | 45 const content::PresentationError& expected_error) |
| 45 : expected_error_(expected_error) {} | 46 : expected_error_(expected_error) {} |
| 46 | 47 |
| 47 void Success(const content::PresentationSessionInfo&, const MediaRoute&) {} | 48 void Success(const content::PresentationSessionInfo&, const MediaRoute&) {} |
| 48 | 49 |
| 49 void Error(const content::PresentationError& error) { | 50 void Error(const content::PresentationError& error) { |
| 50 EXPECT_EQ(expected_error_.error_type, error.error_type); | 51 EXPECT_EQ(expected_error_.error_type, error.error_type); |
| 51 EXPECT_EQ(expected_error_.message, error.message); | 52 EXPECT_EQ(expected_error_.message, error.message); |
| 52 } | 53 } |
| 53 | 54 |
| 54 private: | 55 private: |
| 55 content::PresentationError expected_error_; | 56 content::PresentationError expected_error_; |
| 56 }; | 57 }; |
| 57 | 58 |
| 58 class MockRoutesUpdatedCallback { | 59 class MockRoutesUpdatedCallback { |
| 59 public: | 60 public: |
| 60 MOCK_METHOD2(OnRoutesUpdated, | 61 MOCK_METHOD2(OnRoutesUpdated, |
| 61 void(const std::vector<MediaRoute>& routes, | 62 void(const std::vector<MediaRoute>& routes, |
| 62 const std::vector<MediaRoute::Id>& joinable_route_ids)); | 63 const std::vector<MediaRoute::Id>& joinable_route_ids)); |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 class MediaRouterUITest : public ::testing::Test { | 66 class MediaRouterUITest : public ChromeRenderViewHostTestHarness { |
| 66 public: | 67 public: |
| 67 ~MediaRouterUITest() override { | 68 void TearDown() override { |
| 68 EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)) | 69 EXPECT_CALL(mock_router_, UnregisterMediaSinksObserver(_)) |
| 69 .Times(AnyNumber()); | 70 .Times(AnyNumber()); |
| 70 EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)) | 71 EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)) |
| 71 .Times(AnyNumber()); | 72 .Times(AnyNumber()); |
| 73 web_ui_contents_.reset(); |
| 74 create_session_request_.reset(); |
| 75 media_router_ui_.reset(); |
| 76 message_handler_.reset(); |
| 77 ChromeRenderViewHostTestHarness::TearDown(); |
| 78 } |
| 79 |
| 80 void CreateMediaRouterUIForURL(Profile* profile, const GURL& url) { |
| 81 web_contents()->GetController().LoadURL(url, content::Referrer(), |
| 82 ui::PAGE_TRANSITION_LINK, ""); |
| 83 content::RenderFrameHostTester::CommitPendingLoad( |
| 84 &web_contents()->GetController()); |
| 85 CreateMediaRouterUI(profile); |
| 72 } | 86 } |
| 73 | 87 |
| 74 void CreateMediaRouterUI(Profile* profile) { | 88 void CreateMediaRouterUI(Profile* profile) { |
| 75 initiator_.reset(content::WebContents::Create( | 89 SessionTabHelper::CreateForWebContents(web_contents()); |
| 76 content::WebContents::CreateParams(profile))); | 90 web_ui_contents_.reset( |
| 77 SessionTabHelper::CreateForWebContents(initiator_.get()); | 91 WebContents::Create(WebContents::CreateParams(profile))); |
| 78 web_contents_.reset(content::WebContents::Create( | 92 web_ui_.set_web_contents(web_ui_contents_.get()); |
| 79 content::WebContents::CreateParams(profile))); | |
| 80 web_ui_.set_web_contents(web_contents_.get()); | |
| 81 media_router_ui_.reset(new MediaRouterUI(&web_ui_)); | 93 media_router_ui_.reset(new MediaRouterUI(&web_ui_)); |
| 82 message_handler_.reset( | 94 message_handler_.reset( |
| 83 new MediaRouterWebUIMessageHandler(media_router_ui_.get())); | 95 new MediaRouterWebUIMessageHandler(media_router_ui_.get())); |
| 84 EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) | 96 EXPECT_CALL(mock_router_, RegisterMediaSinksObserver(_)) |
| 85 .WillRepeatedly(Invoke([this](MediaSinksObserver* observer) { | 97 .WillRepeatedly(Invoke([this](MediaSinksObserver* observer) { |
| 86 this->media_sinks_observers_.push_back(observer); | 98 this->media_sinks_observers_.push_back(observer); |
| 87 return true; | 99 return true; |
| 88 })); | 100 })); |
| 89 EXPECT_CALL(mock_router_, RegisterMediaRoutesObserver(_)) | 101 EXPECT_CALL(mock_router_, RegisterMediaRoutesObserver(_)) |
| 90 .Times(AnyNumber()); | 102 .Times(AnyNumber()); |
| 91 media_router_ui_->InitForTest(&mock_router_, initiator_.get(), | 103 media_router_ui_->InitForTest(&mock_router_, web_contents(), |
| 92 message_handler_.get(), | 104 message_handler_.get(), |
| 93 std::move(create_session_request_)); | 105 std::move(create_session_request_)); |
| 94 message_handler_->SetWebUIForTest(&web_ui_); | 106 message_handler_->SetWebUIForTest(&web_ui_); |
| 95 } | 107 } |
| 96 | 108 |
| 97 MediaSink CreateSinkCompatibleWithAllSources() { | 109 MediaSink CreateSinkCompatibleWithAllSources() { |
| 98 MediaSink sink("sinkId", "sinkName", MediaSink::GENERIC); | 110 MediaSink sink("sinkId", "sinkName", MediaSink::GENERIC); |
| 99 for (auto* observer : media_sinks_observers_) | 111 for (auto* observer : media_sinks_observers_) |
| 100 observer->OnSinksUpdated({sink}, std::vector<GURL>()); | 112 observer->OnSinksUpdated({sink}, std::vector<GURL>()); |
| 101 return sink; | 113 return sink; |
| 102 } | 114 } |
| 103 | 115 |
| 104 protected: | 116 protected: |
| 105 MockMediaRouter mock_router_; | 117 MockMediaRouter mock_router_; |
| 106 content::TestBrowserThreadBundle thread_bundle_; | |
| 107 TestingProfile profile_; | |
| 108 std::unique_ptr<content::WebContents> initiator_; | |
| 109 content::TestWebUI web_ui_; | 118 content::TestWebUI web_ui_; |
| 110 std::unique_ptr<content::WebContents> web_contents_; | 119 std::unique_ptr<WebContents> web_ui_contents_; |
| 111 std::unique_ptr<CreatePresentationConnectionRequest> create_session_request_; | 120 std::unique_ptr<CreatePresentationConnectionRequest> create_session_request_; |
| 112 std::unique_ptr<MediaRouterUI> media_router_ui_; | 121 std::unique_ptr<MediaRouterUI> media_router_ui_; |
| 113 std::unique_ptr<MediaRouterWebUIMessageHandler> message_handler_; | 122 std::unique_ptr<MediaRouterWebUIMessageHandler> message_handler_; |
| 114 std::vector<MediaSinksObserver*> media_sinks_observers_; | 123 std::vector<MediaSinksObserver*> media_sinks_observers_; |
| 115 }; | 124 }; |
| 116 | 125 |
| 117 TEST_F(MediaRouterUITest, RouteCreationTimeoutForTab) { | 126 TEST_F(MediaRouterUITest, RouteCreationTimeoutForTab) { |
| 118 CreateMediaRouterUI(&profile_); | 127 CreateMediaRouterUI(profile()); |
| 119 std::vector<MediaRouteResponseCallback> callbacks; | 128 std::vector<MediaRouteResponseCallback> callbacks; |
| 120 EXPECT_CALL( | 129 EXPECT_CALL( |
| 121 mock_router_, | 130 mock_router_, |
| 122 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(60), false)) | 131 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(60), false)) |
| 123 .WillOnce(SaveArg<4>(&callbacks)); | 132 .WillOnce(SaveArg<4>(&callbacks)); |
| 124 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), | 133 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), |
| 125 MediaCastMode::TAB_MIRROR); | 134 MediaCastMode::TAB_MIRROR); |
| 126 | 135 |
| 127 std::string expected_title = l10n_util::GetStringUTF8( | 136 std::string expected_title = l10n_util::GetStringUTF8( |
| 128 IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); | 137 IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); |
| 129 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); | 138 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); |
| 130 std::unique_ptr<RouteRequestResult> result = | 139 std::unique_ptr<RouteRequestResult> result = |
| 131 RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); | 140 RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); |
| 132 for (const auto& callback : callbacks) | 141 for (const auto& callback : callbacks) |
| 133 callback.Run(*result); | 142 callback.Run(*result); |
| 134 } | 143 } |
| 135 | 144 |
| 136 TEST_F(MediaRouterUITest, RouteCreationTimeoutForDesktop) { | 145 TEST_F(MediaRouterUITest, RouteCreationTimeoutForDesktop) { |
| 137 CreateMediaRouterUI(&profile_); | 146 CreateMediaRouterUI(profile()); |
| 138 std::vector<MediaRouteResponseCallback> callbacks; | 147 std::vector<MediaRouteResponseCallback> callbacks; |
| 139 EXPECT_CALL( | 148 EXPECT_CALL( |
| 140 mock_router_, | 149 mock_router_, |
| 141 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(120), false)) | 150 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(120), false)) |
| 142 .WillOnce(SaveArg<4>(&callbacks)); | 151 .WillOnce(SaveArg<4>(&callbacks)); |
| 143 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), | 152 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), |
| 144 MediaCastMode::DESKTOP_MIRROR); | 153 MediaCastMode::DESKTOP_MIRROR); |
| 145 | 154 |
| 146 std::string expected_title = l10n_util::GetStringUTF8( | 155 std::string expected_title = l10n_util::GetStringUTF8( |
| 147 IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_DESKTOP); | 156 IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_DESKTOP); |
| 148 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); | 157 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); |
| 149 std::unique_ptr<RouteRequestResult> result = | 158 std::unique_ptr<RouteRequestResult> result = |
| 150 RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); | 159 RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); |
| 151 for (const auto& callback : callbacks) | 160 for (const auto& callback : callbacks) |
| 152 callback.Run(*result); | 161 callback.Run(*result); |
| 153 } | 162 } |
| 154 | 163 |
| 155 TEST_F(MediaRouterUITest, RouteCreationTimeoutForPresentation) { | 164 TEST_F(MediaRouterUITest, RouteCreationTimeoutForPresentation) { |
| 156 CreateMediaRouterUI(&profile_); | 165 CreateMediaRouterUI(profile()); |
| 157 PresentationRequest presentation_request( | 166 PresentationRequest presentation_request( |
| 158 RenderFrameHostId(0, 0), {GURL("https://presentationurl.com")}, | 167 RenderFrameHostId(0, 0), {GURL("https://presentationurl.com")}, |
| 159 GURL("https://frameurl.fakeurl")); | 168 GURL("https://frameurl.fakeurl")); |
| 160 media_router_ui_->OnDefaultPresentationChanged(presentation_request); | 169 media_router_ui_->OnDefaultPresentationChanged(presentation_request); |
| 161 std::vector<MediaRouteResponseCallback> callbacks; | 170 std::vector<MediaRouteResponseCallback> callbacks; |
| 162 EXPECT_CALL( | 171 EXPECT_CALL( |
| 163 mock_router_, | 172 mock_router_, |
| 164 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(20), false)) | 173 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(20), false)) |
| 165 .WillOnce(SaveArg<4>(&callbacks)); | 174 .WillOnce(SaveArg<4>(&callbacks)); |
| 166 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), | 175 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), |
| 167 MediaCastMode::DEFAULT); | 176 MediaCastMode::DEFAULT); |
| 168 | 177 |
| 169 std::string expected_title = | 178 std::string expected_title = |
| 170 l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT, | 179 l10n_util::GetStringFUTF8(IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT, |
| 171 base::UTF8ToUTF16("frameurl.fakeurl")); | 180 base::UTF8ToUTF16("frameurl.fakeurl")); |
| 172 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); | 181 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); |
| 173 std::unique_ptr<RouteRequestResult> result = | 182 std::unique_ptr<RouteRequestResult> result = |
| 174 RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); | 183 RouteRequestResult::FromError("Timed out", RouteRequestResult::TIMED_OUT); |
| 175 for (const auto& callback : callbacks) | 184 for (const auto& callback : callbacks) |
| 176 callback.Run(*result); | 185 callback.Run(*result); |
| 177 } | 186 } |
| 178 | 187 |
| 179 TEST_F(MediaRouterUITest, RouteCreationParametersCantBeCreated) { | 188 TEST_F(MediaRouterUITest, RouteCreationParametersCantBeCreated) { |
| 180 CreateMediaRouterUI(&profile_); | 189 CreateMediaRouterUI(profile()); |
| 181 MediaSinkSearchResponseCallback sink_callback; | 190 MediaSinkSearchResponseCallback sink_callback; |
| 182 EXPECT_CALL(mock_router_, SearchSinks(_, _, _, _, _)) | 191 EXPECT_CALL(mock_router_, SearchSinks(_, _, _, _, _)) |
| 183 .WillOnce(SaveArg<4>(&sink_callback)); | 192 .WillOnce(SaveArg<4>(&sink_callback)); |
| 184 | 193 |
| 185 // Use DEFAULT mode without setting a PresentationRequest. | 194 // Use DEFAULT mode without setting a PresentationRequest. |
| 186 media_router_ui_->SearchSinksAndCreateRoute("sinkId", "search input", | 195 media_router_ui_->SearchSinksAndCreateRoute("sinkId", "search input", |
| 187 "domain", MediaCastMode::DEFAULT); | 196 "domain", MediaCastMode::DEFAULT); |
| 188 std::string expected_title = l10n_util::GetStringUTF8( | 197 std::string expected_title = l10n_util::GetStringUTF8( |
| 189 IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); | 198 IDS_MEDIA_ROUTER_ISSUE_CREATE_ROUTE_TIMEOUT_FOR_TAB); |
| 190 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); | 199 EXPECT_CALL(mock_router_, AddIssue(IssueTitleEquals(expected_title))); |
| 191 sink_callback.Run("foundSinkId"); | 200 sink_callback.Run("foundSinkId"); |
| 192 } | 201 } |
| 193 | 202 |
| 194 TEST_F(MediaRouterUITest, RouteRequestFromIncognito) { | 203 TEST_F(MediaRouterUITest, RouteRequestFromIncognito) { |
| 195 CreateMediaRouterUI(profile_.GetOffTheRecordProfile()); | 204 CreateMediaRouterUI(profile()->GetOffTheRecordProfile()); |
| 196 | 205 |
| 197 PresentationRequest presentation_request(RenderFrameHostId(0, 0), | 206 PresentationRequest presentation_request(RenderFrameHostId(0, 0), |
| 198 {GURL("https://foo.url.com/")}, | 207 {GURL("https://foo.url.com/")}, |
| 199 GURL("https://frameUrl")); | 208 GURL("https://frameUrl")); |
| 200 media_router_ui_->OnDefaultPresentationChanged(presentation_request); | 209 media_router_ui_->OnDefaultPresentationChanged(presentation_request); |
| 201 | 210 |
| 202 EXPECT_CALL( | 211 EXPECT_CALL( |
| 203 mock_router_, | 212 mock_router_, |
| 204 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(20), true)); | 213 CreateRoute(_, _, _, _, _, base::TimeDelta::FromSeconds(20), true)); |
| 205 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), | 214 media_router_ui_->CreateRoute(CreateSinkCompatibleWithAllSources().id(), |
| 206 MediaCastMode::DEFAULT); | 215 MediaCastMode::DEFAULT); |
| 207 } | 216 } |
| 208 | 217 |
| 209 TEST_F(MediaRouterUITest, SortedSinks) { | 218 TEST_F(MediaRouterUITest, SortedSinks) { |
| 210 CreateMediaRouterUI(&profile_); | 219 CreateMediaRouterUI(profile()); |
| 211 std::vector<MediaSinkWithCastModes> unsorted_sinks; | 220 std::vector<MediaSinkWithCastModes> unsorted_sinks; |
| 212 std::string sink_id1("sink3"); | 221 std::string sink_id1("sink3"); |
| 213 std::string sink_name1("B sink"); | 222 std::string sink_name1("B sink"); |
| 214 MediaSinkWithCastModes sink1( | 223 MediaSinkWithCastModes sink1( |
| 215 MediaSink(sink_id1, sink_name1, MediaSink::IconType::CAST)); | 224 MediaSink(sink_id1, sink_name1, MediaSink::IconType::CAST)); |
| 216 unsorted_sinks.push_back(sink1); | 225 unsorted_sinks.push_back(sink1); |
| 217 | 226 |
| 218 std::string sink_id2("sink1"); | 227 std::string sink_id2("sink1"); |
| 219 std::string sink_name2("A sink"); | 228 std::string sink_name2("A sink"); |
| 220 MediaSinkWithCastModes sink2( | 229 MediaSinkWithCastModes sink2( |
| 221 MediaSink(sink_id2, sink_name2, MediaSink::IconType::CAST)); | 230 MediaSink(sink_id2, sink_name2, MediaSink::IconType::CAST)); |
| 222 unsorted_sinks.push_back(sink2); | 231 unsorted_sinks.push_back(sink2); |
| 223 | 232 |
| 224 std::string sink_id3("sink2"); | 233 std::string sink_id3("sink2"); |
| 225 std::string sink_name3("B sink"); | 234 std::string sink_name3("B sink"); |
| 226 MediaSinkWithCastModes sink3( | 235 MediaSinkWithCastModes sink3( |
| 227 MediaSink(sink_id3, sink_name3, MediaSink::IconType::CAST)); | 236 MediaSink(sink_id3, sink_name3, MediaSink::IconType::CAST)); |
| 228 unsorted_sinks.push_back(sink3); | 237 unsorted_sinks.push_back(sink3); |
| 229 | 238 |
| 230 // Sorted order is 2, 3, 1. | 239 // Sorted order is 2, 3, 1. |
| 231 media_router_ui_->OnResultsUpdated(unsorted_sinks); | 240 media_router_ui_->OnResultsUpdated(unsorted_sinks); |
| 232 const auto& sorted_sinks = media_router_ui_->sinks_; | 241 const auto& sorted_sinks = media_router_ui_->sinks_; |
| 233 EXPECT_EQ(sink_name2, sorted_sinks[0].sink.name()); | 242 EXPECT_EQ(sink_name2, sorted_sinks[0].sink.name()); |
| 234 EXPECT_EQ(sink_id3, sorted_sinks[1].sink.id()); | 243 EXPECT_EQ(sink_id3, sorted_sinks[1].sink.id()); |
| 235 EXPECT_EQ(sink_id1, sorted_sinks[2].sink.id()); | 244 EXPECT_EQ(sink_id1, sorted_sinks[2].sink.id()); |
| 236 } | 245 } |
| 237 | 246 |
| 238 TEST_F(MediaRouterUITest, SortSinksByIconType) { | 247 TEST_F(MediaRouterUITest, SortSinksByIconType) { |
| 239 CreateMediaRouterUI(&profile_); | 248 CreateMediaRouterUI(profile()); |
| 240 std::vector<MediaSinkWithCastModes> unsorted_sinks; | 249 std::vector<MediaSinkWithCastModes> unsorted_sinks; |
| 241 | 250 |
| 242 MediaSinkWithCastModes sink1( | 251 MediaSinkWithCastModes sink1( |
| 243 MediaSink("id1", "sink", MediaSink::IconType::HANGOUT)); | 252 MediaSink("id1", "sink", MediaSink::IconType::HANGOUT)); |
| 244 unsorted_sinks.push_back(sink1); | 253 unsorted_sinks.push_back(sink1); |
| 245 MediaSinkWithCastModes sink2( | 254 MediaSinkWithCastModes sink2( |
| 246 MediaSink("id2", "B sink", MediaSink::IconType::CAST_AUDIO_GROUP)); | 255 MediaSink("id2", "B sink", MediaSink::IconType::CAST_AUDIO_GROUP)); |
| 247 unsorted_sinks.push_back(sink2); | 256 unsorted_sinks.push_back(sink2); |
| 248 MediaSinkWithCastModes sink3( | 257 MediaSinkWithCastModes sink3( |
| 249 MediaSink("id3", "sink", MediaSink::IconType::GENERIC)); | 258 MediaSink("id3", "sink", MediaSink::IconType::GENERIC)); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 | 350 |
| 342 ASSERT_EQ(2u, filtered_joinable_route_ids.size()); | 351 ASSERT_EQ(2u, filtered_joinable_route_ids.size()); |
| 343 EXPECT_EQ(display_route_1.media_route_id(), filtered_joinable_route_ids[0]); | 352 EXPECT_EQ(display_route_1.media_route_id(), filtered_joinable_route_ids[0]); |
| 344 EXPECT_EQ(display_route_2.media_route_id(), filtered_joinable_route_ids[1]); | 353 EXPECT_EQ(display_route_2.media_route_id(), filtered_joinable_route_ids[1]); |
| 345 | 354 |
| 346 EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); | 355 EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); |
| 347 observer.reset(); | 356 observer.reset(); |
| 348 } | 357 } |
| 349 | 358 |
| 350 TEST_F(MediaRouterUITest, UIMediaRoutesObserverAssignsCurrentCastModes) { | 359 TEST_F(MediaRouterUITest, UIMediaRoutesObserverAssignsCurrentCastModes) { |
| 351 CreateMediaRouterUI(&profile_); | 360 CreateMediaRouterUI(profile()); |
| 352 SessionID::id_type tab_id = SessionTabHelper::IdForTab(initiator_.get()); | 361 SessionID::id_type tab_id = SessionTabHelper::IdForTab(web_contents()); |
| 353 MediaSource media_source_1(MediaSourceForTab(tab_id)); | 362 MediaSource media_source_1(MediaSourceForTab(tab_id)); |
| 354 MediaSource media_source_2("mediaSource"); | 363 MediaSource media_source_2("mediaSource"); |
| 355 MediaSource media_source_3(MediaSourceForDesktop()); | 364 MediaSource media_source_3(MediaSourceForDesktop()); |
| 356 MockRoutesUpdatedCallback mock_callback; | 365 MockRoutesUpdatedCallback mock_callback; |
| 357 std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( | 366 std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( |
| 358 new MediaRouterUI::UIMediaRoutesObserver( | 367 new MediaRouterUI::UIMediaRoutesObserver( |
| 359 &mock_router_, MediaSource::Id(), | 368 &mock_router_, MediaSource::Id(), |
| 360 base::Bind(&MediaRouterUI::OnRoutesUpdated, | 369 base::Bind(&MediaRouterUI::OnRoutesUpdated, |
| 361 base::Unretained(media_router_ui_.get())))); | 370 base::Unretained(media_router_ui_.get())))); |
| 362 | 371 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 391 EXPECT_EQ(end(current_cast_modes), cast_mode_entry); | 400 EXPECT_EQ(end(current_cast_modes), cast_mode_entry); |
| 392 cast_mode_entry = current_cast_modes.find(display_route_2.media_route_id()); | 401 cast_mode_entry = current_cast_modes.find(display_route_2.media_route_id()); |
| 393 EXPECT_NE(end(current_cast_modes), cast_mode_entry); | 402 EXPECT_NE(end(current_cast_modes), cast_mode_entry); |
| 394 EXPECT_EQ(MediaCastMode::DESKTOP_MIRROR, cast_mode_entry->second); | 403 EXPECT_EQ(MediaCastMode::DESKTOP_MIRROR, cast_mode_entry->second); |
| 395 | 404 |
| 396 EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); | 405 EXPECT_CALL(mock_router_, UnregisterMediaRoutesObserver(_)).Times(1); |
| 397 observer.reset(); | 406 observer.reset(); |
| 398 } | 407 } |
| 399 | 408 |
| 400 TEST_F(MediaRouterUITest, UIMediaRoutesObserverSkipsUnavailableCastModes) { | 409 TEST_F(MediaRouterUITest, UIMediaRoutesObserverSkipsUnavailableCastModes) { |
| 401 CreateMediaRouterUI(&profile_); | 410 CreateMediaRouterUI(profile()); |
| 402 MediaSource media_source_1("mediaSource1"); | 411 MediaSource media_source_1("mediaSource1"); |
| 403 MediaSource media_source_2("mediaSource2"); | 412 MediaSource media_source_2("mediaSource2"); |
| 404 MediaSource media_source_3(MediaSourceForDesktop()); | 413 MediaSource media_source_3(MediaSourceForDesktop()); |
| 405 MockRoutesUpdatedCallback mock_callback; | 414 MockRoutesUpdatedCallback mock_callback; |
| 406 std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( | 415 std::unique_ptr<MediaRouterUI::UIMediaRoutesObserver> observer( |
| 407 new MediaRouterUI::UIMediaRoutesObserver( | 416 new MediaRouterUI::UIMediaRoutesObserver( |
| 408 &mock_router_, MediaSource::Id(), | 417 &mock_router_, MediaSource::Id(), |
| 409 base::Bind(&MediaRouterUI::OnRoutesUpdated, | 418 base::Bind(&MediaRouterUI::OnRoutesUpdated, |
| 410 base::Unretained(media_router_ui_.get())))); | 419 base::Unretained(media_router_ui_.get())))); |
| 411 | 420 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 486 content::PresentationErrorType::PRESENTATION_ERROR_NO_AVAILABLE_SCREENS, | 495 content::PresentationErrorType::PRESENTATION_ERROR_NO_AVAILABLE_SCREENS, |
| 487 "No screens found."); | 496 "No screens found."); |
| 488 PresentationRequestCallbacks request_callbacks(expected_error); | 497 PresentationRequestCallbacks request_callbacks(expected_error); |
| 489 create_session_request_.reset(new CreatePresentationConnectionRequest( | 498 create_session_request_.reset(new CreatePresentationConnectionRequest( |
| 490 RenderFrameHostId(0, 0), GURL("http://google.com/presentation"), | 499 RenderFrameHostId(0, 0), GURL("http://google.com/presentation"), |
| 491 GURL("http://google.com"), | 500 GURL("http://google.com"), |
| 492 base::Bind(&PresentationRequestCallbacks::Success, | 501 base::Bind(&PresentationRequestCallbacks::Success, |
| 493 base::Unretained(&request_callbacks)), | 502 base::Unretained(&request_callbacks)), |
| 494 base::Bind(&PresentationRequestCallbacks::Error, | 503 base::Bind(&PresentationRequestCallbacks::Error, |
| 495 base::Unretained(&request_callbacks)))); | 504 base::Unretained(&request_callbacks)))); |
| 496 CreateMediaRouterUI(&profile_); | 505 CreateMediaRouterUI(profile()); |
| 497 // Destroying the UI should return the expected error from above to the error | 506 // Destroying the UI should return the expected error from above to the error |
| 498 // callback. | 507 // callback. |
| 499 media_router_ui_.reset(); | 508 media_router_ui_.reset(); |
| 500 } | 509 } |
| 501 | 510 |
| 502 TEST_F(MediaRouterUITest, NotFoundErrorOnCloseWithNoCompatibleSinks) { | 511 TEST_F(MediaRouterUITest, NotFoundErrorOnCloseWithNoCompatibleSinks) { |
| 503 content::PresentationError expected_error( | 512 content::PresentationError expected_error( |
| 504 content::PresentationErrorType::PRESENTATION_ERROR_NO_AVAILABLE_SCREENS, | 513 content::PresentationErrorType::PRESENTATION_ERROR_NO_AVAILABLE_SCREENS, |
| 505 "No screens found."); | 514 "No screens found."); |
| 506 PresentationRequestCallbacks request_callbacks(expected_error); | 515 PresentationRequestCallbacks request_callbacks(expected_error); |
| 507 GURL presentation_url("http://google.com/presentation"); | 516 GURL presentation_url("http://google.com/presentation"); |
| 508 create_session_request_.reset(new CreatePresentationConnectionRequest( | 517 create_session_request_.reset(new CreatePresentationConnectionRequest( |
| 509 RenderFrameHostId(0, 0), presentation_url, GURL("http://google.com"), | 518 RenderFrameHostId(0, 0), presentation_url, GURL("http://google.com"), |
| 510 base::Bind(&PresentationRequestCallbacks::Success, | 519 base::Bind(&PresentationRequestCallbacks::Success, |
| 511 base::Unretained(&request_callbacks)), | 520 base::Unretained(&request_callbacks)), |
| 512 base::Bind(&PresentationRequestCallbacks::Error, | 521 base::Bind(&PresentationRequestCallbacks::Error, |
| 513 base::Unretained(&request_callbacks)))); | 522 base::Unretained(&request_callbacks)))); |
| 514 CreateMediaRouterUI(&profile_); | 523 CreateMediaRouterUI(profile()); |
| 515 | 524 |
| 516 // Send a sink to the UI that is compatible with sources other than the | 525 // Send a sink to the UI that is compatible with sources other than the |
| 517 // presentation url to cause a NotFoundError. | 526 // presentation url to cause a NotFoundError. |
| 518 std::vector<MediaSink> sinks; | 527 std::vector<MediaSink> sinks; |
| 519 sinks.emplace_back("sink id", "sink name", MediaSink::GENERIC); | 528 sinks.emplace_back("sink id", "sink name", MediaSink::GENERIC); |
| 520 std::vector<GURL> origins; | 529 std::vector<GURL> origins; |
| 521 for (auto* observer : media_sinks_observers_) { | 530 for (auto* observer : media_sinks_observers_) { |
| 522 if (observer->source().id() != presentation_url.spec()) { | 531 if (observer->source().id() != presentation_url.spec()) { |
| 523 observer->OnSinksUpdated(sinks, origins); | 532 observer->OnSinksUpdated(sinks, origins); |
| 524 } | 533 } |
| 525 } | 534 } |
| 526 // Destroying the UI should return the expected error from above to the error | 535 // Destroying the UI should return the expected error from above to the error |
| 527 // callback. | 536 // callback. |
| 528 media_router_ui_.reset(); | 537 media_router_ui_.reset(); |
| 529 } | 538 } |
| 530 | 539 |
| 531 TEST_F(MediaRouterUITest, AbortErrorOnClose) { | 540 TEST_F(MediaRouterUITest, AbortErrorOnClose) { |
| 532 content::PresentationError expected_error( | 541 content::PresentationError expected_error( |
| 533 content::PresentationErrorType:: | 542 content::PresentationErrorType:: |
| 534 PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED, | 543 PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED, |
| 535 "Dialog closed."); | 544 "Dialog closed."); |
| 536 PresentationRequestCallbacks request_callbacks(expected_error); | 545 PresentationRequestCallbacks request_callbacks(expected_error); |
| 537 GURL presentation_url("http://google.com/presentation"); | 546 GURL presentation_url("http://google.com/presentation"); |
| 538 create_session_request_.reset(new CreatePresentationConnectionRequest( | 547 create_session_request_.reset(new CreatePresentationConnectionRequest( |
| 539 RenderFrameHostId(0, 0), presentation_url, GURL("http://google.com"), | 548 RenderFrameHostId(0, 0), presentation_url, GURL("http://google.com"), |
| 540 base::Bind(&PresentationRequestCallbacks::Success, | 549 base::Bind(&PresentationRequestCallbacks::Success, |
| 541 base::Unretained(&request_callbacks)), | 550 base::Unretained(&request_callbacks)), |
| 542 base::Bind(&PresentationRequestCallbacks::Error, | 551 base::Bind(&PresentationRequestCallbacks::Error, |
| 543 base::Unretained(&request_callbacks)))); | 552 base::Unretained(&request_callbacks)))); |
| 544 CreateMediaRouterUI(&profile_); | 553 CreateMediaRouterUI(profile()); |
| 545 | 554 |
| 546 // Send a sink to the UI that is compatible with the presentation url to avoid | 555 // Send a sink to the UI that is compatible with the presentation url to avoid |
| 547 // a NotFoundError. | 556 // a NotFoundError. |
| 548 std::vector<MediaSink> sinks; | 557 std::vector<MediaSink> sinks; |
| 549 sinks.emplace_back("sink id", "sink name", MediaSink::GENERIC); | 558 sinks.emplace_back("sink id", "sink name", MediaSink::GENERIC); |
| 550 std::vector<GURL> origins; | 559 std::vector<GURL> origins; |
| 551 MediaSource::Id presentation_source_id = | 560 MediaSource::Id presentation_source_id = |
| 552 MediaSourceForPresentationUrl(presentation_url).id(); | 561 MediaSourceForPresentationUrl(presentation_url).id(); |
| 553 for (auto* observer : media_sinks_observers_) { | 562 for (auto* observer : media_sinks_observers_) { |
| 554 if (observer->source().id() == presentation_source_id) { | 563 if (observer->source().id() == presentation_source_id) { |
| 555 observer->OnSinksUpdated(sinks, origins); | 564 observer->OnSinksUpdated(sinks, origins); |
| 556 } | 565 } |
| 557 } | 566 } |
| 558 // Destroying the UI should return the expected error from above to the error | 567 // Destroying the UI should return the expected error from above to the error |
| 559 // callback. | 568 // callback. |
| 560 media_router_ui_.reset(); | 569 media_router_ui_.reset(); |
| 561 } | 570 } |
| 571 |
| 572 TEST_F(MediaRouterUITest, RecordCastModeSelections) { |
| 573 const GURL url_1a = GURL("https://www.example.com/watch?v=AAAA"); |
| 574 const GURL url_1b = GURL("https://www.example.com/watch?v=BBBB"); |
| 575 const GURL url_2 = GURL("https://example2.com/0000"); |
| 576 const GURL url_3 = GURL("https://www3.example.com/index.html"); |
| 577 |
| 578 CreateMediaRouterUIForURL(profile(), url_1a); |
| 579 EXPECT_FALSE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 580 media_router_ui_->RecordCastModeSelection(MediaCastMode::TAB_MIRROR); |
| 581 EXPECT_TRUE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 582 |
| 583 CreateMediaRouterUIForURL(profile(), url_2); |
| 584 EXPECT_FALSE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 585 |
| 586 CreateMediaRouterUIForURL(profile(), url_1b); |
| 587 // |url_1a| and |url_1b| have the same origin, so the selection made for |
| 588 // |url_1a| should be retrieved. |
| 589 EXPECT_TRUE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 590 media_router_ui_->RecordCastModeSelection(MediaCastMode::DEFAULT); |
| 591 EXPECT_FALSE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 592 |
| 593 media_router_ui_->RecordCastModeSelection(MediaCastMode::TAB_MIRROR); |
| 594 CreateMediaRouterUIForURL(profile(), url_3); |
| 595 // |url_1a| and |url_3| have the same domain "example.com" but different |
| 596 // origins, so their preferences should be separate. |
| 597 EXPECT_FALSE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 598 } |
| 599 |
| 600 TEST_F(MediaRouterUITest, RecordDesktopMirroringCastModeSelection) { |
| 601 const GURL url = GURL("https://www.example.com/watch?v=AAAA"); |
| 602 CreateMediaRouterUIForURL(profile(), url); |
| 603 |
| 604 EXPECT_FALSE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 605 media_router_ui_->RecordCastModeSelection(MediaCastMode::DESKTOP_MIRROR); |
| 606 // Selecting desktop mirroring should not change the recorded preferences. |
| 607 EXPECT_FALSE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 608 |
| 609 media_router_ui_->RecordCastModeSelection(MediaCastMode::TAB_MIRROR); |
| 610 EXPECT_TRUE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 611 media_router_ui_->RecordCastModeSelection(MediaCastMode::DESKTOP_MIRROR); |
| 612 // Selecting desktop mirroring should not change the recorded preferences. |
| 613 EXPECT_TRUE(media_router_ui_->UserSelectedTabMirroringForCurrentOrigin()); |
| 614 } |
| 562 } // namespace media_router | 615 } // namespace media_router |
| OLD | NEW |