1// Copyright 2013 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.
4
5#include "content/child/child_message_filter.h"
6
7#include "base/bind.h"
8#include "base/bind_helpers.h"
9#include "base/location.h"
10#include "base/task_runner.h"
11#include "content/child/child_thread.h"
12#include "content/child/thread_safe_sender.h"
13#include "ipc/message_filter.h"
14
15namespace content {
16
17class ChildMessageFilter::Internal : public IPC::MessageFilter {
18 public:
19  explicit Internal(ChildMessageFilter* filter) : filter_(filter) {}
20
21  virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE {
22    scoped_refptr<base::TaskRunner> runner =
23        filter_->OverrideTaskRunnerForMessage(msg);
24    if (runner.get() && !runner->RunsTasksOnCurrentThread()) {
25      if (!runner->PostTask(
26              FROM_HERE,
27              base::Bind(
28                  base::IgnoreResult(&ChildMessageFilter::OnMessageReceived),
29                  filter_, msg)))
30        filter_->OnStaleMessageReceived(msg);
31      return true;
32    }
33
34    return filter_->OnMessageReceived(msg);
35  }
36
37 private:
38  virtual ~Internal() {}
39  scoped_refptr<ChildMessageFilter> filter_;
40
41  DISALLOW_COPY_AND_ASSIGN(Internal);
42};
43
44bool ChildMessageFilter::Send(IPC::Message* message) {
45  return thread_safe_sender_->Send(message);
46}
47
48base::TaskRunner* ChildMessageFilter::OverrideTaskRunnerForMessage(
49    const IPC::Message& msg) {
50  return NULL;
51}
52
53ChildMessageFilter::ChildMessageFilter()
54    : internal_(NULL),
55      thread_safe_sender_(ChildThread::current()->thread_safe_sender()) {}
56
57ChildMessageFilter::~ChildMessageFilter() {}
58
59IPC::MessageFilter* ChildMessageFilter::GetFilter() {
60  if (!internal_)
61    internal_ = new Internal(this);
62  return internal_;
63}
64
65}  // namespace content
66