1// Copyright (c) 2012 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/browser/browser_plugin/browser_plugin_message_filter.h"
6
7#include "base/supports_user_data.h"
8#include "content/browser/browser_plugin/browser_plugin_guest.h"
9#include "content/browser/gpu/gpu_process_host.h"
10#include "content/browser/web_contents/web_contents_impl.h"
11#include "content/common/browser_plugin/browser_plugin_constants.h"
12#include "content/common/browser_plugin/browser_plugin_messages.h"
13#include "content/common/view_messages.h"
14#include "content/public/browser/browser_context.h"
15#include "content/public/browser/browser_plugin_guest_manager.h"
16#include "content/public/browser/browser_thread.h"
17#include "content/public/browser/render_view_host.h"
18
19namespace content {
20
21BrowserPluginMessageFilter::BrowserPluginMessageFilter(int render_process_id)
22    : BrowserMessageFilter(BrowserPluginMsgStart),
23      render_process_id_(render_process_id) {
24}
25
26BrowserPluginMessageFilter::~BrowserPluginMessageFilter() {
27  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
28}
29
30bool BrowserPluginMessageFilter::OnMessageReceived(
31    const IPC::Message& message) {
32  // Any message requested by a BrowserPluginGuest should be routed through
33  // a BrowserPluginGuestManager.
34  if (BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(message)) {
35    ForwardMessageToGuest(message);
36    // We always swallow messages destined for BrowserPluginGuestManager because
37    // we're on the UI thread and fallback code is expected to be run on the IO
38    // thread.
39    return true;
40  }
41  return false;
42}
43
44void BrowserPluginMessageFilter::OnDestruct() const {
45  BrowserThread::DeleteOnIOThread::Destruct(this);
46}
47
48void BrowserPluginMessageFilter::OverrideThreadForMessage(
49    const IPC::Message& message, BrowserThread::ID* thread) {
50  if (BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(message))
51    *thread = BrowserThread::UI;
52}
53
54void BrowserPluginMessageFilter::ForwardMessageToGuest(
55    const IPC::Message& message) {
56  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57  RenderViewHost* rvh = RenderViewHost::FromID(render_process_id_,
58                                               message.routing_id());
59  if (!rvh)
60    return;
61
62  WebContents* embedder_web_contents = WebContents::FromRenderViewHost(rvh);
63
64  int browser_plugin_instance_id = 0;
65  // All allowed messages must have instance_id as their first parameter.
66  PickleIterator iter(message);
67  bool success = iter.ReadInt(&browser_plugin_instance_id);
68  DCHECK(success);
69  WebContents* guest_web_contents =
70      embedder_web_contents->GetBrowserContext()
71          ->GetGuestManager()
72          ->GetGuestByInstanceID(embedder_web_contents,
73                                 browser_plugin_instance_id);
74  if (!guest_web_contents)
75    return;
76
77  static_cast<WebContentsImpl*>(guest_web_contents)
78      ->GetBrowserPluginGuest()
79      ->OnMessageReceivedFromEmbedder(message);
80}
81
82} // namespace content
83