Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(142)

Side by Side Diff: content/browser/browser_plugin/browser_plugin_web_contents_observer.cc

Issue 9924026: Browser side implementation of browser plugin (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixed comments in browser_plugin_messages.h Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/browser_plugin/browser_plugin_web_contents_observer.h"
6
7 #include "base/lazy_instance.h"
8 #include "content/browser/renderer_host/render_view_host_impl.h"
9 #include "content/browser/tab_contents/tab_contents.h"
10 #include "content/common/browser_plugin/browser_plugin_messages.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/notification_details.h"
13 #include "content/public/browser/notification_source.h"
14 #include "content/public/browser/notification_types.h"
15 #include "content/public/browser/render_process_host.h"
16 #include "content/public/browser/render_widget_host.h"
17 #include "content/public/browser/render_widget_host_view.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/site_instance.h"
20 #include "content/public/browser/web_contents.h"
21 #include "ppapi/proxy/ppapi_messages.h"
22
23 namespace content {
24
25 BrowserPluginWebContentsObserver::BrowserPluginWebContentsObserver(
26 TabContents* tab_contents)
27 : WebContentsObserver(tab_contents),
28 host_(NULL),
29 instance_id_(0) {
30 registrar_.Add(this,
31 NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
32 Source<RenderViewHost>(
33 tab_contents->GetRenderViewHost()));
34 }
35
36 BrowserPluginWebContentsObserver::~BrowserPluginWebContentsObserver() {
37 }
38
39 bool BrowserPluginWebContentsObserver::OnMessageReceived(
40 const IPC::Message& message) {
41 bool handled = true;
42 IPC_BEGIN_MESSAGE_MAP(BrowserPluginWebContentsObserver, message)
43 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ChannelCreated,
44 OnRendererPluginChannelCreated)
45 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_OpenChannel,
46 OnOpenChannelToBrowserPlugin)
47 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_GuestReady, OnGuestReady)
48 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ResizeGuest, OnResizeGuest)
49 IPC_MESSAGE_UNHANDLED(handled = false)
50 IPC_END_MESSAGE_MAP_EX()
51 return handled;
52 }
53
54 void BrowserPluginWebContentsObserver::OnGuestReady() {
55 // We only care about handling this message on guests.
56 if (!host())
57 return;
58
59 // The renderer is now ready to receive ppapi messages.
60 // Let's tell it create a channel with the embedder/host.
61 BrowserPluginMsg_CreateChannel* msg =
62 new BrowserPluginMsg_CreateChannel(
63 host()->GetRenderProcessHost()->GetHandle(),
64 host()->GetRenderProcessHost()->GetID());
65 msg->set_routing_id(web_contents()->GetRenderViewHost()->GetRoutingID());
66 // TODO(fsamuel): If we aren't able to successfully send this message
67 // to the guest then that probably means it crashed. Is there anything
68 // we can do that's cleaner than failing a check?
69 CHECK(Send(msg));
70 }
71
72 void BrowserPluginWebContentsObserver::OnResizeGuest(
73 int width, int height) {
74 // Tell the RenderWidgetHostView to adjust its size.
75 web_contents()->GetRenderViewHost()->GetView()->SetSize(
76 gfx::Size(width, height));
77 }
78
79 void BrowserPluginWebContentsObserver::OnOpenChannelToBrowserPlugin(
80 int instance_id,
81 long long frame_id,
82 const std::string& src,
83 const gfx::Size& size) {
84 BrowserContext* browser_context =
85 web_contents()->GetRenderViewHost()->GetProcess()->GetBrowserContext();
86 DCHECK(browser_context);
87
88 GURL url(src);
89 SiteInstance* site_instance =
90 SiteInstance::CreateForURL(
91 browser_context, url);
92 TabContents* guest_tab_contents =
93 static_cast<TabContents*>(
94 WebContents::Create(
95 browser_context,
96 site_instance,
97 MSG_ROUTING_NONE,
98 NULL, // base tab contents
99 NULL // session storage namespace
100 ));
101 // TODO(fsamuel): Set the WebContentsDelegate here.
102 RenderViewHostImpl* guest_render_view_host =
103 static_cast<RenderViewHostImpl*>(
104 guest_tab_contents->GetRenderViewHost());
105
106 // We need to make sure that the RenderViewHost knows that it's
107 // hosting a guest RenderView so that it informs the RenderView
108 // on a ViewMsg_New. Guest RenderViews will avoid compositing
109 // until a guest-to-host channel has been initialized.
110 guest_render_view_host->set_guest(true);
111
112 guest_tab_contents->GetController().LoadURL(
113 url,
114 Referrer(),
115 PAGE_TRANSITION_HOME_PAGE,
116 std::string());
117
118 guest_render_view_host->GetView()->SetSize(size);
119 BrowserPluginWebContentsObserver* guest_observer =
120 guest_tab_contents->browser_plugin_web_contents_observer();
121 guest_observer->set_host(static_cast<TabContents*>(web_contents()));
122 guest_observer->set_instance_id(instance_id);
123
124 AddGuest(guest_tab_contents, frame_id);
125 }
126
127 void BrowserPluginWebContentsObserver::OnRendererPluginChannelCreated(
128 const IPC::ChannelHandle& channel_handle) {
129 DCHECK(host());
130 // Prepare the handle to send to the renderer.
131 base::ProcessHandle plugin_process =
132 web_contents()->GetRenderProcessHost()->GetHandle();
133 #if defined(OS_WIN)
134 base::ProcessHandle renderer_process =
135 host()->GetRenderProcessHost()->GetHandle();
136 int renderer_id = host()->GetRenderProcessHost()->GetID();
137
138 base::ProcessHandle renderers_plugin_handle = NULL;
139 ::DuplicateHandle(::GetCurrentProcess(), plugin_process,
140 renderer_process, &renderers_plugin_handle,
141 0, FALSE, DUPLICATE_SAME_ACCESS);
142 #elif defined(OS_POSIX)
143 // Don't need to duplicate anything on POSIX since it's just a PID.
144 base::ProcessHandle renderers_plugin_handle = plugin_process;
145 #endif
146 // Tell the BrowserPLuginPlaceholder in the host that we're done
147 // and that it can begin using the guest renderer.
148 host()->GetRenderProcessHost()->Send(
149 new BrowserPluginMsg_GuestReady_ACK(
150 host()->GetRenderViewHost()->GetRoutingID(),
151 instance_id(),
152 renderers_plugin_handle,
153 channel_handle));
154 }
155
156 void BrowserPluginWebContentsObserver::AddGuest(
157 TabContents* guest,
158 int64 frame_id) {
159 guests_[guest] = frame_id;
160 }
161
162 void BrowserPluginWebContentsObserver::RemoveGuest(TabContents* guest) {
163 guests_.erase(guest);
164 }
165
166 void BrowserPluginWebContentsObserver::DestroyGuests() {
167 for (GuestMap::const_iterator it = guests_.begin();
168 it != guests_.end(); ++it) {
169 const TabContents* contents = it->first;
170 delete contents;
171 }
172 guests_.clear();
173 }
174
175 void BrowserPluginWebContentsObserver::DidCommitProvisionalLoadForFrame(
176 int64 frame_id,
177 bool is_main_frame,
178 const GURL& url,
179 PageTransition transition_type) {
180 typedef std::set<TabContents*> GuestSet;
181 GuestSet guests_to_delete;
182 for (GuestMap::const_iterator it = guests_.begin();
183 it != guests_.end(); ++it) {
184 TabContents* contents = it->first;
185 if (it->second == frame_id) {
186 guests_to_delete.insert(contents);
187 }
188 }
189 for (GuestSet::const_iterator it = guests_to_delete.begin();
190 it != guests_to_delete.end(); ++it) {
191 delete *it;
192 guests_.erase(*it);
193 }
194 }
195
196 void BrowserPluginWebContentsObserver::RenderViewDeleted(
197 RenderViewHost* render_view_host) {
198 DestroyGuests();
199 }
200
201 void BrowserPluginWebContentsObserver::RenderViewGone(
202 base::TerminationStatus status) {
203 DestroyGuests();
204 }
205
206 void BrowserPluginWebContentsObserver::WebContentsDestroyed(
207 WebContents* web_contents) {
208 DestroyGuests();
209 }
210
211 void BrowserPluginWebContentsObserver::Observe(
212 int type,
213 const NotificationSource& source,
214 const NotificationDetails& details) {
215 DCHECK(type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED);
216 bool visible = *Details<bool>(details).ptr();
217
218 // If the host is hidden we need to hide the guests as well.
219 for (GuestMap::const_iterator it = guests_.begin();
220 it != guests_.end(); ++it) {
221 TabContents* contents = it->first;
222 if (visible)
223 contents->ShowContents();
224 else
225 contents->HideContents();
226 }
227 }
228
229 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698