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