browser_ppapi_host_impl.cc revision 2385ea399aae016c0806a4f9ef3c9cfe3d2a39df
1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/tracing/trace_message_filter.h"
83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/common/pepper_renderer_instance_data.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/public/common/process_type.h"
113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ipc/ipc_message_macros.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace content {
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// static
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess(
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC::Sender* sender,
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ppapi::PpapiPermissions permissions,
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::ProcessHandle plugin_child_process,
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    IPC::ChannelProxy* channel,
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    net::HostResolver* host_resolver,
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int render_process_id,
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    int render_view_id,
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::FilePath& profile_directory) {
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<PepperMessageFilter> pepper_message_filter(
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new PepperMessageFilter(permissions,
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              host_resolver,
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              render_process_id,
29                              render_view_id));
30
31  // The plugin name and path shouldn't be needed for external plugins.
32  BrowserPpapiHostImpl* browser_ppapi_host =
33      new BrowserPpapiHostImpl(sender, permissions, std::string(),
34                               base::FilePath(), profile_directory, true,
35                               pepper_message_filter);
36  browser_ppapi_host->set_plugin_process_handle(plugin_child_process);
37
38  channel->AddFilter(pepper_message_filter);
39  channel->AddFilter(browser_ppapi_host->message_filter().get());
40  channel->AddFilter(new TraceMessageFilter());
41
42  return browser_ppapi_host;
43}
44
45BrowserPpapiHostImpl::BrowserPpapiHostImpl(
46    IPC::Sender* sender,
47    const ppapi::PpapiPermissions& permissions,
48    const std::string& plugin_name,
49    const base::FilePath& plugin_path,
50    const base::FilePath& profile_data_directory,
51    bool external_plugin,
52    const scoped_refptr<PepperMessageFilter>& pepper_message_filter)
53    : ppapi_host_(new ppapi::host::PpapiHost(sender, permissions)),
54      plugin_process_handle_(base::kNullProcessHandle),
55      plugin_name_(plugin_name),
56      plugin_path_(plugin_path),
57      profile_data_directory_(profile_data_directory),
58      external_plugin_(external_plugin) {
59  message_filter_ = new HostMessageFilter(ppapi_host_.get());
60  ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>(
61      new ContentBrowserPepperHostFactory(this, pepper_message_filter)));
62}
63
64BrowserPpapiHostImpl::~BrowserPpapiHostImpl() {
65  // Notify the filter so it won't foward messages to us.
66  message_filter_->OnHostDestroyed();
67
68  // Delete the host explicitly first. This shutdown will destroy the
69  // resources, which may want to do cleanup in their destructors and expect
70  // their pointers to us to be valid.
71  ppapi_host_.reset();
72}
73
74ppapi::host::PpapiHost* BrowserPpapiHostImpl::GetPpapiHost() {
75  return ppapi_host_.get();
76}
77
78base::ProcessHandle BrowserPpapiHostImpl::GetPluginProcessHandle() const {
79  // Handle should previously have been set before use.
80  DCHECK(plugin_process_handle_ != base::kNullProcessHandle);
81  return plugin_process_handle_;
82}
83
84bool BrowserPpapiHostImpl::IsValidInstance(PP_Instance instance) const {
85  return instance_map_.find(instance) != instance_map_.end();
86}
87
88bool BrowserPpapiHostImpl::GetRenderViewIDsForInstance(
89    PP_Instance instance,
90    int* render_process_id,
91    int* render_view_id) const {
92  InstanceMap::const_iterator found = instance_map_.find(instance);
93  if (found == instance_map_.end()) {
94    *render_process_id = 0;
95    *render_view_id = 0;
96    return false;
97  }
98
99  *render_process_id = found->second.render_process_id;
100  *render_view_id = found->second.render_view_id;
101  return true;
102}
103
104const std::string& BrowserPpapiHostImpl::GetPluginName() {
105  return plugin_name_;
106}
107
108const base::FilePath& BrowserPpapiHostImpl::GetPluginPath() {
109  return plugin_path_;
110}
111
112const base::FilePath& BrowserPpapiHostImpl::GetProfileDataDirectory() {
113  return profile_data_directory_;
114}
115
116GURL BrowserPpapiHostImpl::GetDocumentURLForInstance(PP_Instance instance) {
117  InstanceMap::const_iterator found = instance_map_.find(instance);
118  if (found == instance_map_.end())
119    return GURL();
120  return found->second.document_url;
121}
122
123GURL BrowserPpapiHostImpl::GetPluginURLForInstance(PP_Instance instance) {
124  InstanceMap::const_iterator found = instance_map_.find(instance);
125  if (found == instance_map_.end())
126    return GURL();
127  return found->second.plugin_url;
128}
129
130void BrowserPpapiHostImpl::AddInstance(
131    PP_Instance instance,
132    const PepperRendererInstanceData& instance_data) {
133  DCHECK(instance_map_.find(instance) == instance_map_.end());
134  instance_map_[instance] = instance_data;
135}
136
137void BrowserPpapiHostImpl::DeleteInstance(PP_Instance instance) {
138  InstanceMap::iterator found = instance_map_.find(instance);
139  if (found == instance_map_.end()) {
140    NOTREACHED();
141    return;
142  }
143  instance_map_.erase(found);
144}
145
146bool BrowserPpapiHostImpl::HostMessageFilter::OnMessageReceived(
147    const IPC::Message& msg) {
148  // Don't forward messages if our owner object has been destroyed.
149  if (!ppapi_host_)
150    return false;
151
152  /* TODO(brettw) when we add messages, here, the code should look like this:
153  bool handled = true;
154  IPC_BEGIN_MESSAGE_MAP(BrowserPpapiHostImpl, msg)
155    // Add necessary message handlers here.
156    IPC_MESSAGE_UNHANDLED(handled = ppapi_host_->OnMessageReceived(msg))
157  IPC_END_MESSAGE_MAP();
158  return handled;
159  */
160  return ppapi_host_->OnMessageReceived(msg);
161}
162
163void BrowserPpapiHostImpl::HostMessageFilter::OnHostDestroyed() {
164  DCHECK(ppapi_host_);
165  ppapi_host_ = NULL;
166}
167
168}  // namespace content
169