• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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