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

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: Updated message names 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/common/view_messages.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/notification_details.h"
12 #include "content/public/browser/notification_source.h"
13 #include "content/public/browser/notification_types.h"
14 #include "content/public/browser/render_process_host.h"
15 #include "content/public/browser/render_widget_host.h"
16 #include "content/public/browser/render_widget_host_view.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/site_instance.h"
19 #include "content/public/browser/web_contents.h"
20 #include "ppapi/proxy/ppapi_messages.h"
21
22 typedef std::map<content::WebContents*,
23 content::BrowserPluginWebContentsObserver*> Instances;
24
25 namespace {
26 base::LazyInstance<Instances>::Leaky g_instances = LAZY_INSTANCE_INITIALIZER;
27 } // namespace
28
29 namespace content {
30
31 // static
32 BrowserPluginWebContentsObserver*
33 BrowserPluginWebContentsObserver::Get(
34 WebContents* web_contents) {
35 Instances::iterator it = g_instances.Get().find(web_contents);
36 if (it != g_instances.Get().end())
37 return it->second;
38 return new BrowserPluginWebContentsObserver(web_contents);
39 }
40
41 BrowserPluginWebContentsObserver::BrowserPluginWebContentsObserver(
42 WebContents* web_contents)
43 : WebContentsObserver(web_contents),
44 host_(NULL),
45 instance_id_(0) {
46 registrar_.Add(this,
47 NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
48 Source<RenderViewHost>(
49 web_contents->GetRenderViewHost()));
50 g_instances.Get()[web_contents] = this;
51 }
52
53 BrowserPluginWebContentsObserver::~BrowserPluginWebContentsObserver() {
54 g_instances.Get().erase(web_contents());
55 }
56
57 bool BrowserPluginWebContentsObserver::OnMessageReceived(
58 const IPC::Message& message) {
59 bool handled = true;
60 IPC_BEGIN_MESSAGE_MAP(BrowserPluginWebContentsObserver, message)
61 IPC_MESSAGE_HANDLER(PpapiHostMsg_ChannelCreated,
62 OnRendererPluginChannelCreated)
63 IPC_MESSAGE_HANDLER(ViewHostMsg_OpenChannelToBrowserPlugin,
64 OnOpenChannelToBrowserPlugin)
65 IPC_MESSAGE_HANDLER(ViewHostMsg_GuestReady, OnMsgGuestReady)
66 IPC_MESSAGE_HANDLER(ViewHostMsg_ResizeGuest, OnMsgResizeGuest)
67 IPC_MESSAGE_UNHANDLED(handled = false)
68 IPC_END_MESSAGE_MAP_EX()
69 return handled;
70 }
71
72 void BrowserPluginWebContentsObserver::OnMsgGuestReady() {
jam 2012/04/04 00:54:45 nit: just name handlers OnFoo, no need for "OnMsgF
Fady Samuel 2012/04/04 16:45:40 Done.
73 // We only care about handling this message on guests.
74 if (!host())
75 return;
76
77 // The renderer is now ready to receive ppapi messages.
78 // Let's tell it create a channel with the embedder/host.
79 PpapiMsg_CreateChannel* msg =
80 new PpapiMsg_CreateChannel(host()->GetRenderProcessHost()->GetHandle(),
81 host()->GetRenderProcessHost()->GetID());
82 msg->set_routing_id(web_contents()->GetRenderViewHost()->GetRoutingID());
83 msg->set_unblock(true);
jam 2012/04/04 00:54:45 are you sure you want this (set the unblock flag)?
Fady Samuel 2012/04/04 16:45:40 I believe you're right, I don't want the set_unblo
jam 2012/04/04 21:07:19 ping. are you sure you need this? check the docume
Fady Samuel 2012/04/05 19:35:40 Removed.
84 // TODO(fsamuel): If we aren't able to successfully send this message
85 // to the guest then that probably means it crashed. Is there anything
86 // we can do that's cleaner than failing a check?
87 CHECK(Send(msg));
88 }
89
90 void BrowserPluginWebContentsObserver::OnMsgResizeGuest(
91 int width, int height) {
92 // Tell the RenderWidgetHostView to adjust its size.
93 web_contents()->GetRenderViewHost()->GetView()->SetSize(
94 gfx::Size(width, height));
95 }
96
97 void BrowserPluginWebContentsObserver::OnOpenChannelToBrowserPlugin(
98 int instance_id,
99 long long frame_id,
100 const std::string& src,
101 const gfx::Size& size) {
102 BrowserContext* browser_context =
103 web_contents()->GetRenderViewHost()->GetProcess()->GetBrowserContext();
104 DCHECK(browser_context);
105
106 GURL url(src);
107 SiteInstance* site_instance =
108 SiteInstance::CreateForURL(
109 browser_context, url);
110 WebContents* guest_web_contents =
111 WebContents::Create(
112 browser_context,
113 site_instance,
114 MSG_ROUTING_NONE,
115 NULL, // base tab contents
116 NULL // session storage namespace
117 );
118 // TODO(fsamuel): Set the WebContentsDelegate here.
119 RenderViewHostImpl* guest_render_view_host =
120 static_cast<RenderViewHostImpl*>(
121 guest_web_contents->GetRenderViewHost());
122
123 // We need to make sure that the RenderViewHost knows that it's
124 // hosting a guest RenderView so that it informs the RenderView
125 // on a ViewMsg_New. Guest RenderViews will avoid compositing
126 // until a guest-to-host channel has been initialized.
127 guest_render_view_host->set_guest(true);
128
129 guest_web_contents->GetController().LoadURL(
130 url,
131 Referrer(),
132 PAGE_TRANSITION_HOME_PAGE,
133 std::string());
134
135 guest_render_view_host->GetView()->SetSize(size);
136 BrowserPluginWebContentsObserver* guest_observer = Get(guest_web_contents);
137 guest_observer->set_host(web_contents());
138 guest_observer->set_instance_id(instance_id);
139
140 AddGuest(guest_web_contents, frame_id);
141 }
142
143 // Called when a new plugin <--> renderer channel has been created.
jam 2012/04/04 00:54:45 nit: no need to document message handlers above th
Fady Samuel 2012/04/04 16:45:40 Done.
144 void BrowserPluginWebContentsObserver::OnRendererPluginChannelCreated(
145 const IPC::ChannelHandle& channel_handle) {
146 DCHECK(host());
147 // Prepare the handle to send to the renderer.
148 base::ProcessHandle plugin_process =
149 web_contents()->GetRenderProcessHost()->GetHandle();
150 #if defined(OS_WIN)
151 base::ProcessHandle renderer_process =
152 host()->GetRenderProcessHost()->GetHandle();
153 int renderer_id = host()->GetRenderProcessHost()->GetID();
154
155 base::ProcessHandle renderers_plugin_handle = NULL;
156 ::DuplicateHandle(::GetCurrentProcess(), plugin_process,
157 renderer_process, &renderers_plugin_handle,
158 0, FALSE, DUPLICATE_SAME_ACCESS);
159 #elif defined(OS_POSIX)
160 // Don't need to duplicate anything on POSIX since it's just a PID.
161 base::ProcessHandle renderers_plugin_handle = plugin_process;
162 #endif
163 // Tell the browser loading placeholder that we're done.
164 // and that it can begin using the guest renderer.
165 host()->GetRenderProcessHost()->Send(
166 new ViewMsg_GuestReady_ACK(
167 host()->GetRenderViewHost()->GetRoutingID(),
168 instance_id(),
169 renderers_plugin_handle,
170 channel_handle));
171 }
172
173 void BrowserPluginWebContentsObserver::AddGuest(
174 WebContents* guest,
175 int64 frame_id) {
176 guests_[guest] = frame_id;
177 }
178
179 void BrowserPluginWebContentsObserver::RemoveGuest(
180 WebContents* guest) {
181 guests_.erase(guest);
182 }
183
184 void BrowserPluginWebContentsObserver::DestroyGuests() {
185 for (GuestMap::const_iterator it = guests_.begin();
186 it != guests_.end(); ++it) {
187 const WebContents* contents = it->first;
188 delete contents;
189 }
190 guests_.clear();
191 }
192
193 void BrowserPluginWebContentsObserver::DidCommitProvisionalLoadForFrame(
194 int64 frame_id,
195 bool is_main_frame,
196 const GURL& url,
197 PageTransition transition_type) {
198 GuestSet guests_to_delete;
199 for (GuestMap::const_iterator it = guests_.begin();
200 it != guests_.end(); ++it) {
201 WebContents* contents = it->first;
202 if (it->second == frame_id) {
203 guests_to_delete.insert(contents);
204 }
205 }
206 for (GuestSet::const_iterator it = guests_to_delete.begin();
207 it != guests_to_delete.end(); ++it) {
208 delete *it;
209 guests_.erase(*it);
210 }
211 }
212
213 void BrowserPluginWebContentsObserver::RenderViewDeleted(
214 RenderViewHost* render_view_host) {
215 DestroyGuests();
216 }
217
218 void BrowserPluginWebContentsObserver::RenderViewGone(
219 base::TerminationStatus status) {
220 DestroyGuests();
221 }
222
223 void BrowserPluginWebContentsObserver::WebContentsDestroyed(
224 WebContents* web_contents) {
225 DestroyGuests();
226 }
227
228 void BrowserPluginWebContentsObserver::Observe(
229 int type,
230 const NotificationSource& source,
231 const NotificationDetails& details) {
232 DCHECK(type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED);
233 bool visible = *Details<bool>(details).ptr();
234
235 // If the host is hidden we need to hide the guests as well.
236 for (GuestMap::const_iterator it = guests_.begin();
237 it != guests_.end(); ++it) {
238 WebContents* contents = it->first;
239 if (visible)
240 contents->ShowContents();
241 else
242 contents->HideContents();
243 }
244 }
245
246 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698