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_callback.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 EXPECT_TRUE(msg->IsValid());
27 EXPECT_FALSE(msg->IsReadOnly());
28
29 CefRefPtr<CefListValue> args = msg->GetArgumentList();
30 EXPECT_TRUE(args.get());
31 EXPECT_TRUE(args->IsValid());
32 EXPECT_FALSE(args->IsReadOnly());
33
34 size_t index = 0;
35 args->SetNull(index++);
36 args->SetInt(index++, 5);
37 args->SetDouble(index++, 10.543);
38 args->SetBool(index++, true);
39 args->SetString(index++, "test string");
40 args->SetList(index++, args->Copy());
41
42 EXPECT_EQ(index, args->GetSize());
43
44 return msg;
45 }
46
47 // Renderer side.
48 class SendRecvRendererTest : public ClientAppRenderer::Delegate {
49 public:
SendRecvRendererTest()50 SendRecvRendererTest() {}
51
OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefProcessId source_process,CefRefPtr<CefProcessMessage> message)52 bool OnProcessMessageReceived(CefRefPtr<ClientAppRenderer> app,
53 CefRefPtr<CefBrowser> browser,
54 CefRefPtr<CefFrame> frame,
55 CefProcessId source_process,
56 CefRefPtr<CefProcessMessage> message) override {
57 if (message->GetName() == kSendRecvMsg) {
58 EXPECT_TRUE(browser.get());
59 EXPECT_TRUE(frame.get());
60 EXPECT_EQ(PID_BROWSER, source_process);
61 EXPECT_TRUE(message.get());
62 EXPECT_TRUE(message->IsValid());
63 EXPECT_TRUE(message->IsReadOnly());
64
65 const std::string& url = frame->GetURL();
66 if (url == kSendRecvUrl) {
67 // Echo the message back to the sender natively.
68 frame->SendProcessMessage(PID_BROWSER, message);
69 EXPECT_FALSE(message->IsValid());
70 return true;
71 }
72 }
73
74 // Message not handled.
75 return false;
76 }
77
78 IMPLEMENT_REFCOUNTING(SendRecvRendererTest);
79 };
80
81 // Browser side.
82 class SendRecvTestHandler : public TestHandler {
83 public:
SendRecvTestHandler(cef_thread_id_t send_thread)84 explicit SendRecvTestHandler(cef_thread_id_t send_thread)
85 : send_thread_(send_thread) {}
86
RunTest()87 void RunTest() override {
88 AddResource(kSendRecvUrl, "<html><body>TEST</body></html>", "text/html");
89 CreateBrowser(kSendRecvUrl);
90
91 // Time out the test after a reasonable period of time.
92 SetTestTimeout();
93 }
94
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)95 void OnLoadEnd(CefRefPtr<CefBrowser> browser,
96 CefRefPtr<CefFrame> frame,
97 int httpStatusCode) override {
98 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
99
100 // Send the message to the renderer process.
101 if (!CefCurrentlyOn(send_thread_)) {
102 CefPostTask(send_thread_,
103 base::BindOnce(&SendRecvTestHandler::SendMessage, this,
104 browser, frame));
105 } else {
106 SendMessage(browser, frame);
107 }
108 }
109
OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,CefProcessId source_process,CefRefPtr<CefProcessMessage> message)110 bool OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
111 CefRefPtr<CefFrame> frame,
112 CefProcessId source_process,
113 CefRefPtr<CefProcessMessage> message) override {
114 EXPECT_TRUE(CefCurrentlyOn(TID_UI));
115 EXPECT_TRUE(browser.get());
116 EXPECT_TRUE(frame.get());
117 EXPECT_EQ(PID_RENDERER, source_process);
118 EXPECT_TRUE(message.get());
119 EXPECT_TRUE(message->IsValid());
120 EXPECT_TRUE(message->IsReadOnly());
121
122 // Verify that the recieved message is the same as the sent message.
123 TestProcessMessageEqual(CreateTestMessage(), message);
124
125 got_message_.yes();
126
127 // Test is complete.
128 DestroyTest();
129
130 return true;
131 }
132
133 protected:
DestroyTest()134 void DestroyTest() override {
135 EXPECT_TRUE(got_message_);
136 TestHandler::DestroyTest();
137 }
138
139 private:
SendMessage(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame)140 void SendMessage(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame) {
141 EXPECT_TRUE(CefCurrentlyOn(send_thread_));
142 auto message = CreateTestMessage();
143 frame->SendProcessMessage(PID_RENDERER, message);
144
145 // The message will be invalidated immediately, no matter what thread we
146 // send from.
147 EXPECT_FALSE(message->IsValid());
148 }
149
150 cef_thread_id_t send_thread_;
151 TrackCallback got_message_;
152
153 IMPLEMENT_REFCOUNTING(SendRecvTestHandler);
154 };
155
156 } // namespace
157
158 // Verify send from the UI thread and recieve.
TEST(ProcessMessageTest,SendRecvUI)159 TEST(ProcessMessageTest, SendRecvUI) {
160 CefRefPtr<SendRecvTestHandler> handler = new SendRecvTestHandler(TID_UI);
161 handler->ExecuteTest();
162 ReleaseAndWaitForDestructor(handler);
163 }
164
165 // Verify send from the IO thread and recieve.
TEST(ProcessMessageTest,SendRecvIO)166 TEST(ProcessMessageTest, SendRecvIO) {
167 CefRefPtr<SendRecvTestHandler> handler = new SendRecvTestHandler(TID_IO);
168 handler->ExecuteTest();
169 ReleaseAndWaitForDestructor(handler);
170 }
171
172 // Verify create.
TEST(ProcessMessageTest,Create)173 TEST(ProcessMessageTest, Create) {
174 CefRefPtr<CefProcessMessage> message =
175 CefProcessMessage::Create(kSendRecvMsg);
176 EXPECT_TRUE(message.get());
177 EXPECT_TRUE(message->IsValid());
178 EXPECT_FALSE(message->IsReadOnly());
179 EXPECT_STREQ(kSendRecvMsg, message->GetName().ToString().c_str());
180
181 CefRefPtr<CefListValue> args = message->GetArgumentList();
182 EXPECT_TRUE(args.get());
183 EXPECT_TRUE(args->IsValid());
184 EXPECT_FALSE(args->IsOwned());
185 EXPECT_FALSE(args->IsReadOnly());
186 }
187
188 // Verify copy.
TEST(ProcessMessageTest,Copy)189 TEST(ProcessMessageTest, Copy) {
190 CefRefPtr<CefProcessMessage> message = CreateTestMessage();
191 CefRefPtr<CefProcessMessage> message2 = message->Copy();
192 TestProcessMessageEqual(message, message2);
193 }
194
195 // Entry point for creating process message renderer test objects.
196 // Called from client_app_delegates.cc.
CreateProcessMessageRendererTests(ClientAppRenderer::DelegateSet & delegates)197 void CreateProcessMessageRendererTests(
198 ClientAppRenderer::DelegateSet& delegates) {
199 // For ProcessMessageTest.SendRecv
200 delegates.insert(new SendRecvRendererTest);
201 }
202