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