1558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch// found in the LICENSE file.
4558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
5558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/host_dispatcher_wrapper.h"
6558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
7558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/common/view_messages.h"
8558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_hung_plugin_filter.h"
9558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_plugin_instance_impl.h"
10558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/pepper_proxy_channel_delegate_impl.h"
11558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/plugin_module.h"
12558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/renderer_ppapi_host_impl.h"
13558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "content/renderer/pepper/renderer_restrict_dispatch_group.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/renderer/render_frame_impl.h"
15558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
16558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochnamespace content {
17558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
18558790d6acca3451cf3a6b497803a5f07d0bec58Ben MurdochHostDispatcherWrapper::HostDispatcherWrapper(
19558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    PluginModule* module,
20558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    base::ProcessId peer_pid,
21558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    int plugin_child_id,
22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    const ppapi::PpapiPermissions& perms,
23558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    bool is_external)
24558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    : module_(module),
25558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      peer_pid_(peer_pid),
26558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      plugin_child_id_(plugin_child_id),
27558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      permissions_(perms),
28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      is_external_(is_external) {}
29558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
30a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochHostDispatcherWrapper::~HostDispatcherWrapper() {}
31558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
32558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochbool HostDispatcherWrapper::Init(const IPC::ChannelHandle& channel_handle,
33558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                 PP_GetInterface_Func local_get_interface,
34558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                 const ppapi::Preferences& preferences,
3534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)                                 scoped_refptr<PepperHungPluginFilter> filter) {
36558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (channel_handle.name.empty())
37558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return false;
38558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
39558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#if defined(OS_POSIX)
40558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  DCHECK_NE(-1, channel_handle.socket.fd);
41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (channel_handle.socket.fd == -1)
42558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return false;
43558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#endif
44558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
45558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  dispatcher_delegate_.reset(new PepperProxyChannelDelegateImpl);
46558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  dispatcher_.reset(new ppapi::proxy::HostDispatcher(
4734680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)      module_->pp_module(), local_get_interface, permissions_));
4834680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  // The HungPluginFilter needs to know when we are blocked on a sync message
4934680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  // to the plugin. Note the filter outlives the dispatcher, so there is no
5034680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  // need to remove it as an observer.
5134680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  dispatcher_->AddSyncMessageStatusObserver(filter.get());
5234680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  // Guarantee the hung_plugin_filter_ outlives |dispatcher_|.
5334680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  hung_plugin_filter_ = filter;
54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (!dispatcher_->InitHostWithChannel(dispatcher_delegate_.get(),
56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                        peer_pid_,
57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                        channel_handle,
58558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                        true,  // Client.
59558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                                        preferences)) {
60558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    dispatcher_.reset();
61558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    dispatcher_delegate_.reset();
62558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    return false;
63558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
6434680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  // HungPluginFilter needs to listen for some messages on the IO thread.
6534680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)  dispatcher_->AddIOThreadMessageFilter(filter);
6634680572440d7894ef8dafce81d8039ed80726a2Torne (Richard Coles)
67558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  dispatcher_->channel()->SetRestrictDispatchChannelGroup(
68558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      kRendererRestrictDispatchGroup_Pepper);
69558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return true;
70558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
71558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
72558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochconst void* HostDispatcherWrapper::GetProxiedInterface(const char* name) {
73558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  return dispatcher_->GetProxiedInterface(name);
74558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
75558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
76558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid HostDispatcherWrapper::AddInstance(PP_Instance instance) {
77558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ppapi::proxy::HostDispatcher::SetForInstance(instance, dispatcher_.get());
78558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
79558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  RendererPpapiHostImpl* host =
80558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      RendererPpapiHostImpl::GetForPPInstance(instance);
81558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // TODO(brettw) remove this null check when the old-style pepper-based
82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // browser tag is removed from this file. Getting this notification should
83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // always give us an instance we can find in the map otherwise, but that
84558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // isn't true for browser tag support.
85558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (host) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RenderFrame* render_frame = host->GetRenderFrameForInstance(instance);
87558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    PepperPluginInstance* plugin_instance = host->GetPluginInstance(instance);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    render_frame->Send(new ViewHostMsg_DidCreateOutOfProcessPepperInstance(
89558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        plugin_child_id_,
90558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        instance,
91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        PepperRendererInstanceData(
92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            0,  // The render process id will be supplied in the browser.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            render_frame->GetRoutingID(),
94f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)            host->GetDocumentURL(instance),
95558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch            plugin_instance->GetPluginURL()),
96558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        is_external_));
97558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
98558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
99558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
100558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochvoid HostDispatcherWrapper::RemoveInstance(PP_Instance instance) {
101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  ppapi::proxy::HostDispatcher::RemoveForInstance(instance);
102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  RendererPpapiHostImpl* host =
104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      RendererPpapiHostImpl::GetForPPInstance(instance);
105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  // TODO(brettw) remove null check as described in AddInstance.
106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  if (host) {
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RenderFrame* render_frame = host->GetRenderFrameForInstance(instance);
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (render_frame) {
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      render_frame->Send(new ViewHostMsg_DidDeleteOutOfProcessPepperInstance(
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          plugin_child_id_, instance, is_external_));
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
112558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  }
113558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}
114558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch
115558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch}  // namespace content
116