OLD | NEW |
---|---|
(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 registrar_.Add(this, | |
28 NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, | |
29 Source<RenderViewHost>( | |
30 web_contents->GetRenderViewHost())); | |
Charlie Reis
2012/05/17 21:24:05
This needs another space of indent.
Fady Samuel
2012/05/18 17:37:52
Done.
| |
31 } | |
32 | |
33 BrowserPluginHost::~BrowserPluginHost() { | |
34 } | |
35 | |
36 BrowserPluginHost* BrowserPluginHost::GetGuestByContainerID(int container_id) { | |
37 ContainerInstanceMap::const_iterator it = | |
38 guests_by_container_id_.find(container_id); | |
39 if (it != guests_by_container_id_.end()) | |
40 return it->second; | |
41 return NULL; | |
42 } | |
43 | |
44 void BrowserPluginHost::RegisterContainerInstance( | |
45 int container_id, | |
46 BrowserPluginHost* observer) { | |
47 DCHECK(guests_by_container_id_.find(container_id) == | |
48 guests_by_container_id_.end()); | |
49 guests_by_container_id_[container_id] = observer; | |
50 } | |
51 | |
52 void BrowserPluginHost::OnCrossProcessNavigation(RenderViewHost* dest_rvh) { | |
53 if (web_contents()->GetRenderViewHost() != dest_rvh) { | |
54 pending_render_view_host_ = dest_rvh; | |
55 } | |
56 } | |
57 | |
58 | |
59 bool BrowserPluginHost::OnMessageReceived(const IPC::Message& message) { | |
60 bool handled = true; | |
61 IPC_BEGIN_MESSAGE_MAP(BrowserPluginHost, message) | |
62 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ConnectToChannel, | |
63 OnConnectToChannel) | |
64 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateFromEmbedder, | |
65 OnNavigateFromEmbedder) | |
66 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateFromGuest, | |
67 OnNavigateFromGuest) | |
68 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_MapInstance, | |
69 OnMapInstance) | |
70 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ResizeGuest, OnResizeGuest) | |
71 IPC_MESSAGE_UNHANDLED(handled = false) | |
72 IPC_END_MESSAGE_MAP() | |
73 return handled; | |
74 } | |
75 | |
76 void BrowserPluginHost::OnResizeGuest(int width, int height) { | |
77 // Tell the RenderWidgetHostView to adjust its size. | |
78 web_contents()->GetRenderViewHost()->GetView()->SetSize( | |
Charlie Reis
2012/05/17 21:24:05
This isn't safe. We need to know who sent us the
Fady Samuel
2012/05/18 17:37:52
Done.
| |
79 gfx::Size(width, height)); | |
80 } | |
81 | |
82 void BrowserPluginHost::OnNavigateFromEmbedder( | |
83 int instance_id, | |
84 long long frame_id, | |
85 const std::string& src, | |
86 const gfx::Size& size) { | |
87 BrowserPluginHost* guest_observer = GetGuestByContainerID(instance_id); | |
88 WebContentsImpl* guest_web_contents = | |
89 guest_observer ? | |
90 static_cast<WebContentsImpl*>(guest_observer->web_contents()): NULL; | |
91 if (!guest_observer) { | |
92 GURL url(src); | |
93 guest_web_contents = | |
94 static_cast<WebContentsImpl*>( | |
95 WebContents::Create( | |
96 web_contents()->GetBrowserContext(), | |
97 web_contents()->GetSiteInstance(), | |
Charlie Reis
2012/05/17 21:24:05
Also not safe. The SiteInstance could have just c
Fady Samuel
2012/05/18 17:37:52
Done.
| |
98 MSG_ROUTING_NONE, | |
99 NULL, // base WebContents | |
100 NULL // session storage namespace | |
101 )); | |
102 guest_observer = | |
103 guest_web_contents->browser_plugin_host(); | |
104 guest_observer->set_embedder(static_cast<WebContentsImpl*>(web_contents())); | |
105 guest_observer->set_instance_id(instance_id); | |
106 guest_observer->set_url(url); | |
107 guest_observer->set_initial_size(size); | |
108 RegisterContainerInstance(instance_id, guest_observer); | |
109 AddGuest(guest_web_contents, frame_id); | |
110 } | |
111 | |
112 // TODO(fsamuel): Set the WebContentsDelegate here. | |
113 guest_observer->web_contents()->GetController().LoadURL( | |
Charlie Reis
2012/05/17 21:24:05
I'm skeptical about this and the one below. Where
Fady Samuel
2012/05/18 17:37:52
The string is coming from the browser plugin's src
Charlie Reis
2012/05/18 20:35:24
Ok, I think it'll do for now.
| |
114 guest_observer->url(), | |
115 Referrer(), | |
116 PAGE_TRANSITION_HOME_PAGE, | |
Charlie Reis
2012/05/17 21:24:05
I don't think Home Page is the right transition he
Fady Samuel
2012/05/18 17:37:52
changed to PAGE_TRANSITION_AUTO_SUBFRAME as per of
| |
117 std::string()); | |
118 } | |
119 | |
120 void BrowserPluginHost::OnNavigateFromGuest( | |
121 PP_Instance instance, | |
122 const std::string& src) { | |
123 DCHECK(embedder()); | |
124 GURL url(src); | |
125 web_contents()->GetController().LoadURL( | |
126 url, | |
127 Referrer(), | |
128 PAGE_TRANSITION_HOME_PAGE, | |
129 std::string()); | |
130 } | |
131 | |
132 void BrowserPluginHost::OnMapInstance(int container_id, PP_Instance instance) { | |
133 BrowserPluginHost* guest_observer = GetGuestByContainerID(container_id); | |
134 WebContentsImpl* guest_web_contents = | |
135 static_cast<WebContentsImpl*>(guest_observer->web_contents()); | |
136 // TODO(fsamuel): This should be correct unless we decide at some point to | |
137 // discard the pending_render_view_host for whatever reason. I need to | |
138 // investigate possible corner cases. | |
139 RenderViewHost* rvh = guest_observer->pending_render_view_host() ? | |
140 guest_observer->pending_render_view_host() : | |
141 guest_web_contents->GetRenderViewHost(); | |
Charlie Reis
2012/05/17 21:24:05
No, this isn't safe for the reasons stated above.
Fady Samuel
2012/05/18 17:37:52
This is tricky. OnMapInstance is coming from the e
| |
142 | |
143 // TODO(fsamuel): This is wrong. The current size of the plugin container | |
144 // might not be equal to initial size on subsequent navigations. | |
145 // BrowserPluginHost_MapInstance should also report the current size of | |
146 // the container to the browser process. | |
147 guest_web_contents->GetView()->SizeContents(guest_observer->initial_size()); | |
148 | |
149 rvh->Send(new BrowserPluginMsg_CompleteNavigation( | |
150 rvh->GetRoutingID(), | |
151 instance)); | |
152 } | |
153 | |
154 void BrowserPluginHost::OnConnectToChannel( | |
155 const IPC::ChannelHandle& channel_handle) { | |
156 DCHECK(embedder()); | |
157 // Tell the BrowserPlugin in the embedder that we're done and that it can | |
158 // begin using the guest renderer. | |
159 embedder()->GetRenderProcessHost()->Send( | |
160 new BrowserPluginMsg_LoadGuest( | |
161 instance_id(), | |
162 //embedder_web_contents->GetRenderProcessHost()->GetID(), | |
163 web_contents()->GetPendingSiteInstance()->GetProcess()-> | |
164 GetID(), | |
165 channel_handle)); | |
166 } | |
167 | |
168 void BrowserPluginHost::AddGuest(WebContentsImpl* guest, int64 frame_id) { | |
169 guests_[guest] = frame_id; | |
170 } | |
171 | |
172 void BrowserPluginHost::RemoveGuest(WebContentsImpl* guest) { | |
173 guests_.erase(guest); | |
174 } | |
175 | |
176 void BrowserPluginHost::DestroyGuests() { | |
177 for (GuestMap::const_iterator it = guests_.begin(); | |
178 it != guests_.end(); ++it) { | |
179 WebContentsImpl* web_contents = it->first; | |
180 delete web_contents; | |
181 } | |
182 guests_.clear(); | |
183 guests_by_container_id_.clear(); | |
184 } | |
185 | |
186 void BrowserPluginHost::DidCommitProvisionalLoadForFrame( | |
187 int64 frame_id, | |
188 bool is_main_frame, | |
189 const GURL& url, | |
190 PageTransition transition_type) { | |
191 typedef std::set<WebContentsImpl*> GuestSet; | |
192 GuestSet guests_to_delete; | |
193 for (GuestMap::const_iterator it = guests_.begin(); | |
194 it != guests_.end(); ++it) { | |
195 WebContentsImpl* web_contents = it->first; | |
196 if (it->second == frame_id) { | |
197 guests_to_delete.insert(web_contents); | |
198 } | |
199 } | |
200 for (GuestSet::const_iterator it = guests_to_delete.begin(); | |
201 it != guests_to_delete.end(); ++it) { | |
202 delete *it; | |
203 guests_.erase(*it); | |
204 } | |
205 } | |
206 | |
207 void BrowserPluginHost::RenderViewDeleted(RenderViewHost* render_view_host) { | |
208 // TODO(fsamuel): For some reason ToT hangs when killing a guest, this wasn't | |
209 // the case earlier. Presumably, when a guest is killed/crashes, one of | |
210 // RenderViewDeleted, RenderViewGone or WebContentsDestroyed will get called. | |
211 // At that point, we should remove reference to this BrowserPluginHost | |
212 // from its embedder, in addition to destroying its guests, to ensure | |
213 // that we do not attempt a double delete. | |
214 DestroyGuests(); | |
215 } | |
216 | |
217 void BrowserPluginHost::RenderViewGone(base::TerminationStatus status) { | |
218 DestroyGuests(); | |
219 } | |
220 | |
221 void BrowserPluginHost::WebContentsDestroyed(WebContents* web_contents) { | |
222 DestroyGuests(); | |
223 } | |
224 | |
225 void BrowserPluginHost::Observe( | |
226 int type, | |
227 const NotificationSource& source, | |
228 const NotificationDetails& details) { | |
229 DCHECK(type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED); | |
230 bool visible = *Details<bool>(details).ptr(); | |
231 | |
232 // If the embedder is hidden we need to hide the guests as well. | |
233 for (GuestMap::const_iterator it = guests_.begin(); | |
234 it != guests_.end(); ++it) { | |
235 WebContentsImpl* web_contents = it->first; | |
236 if (visible) | |
237 web_contents->ShowContents(); | |
238 else | |
239 web_contents->HideContents(); | |
240 } | |
241 } | |
242 | |
243 } // namespace content | |
OLD | NEW |