1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/strings/utf_string_conversions.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "content/browser/message_port_service.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/browser/message_port_delegate.h"
11 #include "content/public/browser/message_port_provider.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/test/browser_test_utils.h"
14 #include "content/public/test/content_browser_test.h"
15 #include "content/public/test/content_browser_test_utils.h"
16 #include "content/shell/browser/shell.h"
20 // This test verifies the functionality of the Message Port Provider API.
22 // A mock class for testing message port provider.
23 class MockMessagePortDelegate
: public MessagePortDelegate
{
25 // A container to hold received messages
27 int route_id
; // the routing id of the target port
28 MessagePortMessage data
; // the message data
29 std::vector
<TransferredMessagePort
> sent_ports
; // any transferred ports
32 typedef std::vector
<Message
> Messages
;
34 MockMessagePortDelegate() { }
35 ~MockMessagePortDelegate() override
{ }
37 // MessagePortDelegate implementation
40 const MessagePortMessage
& message
,
41 const std::vector
<TransferredMessagePort
>& sent_message_ports
) override
{
43 m
.route_id
= route_id
;
45 m
.sent_ports
= sent_message_ports
;
46 messages_
.push_back(m
);
49 void SendMessagesAreQueued(int route_id
) override
{ }
51 const Messages
& getReceivedMessages() {
57 DISALLOW_COPY_AND_ASSIGN(MockMessagePortDelegate
);
61 class MessagePortProviderBrowserTest
: public ContentBrowserTest
{
64 // Verify that messages can be posted to main frame.
65 IN_PROC_BROWSER_TEST_F(MessagePortProviderBrowserTest
, PostMessage
) {
66 const std::string data
=
67 "<!DOCTYPE html><html><body>"
68 " <script type=\"text/javascript\">"
69 " onmessage = function (e) { document.title = e.data; }"
72 const base::string16
target_origin(base::UTF8ToUTF16("http://baseurl"));
73 const GURL
base_url(target_origin
);
74 const GURL history_url
;
75 // Load data. Blocks until it is done.
76 content::LoadDataWithBaseURL(shell(), history_url
, data
, base_url
);
77 const base::string16
source_origin(base::UTF8ToUTF16("source"));
78 const base::string16
message(base::UTF8ToUTF16("success"));
79 const std::vector
<TransferredMessagePort
> ports
;
80 content::TitleWatcher
title_watcher(shell()->web_contents(), message
);
81 MessagePortProvider::PostMessageToFrame(shell()->web_contents(),
86 EXPECT_EQ(message
, title_watcher
.WaitAndGetTitle());
91 void VerifyCreateChannelOnIOThread(base::WaitableEvent
* event
) {
93 const base::char16 MESSAGE1
[] = { 0x1000, 0 };
94 const base::char16 MESSAGE2
[] = { 0x1001, 0 };
96 MockMessagePortDelegate delegate
;
100 MessagePortProvider::CreateMessageChannel(&delegate
, &port1
, &port2
);
101 MessagePortService
* service
= MessagePortService::GetInstance();
102 // Send a message to port1 transferring no ports.
103 std::vector
<TransferredMessagePort
> sent_ports
;
104 service
->PostMessage(port1
, MessagePortMessage(base::string16(MESSAGE1
)),
106 // Verify that message is received
107 const MockMessagePortDelegate::Messages
& received
=
108 delegate
.getReceivedMessages();
109 EXPECT_EQ(received
.size(), 1u);
110 // Verify that message sent to port1 is received by entangled port, which is
112 EXPECT_EQ(received
[0].route_id
, port2
);
113 EXPECT_EQ(received
[0].data
.message_as_string
, MESSAGE1
);
114 EXPECT_EQ(received
[0].sent_ports
.size(), 0u);
116 // Create a new channel, and transfer one of its ports to port2, making sure
117 // the transferred port is received.
118 TransferredMessagePort port3
;
119 TransferredMessagePort port4
;
120 MessagePortProvider::CreateMessageChannel(&delegate
, &port3
.id
, &port4
.id
);
121 sent_ports
.push_back(port3
);
122 service
->PostMessage(port1
, MessagePortMessage(base::string16(MESSAGE2
)),
124 EXPECT_EQ(received
.size(), 2u);
125 EXPECT_EQ(received
[1].route_id
, port2
);
126 EXPECT_EQ(received
[1].data
.message_as_string
, MESSAGE2
);
127 EXPECT_EQ(received
[1].sent_ports
.size(), 1u);
128 EXPECT_EQ(received
[1].sent_ports
[0].id
, port3
.id
);
135 // Verify that a message channel can be created and used for exchanging
137 IN_PROC_BROWSER_TEST_F(MessagePortProviderBrowserTest
, CreateChannel
) {
138 base::WaitableEvent
event(true, false);
139 BrowserThread::PostTask(
140 BrowserThread::IO
, FROM_HERE
,
141 base::Bind(&VerifyCreateChannelOnIOThread
, &event
));
145 } // namespace content