[Media Router] Handle multiple Presentation URLs when creating routes

Based on https://codereview.chromium.org/2488403002/

- Implement CanConnectToMediaSource() in media_source_helper.cc
- In PresentationServiceDelegateImpl::JoinSession, pick cast specific url and send it to cast MRP

BUG=627655

Review-Url: https://codereview.chromium.org/2547703002
Cr-Commit-Position: refs/heads/master@{#437035}
diff --git a/chrome/browser/media/router/create_presentation_connection_request.cc b/chrome/browser/media/router/create_presentation_connection_request.cc
index 5bec76d..9dd49c9 100644
--- a/chrome/browser/media/router/create_presentation_connection_request.cc
+++ b/chrome/browser/media/router/create_presentation_connection_request.cc
@@ -15,13 +15,11 @@
 
 CreatePresentationConnectionRequest::CreatePresentationConnectionRequest(
     const RenderFrameHostId& render_frame_host_id,
-    const GURL& presentation_url,
+    const std::vector<GURL>& presentation_urls,
     const GURL& frame_url,
     const PresentationSessionSuccessCallback& success_cb,
     const PresentationSessionErrorCallback& error_cb)
-    : presentation_request_(render_frame_host_id,
-                            {presentation_url},
-                            frame_url),
+    : presentation_request_(render_frame_host_id, presentation_urls, frame_url),
       success_cb_(success_cb),
       error_cb_(error_cb),
       cb_invoked_(false) {
@@ -38,12 +36,12 @@
 
 void CreatePresentationConnectionRequest::InvokeSuccessCallback(
     const std::string& presentation_id,
+    const GURL& presentation_url,
     const MediaRoute& route) {
   DCHECK(!cb_invoked_);
   if (!cb_invoked_) {
     success_cb_.Run(
-        content::PresentationSessionInfo(
-            presentation_request_.presentation_url(), presentation_id),
+        content::PresentationSessionInfo(presentation_url, presentation_id),
         route);
     cb_invoked_ = true;
   }
@@ -66,8 +64,8 @@
     presentation_request->InvokeErrorCallback(content::PresentationError(
         content::PRESENTATION_ERROR_UNKNOWN, result.error()));
   } else {
-    presentation_request->InvokeSuccessCallback(result.presentation_id(),
-                                                *result.route());
+    presentation_request->InvokeSuccessCallback(
+        result.presentation_id(), result.presentation_url(), *result.route());
   }
 }
 
diff --git a/chrome/browser/media/router/create_presentation_connection_request.h b/chrome/browser/media/router/create_presentation_connection_request.h
index 9dd9c03..41e5da49 100644
--- a/chrome/browser/media/router/create_presentation_connection_request.h
+++ b/chrome/browser/media/router/create_presentation_connection_request.h
@@ -7,6 +7,7 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/macros.h"
 #include "chrome/browser/media/router/media_route.h"
@@ -46,7 +47,7 @@
   // |erorr_cb|: Callback to invoke when the request fails. Must be valid.
   CreatePresentationConnectionRequest(
       const RenderFrameHostId& render_frame_host_id,
-      const GURL& presentation_url,
+      const std::vector<GURL>& presentation_urls,
       const GURL& frame_url,
       const PresentationSessionSuccessCallback& success_cb,
       const PresentationSessionErrorCallback& error_cb);
@@ -60,6 +61,7 @@
   // These functions can only be invoked once per instance. It is an error
   // to invoke these functions more than once.
   void InvokeSuccessCallback(const std::string& presentation_id,
+                             const GURL& presentation_url,
                              const MediaRoute& route);
   void InvokeErrorCallback(const content::PresentationError& error);
 
diff --git a/chrome/browser/media/router/create_presentation_connection_request_unittest.cc b/chrome/browser/media/router/create_presentation_connection_request_unittest.cc
index 6d9fdf30..8e71ecb4 100644
--- a/chrome/browser/media/router/create_presentation_connection_request_unittest.cc
+++ b/chrome/browser/media/router/create_presentation_connection_request_unittest.cc
@@ -12,11 +12,13 @@
 
 namespace {
 
-const char kPresentationUrl[] = "http://foo.com";
-const char kFrameUrl[] = "http://google.com";
-const char kPresentationId[] = "presentationId";
-const char kRouteId[] =
-    "urn:x-org.chromium:media:route:presentationId/cast-sink1/http://foo.com";
+constexpr char kPresentationUrl1[] = "http://www.example.com/presentation.html";
+constexpr char kPresentationUrl2[] = "http://www.example.net/alternate.html";
+constexpr char kFrameUrl[] = "http://google.com";
+constexpr char kPresentationId[] = "presentationId";
+constexpr char kRouteId[] =
+    "urn:x-org.chromium:media:route:presentationId/cast-sink1/"
+    "http://www.example.com/presentation.html";
 
 }  // namespace
 
@@ -25,8 +27,8 @@
   CreatePresentationConnectionRequestTest()
       : cb_invoked_(false),
         render_frame_host_id_(1, 2),
-        presentation_url_(kPresentationUrl),
-        presentation_urls_({presentation_url_}) {}
+        presentation_url_(kPresentationUrl1),
+        presentation_urls_({presentation_url_, GURL(kPresentationUrl2)}) {}
 
   ~CreatePresentationConnectionRequestTest() override {}
 
@@ -36,6 +38,7 @@
     cb_invoked_ = true;
     EXPECT_EQ(expected_info.presentation_url, actual_info.presentation_url);
     EXPECT_EQ(expected_info.presentation_id, actual_info.presentation_id);
+    EXPECT_EQ(route.media_route_id(), kRouteId);
   }
 
   void OnError(const content::PresentationError& expected_error,
@@ -65,7 +68,7 @@
   content::PresentationError error(content::PRESENTATION_ERROR_UNKNOWN,
                                    "Unknown error.");
   CreatePresentationConnectionRequest request(
-      render_frame_host_id_, presentation_url_, GURL(kFrameUrl),
+      render_frame_host_id_, presentation_urls_, GURL(kFrameUrl),
       base::Bind(&CreatePresentationConnectionRequestTest::FailOnSuccess,
                  base::Unretained(this)),
       base::Bind(&CreatePresentationConnectionRequestTest::OnError,
@@ -82,14 +85,14 @@
   content::PresentationSessionInfo session_info(presentation_url_,
                                                 kPresentationId);
   CreatePresentationConnectionRequest request(
-      render_frame_host_id_, presentation_url_, GURL(kFrameUrl),
+      render_frame_host_id_, {presentation_url_}, GURL(kFrameUrl),
       base::Bind(&CreatePresentationConnectionRequestTest::OnSuccess,
                  base::Unretained(this), session_info),
       base::Bind(&CreatePresentationConnectionRequestTest::FailOnError,
                  base::Unretained(this)));
   MediaRoute route(kRouteId, MediaSourceForTab(1), "sinkId", "Description",
                    false, "", false);
-  request.InvokeSuccessCallback(kPresentationId, route);
+  request.InvokeSuccessCallback(kPresentationId, presentation_url_, route);
   EXPECT_TRUE(cb_invoked_);
 }
 
@@ -98,7 +101,7 @@
       content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED,
       "This is an error message");
   CreatePresentationConnectionRequest request(
-      render_frame_host_id_, presentation_url_, GURL(kFrameUrl),
+      render_frame_host_id_, presentation_urls_, GURL(kFrameUrl),
       base::Bind(&CreatePresentationConnectionRequestTest::FailOnSuccess,
                  base::Unretained(this)),
       base::Bind(&CreatePresentationConnectionRequestTest::OnError,
diff --git a/chrome/browser/media/router/media_router_dialog_controller_unittest.cc b/chrome/browser/media/router/media_router_dialog_controller_unittest.cc
index a302d35..9b36a4a 100644
--- a/chrome/browser/media/router/media_router_dialog_controller_unittest.cc
+++ b/chrome/browser/media/router/media_router_dialog_controller_unittest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include <memory>
+#include <vector>
 
 #include "chrome/browser/media/router/create_presentation_connection_request.h"
 #include "chrome/browser/media/router/media_router_dialog_controller.h"
@@ -66,13 +67,15 @@
   void RequestError(const content::PresentationError& error) {}
 
   std::unique_ptr<CreatePresentationConnectionRequest> GetRequest() {
-    return base::MakeUnique<CreatePresentationConnectionRequest>(
-        RenderFrameHostId(1, 2), GURL("http://example.com"),
-        GURL("http://google.com"),
-        base::Bind(&MediaRouterDialogControllerTest::RequestSuccess,
-                   base::Unretained(this)),
-        base::Bind(&MediaRouterDialogControllerTest::RequestError,
-                   base::Unretained(this)));
+    return std::unique_ptr<CreatePresentationConnectionRequest>(
+        new CreatePresentationConnectionRequest(
+            RenderFrameHostId(1, 2),
+            {GURL("http://example.com"), GURL("http://example2.com")},
+            GURL("http://google.com"),
+            base::Bind(&MediaRouterDialogControllerTest::RequestSuccess,
+                       base::Unretained(this)),
+            base::Bind(&MediaRouterDialogControllerTest::RequestError,
+                       base::Unretained(this))));
   }
 
   std::unique_ptr<TestMediaRouterDialogController> dialog_controller_;
diff --git a/chrome/browser/media/router/media_source.cc b/chrome/browser/media/router/media_source.cc
index 359ccf1..d08ebbd 100644
--- a/chrome/browser/media/router/media_source.cc
+++ b/chrome/browser/media/router/media_source.cc
@@ -6,15 +6,13 @@
 
 #include <string>
 
-#include "url/gurl.h"
-
 namespace media_router {
 
 MediaSource::MediaSource(const MediaSource::Id& source_id) : id_(source_id) {
 }
 
 MediaSource::MediaSource(const GURL& presentation_url)
-    : id_(presentation_url.spec()) {}
+    : id_(presentation_url.spec()), url_(presentation_url) {}
 
 MediaSource::~MediaSource() {}
 
@@ -22,6 +20,10 @@
   return id_;
 }
 
+GURL MediaSource::url() const {
+  return url_;
+}
+
 bool MediaSource::operator==(const MediaSource& other) const {
   return id_ == other.id();
 }
diff --git a/chrome/browser/media/router/media_source.h b/chrome/browser/media/router/media_source.h
index 279edf0..ac5da714 100644
--- a/chrome/browser/media/router/media_source.h
+++ b/chrome/browser/media/router/media_source.h
@@ -11,8 +11,7 @@
 #include <string>
 
 #include "base/hash.h"
-
-class GURL;
+#include "url/gurl.h"
 
 // TODO(mfoltz): Right now this is a wrapper for std::string.  Factor methods
 // from media_source_helper here so this object becomes useful; and don't just
@@ -30,6 +29,10 @@
   // Gets the ID of the media source.
   MediaSource::Id id() const;
 
+  // If MediaSource is created from a URL, return the URL; otherwise return an
+  // empty GURL.
+  GURL url() const;
+
   // Returns true if two MediaSource objects use the same media ID.
   bool operator==(const MediaSource& other) const;
 
@@ -45,6 +48,7 @@
 
  private:
   MediaSource::Id id_;
+  GURL url_;
 };
 
 }  // namespace media_router
diff --git a/chrome/browser/media/router/media_source_helper.cc b/chrome/browser/media/router/media_source_helper.cc
index 2365cdd..7c618b9 100644
--- a/chrome/browser/media/router/media_source_helper.cc
+++ b/chrome/browser/media/router/media_source_helper.cc
@@ -22,7 +22,8 @@
 constexpr char kDesktopMediaUrn[] = "urn:x-org.chromium.media:source:desktop";
 constexpr char kTabRemotingUrnFormat[] =
     "urn:x-org.chromium.media:source:tab_content_remoting:%d";
-
+constexpr char kCastPresentationUrlDomain[] = "google.com";
+constexpr char kCastPresentationUrlPath[] = "/cast";
 }  // namespace
 
 MediaSource MediaSourceForTab(int tab_id) {
@@ -59,6 +60,17 @@
          IsTabMirroringMediaSource(source);
 }
 
+bool CanConnectToMediaSource(const MediaSource& source) {
+  // compare host, port, scheme, and path prefix for source.url()
+  if (!source.url().SchemeIs(url::kHttpsScheme) ||
+      !source.url().DomainIs(kCastPresentationUrlDomain) ||
+      (!source.url().has_path() ||
+       source.url().path() != kCastPresentationUrlPath))
+    return false;
+
+  return true;
+}
+
 int TabIdFromMediaSource(const MediaSource& source) {
   int tab_id;
   if (sscanf(source.id().c_str(), kTabMediaUrnFormat, &tab_id) == 1)
diff --git a/chrome/browser/media/router/media_source_helper.h b/chrome/browser/media/router/media_source_helper.h
index f9356cd10..64d6e74 100644
--- a/chrome/browser/media/router/media_source_helper.h
+++ b/chrome/browser/media/router/media_source_helper.h
@@ -29,6 +29,10 @@
 bool IsTabMirroringMediaSource(const MediaSource& source);
 bool IsMirroringMediaSource(const MediaSource& source);
 
+// Returns true if |source| is a media source type that can be connected to the
+// Presentation API by from a request initiated by the browser.
+bool CanConnectToMediaSource(const MediaSource& source);
+
 // Parses the |source| and returns the SessionTabHelper tab ID referencing a
 // source tab. Returns a non-positive value on error.
 int TabIdFromMediaSource(const MediaSource& source);
diff --git a/chrome/browser/media/router/media_source_helper_unittest.cc b/chrome/browser/media/router/media_source_helper_unittest.cc
index c556f6cc..1b708fd 100644
--- a/chrome/browser/media/router/media_source_helper_unittest.cc
+++ b/chrome/browser/media/router/media_source_helper_unittest.cc
@@ -45,5 +45,24 @@
       MediaSourceForPresentationUrl(GURL("totally not a url"))));
 }
 
+TEST(MediaSourcesTest, CanConnectToMediaSource) {
+  EXPECT_TRUE(CanConnectToMediaSource(
+      MediaSource(GURL("https://google.com/cast#__castAppId__=233637DE"))));
+  // false scheme
+  EXPECT_FALSE(CanConnectToMediaSource(
+      MediaSource(GURL("http://google.com/cast#__castAppId__=233637DE"))));
+  // false domain
+  EXPECT_FALSE(CanConnectToMediaSource(
+      MediaSource(GURL("https://google2.com/cast#__castAppId__=233637DE"))));
+  // empty path
+  EXPECT_FALSE(
+      CanConnectToMediaSource(MediaSource(GURL("https://www.google.com"))));
+  // false path
+  EXPECT_FALSE(CanConnectToMediaSource(
+      MediaSource(GURL("https://www.google.com/path"))));
+
+  EXPECT_FALSE(CanConnectToMediaSource(MediaSource(GURL(""))));
+}
+
 }  // namespace media_router
 
diff --git a/chrome/browser/media/router/media_source_unittest.cc b/chrome/browser/media/router/media_source_unittest.cc
index 470b572..a4e92148 100644
--- a/chrome/browser/media/router/media_source_unittest.cc
+++ b/chrome/browser/media/router/media_source_unittest.cc
@@ -11,6 +11,14 @@
 TEST(MediaSourceTest, Constructor) {
   MediaSource source1("urn:x-com.google.cast:application:DEADBEEF");
   EXPECT_EQ("urn:x-com.google.cast:application:DEADBEEF", source1.id());
+  EXPECT_EQ(GURL(""), source1.url());
+}
+
+TEST(MediaSourceTest, ConstructorWithGURL) {
+  GURL test_url = GURL("http://google.com");
+  MediaSource source1(test_url);
+  EXPECT_EQ(test_url.spec(), source1.id());
+  EXPECT_EQ(test_url, source1.url());
 }
 
 }  // namespace media_router
diff --git a/chrome/browser/media/router/presentation_request.h b/chrome/browser/media/router/presentation_request.h
index 56265c9ac..1879ec1 100644
--- a/chrome/browser/media/router/presentation_request.h
+++ b/chrome/browser/media/router/presentation_request.h
@@ -32,8 +32,9 @@
   const RenderFrameHostId& render_frame_host_id() const {
     return render_frame_host_id_;
   }
-  // TODO(crbug.com/627655): Use multiple URLs.
-  const GURL& presentation_url() const { return presentation_urls_[0]; }
+  const std::vector<GURL>& presentation_urls() const {
+    return presentation_urls_;
+  }
   const GURL& frame_url() const { return frame_url_; }
 
  private:
diff --git a/chrome/browser/media/router/presentation_request_unittest.cc b/chrome/browser/media/router/presentation_request_unittest.cc
index 9fe5a10a..165b5d0 100644
--- a/chrome/browser/media/router/presentation_request_unittest.cc
+++ b/chrome/browser/media/router/presentation_request_unittest.cc
@@ -9,8 +9,9 @@
 
 TEST(PresentationRequestTest, Equals) {
   GURL frame_url("http://www.site.com/");
-  std::vector<GURL> presentation_urls =
-      {GURL("http://www.example.com/presentation.html")};
+  std::vector<GURL> presentation_urls = {
+      GURL("http://www.example.com/presentation.html"),
+      GURL("http://www.example.net/alternate.html")};
 
   PresentationRequest request1(RenderFrameHostId(1, 2), presentation_urls,
                                frame_url);
@@ -23,7 +24,9 @@
   // Presentation URLs are different.
   PresentationRequest request3(
       RenderFrameHostId(1, 2),
-      {GURL("http://www.example.net/presentation.html")}, frame_url);
+      {GURL("http://www.example.net/presentation.html"),
+       GURL("http://www.example.com/presentation.html")},
+      frame_url);
   EXPECT_FALSE(request1.Equals(request3));
 
   // Frame URLs are different.
@@ -33,7 +36,8 @@
 
   PresentationRequest request5(
       RenderFrameHostId(1, 2),
-      {GURL("http://www.example.com/presentation.html")},
+      {GURL("http://www.example.com/presentation.html"),
+       GURL("http://www.example.net/alternate.html")},
       GURL("http://www.site.com/"));
   EXPECT_TRUE(request1.Equals(request5));
 }
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation_service_delegate_impl.cc
index d0d1a19..1556857 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl.cc
+++ b/chrome/browser/media/router/presentation_service_delegate_impl.cc
@@ -366,9 +366,9 @@
   // Sets or clears the default presentation request and callback for the given
   // frame. Also sets / clears the default presentation requests for the owning
   // tab WebContents.
-  void SetDefaultPresentationUrl(
+  void SetDefaultPresentationUrls(
       const RenderFrameHostId& render_frame_host_id,
-      const GURL& default_presentation_url,
+      const std::vector<GURL>& default_presentation_urls,
       const content::PresentationSessionStartedCallback& callback);
   void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id,
                            DelegateObserver* observer);
@@ -545,21 +545,20 @@
   it->second->ListenForSessionMessages(session, message_cb);
 }
 
-void PresentationFrameManager::SetDefaultPresentationUrl(
+void PresentationFrameManager::SetDefaultPresentationUrls(
     const RenderFrameHostId& render_frame_host_id,
-    const GURL& default_presentation_url,
+    const std::vector<GURL>& default_presentation_urls,
     const content::PresentationSessionStartedCallback& callback) {
   if (!IsMainFrame(render_frame_host_id))
     return;
 
-  if (default_presentation_url.is_empty()) {
+  if (default_presentation_urls.empty()) {
     ClearDefaultPresentationRequest();
   } else {
     DCHECK(!callback.is_null());
     GURL frame_url(
         GetLastCommittedURLForFrame(render_frame_host_id, web_contents_));
-    PresentationRequest request(render_frame_host_id,
-                                std::vector<GURL>({default_presentation_url}),
+    PresentationRequest request(render_frame_host_id, default_presentation_urls,
                                 frame_url);
     default_presentation_started_callback_ = callback;
     SetDefaultPresentationRequest(request);
@@ -726,14 +725,8 @@
     const std::vector<GURL>& default_presentation_urls,
     const content::PresentationSessionStartedCallback& callback) {
   RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
-  if (default_presentation_urls.empty()) {
-    frame_manager_->SetDefaultPresentationUrl(render_frame_host_id, GURL(),
-                                              callback);
-  } else {
-    // TODO(crbug.com/627655): Handle multiple URLs.
-    frame_manager_->SetDefaultPresentationUrl(
-        render_frame_host_id, default_presentation_urls[0], callback);
-  }
+  frame_manager_->SetDefaultPresentationUrls(
+      render_frame_host_id, default_presentation_urls, callback);
 }
 
 void PresentationServiceDelegateImpl::OnJoinRouteResponse(
@@ -790,19 +783,20 @@
     return;
   }
 
-  // TODO(crbug.com/627655): Handle multiple URLs.
-  const GURL& presentation_url = presentation_urls[0];
-  if (presentation_url.is_empty() ||
-      !IsValidPresentationUrl(presentation_url)) {
+  // TODO(crbug.com/670848): Improve handling of invalid URLs in
+  // PresentationService::start().
+  if (presentation_urls.empty() ||
+      std::find_if_not(presentation_urls.begin(), presentation_urls.end(),
+                       IsValidPresentationUrl) != presentation_urls.end()) {
     error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN,
-                                            "Invalid presentation arguments."));
+                                            "Invalid presentation URL."));
     return;
   }
 
   RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
   std::unique_ptr<CreatePresentationConnectionRequest> request(
       new CreatePresentationConnectionRequest(
-          render_frame_host_id, presentation_url,
+          render_frame_host_id, presentation_urls,
           GetLastCommittedURLForFrame(render_frame_host_id, web_contents_),
           base::Bind(&PresentationServiceDelegateImpl::OnStartSessionSucceeded,
                      weak_factory_.GetWeakPtr(), render_process_id,
@@ -825,10 +819,12 @@
     const std::string& presentation_id,
     const content::PresentationSessionStartedCallback& success_cb,
     const content::PresentationSessionErrorCallback& error_cb) {
+  DVLOG(2) << "PresentationServiceDelegateImpl::JoinSession";
   if (presentation_urls.empty()) {
     error_cb.Run(content::PresentationError(
         content::PRESENTATION_ERROR_NO_PRESENTATION_FOUND,
         "Invalid presentation arguments."));
+    return;
   }
 
   // TODO(crbug.com/627655): Handle multiple URLs.
@@ -928,11 +924,14 @@
 void PresentationServiceDelegateImpl::OnRouteResponse(
     const PresentationRequest& presentation_request,
     const RouteRequestResult& result) {
-  if (!result.route())
+  if (!result.route() ||
+      !base::ContainsValue(presentation_request.presentation_urls(),
+                           result.presentation_url())) {
     return;
+  }
 
-  content::PresentationSessionInfo session_info(
-      presentation_request.presentation_url(), result.presentation_id());
+  content::PresentationSessionInfo session_info(result.presentation_url(),
+                                                result.presentation_id());
   frame_manager_->OnDefaultPresentationSessionStarted(
       presentation_request, session_info, *result.route());
 }
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc b/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
index 55c550e..2de3a32f 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
+++ b/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
@@ -31,6 +31,8 @@
 
 const char kPresentationUrl1[] = "http://foo.fakeurl.com/";
 const char kPresentationUrl2[] = "http://bar.fakeurl.com/";
+const char kPresentationUrl3[] =
+    "https://google.com/cast#__castAppId__=233637DE";
 const char kFrameUrl[] = "http://anotherframeurl.fakeurl.com/";
 
 }  // namespace
@@ -284,7 +286,7 @@
   ASSERT_TRUE(delegate_impl_->HasDefaultPresentationRequest());
   PresentationRequest request1 =
       delegate_impl_->GetDefaultPresentationRequest();
-  EXPECT_EQ(presentation_url1_, request1.presentation_url());
+  EXPECT_EQ(presentation_url1_, request1.presentation_urls()[0]);
   EXPECT_EQ(RenderFrameHostId(render_process_id, routing_id),
             request1.render_frame_host_id());
   EXPECT_EQ(frame_url, request1.frame_url());
@@ -296,7 +298,7 @@
   ASSERT_TRUE(delegate_impl_->HasDefaultPresentationRequest());
   PresentationRequest request2 =
       delegate_impl_->GetDefaultPresentationRequest();
-  EXPECT_EQ(presentation_url2_, request2.presentation_url());
+  EXPECT_EQ(presentation_url2_, request2.presentation_urls()[0]);
   EXPECT_EQ(RenderFrameHostId(render_process_id, routing_id),
             request2.render_frame_host_id());
   EXPECT_EQ(frame_url, request2.frame_url());
@@ -385,6 +387,7 @@
       .WillOnce(SaveArg<4>(&route_response_callbacks));
 
   const std::string kPresentationId("pid");
+  presentation_urls_.push_back(GURL(kPresentationUrl3));
   MockCreatePresentationConnnectionCallbacks mock_create_connection_callbacks;
   delegate_impl_->JoinSession(
       render_process_id, routing_id, presentation_urls_, kPresentationId,
diff --git a/chrome/browser/media/router/route_request_result.cc b/chrome/browser/media/router/route_request_result.cc
index 62a257e..7f6f226 100644
--- a/chrome/browser/media/router/route_request_result.cc
+++ b/chrome/browser/media/router/route_request_result.cc
@@ -33,7 +33,10 @@
     : route_(std::move(route)),
       presentation_id_(presentation_id),
       error_(error),
-      result_code_(result_code) {}
+      result_code_(result_code) {
+  if (route_)
+    presentation_url_ = route_->media_source().url();
+}
 
 RouteRequestResult::~RouteRequestResult() = default;
 
diff --git a/chrome/browser/media/router/route_request_result.h b/chrome/browser/media/router/route_request_result.h
index 8b0deea..c953a72 100644
--- a/chrome/browser/media/router/route_request_result.h
+++ b/chrome/browser/media/router/route_request_result.h
@@ -9,6 +9,7 @@
 #include <string>
 
 #include "base/macros.h"
+#include "url/gurl.h"
 
 namespace media_router {
 
@@ -62,6 +63,7 @@
   // create a copy if they wish to use it after this object is destroyed.
   const MediaRoute* route() const { return route_.get(); }
   std::string presentation_id() const { return presentation_id_; }
+  GURL presentation_url() const { return presentation_url_; }
   std::string error() const { return error_; }
   ResultCode result_code() const { return result_code_; }
 
@@ -73,6 +75,7 @@
 
   std::unique_ptr<MediaRoute> route_;
   std::string presentation_id_;
+  GURL presentation_url_;
   std::string error_;
   ResultCode result_code_;