Commit e17728ae authored by zhaobin's avatar zhaobin Committed by Commit bot

[Presentation API] Remove closed connections from PresentationConnectionList

- Added WebPresentationReceiver::RemoveConnection() API
- Added WebPresentationReceiver pointer to ReceiverConnectionProxy. WebPresentationReceiver::RemoveConnection() is invoked when receiver connection changes to 'closed'
- In PresentationDispatcher::OnReceiverConnectionAvailable, pass receiver_ pointer to ReceiverConnectionProxy

BUG=713227

Review-Url: https://codereview.chromium.org/2874483002
Cr-Commit-Position: refs/heads/master@{#473773}
parent 9585ee5e
......@@ -11,6 +11,7 @@
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationConnection.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationController.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationInfo.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationReceiver.h"
namespace content {
......@@ -66,7 +67,7 @@ void PresentationConnectionProxy::DidChangeState(
void PresentationConnectionProxy::OnClose() {
DCHECK(target_connection_ptr_);
source_connection_->DidClose();
DidChangeState(content::PRESENTATION_CONNECTION_STATE_CLOSED);
target_connection_ptr_->DidChangeState(
content::PRESENTATION_CONNECTION_STATE_CLOSED);
}
......@@ -105,8 +106,11 @@ ControllerConnectionProxy::MakeRemoteRequest() {
}
ReceiverConnectionProxy::ReceiverConnectionProxy(
blink::WebPresentationConnection* receiver_connection)
: PresentationConnectionProxy(receiver_connection) {}
blink::WebPresentationConnection* receiver_connection,
blink::WebPresentationReceiver* receiver)
: PresentationConnectionProxy(receiver_connection), receiver_(receiver) {
DCHECK(receiver_);
}
ReceiverConnectionProxy::~ReceiverConnectionProxy() = default;
......@@ -125,4 +129,11 @@ void ReceiverConnectionProxy::BindControllerConnection(
DidChangeState(content::PRESENTATION_CONNECTION_STATE_CONNECTED);
}
void ReceiverConnectionProxy::DidChangeState(
content::PresentationConnectionState state) {
PresentationConnectionProxy::DidChangeState(state);
if (state == content::PRESENTATION_CONNECTION_STATE_CLOSED)
receiver_->RemoveConnection(source_connection_);
}
} // namespace content
......@@ -13,6 +13,7 @@
namespace blink {
class WebPresentationConnection;
class WebPresentationReceiver;
} // namespace blink
namespace content {
......@@ -96,7 +97,6 @@ class CONTENT_EXPORT PresentationConnectionProxy
mojo::InterfacePtr<blink::mojom::PresentationConnection>
target_connection_ptr_;
private:
// Raw pointer to Blink connection object owning this proxy object. Does not
// take ownership.
blink::WebPresentationConnection* const source_connection_;
......@@ -118,8 +118,8 @@ class CONTENT_EXPORT ControllerConnectionProxy
class CONTENT_EXPORT ReceiverConnectionProxy
: public PresentationConnectionProxy {
public:
explicit ReceiverConnectionProxy(
blink::WebPresentationConnection* receiver_connection);
ReceiverConnectionProxy(blink::WebPresentationConnection* receiver_connection,
blink::WebPresentationReceiver* receiver);
~ReceiverConnectionProxy() override;
void Bind(
......@@ -129,6 +129,14 @@ class CONTENT_EXPORT ReceiverConnectionProxy
// called only once.
void BindControllerConnection(
blink::mojom::PresentationConnectionPtr controller_connection_ptr);
// PresentationConnectionProxy override
void DidChangeState(content::PresentationConnectionState state) override;
private:
// Raw pointer to PresentationReceiver. This class does not take ownership of
// |receiver_|.
blink::WebPresentationReceiver* receiver_;
};
} // namespace content
......
......@@ -6,6 +6,7 @@
#include <utility>
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/renderer/presentation/presentation_connection_proxy.h"
#include "content/renderer/presentation/test_presentation_connection.h"
......@@ -13,11 +14,24 @@
#include "third_party/WebKit/public/platform/WebString.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationConnection.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationController.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationInfo.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationReceiver.h"
using ::testing::_;
namespace content {
class MockWebPresentationReceiver : public blink::WebPresentationReceiver {
public:
MOCK_METHOD1(
OnReceiverConnectionAvailable,
blink::WebPresentationConnection*(const blink::WebPresentationInfo&));
MOCK_METHOD1(DidChangeConnectionState,
void(blink::WebPresentationConnectionState));
MOCK_METHOD0(TerminateConnection, void());
MOCK_METHOD1(RemoveConnection, void(blink::WebPresentationConnection*));
};
class PresentationConnectionProxyTest : public ::testing::Test {
public:
PresentationConnectionProxyTest() = default;
......@@ -32,8 +46,8 @@ class PresentationConnectionProxyTest : public ::testing::Test {
new ControllerConnectionProxy(controller_connection_.get());
controller_connection_->BindProxy(
base::WrapUnique(controller_connection_proxy_));
receiver_connection_proxy_ =
new ReceiverConnectionProxy(receiver_connection_.get());
receiver_connection_proxy_ = new ReceiverConnectionProxy(
receiver_connection_.get(), &mock_receiver_);
receiver_connection_->BindProxy(
base::WrapUnique(receiver_connection_proxy_));
......@@ -64,6 +78,7 @@ class PresentationConnectionProxyTest : public ::testing::Test {
std::unique_ptr<TestPresentationConnection> receiver_connection_;
ControllerConnectionProxy* controller_connection_proxy_;
ReceiverConnectionProxy* receiver_connection_proxy_;
MockWebPresentationReceiver mock_receiver_;
private:
content::TestBrowserThreadBundle thread_bundle_;
......@@ -106,6 +121,7 @@ TEST_F(PresentationConnectionProxyTest, TestControllerConnectionCallsClose) {
base::RunLoop run_loop;
EXPECT_CALL(*controller_connection_, DidClose());
EXPECT_CALL(*receiver_connection_, DidClose());
EXPECT_CALL(mock_receiver_, RemoveConnection(receiver_connection_.get()));
controller_connection_proxy_->Close();
run_loop.RunUntilIdle();
}
......@@ -114,6 +130,7 @@ TEST_F(PresentationConnectionProxyTest, TestReceiverConnectionCallsClose) {
base::RunLoop run_loop;
EXPECT_CALL(*controller_connection_, DidClose());
EXPECT_CALL(*receiver_connection_, DidClose());
EXPECT_CALL(mock_receiver_, RemoveConnection(receiver_connection_.get()));
receiver_connection_proxy_->Close();
run_loop.RunUntilIdle();
}
......
......@@ -577,7 +577,8 @@ void PresentationDispatcher::OnReceiverConnectionAvailable(
receiver_->OnReceiverConnectionAvailable(blink::WebPresentationInfo(
presentation_info.presentation_url,
blink::WebString::FromUTF8(presentation_info.presentation_id)));
auto* receiver_connection_proxy = new ReceiverConnectionProxy(connection);
auto* receiver_connection_proxy =
new ReceiverConnectionProxy(connection, receiver_);
connection->BindProxy(base::WrapUnique(receiver_connection_proxy));
receiver_connection_proxy->Bind(std::move(receiver_connection_request));
......
......@@ -120,6 +120,7 @@ class TestPresentationReceiver : public blink::WebPresentationReceiver {
MOCK_METHOD1(DidChangeConnectionState,
void(blink::WebPresentationConnectionState));
MOCK_METHOD0(TerminateConnection, void());
MOCK_METHOD1(RemoveConnection, void(blink::WebPresentationConnection*));
TestPresentationConnection connection_;
};
......
......@@ -23,8 +23,6 @@ async_test(t => {
assert_equals(closeEvent.reason, "closed");
assert_equals(closeEvent.message, "");
assert_equals(connection.state, "closed");
assert_true(receiverConnectionClosed);
t.done();
};
connection.onconnect = () => {
// Open a receiver page and pass controller connection's
......@@ -41,6 +39,7 @@ async_test(t => {
window.addEventListener("message", t.step_func(e => {
if (e.data == "receiver connection closed") {
receiverConnectionClosed = true;
t.done();
} else if (e.data == "receiver connection ready") {
assert_not_equals(connection, null);
connection.close();
......
......@@ -27,11 +27,16 @@ presentationServiceMock.then(mockService => {
const connection = list.connections[0];
connection.onclose = () => {
assert_equals(connection.state, 'closed');
opener.postMessage('receiver connection closed', '*');
setTimeout(() => {
assert_equals(list.connections.length, 0);
opener.postMessage('receiver connection closed', '*');
} ,0);
};
opener.postMessage('receiver connection ready', '*');
if (shouldCallClose) {
connection.close();
list.connections.forEach(theConnection => {
theConnection.close();
});
}
});
});
......
......@@ -40,6 +40,17 @@ void PresentationConnectionList::AddConnection(
connections_.push_back(connection);
}
bool PresentationConnectionList::RemoveConnection(
WebPresentationConnection* connection) {
for (size_t i = 0; i < connections_.size(); i++) {
if (connections_[i] == connection) {
connections_.erase(i);
return true;
}
}
return false;
}
void PresentationConnectionList::DispatchConnectionAvailableEvent(
PresentationConnection* connection) {
DispatchEvent(PresentationConnectionAvailableEvent::Create(
......
......@@ -37,6 +37,9 @@ class MODULES_EXPORT PresentationConnectionList final
DEFINE_ATTRIBUTE_EVENT_LISTENER(connectionavailable);
void AddConnection(PresentationConnection*);
// Remove connection from connection list. Returns true if connection is
// successfully removed; Returns false if connection does not exist.
bool RemoveConnection(WebPresentationConnection*);
void DispatchConnectionAvailableEvent(PresentationConnection*);
bool IsEmpty();
......
......@@ -101,6 +101,12 @@ void PresentationReceiver::TerminateConnection() {
window->close(GetFrame()->GetDocument());
}
void PresentationReceiver::RemoveConnection(
WebPresentationConnection* connection) {
DCHECK(connection_list_);
connection_list_->RemoveConnection(connection);
}
void PresentationReceiver::RegisterConnection(
PresentationConnection* connection) {
DCHECK(connection_list_);
......
......@@ -52,6 +52,7 @@ class MODULES_EXPORT PresentationReceiver final
const WebPresentationInfo&) override;
void DidChangeConnectionState(WebPresentationConnectionState) override;
void TerminateConnection() override;
void RemoveConnection(WebPresentationConnection*) override;
void RegisterConnection(PresentationConnection*);
......
......@@ -228,4 +228,29 @@ TEST_F(PresentationReceiverTest, CreateReceiver) {
new PresentationReceiver(&scope.GetFrame(), &client);
}
TEST_F(PresentationReceiverTest, TestRemoveConnection) {
V8TestingScope scope;
auto receiver = new PresentationReceiver(&scope.GetFrame(), nullptr);
// Receive first connection.
WebPresentationInfo presentation_info1(KURL(KURL(), "http://example1.com"),
"id1");
auto* connection1 =
receiver->OnReceiverConnectionAvailable(presentation_info1);
EXPECT_TRUE(connection1);
// Receive second connection.
WebPresentationInfo presentation_info2(KURL(KURL(), "http://example2.com"),
"id2");
auto* connection2 =
receiver->OnReceiverConnectionAvailable(presentation_info2);
EXPECT_TRUE(connection2);
receiver->connectionList(scope.GetScriptState());
VerifyConnectionListSize(2, receiver);
receiver->RemoveConnection(connection1);
VerifyConnectionListSize(1, receiver);
}
} // namespace blink
......@@ -30,6 +30,10 @@ class BLINK_PLATFORM_EXPORT WebPresentationReceiver {
// Called when any PresentationConnection object on receiver page invokes
// connnection.terminate().
virtual void TerminateConnection() = 0;
// Called when any receiver connection switches to 'closed' state. Remove the
// connection from PresentationReceiver's connection list.
virtual void RemoveConnection(WebPresentationConnection*) = 0;
};
} // namespace blink
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment