summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrobliao <robliao@chromium.org>2015-11-10 17:39:50 -0800
committerCommit bot <commit-bot@chromium.org>2015-11-11 01:40:38 +0000
commit8ed7e286df82468f631e3788155ff0a517f80af9 (patch)
tree16a58d13d009aff8775024bc4b69780360f336c8
parent7608e2ac26c40c2d299f9b1641a4578a45fde4c2 (diff)
downloadchromium_src-8ed7e286df82468f631e3788155ff0a517f80af9.zip
chromium_src-8ed7e286df82468f631e3788155ff0a517f80af9.tar.gz
chromium_src-8ed7e286df82468f631e3788155ff0a517f80af9.tar.bz2
Revert of [Presentation API / Media Router] Clean up default pres URL logic. (patchset #16 id:300001 of https://codereview.chromium.org/1406013003/ )
Reason for revert: Prime suspect in causing mojo_runner_unittests mojo_runner_unittests failures: BackgroundApplicationLoaderTest.Load NativeApplicationLoaderTest.DoesNotExist https://build.chromium.org/p/chromium.linux/builders/Android%20GN/builds/32013 Original issue's description: > [Presentation API / Media Router] Clean up default pres URL logic. > > 1. In presentation_service.mojom, there were 2 methods for default > presentation: ListenForDefaultSessionStart and SetDefaultPresentationURL. > There is no reason they should be called separately. Furthermore, > ListenForDefaultSessionStart is called after connecting to > PresentationService, which is not optimal. This CL removes the former > method. > > 2. Remove OnDefaultSessionStarted from PSD::Observer and replace it > with callbacks. The purpose of PSD::Observer is to notify > PresentationServiceImpl that PresentationServiceDelegate is being > destroyed and shouldn't include specific Pres API logic. > > 3. Fix default request matching logic in PSDImpl to account for all > of (frame, frame url, presentation url). Previously it was only > checking presentation url and always assumes it came from the > current main frame. This is a problem because the main frame of a > WebContents can change over time, i.e. main frame at time of setting > DPU and time of route response could be different). Now we create > a PresentationRequest object to hold all info needed to match default > request and pass it to MRUI, who then binds the request to the route > response callback in PSDImpl/PresentationFrameManager to perform the > matching. > > BUG=544259 > > Committed: https://crrev.com/6104fb062821e3e8584ed2e40cdb3f77502d88f0 > Cr-Commit-Position: refs/heads/master@{#358935} TBR=mfoltz@chromium.org,avayvod@chromium.org,mlamouri@chromium.org,imcheng@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=544259 Review URL: https://codereview.chromium.org/1436703002 Cr-Commit-Position: refs/heads/master@{#359007}
-rw-r--r--chrome/browser/media/android/router/media_router_dialog_controller_android.cc29
-rw-r--r--chrome/browser/media/router/create_presentation_session_request.cc (renamed from chrome/browser/media/router/create_presentation_connection_request.cc)21
-rw-r--r--chrome/browser/media/router/create_presentation_session_request.h (renamed from chrome/browser/media/router/create_presentation_connection_request.h)31
-rw-r--r--chrome/browser/media/router/create_presentation_session_request_unittest.cc (renamed from chrome/browser/media/router/create_presentation_connection_request_unittest.cc)53
-rw-r--r--chrome/browser/media/router/media_router.gypi7
-rw-r--r--chrome/browser/media/router/media_router_dialog_controller.cc12
-rw-r--r--chrome/browser/media/router/media_router_dialog_controller.h17
-rw-r--r--chrome/browser/media/router/presentation_request.cc31
-rw-r--r--chrome/browser/media/router/presentation_request.h49
-rw-r--r--chrome/browser/media/router/presentation_request_unittest.cc39
-rw-r--r--chrome/browser/media/router/presentation_service_delegate_impl.cc261
-rw-r--r--chrome/browser/media/router/presentation_service_delegate_impl.h146
-rw-r--r--chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc179
-rw-r--r--chrome/browser/media/router/render_frame_host_id.h16
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc8
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_ui.cc101
-rw-r--r--chrome/browser/ui/webui/media_router/media_router_ui.h39
-rw-r--r--chrome/chrome_tests_unit.gypi3
-rw-r--r--content/browser/presentation/presentation_service_impl.cc66
-rw-r--r--content/browser/presentation/presentation_service_impl.h34
-rw-r--r--content/browser/presentation/presentation_service_impl_unittest.cc138
-rw-r--r--content/common/presentation/presentation_service.mojom26
-rw-r--r--content/public/browser/presentation_service_delegate.h28
-rw-r--r--content/renderer/presentation/presentation_dispatcher.cc8
-rw-r--r--content/renderer/presentation/presentation_dispatcher.h4
25 files changed, 591 insertions, 755 deletions
diff --git a/chrome/browser/media/android/router/media_router_dialog_controller_android.cc b/chrome/browser/media/android/router/media_router_dialog_controller_android.cc
index df69aee..53ee2ea4 100644
--- a/chrome/browser/media/android/router/media_router_dialog_controller_android.cc
+++ b/chrome/browser/media/android/router/media_router_dialog_controller_android.cc
@@ -10,7 +10,6 @@
#include "chrome/browser/media/router/media_router.h"
#include "chrome/browser/media/router/media_router_factory.h"
#include "chrome/browser/media/router/media_source.h"
-#include "chrome/browser/media/router/presentation_request.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_delegate.h"
@@ -36,17 +35,16 @@ MediaRouterDialogControllerAndroid::GetOrCreateForWebContents(
void MediaRouterDialogControllerAndroid::OnSinkSelected(
JNIEnv* env, jobject obj, jstring jsink_id) {
- scoped_ptr<CreatePresentationConnectionRequest> create_connection_request =
- TakeCreateConnectionRequest();
- const PresentationRequest& presentation_request =
- create_connection_request->presentation_request();
- const MediaSource::Id source_id = presentation_request.GetMediaSource().id();
- const GURL origin = presentation_request.frame_url().GetOrigin();
+ scoped_ptr<CreatePresentationSessionRequest>
+ request(TakePresentationRequest());
+
+ const std::string& source_id = request->media_source().id();
+ const GURL& origin = request->frame_url().GetOrigin();
std::vector<MediaRouteResponseCallback> route_response_callbacks;
route_response_callbacks.push_back(
- base::Bind(&CreatePresentationConnectionRequest::HandleRouteResponse,
- base::Passed(&create_connection_request)));
+ base::Bind(&CreatePresentationSessionRequest::HandleRouteResponse,
+ base::Passed(&request)));
MediaRouter* router = MediaRouterFactory::GetApiForBrowserContext(
initiator()->GetBrowserContext());
@@ -78,8 +76,9 @@ void MediaRouterDialogControllerAndroid::OnDialogCancelled(
}
void MediaRouterDialogControllerAndroid::CancelPresentationRequest() {
- scoped_ptr<CreatePresentationConnectionRequest> request =
- TakeCreateConnectionRequest();
+ scoped_ptr<CreatePresentationSessionRequest> request(
+ TakePresentationRequest());
+
DCHECK(request);
request->InvokeErrorCallback(content::PresentationError(
@@ -110,10 +109,10 @@ MediaRouterDialogControllerAndroid::~MediaRouterDialogControllerAndroid() {
void MediaRouterDialogControllerAndroid::CreateMediaRouterDialog() {
JNIEnv* env = base::android::AttachCurrentThread();
- const MediaSource::Id source_id =
- create_connection_request()->presentation_request().GetMediaSource().id();
+ const MediaSource::Id& media_source_id =
+ presentation_request()->media_source().id();
ScopedJavaLocalRef<jstring> jsource_urn =
- base::android::ConvertUTF8ToJavaString(env, source_id);
+ base::android::ConvertUTF8ToJavaString(env, media_source_id);
// If it's a single route with the same source, show the controller dialog
// instead of the device picker.
@@ -121,7 +120,7 @@ void MediaRouterDialogControllerAndroid::CreateMediaRouterDialog() {
// PresentationServiceDelegateImpl: if the route exists for the same frame
// and tab, show the route controller dialog, if not, show the device picker.
if (single_existing_route_.get() &&
- single_existing_route_->media_source().id() == source_id) {
+ single_existing_route_->media_source().id() == media_source_id) {
ScopedJavaLocalRef<jstring> jmedia_route_id =
base::android::ConvertUTF8ToJavaString(
env, single_existing_route_->media_route_id());
diff --git a/chrome/browser/media/router/create_presentation_connection_request.cc b/chrome/browser/media/router/create_presentation_session_request.cc
index 984f676..b3b4bc8 100644
--- a/chrome/browser/media/router/create_presentation_connection_request.cc
+++ b/chrome/browser/media/router/create_presentation_session_request.cc
@@ -2,7 +2,7 @@
// 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/create_presentation_connection_request.h"
+#include "chrome/browser/media/router/create_presentation_session_request.h"
#include "chrome/browser/media/router/media_source_helper.h"
@@ -11,13 +11,13 @@ using content::PresentationError;
namespace media_router {
-CreatePresentationConnectionRequest::CreatePresentationConnectionRequest(
- const RenderFrameHostId& render_frame_host_id,
+CreatePresentationSessionRequest::CreatePresentationSessionRequest(
const std::string& presentation_url,
const GURL& frame_url,
const PresentationSessionSuccessCallback& success_cb,
const PresentationSessionErrorCallback& error_cb)
- : presentation_request_(render_frame_host_id, presentation_url, frame_url),
+ : media_source_(MediaSourceForPresentationUrl(presentation_url)),
+ frame_url_(frame_url),
success_cb_(success_cb),
error_cb_(error_cb),
cb_invoked_(false) {
@@ -25,27 +25,28 @@ CreatePresentationConnectionRequest::CreatePresentationConnectionRequest(
DCHECK(!error_cb.is_null());
}
-CreatePresentationConnectionRequest::~CreatePresentationConnectionRequest() {
+CreatePresentationSessionRequest::~CreatePresentationSessionRequest() {
if (!cb_invoked_) {
error_cb_.Run(content::PresentationError(
content::PRESENTATION_ERROR_UNKNOWN, "Unknown error."));
}
}
-void CreatePresentationConnectionRequest::InvokeSuccessCallback(
+void CreatePresentationSessionRequest::InvokeSuccessCallback(
const std::string& presentation_id,
const MediaRoute::Id& route_id) {
DCHECK(!cb_invoked_);
if (!cb_invoked_) {
+ // Overwrite presentation ID.
success_cb_.Run(
content::PresentationSessionInfo(
- presentation_request_.presentation_url(), presentation_id),
+ PresentationUrlFromMediaSource(media_source_), presentation_id),
route_id);
cb_invoked_ = true;
}
}
-void CreatePresentationConnectionRequest::InvokeErrorCallback(
+void CreatePresentationSessionRequest::InvokeErrorCallback(
const content::PresentationError& error) {
DCHECK(!cb_invoked_);
if (!cb_invoked_) {
@@ -55,8 +56,8 @@ void CreatePresentationConnectionRequest::InvokeErrorCallback(
}
// static
-void CreatePresentationConnectionRequest::HandleRouteResponse(
- scoped_ptr<CreatePresentationConnectionRequest> presentation_request,
+void CreatePresentationSessionRequest::HandleRouteResponse(
+ scoped_ptr<CreatePresentationSessionRequest> presentation_request,
const MediaRoute* route,
const std::string& presentation_id,
const std::string& error) {
diff --git a/chrome/browser/media/router/create_presentation_connection_request.h b/chrome/browser/media/router/create_presentation_session_request.h
index 024dd1b..9cebcb9 100644
--- a/chrome/browser/media/router/create_presentation_connection_request.h
+++ b/chrome/browser/media/router/create_presentation_session_request.h
@@ -2,16 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_CREATE_PRESENTATION_CONNECTION_REQUEST_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_CREATE_PRESENTATION_CONNECTION_REQUEST_H_
+#ifndef CHROME_BROWSER_MEDIA_ROUTER_CREATE_PRESENTATION_SESSION_REQUEST_H_
+#define CHROME_BROWSER_MEDIA_ROUTER_CREATE_PRESENTATION_SESSION_REQUEST_H_
#include <string>
-#include "base/macros.h"
#include "chrome/browser/media/router/media_route.h"
#include "chrome/browser/media/router/media_source.h"
-#include "chrome/browser/media/router/presentation_request.h"
-#include "chrome/browser/media/router/render_frame_host_id.h"
#include "content/public/browser/presentation_service_delegate.h"
#include "url/gurl.h"
@@ -28,29 +25,28 @@ namespace media_router {
// MediaRouterUI. |success_cb| will be invoked when create-session
// succeeds, or |error_cb| will be invoked when create-session fails or
// the UI closes.
-class CreatePresentationConnectionRequest {
+class CreatePresentationSessionRequest {
public:
using PresentationSessionSuccessCallback =
base::Callback<void(const content::PresentationSessionInfo&,
const MediaRoute::Id&)>;
using PresentationSessionErrorCallback =
- content::PresentationSessionErrorCallback;
+ content::PresentationServiceDelegate::PresentationSessionErrorCallback;
+
// |presentation_url|: The presentation URL of the request. Must be a valid
// URL.
// |frame_url|: The URL of the frame that initiated the presentation request.
// |success_cb|: Callback to invoke when the request succeeds. Must be valid.
// |erorr_cb|: Callback to invoke when the request fails. Must be valid.
- CreatePresentationConnectionRequest(
- const RenderFrameHostId& render_frame_host_id,
+ CreatePresentationSessionRequest(
const std::string& presentation_url,
const GURL& frame_url,
const PresentationSessionSuccessCallback& success_cb,
const PresentationSessionErrorCallback& error_cb);
- ~CreatePresentationConnectionRequest();
+ ~CreatePresentationSessionRequest();
- const PresentationRequest& presentation_request() const {
- return presentation_request_;
- }
+ const MediaSource& media_source() const { return media_source_; }
+ const GURL& frame_url() const { return frame_url_; }
// Invokes |success_cb_| or |error_cb_| with the given arguments.
// These functions can only be invoked once per instance. It is an error
@@ -61,20 +57,21 @@ class CreatePresentationConnectionRequest {
// Handle route creation/joining response by invoking the right callback.
static void HandleRouteResponse(
- scoped_ptr<CreatePresentationConnectionRequest> presentation_request,
+ scoped_ptr<CreatePresentationSessionRequest> presentation_request,
const MediaRoute* route,
const std::string& presentation_id,
const std::string& error);
private:
- const PresentationRequest presentation_request_;
+ const MediaSource media_source_;
+ const GURL frame_url_;
PresentationSessionSuccessCallback success_cb_;
PresentationSessionErrorCallback error_cb_;
bool cb_invoked_;
- DISALLOW_COPY_AND_ASSIGN(CreatePresentationConnectionRequest);
+ DISALLOW_COPY_AND_ASSIGN(CreatePresentationSessionRequest);
};
} // namespace media_router
-#endif // CHROME_BROWSER_MEDIA_ROUTER_CREATE_PRESENTATION_CONNECTION_REQUEST_H_
+#endif // CHROME_BROWSER_MEDIA_ROUTER_CREATE_PRESENTATION_SESSION_REQUEST_H_
diff --git a/chrome/browser/media/router/create_presentation_connection_request_unittest.cc b/chrome/browser/media/router/create_presentation_session_request_unittest.cc
index 7532529..98614c6 100644
--- a/chrome/browser/media/router/create_presentation_connection_request_unittest.cc
+++ b/chrome/browser/media/router/create_presentation_session_request_unittest.cc
@@ -3,7 +3,7 @@
// found in the LICENSE file.
#include "base/bind.h"
-#include "chrome/browser/media/router/create_presentation_connection_request.h"
+#include "chrome/browser/media/router/create_presentation_session_request.h"
#include "chrome/browser/media/router/media_source_helper.h"
#include "content/public/browser/presentation_service_delegate.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -13,18 +13,16 @@ namespace media_router {
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";
} // namespace
-class CreatePresentationConnectionRequestTest : public ::testing::Test {
+class CreatePresentationSessionRequestTest : public ::testing::Test {
public:
- CreatePresentationConnectionRequestTest()
- : cb_invoked_(false), render_frame_host_id_(1, 2) {}
- ~CreatePresentationConnectionRequestTest() override {}
+ CreatePresentationSessionRequestTest() : cb_invoked_(false) {}
+ ~CreatePresentationSessionRequestTest() override {}
void OnSuccess(const content::PresentationSessionInfo& expected_info,
const content::PresentationSessionInfo& actual_info,
@@ -51,49 +49,52 @@ class CreatePresentationConnectionRequestTest : public ::testing::Test {
}
bool cb_invoked_;
- const RenderFrameHostId render_frame_host_id_;
};
// Test that the object's getters match the constructor parameters.
-TEST_F(CreatePresentationConnectionRequestTest, Getters) {
+TEST_F(CreatePresentationSessionRequestTest, Getters) {
+ GURL frame_url("http://frameUrl");
content::PresentationError error(content::PRESENTATION_ERROR_UNKNOWN,
"Unknown error.");
- CreatePresentationConnectionRequest request(
- render_frame_host_id_, kPresentationUrl, GURL(kFrameUrl),
- base::Bind(&CreatePresentationConnectionRequestTest::FailOnSuccess,
+ CreatePresentationSessionRequest request(
+ kPresentationUrl, frame_url,
+ base::Bind(&CreatePresentationSessionRequestTest::FailOnSuccess,
base::Unretained(this)),
- base::Bind(&CreatePresentationConnectionRequestTest::OnError,
+ base::Bind(&CreatePresentationSessionRequestTest::OnError,
base::Unretained(this), error));
-
- PresentationRequest presentation_request(render_frame_host_id_,
- kPresentationUrl, GURL(kFrameUrl));
- EXPECT_TRUE(request.presentation_request().Equals(presentation_request));
+ EXPECT_EQ(frame_url, request.frame_url());
+ EXPECT_EQ(kPresentationUrl,
+ PresentationUrlFromMediaSource(request.media_source()));
// Since we didn't explicitly call Invoke*, the error callback will be
// invoked when |request| is destroyed.
}
-TEST_F(CreatePresentationConnectionRequestTest, SuccessCallback) {
+TEST_F(CreatePresentationSessionRequestTest, SuccessCallback) {
+ GURL frame_url("http://frameUrl");
content::PresentationSessionInfo session_info(kPresentationUrl,
kPresentationId);
- CreatePresentationConnectionRequest request(
- render_frame_host_id_, kPresentationUrl, GURL(kFrameUrl),
- base::Bind(&CreatePresentationConnectionRequestTest::OnSuccess,
+ CreatePresentationSessionRequest request(
+ kPresentationUrl, frame_url,
+ base::Bind(&CreatePresentationSessionRequestTest::OnSuccess,
base::Unretained(this), session_info),
- base::Bind(&CreatePresentationConnectionRequestTest::FailOnError,
+ base::Bind(&CreatePresentationSessionRequestTest::FailOnError,
base::Unretained(this)));
request.InvokeSuccessCallback(kPresentationId, kRouteId);
EXPECT_TRUE(cb_invoked_);
}
-TEST_F(CreatePresentationConnectionRequestTest, ErrorCallback) {
+TEST_F(CreatePresentationSessionRequestTest, ErrorCallback) {
+ GURL frame_url("http://frameUrl");
+ content::PresentationSessionInfo session_info(kPresentationUrl,
+ kPresentationId);
content::PresentationError error(
content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED,
"This is an error message");
- CreatePresentationConnectionRequest request(
- render_frame_host_id_, kPresentationUrl, GURL(kFrameUrl),
- base::Bind(&CreatePresentationConnectionRequestTest::FailOnSuccess,
+ CreatePresentationSessionRequest request(
+ kPresentationUrl, frame_url,
+ base::Bind(&CreatePresentationSessionRequestTest::FailOnSuccess,
base::Unretained(this)),
- base::Bind(&CreatePresentationConnectionRequestTest::OnError,
+ base::Bind(&CreatePresentationSessionRequestTest::OnError,
base::Unretained(this), error));
request.InvokeErrorCallback(error);
EXPECT_TRUE(cb_invoked_);
diff --git a/chrome/browser/media/router/media_router.gypi b/chrome/browser/media/router/media_router.gypi
index 5e27de5..32089b1 100644
--- a/chrome/browser/media/router/media_router.gypi
+++ b/chrome/browser/media/router/media_router.gypi
@@ -6,8 +6,8 @@
'variables': {
# File lists shared with GN build.
'media_router_sources': [
- 'create_presentation_connection_request.cc',
- 'create_presentation_connection_request.h',
+ 'create_presentation_session_request.cc',
+ 'create_presentation_session_request.h',
'issue.cc',
'issue.h',
'issue_manager.cc',
@@ -39,15 +39,12 @@
'presentation_connection_state_observer.h',
'presentation_media_sinks_observer.cc',
'presentation_media_sinks_observer.h',
- 'presentation_request.cc',
- 'presentation_request.h',
'presentation_service_delegate_impl.cc',
'presentation_service_delegate_impl.h',
'presentation_session_messages_observer.cc',
'presentation_session_messages_observer.h',
'presentation_session_state_observer.cc',
'presentation_session_state_observer.h',
- 'render_frame_host_id.h',
],
# Files that are only needed on desktop builds
'media_router_non_android_sources': [
diff --git a/chrome/browser/media/router/media_router_dialog_controller.cc b/chrome/browser/media/router/media_router_dialog_controller.cc
index 2f0583d..f363730 100644
--- a/chrome/browser/media/router/media_router_dialog_controller.cc
+++ b/chrome/browser/media/router/media_router_dialog_controller.cc
@@ -73,14 +73,14 @@ MediaRouterDialogController::~MediaRouterDialogController() {
}
bool MediaRouterDialogController::ShowMediaRouterDialogForPresentation(
- scoped_ptr<CreatePresentationConnectionRequest> request) {
+ scoped_ptr<CreatePresentationSessionRequest> request) {
DCHECK(thread_checker_.CalledOnValidThread());
// Check if the media router dialog exists for |initiator| and return if so.
if (IsShowingMediaRouterDialog())
return false;
- create_connection_request_ = request.Pass();
+ presentation_request_ = request.Pass();
CreateMediaRouterDialog();
// Show the initiator holding the existing media router dialog.
@@ -114,14 +114,14 @@ void MediaRouterDialogController::ActivateInitiatorWebContents() {
initiator_->GetDelegate()->ActivateContents(initiator_);
}
-scoped_ptr<CreatePresentationConnectionRequest>
-MediaRouterDialogController::TakeCreateConnectionRequest() {
- return create_connection_request_.Pass();
+scoped_ptr<CreatePresentationSessionRequest>
+MediaRouterDialogController::TakePresentationRequest() {
+ return presentation_request_.Pass();
}
void MediaRouterDialogController::Reset() {
initiator_observer_.reset();
- create_connection_request_.reset();
+ presentation_request_.reset();
}
} // namespace media_router
diff --git a/chrome/browser/media/router/media_router_dialog_controller.h b/chrome/browser/media/router/media_router_dialog_controller.h
index 4c6b26c..40dce80 100644
--- a/chrome/browser/media/router/media_router_dialog_controller.h
+++ b/chrome/browser/media/router/media_router_dialog_controller.h
@@ -10,7 +10,7 @@
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/threading/thread_checker.h"
-#include "chrome/browser/media/router/create_presentation_connection_request.h"
+#include "chrome/browser/media/router/create_presentation_session_request.h"
#include "content/public/browser/web_contents_observer.h"
namespace content {
@@ -40,7 +40,7 @@ class MediaRouterDialogController {
// If the dialog already exists, brings it to the front but doesn't change the
// dialog with |request|, returns false and |request| is deleted.
bool ShowMediaRouterDialogForPresentation(
- scoped_ptr<CreatePresentationConnectionRequest> request);
+ scoped_ptr<CreatePresentationSessionRequest> request);
// Shows the media router dialog modal to |initiator_|.
// Creates the dialog if it did not exist prior to this call, returns true.
@@ -62,14 +62,13 @@ class MediaRouterDialogController {
// Activates the WebContents that initiated the dialog, e.g. focuses the tab.
void ActivateInitiatorWebContents();
- // Passes the ownership of the CreatePresentationConnectionRequest to the
- // caller.
- scoped_ptr<CreatePresentationConnectionRequest> TakeCreateConnectionRequest();
+ // Passes the ownership of the CreatePresentationSessionRequest to the caller.
+ scoped_ptr<CreatePresentationSessionRequest> TakePresentationRequest();
- // Returns the CreatePresentationConnectionRequest to the caller but keeps the
+ // Returns the CreatePresentationSessionRequest to the caller but keeps the
// ownership with the MediaRouterDialogController.
- const CreatePresentationConnectionRequest* create_connection_request() const {
- return create_connection_request_.get();
+ const CreatePresentationSessionRequest* presentation_request() const {
+ return presentation_request_.get();
}
// Returns the WebContents that initiated showing the dialog.
@@ -95,7 +94,7 @@ class MediaRouterDialogController {
// Data for dialogs created at the request of the Presentation API.
// Passed from the caller via ShowMediaRouterDialogForPresentation to the
// dialog when it is initialized.
- scoped_ptr<CreatePresentationConnectionRequest> create_connection_request_;
+ scoped_ptr<CreatePresentationSessionRequest> presentation_request_;
DISALLOW_COPY_AND_ASSIGN(MediaRouterDialogController);
};
diff --git a/chrome/browser/media/router/presentation_request.cc b/chrome/browser/media/router/presentation_request.cc
deleted file mode 100644
index 1c6df55..0000000
--- a/chrome/browser/media/router/presentation_request.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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/presentation_request.h"
-
-#include "chrome/browser/media/router/media_source_helper.h"
-
-namespace media_router {
-
-PresentationRequest::PresentationRequest(
- const RenderFrameHostId& render_frame_host_id,
- const std::string& presentation_url,
- const GURL& frame_url)
- : render_frame_host_id_(render_frame_host_id),
- presentation_url_(presentation_url),
- frame_url_(frame_url) {}
-
-PresentationRequest::~PresentationRequest() = default;
-
-bool PresentationRequest::Equals(const PresentationRequest& other) const {
- return render_frame_host_id_ == other.render_frame_host_id_ &&
- presentation_url_ == other.presentation_url_ &&
- frame_url_ == other.frame_url_;
-}
-
-MediaSource PresentationRequest::GetMediaSource() const {
- return MediaSourceForPresentationUrl(presentation_url_);
-}
-
-} // namespace media_router
diff --git a/chrome/browser/media/router/presentation_request.h b/chrome/browser/media/router/presentation_request.h
deleted file mode 100644
index a37189f..0000000
--- a/chrome/browser/media/router/presentation_request.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_REQUEST_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_REQUEST_H_
-
-#include <string>
-
-#include "chrome/browser/media/router/media_source.h"
-#include "chrome/browser/media/router/render_frame_host_id.h"
-#include "url/gurl.h"
-
-namespace media_router {
-
-// Represents a presentation request made from a render frame. Contains the
-// presentation URL of the request, and information on the originating frame.
-class PresentationRequest {
- public:
- PresentationRequest(const RenderFrameHostId& render_frame_host_id,
- const std::string& presentation_url,
- const GURL& frame_url);
- ~PresentationRequest();
-
- bool Equals(const PresentationRequest& other) const;
-
- // Helper method to get the MediaSource for |presentation_url_|.
- MediaSource GetMediaSource() const;
-
- const RenderFrameHostId& render_frame_host_id() const {
- return render_frame_host_id_;
- }
- const std::string& presentation_url() const { return presentation_url_; }
- const GURL& frame_url() const { return frame_url_; }
-
- private:
- // ID of RenderFrameHost that initiated the request.
- const RenderFrameHostId render_frame_host_id_;
-
- // URL of presentation.
- const std::string presentation_url_;
-
- // URL of frame from which the request was initiated.
- const GURL frame_url_;
-};
-
-} // namespace media_router
-
-#endif // CHROME_BROWSER_MEDIA_ROUTER_PRESENTATION_REQUEST_H_
diff --git a/chrome/browser/media/router/presentation_request_unittest.cc b/chrome/browser/media/router/presentation_request_unittest.cc
deleted file mode 100644
index 7d21a5e..0000000
--- a/chrome/browser/media/router/presentation_request_unittest.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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/presentation_request.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace media_router {
-
-TEST(PresentationRequestTest, Equals) {
- PresentationRequest request1(RenderFrameHostId(1, 2),
- "http://presentationUrl",
- GURL("http://frameUrl"));
-
- // Frame IDs are different.
- PresentationRequest request2(RenderFrameHostId(3, 4),
- "http://presentationUrl",
- GURL("http://frameUrl"));
- EXPECT_FALSE(request1.Equals(request2));
-
- // Presentation URLs are different.
- PresentationRequest request3(RenderFrameHostId(1, 2),
- "http://anotherPresentationUrl",
- GURL("http://frameUrl"));
- EXPECT_FALSE(request1.Equals(request3));
-
- // Frame URLs are different.
- PresentationRequest request4(RenderFrameHostId(1, 2),
- "http://presentationUrl",
- GURL("http://anotherFrameUrl"));
- EXPECT_FALSE(request1.Equals(request4));
-
- PresentationRequest request5(RenderFrameHostId(1, 2),
- "http://presentationUrl",
- GURL("http://frameUrl"));
- EXPECT_TRUE(request1.Equals(request5));
-}
-
-} // namespace media_router
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.cc b/chrome/browser/media/router/presentation_service_delegate_impl.cc
index d2228e5..e45b394 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl.cc
+++ b/chrome/browser/media/router/presentation_service_delegate_impl.cc
@@ -11,7 +11,7 @@
#include "base/guid.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
-#include "chrome/browser/media/router/create_presentation_connection_request.h"
+#include "chrome/browser/media/router/create_presentation_session_request.h"
#include "chrome/browser/media/router/media_route.h"
#include "chrome/browser/media/router/media_router.h"
#include "chrome/browser/media/router/media_router_dialog_controller.h"
@@ -37,6 +37,10 @@ namespace media_router {
namespace {
using DelegateObserver = content::PresentationServiceDelegate::Observer;
+using PresentationSessionErrorCallback =
+ content::PresentationServiceDelegate::PresentationSessionErrorCallback;
+using PresentationSessionSuccessCallback =
+ content::PresentationServiceDelegate::PresentationSessionSuccessCallback;
// Returns the unique identifier for the supplied RenderFrameHost.
RenderFrameHostId GetRenderFrameHostId(RenderFrameHost* render_frame_host) {
@@ -80,7 +84,6 @@ class PresentationFrame {
void ListenForSessionMessages(
const content::PresentationSessionInfo& session,
const content::PresentationSessionMessageCallback& message_cb);
-
void Reset();
const MediaRoute::Id GetRouteId(const std::string& presentation_id) const;
@@ -88,6 +91,7 @@ class PresentationFrame {
void OnPresentationSessionClosed(const std::string& presentation_id);
void OnPresentationSessionStarted(
+ bool is_default_presentation,
const content::PresentationSessionInfo& session,
const MediaRoute::Id& route_id);
void OnPresentationServiceDelegateDestroyed() const;
@@ -131,12 +135,15 @@ void PresentationFrame::OnPresentationServiceDelegateDestroyed() const {
}
void PresentationFrame::OnPresentationSessionStarted(
+ bool is_default_presentation,
const content::PresentationSessionInfo& session,
const MediaRoute::Id& route_id) {
presentation_id_to_route_id_[session.presentation_id] = route_id;
route_id_to_presentation_.Add(route_id, session);
if (session_state_observer_)
session_state_observer_->OnPresentationSessionConnected(route_id);
+ if (is_default_presentation && delegate_observer_)
+ delegate_observer_->OnDefaultPresentationStarted(session);
}
void PresentationFrame::OnPresentationSessionClosed(
@@ -204,7 +211,6 @@ void PresentationFrame::Reset() {
sinks_observer_.reset();
if (session_state_observer_)
session_state_observer_->Reset();
-
session_messages_observers_.clear();
}
@@ -259,23 +265,9 @@ class PresentationFrameManager {
const RenderFrameHostId& render_frame_host_id,
const content::PresentationSessionInfo& session,
const content::PresentationSessionMessageCallback& message_cb);
-
- // 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(
- const RenderFrameHostId& render_frame_host_id,
- const std::string& default_presentation_url,
- const content::PresentationSessionStartedCallback& callback);
void AddDelegateObserver(const RenderFrameHostId& render_frame_host_id,
DelegateObserver* observer);
void RemoveDelegateObserver(const RenderFrameHostId& render_frame_host_id);
- void AddDefaultPresentationRequestObserver(
- PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
- observer);
- void RemoveDefaultPresentationRequestObserver(
- PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
- observer);
void Reset(const RenderFrameHostId& render_frame_host_id);
bool HasScreenAvailabilityListenerForTest(
const RenderFrameHostId& render_frame_host_id,
@@ -284,10 +276,7 @@ class PresentationFrameManager {
void OnPresentationSessionStarted(
const RenderFrameHostId& render_frame_host_id,
- const content::PresentationSessionInfo& session,
- const MediaRoute::Id& route_id);
- void OnDefaultPresentationSessionStarted(
- const PresentationRequest& request,
+ bool is_default_presentation,
const content::PresentationSessionInfo& session,
const MediaRoute::Id& route_id);
@@ -299,44 +288,15 @@ class PresentationFrameManager {
const std::vector<MediaRoute::Id> GetRouteIds(
const RenderFrameHostId& render_frame_host_id) const;
- const PresentationRequest* default_presentation_request() const {
- return default_presentation_request_.get();
- }
-
private:
PresentationFrame* GetOrAddPresentationFrame(
const RenderFrameHostId& render_frame_host_id);
- // Sets the default presentation request for the owning WebContents and
- // notifies observers of changes.
- void SetDefaultPresentationRequest(
- const PresentationRequest& default_presentation_request);
-
- // Clears the default presentation request for the owning WebContents and
- // notifies observers of changes. Also resets
- // |default_presentation_started_callback_|.
- void ClearDefaultPresentationRequest();
-
- bool IsMainFrame(const RenderFrameHostId& render_frame_host_id) const;
-
// Maps a frame identifier to a PresentationFrame object for frames
// that are using presentation API.
base::ScopedPtrHashMap<RenderFrameHostId, scoped_ptr<PresentationFrame>>
presentation_frames_;
- // Default presentation request for the owning tab WebContents.
- scoped_ptr<PresentationRequest> default_presentation_request_;
-
- // Callback to invoke when default presentation has started.
- content::PresentationSessionStartedCallback
- default_presentation_started_callback_;
-
- // References to the observers listening for changes to this tab WebContent's
- // default presentation.
- base::ObserverList<
- PresentationServiceDelegateImpl::DefaultPresentationRequestObserver>
- default_presentation_request_observers_;
-
// References to the owning WebContents, and the corresponding MediaRouter.
MediaRouter* router_;
content::WebContents* web_contents_;
@@ -357,26 +317,13 @@ PresentationFrameManager::~PresentationFrameManager() {
void PresentationFrameManager::OnPresentationSessionStarted(
const RenderFrameHostId& render_frame_host_id,
+ bool is_default_presentation,
const content::PresentationSessionInfo& session,
const MediaRoute::Id& route_id) {
auto presentation_frame = presentation_frames_.get(render_frame_host_id);
if (presentation_frame)
- presentation_frame->OnPresentationSessionStarted(session, route_id);
-}
-
-void PresentationFrameManager::OnDefaultPresentationSessionStarted(
- const PresentationRequest& request,
- const content::PresentationSessionInfo& session,
- const MediaRoute::Id& route_id) {
- auto presentation_frame =
- presentation_frames_.get(request.render_frame_host_id());
- if (presentation_frame)
- presentation_frame->OnPresentationSessionStarted(session, route_id);
-
- if (default_presentation_request_ &&
- default_presentation_request_->Equals(request)) {
- default_presentation_started_callback_.Run(session);
- }
+ presentation_frame->OnPresentationSessionStarted(is_default_presentation,
+ session, route_id);
}
void PresentationFrameManager::OnPresentationSessionClosed(
@@ -450,25 +397,6 @@ void PresentationFrameManager::ListenForSessionMessages(
presentation_frame->ListenForSessionMessages(session, message_cb);
}
-void PresentationFrameManager::SetDefaultPresentationUrl(
- const RenderFrameHostId& render_frame_host_id,
- const std::string& default_presentation_url,
- const content::PresentationSessionStartedCallback& callback) {
- if (!IsMainFrame(render_frame_host_id))
- return;
-
- if (default_presentation_url.empty()) {
- ClearDefaultPresentationRequest();
- } else {
- DCHECK(!callback.is_null());
- GURL frame_url(GetLastCommittedURLForFrame(render_frame_host_id));
- PresentationRequest request(render_frame_host_id, default_presentation_url,
- frame_url);
- default_presentation_started_callback_ = callback;
- SetDefaultPresentationRequest(request);
- }
-}
-
void PresentationFrameManager::AddDelegateObserver(
const RenderFrameHostId& render_frame_host_id,
DelegateObserver* observer) {
@@ -485,29 +413,11 @@ void PresentationFrameManager::RemoveDelegateObserver(
}
}
-void PresentationFrameManager::AddDefaultPresentationRequestObserver(
- PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
- observer) {
- default_presentation_request_observers_.AddObserver(observer);
-}
-
-void PresentationFrameManager::RemoveDefaultPresentationRequestObserver(
- PresentationServiceDelegateImpl::DefaultPresentationRequestObserver*
- observer) {
- default_presentation_request_observers_.RemoveObserver(observer);
-}
-
void PresentationFrameManager::Reset(
const RenderFrameHostId& render_frame_host_id) {
auto presentation_frame = presentation_frames_.get(render_frame_host_id);
if (presentation_frame)
presentation_frame->Reset();
-
- if (default_presentation_request_ &&
- render_frame_host_id ==
- default_presentation_request_->render_frame_host_id()) {
- ClearDefaultPresentationRequest();
- }
}
PresentationFrame* PresentationFrameManager::GetOrAddPresentationFrame(
@@ -521,37 +431,6 @@ PresentationFrame* PresentationFrameManager::GetOrAddPresentationFrame(
return presentation_frames_.get(render_frame_host_id);
}
-void PresentationFrameManager::ClearDefaultPresentationRequest() {
- default_presentation_started_callback_.Reset();
- if (!default_presentation_request_)
- return;
-
- default_presentation_request_.reset();
- FOR_EACH_OBSERVER(
- PresentationServiceDelegateImpl::DefaultPresentationRequestObserver,
- default_presentation_request_observers_, OnDefaultPresentationRemoved());
-}
-
-bool PresentationFrameManager::IsMainFrame(
- const RenderFrameHostId& render_frame_host_id) const {
- RenderFrameHost* main_frame = web_contents_->GetMainFrame();
- return main_frame && GetRenderFrameHostId(main_frame) == render_frame_host_id;
-}
-
-void PresentationFrameManager::SetDefaultPresentationRequest(
- const PresentationRequest& default_presentation_request) {
- if (default_presentation_request_ &&
- default_presentation_request_->Equals(default_presentation_request))
- return;
-
- default_presentation_request_.reset(
- new PresentationRequest(default_presentation_request));
- FOR_EACH_OBSERVER(
- PresentationServiceDelegateImpl::DefaultPresentationRequestObserver,
- default_presentation_request_observers_,
- OnDefaultPresentationChanged(*default_presentation_request_));
-}
-
void PresentationFrameManager::SetMediaRouterForTest(MediaRouter* router) {
router_ = router;
}
@@ -615,24 +494,60 @@ void PresentationServiceDelegateImpl::Reset(int render_process_id,
int render_frame_id) {
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
frame_manager_->Reset(render_frame_host_id);
+ if (render_frame_host_id == default_presentation_render_frame_host_id_) {
+ UpdateDefaultMediaSourceAndNotifyObservers(RenderFrameHostId(),
+ MediaSource(), GURL());
+ }
}
void PresentationServiceDelegateImpl::SetDefaultPresentationUrl(
int render_process_id,
int render_frame_id,
- const std::string& default_presentation_url,
- const content::PresentationSessionStartedCallback& callback) {
+ const std::string& default_presentation_url) {
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
- frame_manager_->SetDefaultPresentationUrl(render_frame_host_id,
- default_presentation_url, callback);
+ if (IsMainFrame(render_process_id, render_frame_id)) {
+ // This is the main frame, which means tab-level default presentation
+ // might have been updated.
+ MediaSource default_source;
+ if (!default_presentation_url.empty())
+ default_source = MediaSourceForPresentationUrl(default_presentation_url);
+
+ GURL default_frame_url = GetLastCommittedURLForFrame(render_frame_host_id);
+ UpdateDefaultMediaSourceAndNotifyObservers(
+ render_frame_host_id, default_source, default_frame_url);
+ }
+}
+
+bool PresentationServiceDelegateImpl::IsMainFrame(int render_process_id,
+ int render_frame_id) const {
+ RenderFrameHost* main_frame = web_contents_->GetMainFrame();
+ return main_frame &&
+ GetRenderFrameHostId(main_frame) ==
+ RenderFrameHostId(render_process_id, render_frame_id);
+}
+
+void PresentationServiceDelegateImpl::
+ UpdateDefaultMediaSourceAndNotifyObservers(
+ const RenderFrameHostId& render_frame_host_id,
+ const MediaSource& new_default_source,
+ const GURL& new_default_frame_url) {
+ default_presentation_render_frame_host_id_ = render_frame_host_id;
+ if (!new_default_source.Equals(default_source_) ||
+ new_default_frame_url != default_frame_url_) {
+ default_source_ = new_default_source;
+ default_frame_url_ = new_default_frame_url;
+ FOR_EACH_OBSERVER(
+ DefaultMediaSourceObserver, default_media_source_observers_,
+ OnDefaultMediaSourceChanged(default_source_, default_frame_url_));
+ }
}
void PresentationServiceDelegateImpl::OnJoinRouteResponse(
int render_process_id,
int render_frame_id,
const content::PresentationSessionInfo& session,
- const content::PresentationSessionStartedCallback& success_cb,
- const content::PresentationSessionErrorCallback& error_cb,
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb,
const MediaRoute* route,
const std::string& presentation_id,
const std::string& error_text) {
@@ -646,7 +561,7 @@ void PresentationServiceDelegateImpl::OnJoinRouteResponse(
<< ", presentation ID: " << session.presentation_id;
DCHECK_EQ(session.presentation_id, presentation_id);
frame_manager_->OnPresentationSessionStarted(
- RenderFrameHostId(render_process_id, render_frame_id), session,
+ RenderFrameHostId(render_process_id, render_frame_id), false, session,
route->media_route_id());
success_cb.Run(session);
}
@@ -655,7 +570,7 @@ void PresentationServiceDelegateImpl::OnJoinRouteResponse(
void PresentationServiceDelegateImpl::OnStartSessionSucceeded(
int render_process_id,
int render_frame_id,
- const content::PresentationSessionStartedCallback& success_cb,
+ const PresentationSessionSuccessCallback& success_cb,
const content::PresentationSessionInfo& new_session,
const MediaRoute::Id& route_id) {
DVLOG(1) << "OnStartSessionSucceeded: "
@@ -663,7 +578,7 @@ void PresentationServiceDelegateImpl::OnStartSessionSucceeded(
<< ", presentation URL: " << new_session.presentation_url
<< ", presentation ID: " << new_session.presentation_id;
frame_manager_->OnPresentationSessionStarted(
- RenderFrameHostId(render_process_id, render_frame_id), new_session,
+ RenderFrameHostId(render_process_id, render_frame_id), false, new_session,
route_id);
success_cb.Run(new_session);
}
@@ -672,26 +587,25 @@ void PresentationServiceDelegateImpl::StartSession(
int render_process_id,
int render_frame_id,
const std::string& presentation_url,
- const content::PresentationSessionStartedCallback& success_cb,
- const content::PresentationSessionErrorCallback& error_cb) {
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb) {
if (presentation_url.empty() || !IsValidPresentationUrl(presentation_url)) {
error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN,
"Invalid presentation arguments."));
return;
}
-
RenderFrameHostId render_frame_host_id(render_process_id, render_frame_id);
- scoped_ptr<CreatePresentationConnectionRequest> request(
- new CreatePresentationConnectionRequest(
- render_frame_host_id, presentation_url,
- GetLastCommittedURLForFrame(render_frame_host_id),
+
+ scoped_ptr<CreatePresentationSessionRequest> context(
+ new CreatePresentationSessionRequest(
+ presentation_url, GetLastCommittedURLForFrame(render_frame_host_id),
base::Bind(&PresentationServiceDelegateImpl::OnStartSessionSucceeded,
weak_factory_.GetWeakPtr(), render_process_id,
render_frame_id, success_cb),
error_cb));
MediaRouterDialogController* controller =
MediaRouterDialogController::GetOrCreateForWebContents(web_contents_);
- if (!controller->ShowMediaRouterDialogForPresentation(request.Pass())) {
+ if (!controller->ShowMediaRouterDialogForPresentation(context.Pass())) {
LOG(ERROR) << "Media router dialog already exists. Ignoring StartSession.";
error_cb.Run(content::PresentationError(content::PRESENTATION_ERROR_UNKNOWN,
"Unable to create dialog."));
@@ -704,8 +618,8 @@ void PresentationServiceDelegateImpl::JoinSession(
int render_frame_id,
const std::string& presentation_url,
const std::string& presentation_id,
- const content::PresentationSessionStartedCallback& success_cb,
- const content::PresentationSessionErrorCallback& error_cb) {
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb) {
std::vector<MediaRouteResponseCallback> route_response_callbacks;
route_response_callbacks.push_back(base::Bind(
&PresentationServiceDelegateImpl::OnJoinRouteResponse,
@@ -775,37 +689,34 @@ void PresentationServiceDelegateImpl::ListenForSessionStateChange(
}
void PresentationServiceDelegateImpl::OnRouteResponse(
- const PresentationRequest& presentation_request,
const MediaRoute* route,
const std::string& presentation_id,
const std::string& error) {
if (!route)
return;
-
- content::PresentationSessionInfo session_info(
- presentation_request.presentation_url(), presentation_id);
- frame_manager_->OnDefaultPresentationSessionStarted(
- presentation_request, session_info, route->media_route_id());
-}
-
-void PresentationServiceDelegateImpl::AddDefaultPresentationRequestObserver(
- DefaultPresentationRequestObserver* observer) {
- frame_manager_->AddDefaultPresentationRequestObserver(observer);
-}
-
-void PresentationServiceDelegateImpl::RemoveDefaultPresentationRequestObserver(
- DefaultPresentationRequestObserver* observer) {
- frame_manager_->RemoveDefaultPresentationRequestObserver(observer);
+ const MediaSource& source = route->media_source();
+ DCHECK(!source.Empty());
+ if (!default_source_.Equals(source))
+ return;
+ RenderFrameHost* main_frame = web_contents_->GetMainFrame();
+ if (!main_frame)
+ return;
+ RenderFrameHostId render_frame_host_id(GetRenderFrameHostId(main_frame));
+ frame_manager_->OnPresentationSessionStarted(
+ render_frame_host_id, true,
+ content::PresentationSessionInfo(PresentationUrlFromMediaSource(source),
+ presentation_id),
+ route->media_route_id());
}
-PresentationRequest
-PresentationServiceDelegateImpl::GetDefaultPresentationRequest() const {
- DCHECK(HasDefaultPresentationRequest());
- return *frame_manager_->default_presentation_request();
+void PresentationServiceDelegateImpl::AddDefaultMediaSourceObserver(
+ DefaultMediaSourceObserver* observer) {
+ default_media_source_observers_.AddObserver(observer);
}
-bool PresentationServiceDelegateImpl::HasDefaultPresentationRequest() const {
- return frame_manager_->default_presentation_request() != nullptr;
+void PresentationServiceDelegateImpl::RemoveDefaultMediaSourceObserver(
+ DefaultMediaSourceObserver* observer) {
+ default_media_source_observers_.RemoveObserver(observer);
}
base::WeakPtr<PresentationServiceDelegateImpl>
diff --git a/chrome/browser/media/router/presentation_service_delegate_impl.h b/chrome/browser/media/router/presentation_service_delegate_impl.h
index 0e6b633..03ad8c7 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl.h
+++ b/chrome/browser/media/router/presentation_service_delegate_impl.h
@@ -16,8 +16,6 @@
#include "base/observer_list.h"
#include "chrome/browser/media/router/media_router.h"
#include "chrome/browser/media/router/media_source.h"
-#include "chrome/browser/media/router/presentation_request.h"
-#include "chrome/browser/media/router/render_frame_host_id.h"
#include "content/public/browser/presentation_service_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
@@ -37,6 +35,8 @@ class MediaSinksObserver;
class PresentationFrameManager;
class PresentationSessionStateObserver;
+using RenderFrameHostId = std::pair<int, int>;
+
// Implementation of PresentationServiceDelegate that interfaces an
// instance of WebContents with the Chrome Media Router. It uses the Media
// Router to handle presentation API calls forwarded from
@@ -49,23 +49,6 @@ class PresentationServiceDelegateImpl
: public content::WebContentsUserData<PresentationServiceDelegateImpl>,
public content::PresentationServiceDelegate {
public:
- // Observer interface for listening to default presentation request
- // changes for the WebContents.
- class DefaultPresentationRequestObserver {
- public:
- virtual ~DefaultPresentationRequestObserver() = default;
-
- // Called when default presentation request for the corresponding
- // WebContents is set or changed.
- // |default_presentation_info|: New default presentation request.
- virtual void OnDefaultPresentationChanged(
- const PresentationRequest& default_presentation_request) = 0;
-
- // Called when default presentation request for the corresponding
- // WebContents has been removed.
- virtual void OnDefaultPresentationRemoved() = 0;
- };
-
// Retrieves the instance of PresentationServiceDelegateImpl that was attached
// to the specified WebContents. If no instance was attached, creates one,
// and attaches it to the specified WebContents.
@@ -92,21 +75,18 @@ class PresentationServiceDelegateImpl
void SetDefaultPresentationUrl(
int render_process_id,
int render_frame_id,
- const std::string& default_presentation_url,
- const content::PresentationSessionStartedCallback& callback) override;
- void StartSession(
- int render_process_id,
- int render_frame_id,
- const std::string& presentation_url,
- const content::PresentationSessionStartedCallback& success_cb,
- const content::PresentationSessionErrorCallback& error_cb) override;
- void JoinSession(
- int render_process_id,
- int render_frame_id,
- const std::string& presentation_url,
- const std::string& presentation_id,
- const content::PresentationSessionStartedCallback& success_cb,
- const content::PresentationSessionErrorCallback& error_cb) override;
+ const std::string& default_presentation_url) override;
+ void StartSession(int render_process_id,
+ int render_frame_id,
+ const std::string& presentation_url,
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb) override;
+ void JoinSession(int render_process_id,
+ int render_frame_id,
+ const std::string& presentation_url,
+ const std::string& presentation_id,
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb) override;
void CloseSession(int render_process_id,
int render_frame_id,
const std::string& presentation_id) override;
@@ -125,34 +105,39 @@ class PresentationServiceDelegateImpl
int render_frame_id,
const content::SessionStateChangedCallback& state_changed_cb) override;
- // Callback invoked when a default PresentationRequest is started from a
- // browser-initiated dialog.
- void OnRouteResponse(const PresentationRequest& request,
- const MediaRoute* route,
+ // Callback invoked when there is a route response from CreateRoute/JoinRoute
+ // outside of a Presentation API request. This could be due to
+ // browser action (e.g., browser initiated media router dialog) or
+ // a media route provider (e.g., autojoin).
+ void OnRouteResponse(const MediaRoute* route,
const std::string& presentation_id,
const std::string& error);
- // Adds / removes an observer for listening to default PresentationRequest
- // changes. This class does not own |observer|. When |observer| is about to
- // be destroyed, |RemoveDefaultPresentationRequestObserver| must be called.
- void AddDefaultPresentationRequestObserver(
- DefaultPresentationRequestObserver* observer);
- void RemoveDefaultPresentationRequestObserver(
- DefaultPresentationRequestObserver* observer);
+ // Returns the default MediaSource for this tab if there is one.
+ // Returns an empty MediaSource otherwise.
+ MediaSource default_source() const { return default_source_; }
- // Gets the default presentation request for the owning tab WebContents. It
- // is an error to call this method if the default presentation request does
- // not exist.
- PresentationRequest GetDefaultPresentationRequest() const;
+ content::WebContents* web_contents() const { return web_contents_; }
+ const GURL& default_frame_url() const { return default_frame_url_; }
- // Returns true if there is a default presentation request for the owning tab
+ // Observer interface for listening to default MediaSource changes for the
// WebContents.
- bool HasDefaultPresentationRequest() const;
-
- // Returns the WebContents that owns this instance.
- content::WebContents* web_contents() const { return web_contents_; }
+ class DefaultMediaSourceObserver {
+ public:
+ virtual ~DefaultMediaSourceObserver() {}
+
+ // Called when default media source for the corresponding WebContents has
+ // changed.
+ // |source|: New default MediaSource, or empty if default was removed.
+ // |frame_url|: URL of the frame that contains the default media
+ // source, or empty if there is no default media source.
+ virtual void OnDefaultMediaSourceChanged(const MediaSource& source,
+ const GURL& frame_url) = 0;
+ };
- base::WeakPtr<PresentationServiceDelegateImpl> GetWeakPtr();
+ // Adds / removes an observer for listening to default MediaSource changes.
+ void AddDefaultMediaSourceObserver(DefaultMediaSourceObserver* observer);
+ void RemoveDefaultMediaSourceObserver(DefaultMediaSourceObserver* observer);
void SetMediaRouterForTest(MediaRouter* router);
bool HasScreenAvailabilityListenerForTest(
@@ -160,16 +145,12 @@ class PresentationServiceDelegateImpl
int render_frame_id,
const MediaSource::Id& source_id) const;
+ base::WeakPtr<PresentationServiceDelegateImpl> GetWeakPtr();
+
private:
friend class content::WebContentsUserData<PresentationServiceDelegateImpl>;
FRIEND_TEST_ALL_PREFIXES(PresentationServiceDelegateImplTest,
DelegateObservers);
- FRIEND_TEST_ALL_PREFIXES(PresentationServiceDelegateImplTest,
- SetDefaultPresentationUrl);
- FRIEND_TEST_ALL_PREFIXES(PresentationServiceDelegateImplTest,
- DefaultPresentationRequestObserver);
- FRIEND_TEST_ALL_PREFIXES(PresentationServiceDelegateImplTest,
- DefaultPresentationUrlCallback);
explicit PresentationServiceDelegateImpl(content::WebContents* web_contents);
@@ -178,26 +159,47 @@ class PresentationServiceDelegateImpl
MediaSource GetMediaSourceFromListener(
content::PresentationScreenAvailabilityListener* listener);
- void OnJoinRouteResponse(
- int render_process_id,
- int render_frame_id,
- const content::PresentationSessionInfo& session,
- const content::PresentationSessionStartedCallback& success_cb,
- const content::PresentationSessionErrorCallback& error_cb,
- const MediaRoute* route,
- const std::string& presentation_id,
- const std::string& error_text);
+ void OnJoinRouteResponse(int render_process_id,
+ int render_frame_id,
+ const content::PresentationSessionInfo& session,
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb,
+ const MediaRoute* route,
+ const std::string& presentation_id,
+ const std::string& error_text);
void OnStartSessionSucceeded(
int render_process_id,
int render_frame_id,
- const content::PresentationSessionStartedCallback& success_cb,
+ const PresentationSessionSuccessCallback& success_cb,
const content::PresentationSessionInfo& new_session,
const MediaRoute::Id& route_id);
+ // Returns |true| if the frame is the main frame of |web_contents_|.
+ bool IsMainFrame(int render_process_id, int render_frame_id) const;
+
+ // Updates tab-level default MediaSource, default frame URL, and the
+ // originating frame. If the source or frame URL changed, notify the
+ // observers.
+ void UpdateDefaultMediaSourceAndNotifyObservers(
+ const RenderFrameHostId& render_frame_host_id,
+ const MediaSource& new_default_source,
+ const GURL& new_default_frame_url);
+
+ // ID of RenderFrameHost that contains the default presentation.
+ RenderFrameHostId default_presentation_render_frame_host_id_;
+ // Default MediaSource for the tab associated with this instance.
+ MediaSource default_source_;
+ // URL of the frame that contains the default MediaSource.
+ GURL default_frame_url_;
+
+ // References to the observers listening for changes to default media source.
+ base::ObserverList<
+ DefaultMediaSourceObserver> default_media_source_observers_;
+
// References to the WebContents that owns this instance, and associated
// browser profile's MediaRouter instance.
- content::WebContents* const web_contents_;
+ content::WebContents* web_contents_;
MediaRouter* router_;
scoped_ptr<PresentationFrameManager> frame_manager_;
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 c3099aa..056f05d 100644
--- a/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
+++ b/chrome/browser/media/router/presentation_service_delegate_impl_unittest.cc
@@ -24,7 +24,6 @@
using ::testing::_;
using ::testing::Mock;
using ::testing::Return;
-using ::testing::SaveArg;
using ::testing::StrictMock;
namespace media_router {
@@ -37,12 +36,11 @@ class MockDelegateObserver
void(const content::PresentationSessionInfo&));
};
-class MockDefaultPresentationRequestObserver
- : public PresentationServiceDelegateImpl::
- DefaultPresentationRequestObserver {
+class MockDefaultMediaSourceObserver
+ : public PresentationServiceDelegateImpl::DefaultMediaSourceObserver {
public:
- MOCK_METHOD1(OnDefaultPresentationChanged, void(const PresentationRequest&));
- MOCK_METHOD0(OnDefaultPresentationRemoved, void());
+ MOCK_METHOD2(OnDefaultMediaSourceChanged,
+ void(const MediaSource&, const GURL&));
};
class PresentationServiceDelegateImplTest
@@ -57,9 +55,6 @@ class PresentationServiceDelegateImplTest
delegate_impl_->SetMediaRouterForTest(&router_);
}
- MOCK_METHOD1(OnDefaultPresentationStarted,
- void(const content::PresentationSessionInfo& session_info));
-
PresentationServiceDelegateImpl* delegate_impl_;
MockMediaRouter router_;
};
@@ -67,8 +62,8 @@ class PresentationServiceDelegateImplTest
TEST_F(PresentationServiceDelegateImplTest, AddScreenAvailabilityListener) {
ON_CALL(router_, RegisterMediaSinksObserver(_)).WillByDefault(Return(true));
- std::string presentation_url1("http://url1.fakeUrl");
- std::string presentation_url2("http://url2.fakeUrl");
+ std::string presentation_url1("http://url1");
+ std::string presentation_url2("http://url2");
MediaSource source1 = MediaSourceForPresentationUrl(presentation_url1);
MediaSource source2 = MediaSourceForPresentationUrl(presentation_url2);
MockScreenAvailabilityListener listener1(presentation_url1);
@@ -103,7 +98,7 @@ TEST_F(PresentationServiceDelegateImplTest, AddScreenAvailabilityListener) {
TEST_F(PresentationServiceDelegateImplTest, AddSameListenerTwice) {
ON_CALL(router_, RegisterMediaSinksObserver(_)).WillByDefault(Return(true));
- std::string presentation_url1("http://url1.fakeUrl");
+ std::string presentation_url1("http://url1");
MediaSource source1(MediaSourceForPresentationUrl(presentation_url1));
MockScreenAvailabilityListener listener1(presentation_url1);
int render_process_id = 1;
@@ -124,144 +119,76 @@ TEST_F(PresentationServiceDelegateImplTest, AddSameListenerTwice) {
render_process_id, render_frame_id, source1.id()));
}
-// TODO(imcheng): Add a test to set default presentation URL in a different
-// RenderFrameHost and verify that it works.
TEST_F(PresentationServiceDelegateImplTest, SetDefaultPresentationUrl) {
- EXPECT_FALSE(delegate_impl_->HasDefaultPresentationRequest());
-
- GURL frame_url("http://www.google.com");
- content::WebContentsTester::For(web_contents())->NavigateAndCommit(frame_url);
+ content::WebContentsTester::For(web_contents())
+ ->NavigateAndCommit(GURL("http://www.google.com"));
content::RenderFrameHost* main_frame = web_contents()->GetMainFrame();
ASSERT_TRUE(main_frame);
int render_process_id = main_frame->GetProcess()->GetID();
int routing_id = main_frame->GetRoutingID();
- auto callback = base::Bind(
- &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted,
- base::Unretained(this));
- std::string presentation_url1("http://foo.fakeUrl");
+ std::string presentation_url1("http://foo");
delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id,
- presentation_url1, callback);
- ASSERT_TRUE(delegate_impl_->HasDefaultPresentationRequest());
- PresentationRequest request1 =
- delegate_impl_->GetDefaultPresentationRequest();
- EXPECT_EQ(presentation_url1, request1.presentation_url());
- EXPECT_EQ(RenderFrameHostId(render_process_id, routing_id),
- request1.render_frame_host_id());
- EXPECT_EQ(frame_url, request1.frame_url());
-
- // Set to a new default presentation URL
- std::string presentation_url2("https://youtube.com");
- delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id,
- presentation_url2, callback);
- ASSERT_TRUE(delegate_impl_->HasDefaultPresentationRequest());
- PresentationRequest request2 =
- delegate_impl_->GetDefaultPresentationRequest();
- EXPECT_EQ(presentation_url2, request2.presentation_url());
- EXPECT_EQ(RenderFrameHostId(render_process_id, routing_id),
- request2.render_frame_host_id());
- EXPECT_EQ(frame_url, request2.frame_url());
+ presentation_url1);
+ EXPECT_TRUE(delegate_impl_->default_source().Equals(
+ MediaSourceForPresentationUrl(presentation_url1)));
// Remove default presentation URL.
- delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id, "",
- callback);
- EXPECT_FALSE(delegate_impl_->HasDefaultPresentationRequest());
-}
+ delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id, "");
+ EXPECT_TRUE(delegate_impl_->default_source().Empty());
-TEST_F(PresentationServiceDelegateImplTest, DefaultPresentationUrlCallback) {
- content::RenderFrameHost* main_frame = web_contents()->GetMainFrame();
- ASSERT_TRUE(main_frame);
- int render_process_id = main_frame->GetProcess()->GetID();
- int routing_id = main_frame->GetRoutingID();
-
- auto callback = base::Bind(
- &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted,
- base::Unretained(this));
- std::string presentation_url1("http://foo.fakeUrl");
+ // Set to a new default presentation URL
+ std::string presentation_url2("https://youtube.com");
delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id,
- presentation_url1, callback);
-
- ASSERT_TRUE(delegate_impl_->HasDefaultPresentationRequest());
- PresentationRequest request = delegate_impl_->GetDefaultPresentationRequest();
-
- // Should not trigger callback since route response is error.
- delegate_impl_->OnRouteResponse(request, nullptr, "", "Error");
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
-
- // Should not trigger callback since request doesn't match.
- std::string presentation_url2("http://bar.fakeUrl");
- PresentationRequest different_request(RenderFrameHostId(100, 200),
- presentation_url2,
- GURL("http://anotherFrameUrl.fakeUrl"));
- MediaRoute different_route("differentRouteId",
- MediaSourceForPresentationUrl(presentation_url2),
- "mediaSinkId", "", true, "", true);
- delegate_impl_->OnRouteResponse(different_request, &different_route,
- "differentPresentationId", "");
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(this));
-
- // Should trigger callback since request matches.
- MediaRoute route("routeId", MediaSourceForPresentationUrl(presentation_url1),
- "mediaSinkId", "", true, "", true);
- EXPECT_CALL(*this, OnDefaultPresentationStarted(_)).Times(1);
- delegate_impl_->OnRouteResponse(request, &route, "presentationId", "");
+ presentation_url2);
+ EXPECT_TRUE(delegate_impl_->default_source().Equals(
+ MediaSourceForPresentationUrl(presentation_url2)));
}
-TEST_F(PresentationServiceDelegateImplTest,
- DefaultPresentationRequestObserver) {
- auto callback = base::Bind(
- &PresentationServiceDelegateImplTest::OnDefaultPresentationStarted,
- base::Unretained(this));
-
- StrictMock<MockDefaultPresentationRequestObserver> observer;
- delegate_impl_->AddDefaultPresentationRequestObserver(&observer);
-
- GURL frame_url("http://www.google.com");
- content::WebContentsTester::For(web_contents())->NavigateAndCommit(frame_url);
+TEST_F(PresentationServiceDelegateImplTest, DefaultMediaSourceObserver) {
+ content::WebContentsTester::For(web_contents())
+ ->NavigateAndCommit(GURL("http://www.google.com"));
content::RenderFrameHost* main_frame = web_contents()->GetMainFrame();
ASSERT_TRUE(main_frame);
int render_process_id = main_frame->GetProcess()->GetID();
int routing_id = main_frame->GetRoutingID();
-
- std::string url1("http://foo.fakeUrl");
- PresentationRequest observed_request1(
- RenderFrameHostId(render_process_id, routing_id), url1, frame_url);
- EXPECT_CALL(observer, OnDefaultPresentationChanged(Equals(observed_request1)))
- .Times(1);
- delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id, url1,
- callback);
-
- ASSERT_TRUE(delegate_impl_->HasDefaultPresentationRequest());
- PresentationRequest request1 =
- delegate_impl_->GetDefaultPresentationRequest();
- EXPECT_TRUE(request1.Equals(observed_request1));
-
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
-
+ StrictMock<MockDefaultMediaSourceObserver> observer1;
+ StrictMock<MockDefaultMediaSourceObserver> observer2;
+ delegate_impl_->AddDefaultMediaSourceObserver(&observer1);
+ delegate_impl_->AddDefaultMediaSourceObserver(&observer2);
+ std::string url1("http://foo");
+ EXPECT_CALL(observer1, OnDefaultMediaSourceChanged(
+ Equals(MediaSourceForPresentationUrl(url1)),
+ GURL("http://www.google.com"))).Times(1);
+ EXPECT_CALL(observer2, OnDefaultMediaSourceChanged(
+ Equals(MediaSourceForPresentationUrl(url1)),
+ GURL("http://www.google.com"))).Times(1);
+ delegate_impl_->SetDefaultPresentationUrl(render_process_id,
+ routing_id, url1);
+
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer2));
+
+ delegate_impl_->RemoveDefaultMediaSourceObserver(&observer2);
std::string url2("http://youtube.com");
- PresentationRequest observed_request2(
- RenderFrameHostId(render_process_id, routing_id), url2, frame_url);
- EXPECT_CALL(observer, OnDefaultPresentationChanged(Equals(observed_request2)))
- .Times(1);
- delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id, url2,
- callback);
- ASSERT_TRUE(delegate_impl_->HasDefaultPresentationRequest());
- PresentationRequest request2 =
- delegate_impl_->GetDefaultPresentationRequest();
- EXPECT_TRUE(request2.Equals(observed_request2));
-
- EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer));
+ EXPECT_CALL(observer1, OnDefaultMediaSourceChanged(
+ Equals(MediaSourceForPresentationUrl(url2)),
+ GURL("http://www.google.com"))).Times(1);
+ delegate_impl_->SetDefaultPresentationUrl(render_process_id,
+ routing_id, url2);
+ EXPECT_TRUE(Mock::VerifyAndClearExpectations(&observer1));
// Remove default presentation URL.
- EXPECT_CALL(observer, OnDefaultPresentationRemoved()).Times(1);
- delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id, "",
- callback);
+ EXPECT_CALL(observer1, OnDefaultMediaSourceChanged(
+ Equals(MediaSource()),
+ GURL("http://www.google.com"))).Times(1);
+ delegate_impl_->SetDefaultPresentationUrl(render_process_id, routing_id, "");
}
TEST_F(PresentationServiceDelegateImplTest, Reset) {
ON_CALL(router_, RegisterMediaSinksObserver(_)).WillByDefault(Return(true));
- std::string presentation_url1("http://url1.fakeUrl");
+ std::string presentation_url1("http://url1");
MediaSource source = MediaSourceForPresentationUrl(presentation_url1);
MockScreenAvailabilityListener listener1(presentation_url1);
int render_process_id = 1;
@@ -298,7 +225,7 @@ TEST_F(PresentationServiceDelegateImplTest, DelegateObservers) {
TEST_F(PresentationServiceDelegateImplTest, SinksObserverCantRegister) {
ON_CALL(router_, RegisterMediaSinksObserver(_)).WillByDefault(Return(false));
- const std::string presentation_url("http://url1.fakeUrl");
+ const std::string presentation_url("http://url1");
MockScreenAvailabilityListener listener(presentation_url);
const int render_process_id = 10;
const int render_frame_id = 1;
diff --git a/chrome/browser/media/router/render_frame_host_id.h b/chrome/browser/media/router/render_frame_host_id.h
deleted file mode 100644
index d9fb005..0000000
--- a/chrome/browser/media/router/render_frame_host_id.h
+++ /dev/null
@@ -1,16 +0,0 @@
-// 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.
-
-#ifndef CHROME_BROWSER_MEDIA_ROUTER_RENDER_FRAME_HOST_ID_H_
-#define CHROME_BROWSER_MEDIA_ROUTER_RENDER_FRAME_HOST_ID_H_
-
-#include <utility>
-
-namespace media_router {
-
-using RenderFrameHostId = std::pair<int, int>;
-
-} // namespace media_router
-
-#endif // CHROME_BROWSER_MEDIA_ROUTER_RENDER_FRAME_HOST_ID_H_
diff --git a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
index d81c695..ffcecc2 100644
--- a/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_dialog_controller_impl.cc
@@ -274,18 +274,18 @@ void MediaRouterDialogControllerImpl::PopulateDialog(
return;
}
- scoped_ptr<CreatePresentationConnectionRequest> create_connection_request(
- TakeCreateConnectionRequest());
+ scoped_ptr<CreatePresentationSessionRequest> presentation_request(
+ TakePresentationRequest());
// TODO(imcheng): Don't create PresentationServiceDelegateImpl if it doesn't
// exist (crbug.com/508695).
base::WeakPtr<PresentationServiceDelegateImpl> delegate =
PresentationServiceDelegateImpl::GetOrCreateForWebContents(initiator())
->GetWeakPtr();
- if (!create_connection_request.get()) {
+ if (!presentation_request.get()) {
media_router_ui->InitWithDefaultMediaSource(delegate);
} else {
media_router_ui->InitWithPresentationSessionRequest(
- initiator(), delegate, create_connection_request.Pass());
+ initiator(), delegate, presentation_request.Pass());
}
}
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 afb9c42..4d05a51 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui.cc
+++ b/chrome/browser/ui/webui/media_router/media_router_ui.cc
@@ -9,7 +9,7 @@
#include "base/guid.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "chrome/browser/media/router/create_presentation_connection_request.h"
+#include "chrome/browser/media/router/create_presentation_session_request.h"
#include "chrome/browser/media/router/issue.h"
#include "chrome/browser/media/router/issues_observer.h"
#include "chrome/browser/media/router/media_route.h"
@@ -163,12 +163,11 @@ MediaRouterUI::~MediaRouterUI() {
if (query_result_manager_.get())
query_result_manager_->RemoveObserver(this);
if (presentation_service_delegate_.get())
- presentation_service_delegate_->RemoveDefaultPresentationRequestObserver(
- this);
- // If |create_session_request_| still exists, then it means presentation route
+ presentation_service_delegate_->RemoveDefaultMediaSourceObserver(this);
+ // If |presentation_request_| still exists, then it means presentation route
// request was never attempted.
- if (create_session_request_) {
- create_session_request_->InvokeErrorCallback(content::PresentationError(
+ if (presentation_request_) {
+ presentation_request_->InvokeErrorCallback(content::PresentationError(
content::PRESENTATION_ERROR_SESSION_REQUEST_CANCELLED,
"Dialog closed."));
}
@@ -181,30 +180,30 @@ void MediaRouterUI::InitWithDefaultMediaSource(
DCHECK(!query_result_manager_.get());
presentation_service_delegate_ = delegate;
- presentation_service_delegate_->AddDefaultPresentationRequestObserver(this);
- InitCommon(presentation_service_delegate_->web_contents());
- if (presentation_service_delegate_->HasDefaultPresentationRequest()) {
- OnDefaultPresentationChanged(
- presentation_service_delegate_->GetDefaultPresentationRequest());
- }
+ presentation_service_delegate_->AddDefaultMediaSourceObserver(this);
+ InitCommon(presentation_service_delegate_->web_contents(),
+ presentation_service_delegate_->default_source(),
+ presentation_service_delegate_->default_frame_url());
}
void MediaRouterUI::InitWithPresentationSessionRequest(
content::WebContents* initiator,
const base::WeakPtr<PresentationServiceDelegateImpl>& delegate,
- scoped_ptr<CreatePresentationConnectionRequest> create_session_request) {
+ scoped_ptr<CreatePresentationSessionRequest> presentation_request) {
DCHECK(initiator);
- DCHECK(create_session_request);
- DCHECK(!create_session_request_);
+ DCHECK(presentation_request);
+ DCHECK(!presentation_request_);
DCHECK(!query_result_manager_);
- create_session_request_ = create_session_request.Pass();
+ presentation_request_ = presentation_request.Pass();
presentation_service_delegate_ = delegate;
- InitCommon(initiator);
- OnDefaultPresentationChanged(create_session_request_->presentation_request());
+ InitCommon(initiator, presentation_request_->media_source(),
+ presentation_request_->frame_url());
}
-void MediaRouterUI::InitCommon(content::WebContents* initiator) {
+void MediaRouterUI::InitCommon(content::WebContents* initiator,
+ const MediaSource& default_source,
+ const GURL& default_frame_url) {
DCHECK(initiator);
DCHECK(router_);
@@ -224,31 +223,26 @@ void MediaRouterUI::InitCommon(content::WebContents* initiator) {
MediaSourceForTab(SessionTabHelper::IdForTab(initiator)));
query_result_manager_->StartSinksQuery(
MediaCastMode::TAB_MIRROR, mirroring_source);
-}
-void MediaRouterUI::OnDefaultPresentationChanged(
- const PresentationRequest& presentation_request) {
- presentation_request_.reset(new PresentationRequest(presentation_request));
- query_result_manager_->StartSinksQuery(
- MediaCastMode::DEFAULT, presentation_request_->GetMediaSource());
- UpdateCastModes();
+ OnDefaultMediaSourceChanged(default_source, default_frame_url);
}
-void MediaRouterUI::OnDefaultPresentationRemoved() {
- presentation_request_.reset();
- query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT);
- UpdateCastModes();
+void MediaRouterUI::OnDefaultMediaSourceChanged(const MediaSource& source,
+ const GURL& frame_url) {
+ if (source.Empty()) {
+ query_result_manager_->StopSinksQuery(MediaCastMode::DEFAULT);
+ } else {
+ query_result_manager_->StartSinksQuery(MediaCastMode::DEFAULT, source);
+ }
+ UpdateSourceHostAndCastModes(frame_url);
}
-void MediaRouterUI::UpdateCastModes() {
- // Gets updated cast modes from |query_result_manager_| and forwards it to UI.
+void MediaRouterUI::UpdateSourceHostAndCastModes(const GURL& frame_url) {
+ DCHECK(query_result_manager_);
+ frame_url_ = frame_url;
query_result_manager_->GetSupportedCastModes(&cast_modes_);
- if (ui_initialized_) {
- handler_->UpdateCastModes(
- cast_modes_, presentation_request_
- ? GetHostFromURL(presentation_request_->frame_url())
- : std::string());
- }
+ if (ui_initialized_)
+ handler_->UpdateCastModes(cast_modes_, GetHostFromURL(frame_url_));
}
void MediaRouterUI::Close() {
@@ -274,11 +268,11 @@ bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id,
DCHECK(initiator_);
// Note that there is a rarely-encountered bug, where the MediaCastMode to
- // MediaSource mapping could have been updated, between when the user clicked
- // on the UI to start a create route request, and when this function is
- // called. However, since the user does not have visibility into the
- // MediaSource, and that it occurs very rarely in practice, we leave it as-is
- // for now.
+ // MediaSource mapping could have been updated, between when the user
+ // clicked on the UI to start a create route request,
+ // and when this function is called.
+ // However, since the user does not have visibility into the MediaSource, and
+ // that it occurs very rarely in practice, we leave it as-is for now.
MediaSource source = query_result_manager_->GetSourceForCastMode(cast_mode);
if (source.Empty()) {
LOG(ERROR) << "No corresponding MediaSource for cast mode " << cast_mode;
@@ -286,16 +280,11 @@ bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id,
}
requesting_route_for_default_source_ = cast_mode == MediaCastMode::DEFAULT;
- if (requesting_route_for_default_source_ && !presentation_request_) {
- DLOG(ERROR) << "Requested to create a route for presentation, but "
- << "presentation request is missing.";
- return false;
- }
-
current_route_request_id_ = ++route_request_counter_;
GURL origin;
+ // TODO(imcheng): What is the origin if not creating route in DEFAULT mode?
if (requesting_route_for_default_source_) {
- origin = presentation_request_->frame_url().GetOrigin();
+ origin = frame_url_.GetOrigin();
} else {
// Requesting route for mirroring. Use a placeholder URL as origin.
origin = GURL(chrome::kChromeUIMediaRouterURL);
@@ -308,7 +297,7 @@ bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id,
// (1) Non-presentation route request (e.g., mirroring). No additional
// notification necessary.
// (2) Presentation route request for a Presentation API startSession call.
- // The startSession (CreatePresentationConnectionRequest) will need to be
+ // The startSession (CreatePresentationSessionRequest) will need to be
// answered with the
// route response.
// (3) Browser-initiated presentation route request. If successful,
@@ -321,16 +310,16 @@ bool MediaRouterUI::CreateRoute(const MediaSink::Id& sink_id,
weak_factory_.GetWeakPtr(), current_route_request_id_,
sink_id));
if (requesting_route_for_default_source_) {
- if (create_session_request_) {
- // |create_session_request_| will be nullptr after this call, as the
+ if (presentation_request_) {
+ // |presentation_request_| will be nullptr after this call, as the
// object will be transferred to the callback.
route_response_callbacks.push_back(
- base::Bind(&CreatePresentationConnectionRequest::HandleRouteResponse,
- base::Passed(&create_session_request_)));
+ base::Bind(&CreatePresentationSessionRequest::HandleRouteResponse,
+ base::Passed(&presentation_request_)));
} else if (presentation_service_delegate_) {
route_response_callbacks.push_back(
base::Bind(&PresentationServiceDelegateImpl::OnRouteResponse,
- presentation_service_delegate_, *presentation_request_));
+ presentation_service_delegate_));
}
}
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 4c8ef33..3d7859f 100644
--- a/chrome/browser/ui/webui/media_router/media_router_ui.h
+++ b/chrome/browser/ui/webui/media_router/media_router_ui.h
@@ -38,13 +38,13 @@ class MediaRouterWebUIMessageHandler;
class MediaRoutesObserver;
class MediaSink;
class MediaSinksObserver;
-class CreatePresentationConnectionRequest;
+class CreatePresentationSessionRequest;
// Implements the chrome://media-router user interface.
-class MediaRouterUI : public ConstrainedWebDialogUI,
- public QueryResultManager::Observer,
- public PresentationServiceDelegateImpl::
- DefaultPresentationRequestObserver {
+class MediaRouterUI
+ : public ConstrainedWebDialogUI,
+ public QueryResultManager::Observer,
+ public PresentationServiceDelegateImpl::DefaultMediaSourceObserver {
public:
// |web_ui| owns this object and is used to initialize the base class.
explicit MediaRouterUI(content::WebUI* web_ui);
@@ -79,7 +79,7 @@ class MediaRouterUI : public ConstrainedWebDialogUI,
void InitWithPresentationSessionRequest(
content::WebContents* initiator,
const base::WeakPtr<PresentationServiceDelegateImpl>& delegate,
- scoped_ptr<CreatePresentationConnectionRequest> presentation_request);
+ scoped_ptr<CreatePresentationSessionRequest> presentation_request);
// Closes the media router UI.
void Close();
@@ -163,17 +163,20 @@ class MediaRouterUI : public ConstrainedWebDialogUI,
// Creates and sends an issue if route creation times out.
void RouteCreationTimeout();
- // Initializes the dialog with mirroring sources derived from |initiator|.
- void InitCommon(content::WebContents* initiator);
+ // Sets the source host name to be displayed in the UI.
+ // Gets cast modes from |query_result_manager_| and forwards it to UI.
+ // One of the Init* functions must have been called before.
+ void UpdateSourceHostAndCastModes(const GURL& frame_url);
- // PresentationServiceDelegateImpl::DefaultPresentationObserver
- void OnDefaultPresentationChanged(
- const PresentationRequest& presentation_request) override;
- void OnDefaultPresentationRemoved() override;
+ // Initializes the dialog with mirroring sources derived from |initiator|,
+ // and optional |default_source| and |default_frame_url| if any.
+ void InitCommon(content::WebContents* initiator,
+ const MediaSource& default_source,
+ const GURL& default_frame_url);
- // Updates the set of supported cast modes and sends the updated set to
- // |handler_|.
- void UpdateCastModes();
+ // PresentationServiceDelegateImpl::DefaultMediaSourceObserver
+ void OnDefaultMediaSourceChanged(const MediaSource& source,
+ const GURL& frame_url) override;
// Owned by the |web_ui| passed in the ctor, and guaranteed to be deleted
// only after it has deleted |this|.
@@ -205,11 +208,7 @@ class MediaRouterUI : public ConstrainedWebDialogUI,
// If set, then the result of the next presentation route request will
// be handled by this object.
- scoped_ptr<CreatePresentationConnectionRequest> create_session_request_;
-
- // Set to the presentation request corresponding to the presentation cast
- // mode, if supported. Otherwise set to nullptr.
- scoped_ptr<PresentationRequest> presentation_request_;
+ scoped_ptr<CreatePresentationSessionRequest> presentation_request_;
// It's possible for PresentationServiceDelegateImpl to be destroyed before
// this class.
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index cd0acad..7f6712f 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -1432,7 +1432,7 @@
'browser/supervised_user/legacy/supervised_user_sync_service_unittest.cc',
],
'chrome_unit_tests_media_router_sources': [
- 'browser/media/router/create_presentation_connection_request_unittest.cc',
+ 'browser/media/router/create_presentation_session_request_unittest.cc',
'browser/media/router/issue_manager_unittest.cc',
'browser/media/router/issue_unittest.cc',
'browser/media/router/media_route_unittest.cc',
@@ -1440,7 +1440,6 @@
'browser/media/router/media_source_helper_unittest.cc',
'browser/media/router/media_source_unittest.cc',
'browser/media/router/presentation_media_sinks_observer_unittest.cc',
- 'browser/media/router/presentation_request_unittest.cc',
'browser/media/router/presentation_service_delegate_impl_unittest.cc',
'browser/media/router/presentation_session_state_observer_unittest.cc',
],
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc
index 5d20a31..dd5203d 100644
--- a/content/browser/presentation/presentation_service_impl.cc
+++ b/content/browser/presentation/presentation_service_impl.cc
@@ -224,6 +224,13 @@ void PresentationServiceImpl::StopListeningForScreenAvailability(
screen_availability_listeners_.erase(listener_it);
}
+void PresentationServiceImpl::ListenForDefaultSessionStart(
+ const DefaultSessionMojoCallback& callback) {
+ if (!default_session_start_context_.get())
+ default_session_start_context_.reset(new DefaultSessionStartContext);
+ default_session_start_context_->AddCallback(callback);
+}
+
void PresentationServiceImpl::StartSession(
const mojo::String& presentation_url,
const NewSessionMojoCallback& callback) {
@@ -361,12 +368,11 @@ void PresentationServiceImpl::SetDefaultPresentationURL(
const std::string& new_default_url = url.get();
if (default_presentation_url_ == new_default_url)
return;
-
- default_presentation_url_ = new_default_url;
delegate_->SetDefaultPresentationUrl(
- render_process_id_, render_frame_id_, new_default_url,
- base::Bind(&PresentationServiceImpl::OnDefaultPresentationStarted,
- weak_factory_.GetWeakPtr()));
+ render_process_id_,
+ render_frame_id_,
+ new_default_url);
+ default_presentation_url_ = new_default_url;
}
void PresentationServiceImpl::SendSessionMessage(
@@ -515,6 +521,8 @@ void PresentationServiceImpl::Reset() {
pending_join_session_cbs_.clear();
+ default_session_start_context_.reset();
+
if (on_session_messages_callback_.get()) {
on_session_messages_callback_->Run(
mojo::Array<presentation::SessionMessagePtr>());
@@ -536,10 +544,9 @@ void PresentationServiceImpl::OnDelegateDestroyed() {
}
void PresentationServiceImpl::OnDefaultPresentationStarted(
- const PresentationSessionInfo& session_info) {
- DCHECK(client_.get());
- client_->OnDefaultSessionStarted(
- presentation::PresentationSessionInfo::From(session_info));
+ const PresentationSessionInfo& session) {
+ if (default_session_start_context_.get())
+ default_session_start_context_->set_session(session);
}
PresentationServiceImpl::ScreenAvailabilityListenerImpl
@@ -590,4 +597,45 @@ void PresentationServiceImpl::NewSessionMojoCallbackWrapper::Run(
callback_.reset();
}
+PresentationServiceImpl::DefaultSessionStartContext
+::DefaultSessionStartContext() {
+}
+
+PresentationServiceImpl::DefaultSessionStartContext
+::~DefaultSessionStartContext() {
+ Reset();
+}
+
+void PresentationServiceImpl::DefaultSessionStartContext::AddCallback(
+ const DefaultSessionMojoCallback& callback) {
+ if (session_.get()) {
+ DCHECK(callbacks_.empty());
+ callback.Run(presentation::PresentationSessionInfo::From(*session_));
+ session_.reset();
+ } else {
+ callbacks_.push_back(new DefaultSessionMojoCallback(callback));
+ }
+}
+
+void PresentationServiceImpl::DefaultSessionStartContext::set_session(
+ const PresentationSessionInfo& session) {
+ if (callbacks_.empty()) {
+ session_.reset(new PresentationSessionInfo(session));
+ } else {
+ DCHECK(!session_.get());
+ ScopedVector<DefaultSessionMojoCallback> callbacks;
+ callbacks.swap(callbacks_);
+ for (const auto& callback : callbacks)
+ callback->Run(presentation::PresentationSessionInfo::From(session));
+ }
+}
+
+void PresentationServiceImpl::DefaultSessionStartContext::Reset() {
+ ScopedVector<DefaultSessionMojoCallback> callbacks;
+ callbacks.swap(callbacks_);
+ for (const auto& callback : callbacks)
+ callback->Run(presentation::PresentationSessionInfoPtr());
+ session_.reset();
+}
+
} // namespace content
diff --git a/content/browser/presentation/presentation_service_impl.h b/content/browser/presentation/presentation_service_impl.h
index 54e1a4c..220c256 100644
--- a/content/browser/presentation/presentation_service_impl.h
+++ b/content/browser/presentation/presentation_service_impl.h
@@ -94,7 +94,7 @@ class CONTENT_EXPORT PresentationServiceImpl
// Maximum number of pending JoinSession requests at any given time.
static const int kMaxNumQueuedSessionRequests = 10;
- using PresentationSessionMojoCallback =
+ using DefaultSessionMojoCallback =
mojo::Callback<void(presentation::PresentationSessionInfoPtr)>;
using SessionStateCallback =
mojo::Callback<void(presentation::PresentationSessionInfoPtr,
@@ -125,6 +125,27 @@ class CONTENT_EXPORT PresentationServiceImpl
PresentationServiceImpl* const service_;
};
+ class CONTENT_EXPORT DefaultSessionStartContext {
+ public:
+ DefaultSessionStartContext();
+ ~DefaultSessionStartContext();
+
+ // Adds a callback. May invoke the callback immediately if |session| using
+ // default presentation URL was already started.
+ void AddCallback(const DefaultSessionMojoCallback& callback);
+
+ // Sets the session info. Maybe invoke callbacks queued with AddCallback().
+ void set_session(const PresentationSessionInfo& session);
+
+ private:
+ // Flush all queued callbacks by invoking them with null
+ // PresentationSessionInfoPtr.
+ void Reset();
+
+ ScopedVector<DefaultSessionMojoCallback> callbacks_;
+ scoped_ptr<PresentationSessionInfo> session_;
+ };
+
// Ensures the provided NewSessionMojoCallback is invoked exactly once
// before it goes out of scope.
class NewSessionMojoCallbackWrapper {
@@ -156,6 +177,8 @@ class CONTENT_EXPORT PresentationServiceImpl
void SetClient(presentation::PresentationServiceClientPtr client) override;
void ListenForScreenAvailability(const mojo::String& url) override;
void StopListeningForScreenAvailability(const mojo::String& url) override;
+ void ListenForDefaultSessionStart(
+ const DefaultSessionMojoCallback& callback) override;
void StartSession(
const mojo::String& presentation_url,
const NewSessionMojoCallback& callback) override;
@@ -185,11 +208,8 @@ class CONTENT_EXPORT PresentationServiceImpl
// PresentationServiceDelegate::Observer
void OnDelegateDestroyed() override;
-
- // Passed to embedder's implementation of PresentationServiceDelegate for
- // later invocation when default presentation has started.
- void OnDefaultPresentationStarted(
- const PresentationSessionInfo& session_info);
+ void OnDefaultPresentationStarted(const PresentationSessionInfo& session)
+ override;
// Finds the callback from |pending_join_session_cbs_| using
// |request_session_id|.
@@ -264,6 +284,8 @@ class CONTENT_EXPORT PresentationServiceImpl
base::hash_map<int, linked_ptr<NewSessionMojoCallbackWrapper>>
pending_join_session_cbs_;
+ scoped_ptr<DefaultSessionStartContext> default_session_start_context_;
+
// RAII binding of |this| to an Presentation interface request.
// The binding is removed when binding_ is cleared or goes out of scope.
scoped_ptr<mojo::Binding<presentation::PresentationService>> binding_;
diff --git a/content/browser/presentation/presentation_service_impl_unittest.cc b/content/browser/presentation/presentation_service_impl_unittest.cc
index b85fc84..3716586 100644
--- a/content/browser/presentation/presentation_service_impl_unittest.cc
+++ b/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -41,6 +41,12 @@ MATCHER_P(Equals, expected, "") {
const char *const kPresentationId = "presentationId";
const char *const kPresentationUrl = "http://foo.com/index.html";
+bool ArePresentationSessionsEqual(
+ const presentation::PresentationSessionInfo& expected,
+ const presentation::PresentationSessionInfo& actual) {
+ return expected.url == actual.url && expected.id == actual.id;
+}
+
bool ArePresentationSessionMessagesEqual(
const presentation::SessionMessage* expected,
const presentation::SessionMessage* actual) {
@@ -85,24 +91,26 @@ class MockPresentationServiceDelegate : public PresentationServiceDelegate {
void(
int render_process_id,
int routing_id));
- MOCK_METHOD4(SetDefaultPresentationUrl,
- void(int render_process_id,
- int routing_id,
- const std::string& default_presentation_url,
- const PresentationSessionStartedCallback& callback));
+ MOCK_METHOD3(SetDefaultPresentationUrl,
+ void(
+ int render_process_id,
+ int routing_id,
+ const std::string& default_presentation_url));
MOCK_METHOD5(StartSession,
- void(int render_process_id,
- int render_frame_id,
- const std::string& presentation_url,
- const PresentationSessionStartedCallback& success_cb,
- const PresentationSessionErrorCallback& error_cb));
+ void(
+ int render_process_id,
+ int render_frame_id,
+ const std::string& presentation_url,
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb));
MOCK_METHOD6(JoinSession,
- void(int render_process_id,
- int render_frame_id,
- const std::string& presentation_url,
- const std::string& presentation_id,
- const PresentationSessionStartedCallback& success_cb,
- const PresentationSessionErrorCallback& error_cb));
+ void(
+ int render_process_id,
+ int render_frame_id,
+ const std::string& presentation_url,
+ const std::string& presentation_id,
+ const PresentationSessionSuccessCallback& success_cb,
+ const PresentationSessionErrorCallback& error_cb));
MOCK_METHOD3(CloseSession,
void(int render_process_id,
int render_frame_id,
@@ -164,13 +172,6 @@ class MockPresentationServiceClient :
}
MOCK_METHOD0(MessagesReceived, void());
- void OnDefaultSessionStarted(
- presentation::PresentationSessionInfoPtr session_info) override {
- OnDefaultSessionStarted(*session_info);
- }
- MOCK_METHOD1(OnDefaultSessionStarted,
- void(const presentation::PresentationSessionInfo& session_info));
-
mojo::Array<presentation::SessionMessagePtr> messages_received_;
};
@@ -256,6 +257,7 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
EXPECT_EQ(
service_impl_->screen_availability_listeners_.find(kPresentationUrl),
service_impl_->screen_availability_listeners_.end());
+ EXPECT_FALSE(service_impl_->default_session_start_context_.get());
EXPECT_FALSE(service_impl_->on_session_messages_callback_.get());
}
@@ -277,6 +279,25 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
run_loop_quit_closure_.Run();
}
+ void ExpectDefaultSessionStarted(
+ const presentation::PresentationSessionInfo& expected_session,
+ presentation::PresentationSessionInfoPtr actual_session) {
+ ASSERT_TRUE(!actual_session.is_null());
+ EXPECT_TRUE(ArePresentationSessionsEqual(
+ expected_session, *actual_session));
+ ++default_session_started_count_;
+ if (!run_loop_quit_closure_.is_null())
+ run_loop_quit_closure_.Run();
+ }
+
+ void ExpectDefaultSessionNull(
+ presentation::PresentationSessionInfoPtr actual_session) {
+ EXPECT_TRUE(actual_session.is_null());
+ ++default_session_started_count_;
+ if (!run_loop_quit_closure_.is_null())
+ run_loop_quit_closure_.Run();
+ }
+
void ExpectSessionMessages(
const mojo::Array<presentation::SessionMessagePtr>& expected_msgs,
const mojo::Array<presentation::SessionMessagePtr>& actual_msgs) {
@@ -429,30 +450,24 @@ TEST_F(PresentationServiceImplTest, DelegateFails) {
TEST_F(PresentationServiceImplTest, SetDefaultPresentationUrl) {
std::string url1("http://fooUrl");
- EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrl(_, _, Eq(url1), _))
+ EXPECT_CALL(mock_delegate_,
+ SetDefaultPresentationUrl(_, _, Eq(url1)))
.Times(1);
service_impl_->SetDefaultPresentationURL(url1);
EXPECT_EQ(url1, service_impl_->default_presentation_url_);
std::string url2("http://barUrl");
// Sets different DPU.
- content::PresentationSessionStartedCallback callback;
- EXPECT_CALL(mock_delegate_, SetDefaultPresentationUrl(_, _, Eq(url2), _))
- .WillOnce(SaveArg<3>(&callback));
+ EXPECT_CALL(mock_delegate_,
+ SetDefaultPresentationUrl(_, _, Eq(url2)))
+ .Times(1);
service_impl_->SetDefaultPresentationURL(url2);
EXPECT_EQ(url2, service_impl_->default_presentation_url_);
-
- presentation::PresentationSessionInfo session_info;
- session_info.url = url2;
- session_info.id = kPresentationId;
- EXPECT_CALL(mock_client_, OnDefaultSessionStarted(Equals(session_info)))
- .Times(1);
- callback.Run(content::PresentationSessionInfo(url2, kPresentationId));
}
TEST_F(PresentationServiceImplTest, SetSameDefaultPresentationUrl) {
EXPECT_CALL(mock_delegate_,
- SetDefaultPresentationUrl(_, _, Eq(kPresentationUrl), _))
+ SetDefaultPresentationUrl(_, _, Eq(kPresentationUrl)))
.Times(1);
service_impl_->SetDefaultPresentationURL(kPresentationUrl);
EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_delegate_));
@@ -577,6 +592,59 @@ TEST_F(PresentationServiceImplTest, StartSessionInProgress) {
SaveQuitClosureAndRunLoop();
}
+TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStart) {
+ presentation::PresentationSessionInfo expected_session;
+ expected_session.url = kPresentationUrl;
+ expected_session.id = kPresentationId;
+ service_ptr_->ListenForDefaultSessionStart(
+ base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
+ base::Unretained(this),
+ expected_session));
+ RunLoopFor(base::TimeDelta::FromMilliseconds(50));
+ service_impl_->OnDefaultPresentationStarted(
+ content::PresentationSessionInfo(kPresentationUrl, kPresentationId));
+ SaveQuitClosureAndRunLoop();
+ EXPECT_EQ(1, default_session_started_count_);
+}
+
+TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStartAfterSet) {
+ // Note that the callback will only pick up presentation_url2/id2 since
+ // ListenForDefaultSessionStart wasn't called yet when the DPU was still
+ // presentation_url1.
+ std::string presentation_url1("http://fooUrl1");
+ std::string presentation_id1("presentationId1");
+ std::string presentation_url2("http://fooUrl2");
+ std::string presentation_id2("presentationId2");
+ service_impl_->OnDefaultPresentationStarted(
+ content::PresentationSessionInfo(presentation_url1, presentation_id1));
+
+ presentation::PresentationSessionInfo expected_session;
+ expected_session.url = presentation_url2;
+ expected_session.id = presentation_id2;
+ service_ptr_->ListenForDefaultSessionStart(
+ base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
+ base::Unretained(this),
+ expected_session));
+ RunLoopFor(base::TimeDelta::FromMilliseconds(50));
+ service_impl_->OnDefaultPresentationStarted(
+ content::PresentationSessionInfo(presentation_url2, presentation_id2));
+ SaveQuitClosureAndRunLoop();
+ EXPECT_EQ(1, default_session_started_count_);
+}
+
+TEST_F(PresentationServiceImplTest, DefaultSessionStartReset) {
+ service_ptr_->ListenForDefaultSessionStart(
+ base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionNull,
+ base::Unretained(this)));
+ RunLoopFor(TestTimeouts::tiny_timeout());
+
+ ExpectReset();
+ service_impl_->Reset();
+ ExpectCleanState();
+ SaveQuitClosureAndRunLoop();
+ EXPECT_EQ(1, default_session_started_count_);
+}
+
TEST_F(PresentationServiceImplTest, SendStringMessage) {
std::string message("Test presentation session message");
diff --git a/content/common/presentation/presentation_service.mojom b/content/common/presentation/presentation_service.mojom
index 422ae58..3256a96 100644
--- a/content/common/presentation/presentation_service.mojom
+++ b/content/common/presentation/presentation_service.mojom
@@ -42,14 +42,12 @@ struct SessionMessage {
};
interface PresentationService {
- // Sets the PresentationServiceClient.
- SetClient(PresentationServiceClient client);
-
// Called when the frame sets or changes the default presentation URL.
- // When the default presentation is started on this frame,
- // PresentationServiceClient::OnDefaultSessionStarted will be invoked.
SetDefaultPresentationURL(string url);
+ // Sets the PresentationServiceClient.
+ SetClient(PresentationServiceClient client);
+
// Starts listening for screen availability for presentation of
// |url|. Availability results will be returned to the client via
// PresentationServiceClient::OnScreenAvailabilityUpdated.
@@ -60,6 +58,13 @@ interface PresentationService {
// |url|.
StopListeningForScreenAvailability(string url);
+ // Called when the renderer is ready to receive the browser initiated
+ // session. If the default session is started by the embedder before this
+ // call, the embedder may queue it and run the callback when the call is
+ // performed.
+ ListenForDefaultSessionStart()
+ => (PresentationSessionInfo? defaultSessionInfo);
+
// Called when startSession() is called by the frame. The result callback
// will return a non-null and valid PresentationSessionInfo if starting the
// session succeeded, or null with a PresentationError if starting the
@@ -84,8 +89,7 @@ interface PresentationService {
// The false in the result callback notifies the renderer to stop sending
// the send requests and invalidate all pending requests. This occurs
// for eg., when frame is deleted or navigated away.
- SendSessionMessage(PresentationSessionInfo sessionInfo,
- SessionMessage message_request) => (bool success);
+ SendSessionMessage(PresentationSessionInfo sessionInfo, SessionMessage message_request) => (bool success);
// Called when closeSession() is called by the frame.
CloseSession(string presentation_url, string presentation_id);
@@ -121,9 +125,5 @@ interface PresentationServiceClient {
PresentationConnectionState newState);
// See PresentationService::ListenForSessionMessages.
- OnSessionMessagesReceived(PresentationSessionInfo sessionInfo,
- array<SessionMessage> messages);
-
- // See PresentationService::SetDefaultPresentationURL.
- OnDefaultSessionStarted(PresentationSessionInfo sessionInfo);
-};
+ OnSessionMessagesReceived(PresentationSessionInfo sessionInfo, array<SessionMessage> messages);
+};
diff --git a/content/public/browser/presentation_service_delegate.h b/content/public/browser/presentation_service_delegate.h
index ba0bf99..5c4e5c8 100644
--- a/content/public/browser/presentation_service_delegate.h
+++ b/content/public/browser/presentation_service_delegate.h
@@ -19,10 +19,6 @@ namespace content {
class PresentationScreenAvailabilityListener;
-using PresentationSessionStartedCallback =
- base::Callback<void(const PresentationSessionInfo&)>;
-using PresentationSessionErrorCallback =
- base::Callback<void(const PresentationError&)>;
using SessionStateChangedCallback =
base::Callback<void(const PresentationSessionInfo&,
PresentationConnectionState)>;
@@ -43,10 +39,21 @@ class CONTENT_EXPORT PresentationServiceDelegate {
// Called when the PresentationServiceDelegate is being destroyed.
virtual void OnDelegateDestroyed() = 0;
+ // Called when the default presentation has been started outside of a
+ // Presentation API context (e.g., browser action). This will not be called
+ // if the session was created as a result of Presentation API's
+ // StartSession()/JoinSession().
+ virtual void OnDefaultPresentationStarted(
+ const PresentationSessionInfo& session) = 0;
+
protected:
virtual ~Observer() {}
};
+ using PresentationSessionSuccessCallback =
+ base::Callback<void(const PresentationSessionInfo&)>;
+ using PresentationSessionErrorCallback =
+ base::Callback<void(const PresentationError&)>;
using SendMessageCallback = base::Callback<void(bool)>;
virtual ~PresentationServiceDelegate() {}
@@ -94,16 +101,13 @@ class CONTENT_EXPORT PresentationServiceDelegate {
int render_frame_id) = 0;
// Sets the default presentation URL for frame given by |render_process_id|
- // and |render_frame_id|. When the default presentation is started on this
- // frame, |callback| will be invoked with the corresponding
- // PresentationSessionInfo object.
+ // and |render_frame_id|.
// If |default_presentation_url| is empty, the default presentation URL will
- // be cleared and the previously registered callback (if any) will be removed.
+ // be cleared.
virtual void SetDefaultPresentationUrl(
int render_process_id,
int render_frame_id,
- const std::string& default_presentation_url,
- const PresentationSessionStartedCallback& callback) = 0;
+ const std::string& default_presentation_url) = 0;
// Starts a new presentation session. The presentation id of the session will
// be the default presentation ID if any or a generated one otherwise.
@@ -119,7 +123,7 @@ class CONTENT_EXPORT PresentationServiceDelegate {
int render_process_id,
int render_frame_id,
const std::string& presentation_url,
- const PresentationSessionStartedCallback& success_cb,
+ const PresentationSessionSuccessCallback& success_cb,
const PresentationSessionErrorCallback& error_cb) = 0;
// Joins an existing presentation session. Unlike StartSession(), this
@@ -135,7 +139,7 @@ class CONTENT_EXPORT PresentationServiceDelegate {
int render_frame_id,
const std::string& presentation_url,
const std::string& presentation_id,
- const PresentationSessionStartedCallback& success_cb,
+ const PresentationSessionSuccessCallback& success_cb,
const PresentationSessionErrorCallback& error_cb) = 0;
// Close an existing presentation session.
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc
index 1a249e8..9eb9c67 100644
--- a/content/renderer/presentation/presentation_dispatcher.cc
+++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -337,6 +337,11 @@ void PresentationDispatcher::OnDefaultSessionStarted(
if (!controller_)
return;
+ // Reset the callback to get the next event.
+ presentation_service_->ListenForDefaultSessionStart(base::Bind(
+ &PresentationDispatcher::OnDefaultSessionStarted,
+ base::Unretained(this)));
+
if (!session_info.is_null()) {
controller_->didStartDefaultSession(
new PresentationConnectionClient(session_info.Clone()));
@@ -421,6 +426,9 @@ void PresentationDispatcher::ConnectToPresentationServiceIfNeeded() {
binding_.Bind(GetProxy(&client_ptr));
presentation_service_->SetClient(client_ptr.Pass());
+ presentation_service_->ListenForDefaultSessionStart(base::Bind(
+ &PresentationDispatcher::OnDefaultSessionStarted,
+ base::Unretained(this)));
presentation_service_->ListenForSessionStateChange();
}
diff --git a/content/renderer/presentation/presentation_dispatcher.h b/content/renderer/presentation/presentation_dispatcher.h
index 7311329..54c259b 100644
--- a/content/renderer/presentation/presentation_dispatcher.h
+++ b/content/renderer/presentation/presentation_dispatcher.h
@@ -100,13 +100,13 @@ class CONTENT_EXPORT PresentationDispatcher
void OnSessionMessagesReceived(
presentation::PresentationSessionInfoPtr session_info,
mojo::Array<presentation::SessionMessagePtr> messages) override;
- void OnDefaultSessionStarted(
- presentation::PresentationSessionInfoPtr session_info) override;
void OnSessionCreated(
blink::WebPresentationConnectionClientCallbacks* callback,
presentation::PresentationSessionInfoPtr session_info,
presentation::PresentationErrorPtr error);
+ void OnDefaultSessionStarted(
+ presentation::PresentationSessionInfoPtr session_info);
// Call to PresentationService to send the message in |request|.
// |session_info| and |message| of |reuqest| will be consumed.