summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorimcheng <imcheng@google.com>2015-04-24 12:41:17 -0700
committerCommit bot <commit-bot@chromium.org>2015-04-24 19:41:21 +0000
commit2ed5f820be60cfe8ef53f2e25605ae94bda8de0a (patch)
treefe00ed46c37b4c2949d565d9c218b9c9d3af6365 /content
parent5f663d8a8fcbe8f4be26d908b1b6cb4cb9124cc6 (diff)
downloadchromium_src-2ed5f820be60cfe8ef53f2e25605ae94bda8de0a.zip
chromium_src-2ed5f820be60cfe8ef53f2e25605ae94bda8de0a.tar.gz
chromium_src-2ed5f820be60cfe8ef53f2e25605ae94bda8de0a.tar.bz2
Reland of: [Presentation API] Implement ondefaultsessionstart in PSImpl.
To fix PresentationServiceImplTest.DefaultSessionStartReset timeout in Android Tests (dbg). TEST=git cl try + linux_android_dbg_ng ---- Added DefaultSessionStartContext for coordinating sending default session back to PresentationDispatcher. When ListenForDefaultSessionStart is called, DefaultSessionStartContext will be installed on PresentationServiceImpl. When both the default session and PresentationDispatcher's callback are available, the callback will be invoked with the session. On Reset(), if a callback is available, it will be invoked with null. Changed PresentationDispatcher to not update Blink in that case. Also, PSImpl now keeps track of the corresponding RFH's ID instead of RFH* since most of the time we only need to use the ID. Changed PresentationServiceDelegate's Add/RemoveObserver interface, since the PresentationServiceDelegate need to be able to correlate an Observer with a RFH. (at most 1 per RFH, as it stands today). Added OnDefaultPresentationStarted to PresentationServiceDelegate::Observer interface and implemented it in PresentationServiceImpl. Added tests in PresentationServiceImpl. BUG=459001 Review URL: https://codereview.chromium.org/1055053004 Cr-Commit-Position: refs/heads/master@{#326859}
Diffstat (limited to 'content')
-rw-r--r--content/browser/presentation/presentation_service_impl.cc112
-rw-r--r--content/browser/presentation/presentation_service_impl.h39
-rw-r--r--content/browser/presentation/presentation_service_impl_unittest.cc111
-rw-r--r--content/common/presentation/presentation_service.mojom2
-rw-r--r--content/public/browser/presentation_service_delegate.h24
-rw-r--r--content/renderer/presentation/presentation_dispatcher.cc7
6 files changed, 243 insertions, 52 deletions
diff --git a/content/browser/presentation/presentation_service_impl.cc b/content/browser/presentation/presentation_service_impl.cc
index 2d6769e..e22e914 100644
--- a/content/browser/presentation/presentation_service_impl.cc
+++ b/content/browser/presentation/presentation_service_impl.cc
@@ -23,23 +23,24 @@ PresentationServiceImpl::PresentationServiceImpl(
WebContents* web_contents,
PresentationServiceDelegate* delegate)
: WebContentsObserver(web_contents),
- render_frame_host_(render_frame_host),
delegate_(delegate),
is_start_session_pending_(false),
next_request_session_id_(0),
weak_factory_(this) {
- DCHECK(render_frame_host_);
+ DCHECK(render_frame_host);
DCHECK(web_contents);
+
+ render_process_id_ = render_frame_host->GetProcess()->GetID();
+ render_frame_id_ = render_frame_host->GetRoutingID();
DVLOG(2) << "PresentationServiceImpl: "
- << render_frame_host_->GetProcess()->GetID() << ", "
- << render_frame_host_->GetRoutingID();
+ << render_process_id_ << ", " << render_frame_id_;
if (delegate_)
- delegate_->AddObserver(this);
+ delegate_->AddObserver(render_process_id_, render_frame_id_, this);
}
PresentationServiceImpl::~PresentationServiceImpl() {
if (delegate_)
- delegate_->RemoveObserver(this);
+ delegate_->RemoveObserver(render_process_id_, render_frame_id_);
FlushNewSessionCallbacks();
}
@@ -83,9 +84,7 @@ PresentationServiceImpl::GetOrCreateAvailabilityContext(
linked_ptr<ScreenAvailabilityContext> context(
new ScreenAvailabilityContext(presentation_url));
if (!delegate_->AddScreenAvailabilityListener(
- render_frame_host_->GetProcess()->GetID(),
- render_frame_host_->GetRoutingID(),
- context.get())) {
+ render_process_id_, render_frame_id_, context.get())) {
DVLOG(1) << "AddScreenAvailabilityListener failed. Ignoring request.";
return nullptr;
}
@@ -125,9 +124,7 @@ void PresentationServiceImpl::RemoveScreenAvailabilityListener(
return;
delegate_->RemoveScreenAvailabilityListener(
- render_frame_host_->GetProcess()->GetID(),
- render_frame_host_->GetRoutingID(),
- it->second.get());
+ render_process_id_, render_frame_id_, it->second.get());
// Resolve the context's pending callbacks before removing it.
it->second->OnScreenAvailabilityChanged(false);
availability_contexts_.erase(it);
@@ -135,7 +132,9 @@ void PresentationServiceImpl::RemoveScreenAvailabilityListener(
void PresentationServiceImpl::ListenForDefaultSessionStart(
const DefaultSessionMojoCallback& callback) {
- NOTIMPLEMENTED();
+ if (!default_session_start_context_.get())
+ default_session_start_context_.reset(new DefaultSessionStartContext);
+ default_session_start_context_->AddCallback(callback);
}
void PresentationServiceImpl::StartSession(
@@ -169,8 +168,8 @@ void PresentationServiceImpl::JoinSession(
int request_session_id = RegisterNewSessionCallback(callback);
delegate_->JoinSession(
- render_frame_host_->GetProcess()->GetID(),
- render_frame_host_->GetRoutingID(),
+ render_process_id_,
+ render_frame_id_,
presentation_url,
presentation_id,
base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded,
@@ -214,8 +213,8 @@ void PresentationServiceImpl::DoStartSession(
int request_session_id = RegisterNewSessionCallback(callback);
is_start_session_pending_ = true;
delegate_->StartSession(
- render_frame_host_->GetProcess()->GetID(),
- render_frame_host_->GetRoutingID(),
+ render_process_id_,
+ render_frame_id_,
presentation_url,
presentation_id,
base::Bind(&PresentationServiceImpl::OnStartOrJoinSessionSucceeded,
@@ -266,8 +265,8 @@ void PresentationServiceImpl::DoSetDefaultPresentationUrl(
const std::string& default_presentation_id) {
DCHECK(delegate_);
delegate_->SetDefaultPresentationUrl(
- render_frame_host_->GetProcess()->GetID(),
- render_frame_host_->GetRoutingID(),
+ render_process_id_,
+ render_frame_id_,
default_presentation_url,
default_presentation_id);
default_presentation_url_ = default_presentation_url;
@@ -307,8 +306,8 @@ void PresentationServiceImpl::SetDefaultPresentationURL(
// Remove listener for old default presentation URL.
delegate_->RemoveScreenAvailabilityListener(
- render_frame_host_->GetProcess()->GetID(),
- render_frame_host_->GetRoutingID(),
+ render_process_id_,
+ render_frame_id_,
old_it->second.get());
availability_contexts_.erase(old_it);
DoSetDefaultPresentationUrl(new_default_url, default_presentation_id);
@@ -325,12 +324,21 @@ void PresentationServiceImpl::ListenForSessionStateChange(
NOTIMPLEMENTED();
}
+bool PresentationServiceImpl::FrameMatches(
+ content::RenderFrameHost* render_frame_host) const {
+ if (!render_frame_host)
+ return false;
+
+ return render_frame_host->GetProcess()->GetID() == render_process_id_ &&
+ render_frame_host->GetRoutingID() == render_frame_id_;
+}
+
void PresentationServiceImpl::DidNavigateAnyFrame(
content::RenderFrameHost* render_frame_host,
const content::LoadCommittedDetails& details,
const content::FrameNavigateParams& params) {
DVLOG(2) << "PresentationServiceImpl::DidNavigateAnyFrame";
- if (render_frame_host_ != render_frame_host)
+ if (!FrameMatches(render_frame_host))
return;
std::string prev_url_host = details.previous_url.host();
@@ -355,29 +363,26 @@ void PresentationServiceImpl::DidNavigateAnyFrame(
void PresentationServiceImpl::RenderFrameDeleted(
content::RenderFrameHost* render_frame_host) {
DVLOG(2) << "PresentationServiceImpl::RenderFrameDeleted";
- if (render_frame_host_ != render_frame_host)
+ if (!FrameMatches(render_frame_host))
return;
- // RenderFrameDeleted means |render_frame_host_| is going to be deleted soon.
+ // RenderFrameDeleted means the associated RFH is going to be deleted soon.
// This object should also be deleted.
Reset();
- render_frame_host_ = nullptr;
delete this;
}
void PresentationServiceImpl::Reset() {
DVLOG(2) << "PresentationServiceImpl::Reset";
- if (delegate_) {
- delegate_->Reset(
- render_frame_host_->GetProcess()->GetID(),
- render_frame_host_->GetRoutingID());
- }
+ if (delegate_)
+ delegate_->Reset(render_process_id_, render_frame_id_);
default_presentation_url_.clear();
default_presentation_id_.clear();
availability_contexts_.clear();
queued_start_session_requests_.clear();
FlushNewSessionCallbacks();
+ default_session_start_context_.reset();
}
// static
@@ -395,6 +400,12 @@ void PresentationServiceImpl::OnDelegateDestroyed() {
Reset();
}
+void PresentationServiceImpl::OnDefaultPresentationStarted(
+ const PresentationSessionInfo& session) {
+ if (default_session_start_context_.get())
+ default_session_start_context_->set_session(session);
+}
+
PresentationServiceImpl::ScreenAvailabilityContext::ScreenAvailabilityContext(
const std::string& presentation_url)
: presentation_url_(presentation_url) {
@@ -478,5 +489,46 @@ PresentationServiceImpl::StartSessionRequest::PassCallback() {
return callback;
}
+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 84962e7..21de733 100644
--- a/content/browser/presentation/presentation_service_impl.h
+++ b/content/browser/presentation/presentation_service_impl.h
@@ -109,6 +109,27 @@ class CONTENT_EXPORT PresentationServiceImpl
scoped_ptr<bool> available_ptr_;
};
+ 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_;
+ };
+
// Context for a StartSession request.
class CONTENT_EXPORT StartSessionRequest {
public:
@@ -146,6 +167,12 @@ class CONTENT_EXPORT PresentationServiceImpl
SetSameDefaultPresentationUrl);
FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
ClearDefaultPresentationUrl);
+ FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
+ ListenForDefaultSessionStart);
+ FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
+ ListenForDefaultSessionStartAfterSet);
+ FRIEND_TEST_ALL_PREFIXES(PresentationServiceImplTest,
+ DefaultSessionStartReset);
// |render_frame_host|: The RFH this instance is associated with.
// |web_contents|: The WebContents to observe.
@@ -197,6 +224,8 @@ class CONTENT_EXPORT PresentationServiceImpl
// PresentationServiceDelegate::Observer
void OnDelegateDestroyed() override;
+ void OnDefaultPresentationStarted(const PresentationSessionInfo& session)
+ override;
// Finds the callback from |pending_session_cbs_| using |request_session_id|.
// If it exists, invoke it with |session| and |error|, then erase it from
@@ -256,7 +285,9 @@ class CONTENT_EXPORT PresentationServiceImpl
ScreenAvailabilityContext* GetOrCreateAvailabilityContext(
const std::string& presentation_url);
- RenderFrameHost* render_frame_host_;
+ // Returns true if this object is associated with |render_frame_host|.
+ bool FrameMatches(content::RenderFrameHost* render_frame_host) const;
+
PresentationServiceDelegate* delegate_;
// Map from presentation URL to its ScreenAvailabilityContext state machine.
@@ -277,10 +308,16 @@ class CONTENT_EXPORT PresentationServiceImpl
int next_request_session_id_;
base::hash_map<int, linked_ptr<NewSessionMojoCallback>> pending_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_;
+ // ID of the RenderFrameHost this object is associated with.
+ int render_process_id_;
+ int render_frame_id_;
+
// NOTE: Weak pointers must be invalidated before all other member variables.
base::WeakPtrFactory<PresentationServiceImpl> weak_factory_;
diff --git a/content/browser/presentation/presentation_service_impl_unittest.cc b/content/browser/presentation/presentation_service_impl_unittest.cc
index 1f7f758..2f25256 100644
--- a/content/browser/presentation/presentation_service_impl_unittest.cc
+++ b/content/browser/presentation/presentation_service_impl_unittest.cc
@@ -5,6 +5,7 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
+#include "base/test/test_timeouts.h"
#include "content/browser/presentation/presentation_service_impl.h"
#include "content/public/browser/presentation_service_delegate.h"
#include "content/public/browser/presentation_session.h"
@@ -23,12 +24,23 @@ using ::testing::SaveArg;
namespace content {
+namespace {
+
+bool ArePresentationSessionsEqual(
+ const presentation::PresentationSessionInfo& expected,
+ const presentation::PresentationSessionInfo& actual) {
+ return expected.url == actual.url && expected.id == actual.id;
+}
+} // namespace
+
class MockPresentationServiceDelegate : public PresentationServiceDelegate {
public:
- MOCK_METHOD1(AddObserver,
- void(PresentationServiceDelegate::Observer* observer));
- MOCK_METHOD1(RemoveObserver,
- void(PresentationServiceDelegate::Observer* observer));
+ MOCK_METHOD3(AddObserver,
+ void(int render_process_id,
+ int render_frame_id,
+ PresentationServiceDelegate::Observer* observer));
+ MOCK_METHOD2(RemoveObserver,
+ void(int render_process_id, int render_frame_id));
MOCK_METHOD3(AddScreenAvailabilityListener,
bool(
int render_process_id,
@@ -69,13 +81,15 @@ class MockPresentationServiceDelegate : public PresentationServiceDelegate {
class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
public:
- PresentationServiceImplTest() : callback_count_(0) {}
+ PresentationServiceImplTest()
+ : callback_count_(0), default_session_started_count_(0) {}
void SetUp() override {
RenderViewHostImplTestHarness::SetUp();
auto request = mojo::GetProxy(&service_ptr_);
- EXPECT_CALL(mock_delegate_, AddObserver(_)).Times(1);
+
+ EXPECT_CALL(mock_delegate_, AddObserver(_, _, _)).Times(1);
service_impl_.reset(new PresentationServiceImpl(
contents()->GetMainFrame(), contents(), &mock_delegate_));
service_impl_->Bind(request.Pass());
@@ -84,11 +98,9 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
void TearDown() override {
service_ptr_.reset();
if (service_impl_.get()) {
- EXPECT_CALL(mock_delegate_, RemoveObserver(Eq(service_impl_.get())))
- .Times(1);
+ EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
service_impl_.reset();
}
-
RenderViewHostImplTestHarness::TearDown();
}
@@ -155,8 +167,7 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
}
void ExpectReset() {
- EXPECT_CALL(mock_delegate_, Reset(_, _))
- .Times(1);
+ EXPECT_CALL(mock_delegate_, Reset(_, _)).Times(1);
}
void ExpectCleanState() {
@@ -164,6 +175,7 @@ class PresentationServiceImplTest : public RenderViewHostImplTestHarness {
EXPECT_TRUE(service_impl_->default_presentation_url_.empty());
EXPECT_TRUE(service_impl_->default_presentation_id_.empty());
EXPECT_TRUE(service_impl_->queued_start_session_requests_.empty());
+ EXPECT_FALSE(service_impl_->default_session_start_context_.get());
}
void ExpectNewSessionMojoCallbackSuccess(
@@ -184,11 +196,31 @@ 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();
+ }
+
MockPresentationServiceDelegate mock_delegate_;
scoped_ptr<PresentationServiceImpl> service_impl_;
mojo::InterfacePtr<presentation::PresentationService> service_ptr_;
base::Closure run_loop_quit_closure_;
int callback_count_;
+ int default_session_started_count_;
};
TEST_F(PresentationServiceImplTest, ListenForScreenAvailability) {
@@ -294,7 +326,7 @@ TEST_F(PresentationServiceImplTest, ThisRenderFrameDeleted) {
// Since the frame matched the service, |service_impl_| will be deleted.
PresentationServiceImpl* service = service_impl_.release();
- EXPECT_CALL(mock_delegate_, RemoveObserver(Eq(service))).Times(1);
+ EXPECT_CALL(mock_delegate_, RemoveObserver(_, _)).Times(1);
service->RenderFrameDeleted(contents()->GetMainFrame());
}
@@ -581,4 +613,59 @@ TEST_F(PresentationServiceImplTest, StartSessionInProgress) {
SaveQuitClosureAndRunLoop();
}
+TEST_F(PresentationServiceImplTest, ListenForDefaultSessionStart) {
+ std::string presentation_url1("http://fooUrl1");
+ std::string presentation_id1("presentationId1");
+ presentation::PresentationSessionInfo expected_session;
+ expected_session.url = presentation_url1;
+ expected_session.id = presentation_id1;
+ service_ptr_->ListenForDefaultSessionStart(
+ base::Bind(&PresentationServiceImplTest::ExpectDefaultSessionStarted,
+ base::Unretained(this),
+ expected_session));
+ RunLoopFor(base::TimeDelta::FromMilliseconds(50));
+ service_impl_->OnDefaultPresentationStarted(
+ content::PresentationSessionInfo(presentation_url1, presentation_id1));
+ 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_);
+}
+
} // namespace content
diff --git a/content/common/presentation/presentation_service.mojom b/content/common/presentation/presentation_service.mojom
index 36756e2..91da501 100644
--- a/content/common/presentation/presentation_service.mojom
+++ b/content/common/presentation/presentation_service.mojom
@@ -52,7 +52,7 @@ interface PresentationService {
// call, the embedder may queue it and run the callback when the call is
// performed.
ListenForDefaultSessionStart()
- => (PresentationSessionInfo defaultSessionInfo);
+ => (PresentationSessionInfo? defaultSessionInfo);
// Called when startSession() is called by the frame. The result callback
// will return a non-null and valid PresentationSessionInfo if starting the
diff --git a/content/public/browser/presentation_service_delegate.h b/content/public/browser/presentation_service_delegate.h
index 817cd28..fd82045 100644
--- a/content/public/browser/presentation_service_delegate.h
+++ b/content/public/browser/presentation_service_delegate.h
@@ -23,6 +23,13 @@ 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() {}
};
@@ -34,12 +41,19 @@ class CONTENT_EXPORT PresentationServiceDelegate {
virtual ~PresentationServiceDelegate() {}
- // Registers an observer with this class to listen for updates to this class.
+ // Registers an observer associated with frame with |render_process_id|
+ // and |render_frame_id| with this class to listen for updates.
// This class does not own the observer.
- // It is an error to add an observer if it has already been added before.
- virtual void AddObserver(Observer* observer) = 0;
- // Unregisters an observer with this class.
- virtual void RemoveObserver(Observer* observer) = 0;
+ // It is an error to add an observer if there is already an observer for that
+ // frame.
+ virtual void AddObserver(int render_process_id,
+ int render_frame_id,
+ Observer* observer) = 0;
+
+ // Unregisters the observer associated with the frame with |render_process_id|
+ // and |render_frame_id|.
+ // The observer will no longer receive updates.
+ virtual void RemoveObserver(int render_process_id, int render_frame_id) = 0;
// Registers |listener| to continuously listen for
// availability updates for a presentation URL, originated from the frame
diff --git a/content/renderer/presentation/presentation_dispatcher.cc b/content/renderer/presentation/presentation_dispatcher.cc
index 39e5238..c074df3 100644
--- a/content/renderer/presentation/presentation_dispatcher.cc
+++ b/content/renderer/presentation/presentation_dispatcher.cc
@@ -172,9 +172,10 @@ void PresentationDispatcher::OnDefaultSessionStarted(
&PresentationDispatcher::OnDefaultSessionStarted,
base::Unretained(this)));
- DCHECK(!session_info.is_null());
- controller_->didStartDefaultSession(
- new PresentationSessionClient(session_info.Pass()));
+ if (!session_info.is_null()) {
+ controller_->didStartDefaultSession(
+ new PresentationSessionClient(session_info.Pass()));
+ }
}
void PresentationDispatcher::OnSessionCreated(