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

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

Issue 10377170: Browser Plugin: browser process side changes (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Updated according to creis@ Created 8 years, 7 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_host.h"
6
7 #include "content/browser/renderer_host/render_view_host_impl.h"
8 #include "content/browser/web_contents/web_contents_impl.h"
9 #include "content/common/browser_plugin_messages.h"
10 #include "content/public/browser/notification_details.h"
11 #include "content/public/browser/notification_source.h"
12 #include "content/public/browser/notification_types.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/render_widget_host_view.h"
15 #include "content/public/browser/site_instance.h"
16 #include "content/public/browser/web_contents_view.h"
17 #include "ppapi/proxy/ppapi_messages.h"
18
19 namespace content {
20
21 BrowserPluginHost::BrowserPluginHost(
22 WebContentsImpl* web_contents)
23 : WebContentsObserver(web_contents),
24 embedder_(NULL),
25 instance_id_(0),
26 pending_render_view_host_(NULL) {
27 // Listen to visibility changes so that an embedder hides its guests
28 // as well.
29 registrar_.Add(this,
30 NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
31 Source<RenderViewHost>(
32 web_contents->GetRenderViewHost()));
Charlie Reis 2012/05/18 20:35:24 Just want to sanity check that we know this is the
Fady Samuel 2012/05/21 14:30:17 Using the new NOTIFICATION_WEB_CONTENTS_VISIBLITY_
33 }
34
35 BrowserPluginHost::~BrowserPluginHost() {
36 }
37
38 BrowserPluginHost* BrowserPluginHost::GetGuestByContainerID(int container_id) {
39 ContainerInstanceMap::const_iterator it =
40 guests_by_container_id_.find(container_id);
41 if (it != guests_by_container_id_.end())
42 return it->second;
43 return NULL;
44 }
45
46 void BrowserPluginHost::RegisterContainerInstance(
47 int container_id,
48 BrowserPluginHost* observer) {
49 DCHECK(guests_by_container_id_.find(container_id) ==
50 guests_by_container_id_.end());
51 guests_by_container_id_[container_id] = observer;
52 }
53
54 void BrowserPluginHost::OnCrossProcessNavigation(RenderViewHost* dest_rvh) {
55 if (web_contents()->GetRenderViewHost() != dest_rvh) {
56 pending_render_view_host_ = dest_rvh;
57 }
58 }
59
60
61 bool BrowserPluginHost::OnMessageReceived(const IPC::Message& message) {
62 bool handled = true;
63 IPC_BEGIN_MESSAGE_MAP(BrowserPluginHost, message)
64 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ConnectToChannel,
65 OnConnectToChannel)
66 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateFromGuest,
67 OnNavigateFromGuest)
68 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_MapInstance,
69 OnMapInstance)
70 IPC_MESSAGE_UNHANDLED(handled = false)
71 IPC_END_MESSAGE_MAP()
72 return handled;
73 }
74
75 void BrowserPluginHost::NavigateGuestFromEmbedder(
76 RenderViewHost* render_view_host,
77 int container_instance_id,
78 long long frame_id,
79 const std::string& src,
80 const gfx::Size& size) {
81 BrowserPluginHost* guest_observer =
82 GetGuestByContainerID(container_instance_id);
83 WebContentsImpl* guest_web_contents =
84 guest_observer ?
85 static_cast<WebContentsImpl*>(guest_observer->web_contents()): NULL;
86 if (!guest_observer) {
87 GURL url(src);
88 guest_web_contents =
89 static_cast<WebContentsImpl*>(
90 WebContents::Create(
91 web_contents()->GetBrowserContext(),
92 render_view_host->GetSiteInstance(),
93 MSG_ROUTING_NONE,
94 NULL, // base WebContents
95 NULL // session storage namespace
96 ));
97 guest_observer =
98 guest_web_contents->browser_plugin_host();
99 guest_observer->set_embedder(static_cast<WebContentsImpl*>(web_contents()));
100 guest_observer->set_instance_id(container_instance_id);
101 guest_observer->set_url(url);
Charlie Reis 2012/05/18 20:35:24 Does the observer need to know the url? The fewer
Fady Samuel 2012/05/21 14:30:17 Done. Initial size will go away in a subsequent pa
102 guest_observer->set_initial_size(size);
103 RegisterContainerInstance(container_instance_id, guest_observer);
104 AddGuest(guest_web_contents, frame_id);
105 }
106
107 guest_observer->web_contents()->SetDelegate(guest_observer);
108 guest_observer->web_contents()->GetController().LoadURL(
109 guest_observer->url(),
110 Referrer(),
111 PAGE_TRANSITION_AUTO_SUBFRAME,
112 std::string());
113 }
114
115 void BrowserPluginHost::OnNavigateFromGuest(
116 PP_Instance instance,
117 const std::string& src) {
118 DCHECK(embedder());
119 GURL url(src);
120 web_contents()->GetController().LoadURL(
121 url,
122 Referrer(),
123 PAGE_TRANSITION_AUTO_SUBFRAME,
124 std::string());
125 }
126
127 // TODO(fsamuel): This handler is all kinds of bad and could be racy.
Charlie Reis 2012/05/18 20:35:24 Please add more of an explanation why this is racy
Fady Samuel 2012/05/21 14:30:17 I don't think that's the issue. The problem here i
128 // The correct solution is probably to send
129 // "BrowserPluginMsg_CompleteNavigation" over the pepper channel to the guest
130 // and then have the guest send the browser "BrowserPluginHostMsg_ResizeGuest"
131 // to resize appropriately.
132 void BrowserPluginHost::OnMapInstance(int container_instance_id,
133 PP_Instance instance) {
134 BrowserPluginHost* guest_observer =
135 GetGuestByContainerID(container_instance_id);
136 WebContentsImpl* guest_web_contents =
137 static_cast<WebContentsImpl*>(guest_observer->web_contents());
138 RenderViewHost* rvh = guest_observer->pending_render_view_host() ?
139 guest_observer->pending_render_view_host() :
140 guest_web_contents->GetRenderViewHost();
141
142 guest_web_contents->GetView()->SizeContents(guest_observer->initial_size());
143
144 rvh->Send(new BrowserPluginMsg_CompleteNavigation(
145 rvh->GetRoutingID(),
146 instance));
147 }
148
149 void BrowserPluginHost::OnConnectToChannel(
150 const IPC::ChannelHandle& channel_handle) {
151 DCHECK(embedder());
152 // Tell the BrowserPlugin in the embedder that we're done and that it can
153 // begin using the guest renderer.
154 embedder()->GetRenderProcessHost()->Send(
Charlie Reis 2012/05/18 20:35:24 This looks unsafe as well, as does the GetPendingS
Fady Samuel 2012/05/21 14:30:17 Yes, the guest BrowserPluginHost can keep track of
155 new BrowserPluginMsg_LoadGuest(
156 instance_id(),
157 //embedder_web_contents->GetRenderProcessHost()->GetID(),
Charlie Reis 2012/05/18 20:35:24 Remove commented code.
Fady Samuel 2012/05/21 14:30:17 Done.
158 web_contents()->GetPendingSiteInstance()->GetProcess()->
159 GetID(),
160 channel_handle));
161 }
162
163 void BrowserPluginHost::AddGuest(WebContentsImpl* guest, int64 frame_id) {
164 guests_[guest] = frame_id;
165 }
166
167 void BrowserPluginHost::RemoveGuest(WebContentsImpl* guest) {
168 guests_.erase(guest);
169 }
170
171 void BrowserPluginHost::DestroyGuests() {
172 for (GuestMap::const_iterator it = guests_.begin();
173 it != guests_.end(); ++it) {
174 WebContentsImpl* web_contents = it->first;
175 delete web_contents;
176 }
177 guests_.clear();
178 guests_by_container_id_.clear();
179 }
180
181 void BrowserPluginHost::DidCommitProvisionalLoadForFrame(
182 int64 frame_id,
183 bool is_main_frame,
184 const GURL& url,
185 PageTransition transition_type,
186 RenderViewHost* render_view_host) {
187 // Clean-up guests that lie in the frame that we're navigating.
188 typedef std::set<WebContentsImpl*> GuestSet;
189 GuestSet guests_to_delete;
190 for (GuestMap::const_iterator it = guests_.begin();
191 it != guests_.end(); ++it) {
192 WebContentsImpl* web_contents = it->first;
193 if (it->second == frame_id) {
194 guests_to_delete.insert(web_contents);
195 }
196 }
197 for (GuestSet::const_iterator it = guests_to_delete.begin();
198 it != guests_to_delete.end(); ++it) {
199 delete *it;
200 guests_.erase(*it);
201 }
202 }
203
204 void BrowserPluginHost::RenderViewDeleted(RenderViewHost* render_view_host) {
205 // TODO(fsamuel): For some reason ToT hangs when killing a guest, this wasn't
206 // the case earlier. Presumably, when a guest is killed/crashes, one of
207 // RenderViewDeleted, RenderViewGone or WebContentsDestroyed will get called.
208 // At that point, we should remove reference to this BrowserPluginHost
209 // from its embedder, in addition to destroying its guests, to ensure
210 // that we do not attempt a double delete.
211 DestroyGuests();
212 }
213
214 void BrowserPluginHost::RenderViewGone(base::TerminationStatus status) {
215 DestroyGuests();
216 }
217
218 void BrowserPluginHost::WebContentsDestroyed(WebContents* web_contents) {
219 DestroyGuests();
220 }
221
222 void BrowserPluginHost::Observe(
223 int type,
224 const NotificationSource& source,
225 const NotificationDetails& details) {
226 DCHECK(type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED);
227 bool visible = *Details<bool>(details).ptr();
228
229 // If the embedder is hidden we need to hide the guests as well.
230 for (GuestMap::const_iterator it = guests_.begin();
231 it != guests_.end(); ++it) {
232 WebContentsImpl* web_contents = it->first;
233 if (visible)
234 web_contents->ShowContents();
235 else
236 web_contents->HideContents();
237 }
238 }
239
240 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698