1 // Copyright (c) 2012 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4
5 #include "include/base/cef_bind.h"
6 #include "include/cef_process_message.h"
7 #include "include/cef_task.h"
8 #include "include/wrapper/cef_closure_task.h"
9 #include "tests/ceftests/test_handler.h"
10 #include "tests/ceftests/test_util.h"
11 #include "tests/gtest/include/gtest/gtest.h"
12 #include "tests/shared/renderer/client_app_renderer.h"
13
14 using client::ClientAppRenderer;
15
16 namespace {
17
18 // Unique values for the SendRecv test.
19 const char kSendRecvUrl[] = "http://tests/ProcessMessageTest.SendRecv";
20 const char kSendRecvMsg[] = "ProcessMessageTest.SendRecv";
21
22 // Creates a test message.
CreateTestMessage()23 CefRefPtr<CefProcessMessage> CreateTestMessage() {
24 CefRefPtr<CefProcessMessage> msg = CefProcessMessage::Create(kSendRecvMsg);
25 EXPECT_TRUE(msg.get());
26
27 CefRefPtr<CefListValue> args = msg->GetArgumentList();
28 EXPECT_TRUE(args.get());
29
30 size_t index = 0;
31 args->SetNull(index++);
32 args->SetInt(index++, 5);
33 args->SetDouble(index++, 10.543);
34 args->SetBool(index++, true);
35 args->SetString(index++, "test string");
36 args->SetList(index++, args->Copy());
37
38 EXPECT_EQ(index, args->GetSize());
39
40 return msg;
41 }
42
43 // Renderer side.
44 class SendRecvRendererTest : public ClientAppRenderer::Delegate {
45 public:
SendRecvRendererTest()46 SendRecvRendererTest() {}
47
OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefProcessId source_process,CefRefPtr<CefProcessMessage> message)48 bool OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,
49 CefRefPtr<CefBrowser> browser,
50 CefRefPtr<CefFrame> frame,
51 CefProcessId source_process,
52 CefRefPtr<CefProcessMessage> message) override {
53 if (message->GetName() == kSendRecvMsg) {
54 EXPECT_TRUE(browser.get());
55 EXPECT_TRUE(frame.get());
56 EXPECT_EQ(PID_BROWSER, source_process);
57 EXPECT_TRUE(message.get());
58
59 const std::string& url = frame->GetURL();
60 if (url == kSendRecvUrl) {
61 // Echo the message back to the sender natively.
62 frame->SendProcessMessage(PID_BROWSER, message);
63 return true;
64 }
65 }
66
67 // Message not handled.
68 return false;
69 }
70
71 IMPLEMENT_REFCOUNTING(SendRecvRendererTest);
72 };
73
74 // Browser side.
75 class SendRecvTestHandler : public TestHandler {
76 public:
SendRecvTestHandler(cef_thread_id_t send_thread)77 explicit SendRecvTestHandler(cef_thread_id_t send_thread)
78 : send_thread_(send_thread) {}
79
RunTest()80 void RunTest() override {
81 message_ = CreateTestMessage();
82
83 AddResource(kSendRecvUrl, "<html><body>TEST</body></html>", "text/html");
84 CreateBrowser(kSendRecvUrl);
85
86 // Time out the test after a reasonable period of time.
87 SetTestTimeout();
88 }
89
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)90 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
91 CefRefPtr<CefFrame> frame,
92 int httpStatusCode) override {
93 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
94
95 // Send the message to the renderer process.
96 if (!CefCurrentlyOn(send_thread_)) {
97 CefPostTask(send_thread_, base::Bind(&SendRecvTestHandler::SendMessage,
98 this, browser, frame));
99 } else {
100 SendMessage(browser, frame);
101 }
102 }
103
OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefProcessId source_process,CefRefPtr<CefProcessMessage> message)104 bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
105 CefRefPtr<CefFrame> frame,
106 CefProcessId source_process,
107 CefRefPtr<CefProcessMessage> message) override {
108 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
109 EXPECT_TRUE(browser.get());
110 EXPECT_TRUE(frame.get());
111 EXPECT_EQ(PID_RENDERER, source_process);
112 EXPECT_TRUE(message.get());
113 EXPECT_TRUE(message->IsReadOnly());
114
115 // Verify that the recieved message is the same as the sent message.
116 TestProcessMessageEqual(message_, message);
117
118 got_message_.yes();
119
120 // Test is complete.
121 DestroyTest();
122
123 return true;
124 }
125
126 protected:
DestroyTest()127 void DestroyTest() override {
128 EXPECT_TRUE(got_message_);
129 TestHandler::DestroyTest();
130 }
131
132 private:
SendMessage(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)133 void SendMessage(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame) {
134 EXPECT_TRUE(CefCurrentlyOn(send_thread_));
135 frame->SendProcessMessage(PID_RENDERER, message_);
136 }
137
138 cef_thread_id_t send_thread_;
139
140 CefRefPtr<CefProcessMessage> message_;
141 TrackCallback got_message_;
142
143 IMPLEMENT_REFCOUNTING(SendRecvTestHandler);
144 };
145
146 } // namespace
147
148 // Verify send from the UI thread and recieve.
TEST(ProcessMessageTest,SendRecvUI)149 TEST(ProcessMessageTest, SendRecvUI) {
150 CefRefPtr<SendRecvTestHandler> handler = new SendRecvTestHandler(TID_UI);
151 handler->ExecuteTest();
152 ReleaseAndWaitForDestructor(handler);
153 }
154
155 // Verify send from the IO thread and recieve.
TEST(ProcessMessageTest,SendRecvIO)156 TEST(ProcessMessageTest, SendRecvIO) {
157 CefRefPtr<SendRecvTestHandler> handler = new SendRecvTestHandler(TID_IO);
158 handler->ExecuteTest();
159 ReleaseAndWaitForDestructor(handler);
160 }
161
162 // Verify create.
TEST(ProcessMessageTest,Create)163 TEST(ProcessMessageTest, Create) {
164 CefRefPtr<CefProcessMessage> message =
165 CefProcessMessage::Create(kSendRecvMsg);
166 EXPECT_TRUE(message.get());
167 EXPECT_TRUE(message->IsValid());
168 EXPECT_FALSE(message->IsReadOnly());
169 EXPECT_STREQ(kSendRecvMsg, message->GetName().ToString().c_str());
170
171 CefRefPtr<CefListValue> args = message->GetArgumentList();
172 EXPECT_TRUE(args.get());
173 EXPECT_TRUE(args->IsValid());
174 EXPECT_TRUE(args->IsOwned());
175 EXPECT_FALSE(args->IsReadOnly());
176 }
177
178 // Verify copy.
TEST(ProcessMessageTest,Copy)179 TEST(ProcessMessageTest, Copy) {
180 CefRefPtr<CefProcessMessage> message = CreateTestMessage();
181 CefRefPtr<CefProcessMessage> message2 = message->Copy();
182 TestProcessMessageEqual(message, message2);
183 }
184
185 // Entry point for creating process message renderer test objects.
186 // Called from client_app_delegates.cc.
CreateProcessMessageRendererTests(ClientAppRenderer::DelegateSet & delegates)187 void CreateProcessMessageRendererTests(
188 ClientAppRenderer::DelegateSet& delegates) {
189 // For ProcessMessageTest.SendRecv
190 delegates.insert(new SendRecvRendererTest);
191 }
192