12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/bind_helpers.h"
79ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h"
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/run_loop.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_errors.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/host_message_context.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/resource_host.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/resource_message_filter.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ppapi {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace host {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::WaitableEvent g_handler_completion(true, false);
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)enum TestMessageTypes {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MSG1_TYPE = 1,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MSG2_TYPE,
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MSG3_TYPE,
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  REPLY_MSG1_TYPE,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  REPLY_MSG2_TYPE,
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  REPLY_MSG3_TYPE,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Dummy resource host which simply stores a copy of messages it handles.
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// |SendReply| is overridden to store a copy of the outgoing message and the
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// message loop on which it was sent.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MyResourceHost : public ResourceHost {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Messages of type |msg_type| will be handled (simply by replying with a
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // message of type |reply_msg_type|).
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MyResourceHost(PpapiHost* host,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 PP_Instance instance,
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 PP_Resource resource,
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 uint32 msg_type,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 uint32 reply_msg_type)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : ResourceHost(host, instance, resource),
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        msg_type_(msg_type),
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reply_msg_type_(reply_msg_type),
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        last_reply_message_loop_(NULL) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const IPC::Message& last_handled_msg() const { return last_handled_msg_; }
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const IPC::Message& last_reply_msg() const { return last_reply_msg_; }
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop* last_reply_message_loop() const {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return last_reply_message_loop_;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddMessageFilter(scoped_refptr<ResourceMessageFilter> filter) {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddFilter(filter);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual int32_t OnResourceMessageReceived(
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const IPC::Message& msg,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostMessageContext* context) OVERRIDE {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_handled_msg_ = msg;
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (msg.type() == msg_type_) {
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      context->reply_msg = IPC::Message(0, reply_msg_type_,
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                        IPC::Message::PRIORITY_NORMAL);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return PP_OK;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_FAILED;
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SendReply(const ReplyMessageContext& context,
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         const IPC::Message& msg) OVERRIDE {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_reply_msg_ = msg;
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_reply_message_loop_ = base::MessageLoop::current();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    g_handler_completion.Signal();
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 msg_type_;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 reply_msg_type_;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC::Message last_handled_msg_;
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC::Message last_reply_msg_;
87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop* last_reply_message_loop_;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Dummy message filter which simply stores a copy of messages it handles.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The message loop on which the message is handled is also stored for checking
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// later.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MyResourceFilter : public ResourceMessageFilter {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Messages of type |msg_type| will be handled (simply by replying with a
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // message of type |reply_msg_type|). |io_thread| is the thread on which
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // replies should be sent. |bg_thread| is the thread on which the message
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // should be handled.
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MyResourceFilter(const base::Thread& io_thread,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   const base::Thread& bg_thread,
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   uint32 msg_type,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   uint32 reply_msg_type)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : ResourceMessageFilter(io_thread.message_loop_proxy()),
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        message_loop_proxy_(bg_thread.message_loop_proxy()),
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        msg_type_(msg_type),
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        reply_msg_type_(reply_msg_type),
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        last_message_loop_(NULL) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const IPC::Message& last_handled_msg() const { return last_handled_msg_; }
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop* last_message_loop() const { return last_message_loop_; }
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage(
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const IPC::Message& msg) OVERRIDE {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (msg.type() == msg_type_)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return message_loop_proxy_;
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return NULL;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual int32_t OnResourceMessageReceived(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const IPC::Message& msg,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      HostMessageContext* context) OVERRIDE {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    last_handled_msg_ = msg;
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    last_message_loop_ = base::MessageLoop::current();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (msg.type() == msg_type_) {
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      context->reply_msg = IPC::Message(0, reply_msg_type_,
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                        IPC::Message::PRIORITY_NORMAL);
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return PP_OK;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return PP_ERROR_FAILED;
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> message_loop_proxy_;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 msg_type_;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  uint32 reply_msg_type_;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  IPC::Message last_handled_msg_;
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::MessageLoop* last_message_loop_;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class ResourceMessageFilterTest : public testing::Test {
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) public:
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void TestHandleMessageImpl() {
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Thread io_thread("test_io_thread");
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(io_thread.Start());
149f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Thread bg_thread1("test_background_thread1");
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(bg_thread1.Start());
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<MyResourceFilter> filter1 =
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MyResourceFilter(io_thread, bg_thread1, MSG1_TYPE, REPLY_MSG1_TYPE);
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    base::Thread bg_thread2("test_background_thread2");
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ASSERT_TRUE(bg_thread2.Start());
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    scoped_refptr<MyResourceFilter> filter2 =
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        new MyResourceFilter(io_thread, bg_thread2, MSG2_TYPE, REPLY_MSG2_TYPE);
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PP_Instance instance = 12345;
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    PP_Resource resource = 67890;
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    MyResourceHost host(NULL, instance, resource, MSG3_TYPE, REPLY_MSG3_TYPE);
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host.AddMessageFilter(filter1);
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host.AddMessageFilter(filter2);
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    proxy::ResourceMessageCallParams params(resource, 1);
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    params.set_has_callback();
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    HostMessageContext context(params);
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC::Message message1(0, MSG1_TYPE, IPC::Message::PRIORITY_NORMAL);
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC::Message message2(0, MSG2_TYPE, IPC::Message::PRIORITY_NORMAL);
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    IPC::Message message3(0, MSG3_TYPE, IPC::Message::PRIORITY_NORMAL);
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Message 1 handled by the first filter.
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host.HandleMessage(message1, &context);
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    g_handler_completion.Wait();
176f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(filter1->last_handled_msg().type(), message1.type());
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(filter1->last_message_loop(), bg_thread1.message_loop());
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(host.last_reply_msg().type(),
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              static_cast<uint32>(REPLY_MSG1_TYPE));
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(host.last_reply_message_loop(), io_thread.message_loop());
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    g_handler_completion.Reset();
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Message 2 handled by the second filter.
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host.HandleMessage(message2, &context);
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    g_handler_completion.Wait();
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(filter2->last_handled_msg().type(), message2.type());
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(filter2->last_message_loop(), bg_thread2.message_loop());
188f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(host.last_reply_msg().type(),
189f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              static_cast<uint32>(REPLY_MSG2_TYPE));
190f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(host.last_reply_message_loop(), io_thread.message_loop());
191f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    g_handler_completion.Reset();
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    // Message 3 handled by the resource host.
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    host.HandleMessage(message3, &context);
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(host.last_handled_msg().type(), message3.type());
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    EXPECT_EQ(host.last_reply_msg().type(),
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              static_cast<uint32>(REPLY_MSG3_TYPE));
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    io_thread.Stop();
200f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bg_thread1.Stop();
201f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    bg_thread2.Stop();
202f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
203f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)};
204f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test that messages are filtered correctly and handlers are run on the correct
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// threads.
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(ResourceMessageFilterTest, TestHandleMessage) {
208f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // ResourceMessageFilter instances need to be created on a thread with message
209f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // loop. Therefore, we create a message loop and run the testing logic as a
210f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // task on it.
211f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::MessageLoop main_message_loop;
212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // It should be safe to use base::Unretained() because the object won't be
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // destroyed before the task is run.
215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  main_message_loop.PostTask(
216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      FROM_HERE,
217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      base::Bind(&ResourceMessageFilterTest::TestHandleMessageImpl,
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                 base::Unretained(this)));
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
220f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  base::RunLoop().RunUntilIdle();
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace proxy
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace ppapi
225