browser_ppapi_host_impl.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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/renderer_host/pepper/browser_ppapi_host_impl.h"
6
7#include "content/browser/renderer_host/pepper/pepper_message_filter.h"
8#include "content/browser/tracing/trace_message_filter.h"
9#include "content/common/pepper_renderer_instance_data.h"
10#include "content/public/browser/render_view_host.h"
11#include "content/public/common/process_type.h"
12#include "ipc/ipc_message_macros.h"
13
14namespace content {
15
16// static
17BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess(
18    IPC::Sender* sender,
19    ppapi::PpapiPermissions permissions,
20    base::ProcessHandle plugin_child_process,
21    IPC::ChannelProxy* channel,
22    net::HostResolver* host_resolver,
23    int render_process_id,
24    int render_view_id,
25    const base::FilePath& profile_directory) {
26  // TODO(raymes): Figure out how to plumb plugin_name through for NaCl. It is
27  // currently only needed for PPB_Flash_File interfaces so it doesn't matter.
28  std::string plugin_name;
29  BrowserPpapiHostImpl* browser_ppapi_host =
30      new BrowserPpapiHostImpl(sender, permissions, plugin_name,
31                               profile_directory,
32                               true);
33  browser_ppapi_host->set_plugin_process_handle(plugin_child_process);
34
35  channel->AddFilter(
36      new PepperMessageFilter(permissions,
37                              host_resolver,
38                              render_process_id,
39                              render_view_id));
40  channel->AddFilter(browser_ppapi_host->message_filter());
41  channel->AddFilter(new TraceMessageFilter());
42
43  return browser_ppapi_host;
44}
45
46BrowserPpapiHostImpl::BrowserPpapiHostImpl(
47    IPC::Sender* sender,
48    const ppapi::PpapiPermissions& permissions,
49    const std::string& plugin_name,
50    const base::FilePath& profile_data_directory,
51    bool external_plugin)
52    : ppapi_host_(new ppapi::host::PpapiHost(sender, permissions)),
53      plugin_process_handle_(base::kNullProcessHandle),
54      plugin_name_(plugin_name),
55      profile_data_directory_(profile_data_directory),
56      external_plugin_(external_plugin) {
57  message_filter_ = new HostMessageFilter(ppapi_host_.get());
58  ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>(
59      new ContentBrowserPepperHostFactory(this)));
60}
61
62BrowserPpapiHostImpl::~BrowserPpapiHostImpl() {
63  // Notify the filter so it won't foward messages to us.
64  message_filter_->OnHostDestroyed();
65
66  // Delete the host explicitly first. This shutdown will destroy the
67  // resources, which may want to do cleanup in their destructors and expect
68  // their pointers to us to be valid.
69  ppapi_host_.reset();
70}
71
72ppapi::host::PpapiHost* BrowserPpapiHostImpl::GetPpapiHost() {
73  return ppapi_host_.get();
74}
75
76base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const {
77  // Handle should previously have been set before use.
78  DCHECK(plugin_process_handle_ != base::kNullProcessHandle);
79  return plugin_process_handle_;
80}
81
82bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
83  return instance_map_.find(instance) != instance_map_.end();
84}
85
86bool BrowserPpapiHostImpl::GetRenderViewIDsForInstance(
87    PP_Instance instance,
88    int* render_process_id,
89    int* render_view_id) const {
90  InstanceMap::const_iterator found = instance_map_.find(instance);
91  if (found == instance_map_.end()) {
92    *render_process_id = 0;
93    *render_view_id = 0;
94    return false;
95  }
96
97  *render_process_id = found->second.render_process_id;
98  *render_view_id = found->second.render_view_id;
99  return true;
100}
101
102const std::string& BrowserPpapiHostImpl::GetPluginName() {
103  return plugin_name_;
104}
105
106const base::FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() {
107  return profile_data_directory_;
108}
109
110GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) {
111  InstanceMap::const_iterator found = instance_map_.find(instance);
112  if (found == instance_map_.end())
113    return GURL();
114  return found->second.document_url;
115}
116
117GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) {
118  InstanceMap::const_iterator found = instance_map_.find(instance);
119  if (found == instance_map_.end())
120    return GURL();
121  return found->second.plugin_url;
122}
123
124void BrowserPpapiHostImpl::AddInstance(
125    PP_Instance instance,
126    const PepperRendererInstanceData& instance_data) {
127  DCHECK(instance_map_.find(instance) == instance_map_.end());
128  instance_map_[instance] = instance_data;
129}
130
131void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) {
132  InstanceMap::iterator found = instance_map_.find(instance);
133  if (found == instance_map_.end()) {
134    NOTREACHED();
135    return;
136  }
137  instance_map_.erase(found);
138}
139
140bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived(
141    const IPC::Message& msg) {
142  // Don't forward messages if our owner object has been destroyed.
143  if (!ppapi_host_)
144    return false;
145
146  /* TODO(brettw) when we add messages, here, the code should look like this:
147  bool handled = true;
148  IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl, msg)
149    // Add necessary message handlers here.
150    IPC_MESSAGE_UNHANDLED(handled = ppapi_host_->OnMessageReceived(msg))
151  IPC_END_MESSAGE_MAP();
152  return handled;
153  */
154  return ppapi_host_->OnMessageReceived(msg);
155}
156
157void BrowserPpapiHostImpl::HostMessageFilter::OnHostDestroyed() {
158  DCHECK(ppapi_host_);
159  ppapi_host_ = NULL;
160}
161
162}  // namespace content
163