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

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

Issue 10868012: Browser Plugin: New Implementation (Browser Side) (Closed) Base URL: http://git.chromium.org/chromium/src.git@master-trial-obrowser
Patch Set: Rewrite test to *not* use NOTIFICATION_* Created 8 years, 3 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
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_embedder.h"
6
7 #include "base/logging.h"
8 #include "base/time.h"
9 #include "content/browser/browser_plugin/browser_plugin_embedder_helper.h"
10 #include "content/browser/browser_plugin/browser_plugin_guest.h"
11 #include "content/browser/browser_plugin/browser_plugin_guest_helper.h"
12 #include "content/browser/browser_plugin/browser_plugin_host_factory.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/renderer_host/render_widget_host_impl.h"
15 #include "content/browser/web_contents/web_contents_impl.h"
16 #include "content/common/browser_plugin_messages.h"
17 #include "content/common/view_messages.h"
18 #include "content/public/browser/notification_details.h"
19 #include "content/public/browser/notification_service.h"
20 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/notification_types.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/render_view_host.h"
24 #include "content/public/browser/render_widget_host_view.h"
25 #include "content/public/browser/web_contents_observer.h"
26 #include "content/public/browser/web_contents_view.h"
27 #include "content/public/common/url_constants.h"
28 #include "ui/gfx/size.h"
29
30 namespace content {
31
32 // static
33 BrowserPluginHostFactory* BrowserPluginEmbedder::factory_ = NULL;
34
35 BrowserPluginEmbedder::BrowserPluginEmbedder(
36 WebContentsImpl* web_contents,
37 RenderViewHost* render_view_host)
38 : WebContentsObserver(web_contents) {
39 // Listen to visibility changes so that an embedder hides its guests
40 // as well.
41 registrar_.Add(this,
42 NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED,
43 Source<WebContents>(web_contents));
44
45 new BrowserPluginEmbedderHelper(this, render_view_host);
46 }
47
48 BrowserPluginEmbedder::~BrowserPluginEmbedder() {
49 }
50
51 // static
52 BrowserPluginEmbedder* BrowserPluginEmbedder::CreateInstance(
53 WebContentsImpl* web_contents,
54 content::RenderViewHost* render_view_host) {
55 if (factory_) {
56 return factory_->CreateBrowserPluginEmbedder(web_contents,
57 render_view_host);
58 }
59 return new BrowserPluginEmbedder(web_contents, render_view_host);
60 }
61
62 BrowserPluginGuest* BrowserPluginEmbedder:: GetGuestByInstanceID(
63 int instance_id) const {
64 ContainerInstanceMap::const_iterator it =
65 guests_by_instance_id_.find(instance_id);
66 if (it != guests_by_instance_id_.end())
67 return it->second;
68 return NULL;
69 }
70
71 void BrowserPluginEmbedder::AddGuest(int instance_id,
72 BrowserPluginGuest* guest,
73 int64 frame_id) {
74 DCHECK(guests_by_instance_id_.find(instance_id) ==
75 guests_by_instance_id_.end());
76 guests_by_instance_id_[instance_id] = guest;
77 guest_web_contents_container_[guest->web_contents()] = frame_id;
78 }
79
80 void BrowserPluginEmbedder::NavigateGuest(RenderViewHost* render_view_host,
81 int instance_id,
82 int64 frame_id,
83 const std::string& src,
84 const gfx::Size& size) {
85 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
86 WebContentsImpl* guest_web_contents = NULL;
87 GURL url(src);
88 if (!guest) {
89 // The SiteInstance of a given guest is based on the fact that it's a guest
90 // in addition to which platform application the guest belongs to, rather
91 // than the URL that the guest is being navigated to.
92 std::string host = render_view_host->GetSiteInstance()->GetSite().host();
93 GURL guest_site(
94 base::StringPrintf("%s://%s", chrome::kGuestScheme, host.c_str()));
95 SiteInstance* guest_site_instance =
96 SiteInstance::CreateForURL(web_contents()->GetBrowserContext(),
97 guest_site);
98 guest_web_contents =
99 static_cast<WebContentsImpl*>(
100 WebContents::Create(web_contents()->GetBrowserContext(),
101 guest_site_instance,
102 MSG_ROUTING_NONE,
103 NULL, // base WebContents
104 NULL // session storage namespace
105 ));
106
107 guest = guest_web_contents->SetBrowserPluginGuest(instance_id);
108 guest->set_embedder_render_process_host(
109 render_view_host->GetProcess());
110
111 guest_web_contents->GetMutableRendererPrefs()->
112 throttle_input_events = false;
113 AddGuest(instance_id, guest, frame_id);
114 guest->web_contents()->SetDelegate(guest);
115 } else {
116 guest_web_contents = static_cast<WebContentsImpl*>(guest->web_contents());
117 }
118 guest->web_contents()->GetController().LoadURL(url,
119 Referrer(),
120 PAGE_TRANSITION_AUTO_SUBFRAME,
121 std::string());
122 if (!size.IsEmpty())
123 guest_web_contents->GetView()->SizeContents(size);
124 }
125
126 void BrowserPluginEmbedder::UpdateRectACK(int instance_id,
127 int message_id,
128 const gfx::Size& size) {
129 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
130 if (guest)
131 guest->UpdateRectACK(message_id, size);
132 }
133
134 void BrowserPluginEmbedder::ResizeGuest(int instance_id,
135 TransportDIB* damage_buffer,
136 int width,
137 int height,
138 bool resize_pending,
139 float scale_factor) {
140 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
141 if (!guest)
142 return;
143 WebContentsImpl* guest_web_contents =
144 static_cast<WebContentsImpl*>(guest->web_contents());
145 guest->SetDamageBuffer(damage_buffer, gfx::Size(width, height), scale_factor);
146 if (!resize_pending)
147 guest_web_contents->GetView()->SizeContents(gfx::Size(width, height));
148 }
149
150 void BrowserPluginEmbedder::SetFocus(int instance_id,
151 bool focused) {
152 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
153 if (guest)
154 guest->SetFocus(focused);
155 }
156
157 void BrowserPluginEmbedder::DestroyGuests() {
158 for (GuestWebContentsMap::const_iterator it =
159 guest_web_contents_container_.begin();
160 it != guest_web_contents_container_.end(); ++it) {
161 WebContents* web_contents = it->first;
162 delete web_contents;
163 }
164 guest_web_contents_container_.clear();
165 guests_by_instance_id_.clear();
166 }
167
168 void BrowserPluginEmbedder::HandleInputEvent(int instance_id,
169 RenderViewHost* render_view_host,
170 const gfx::Rect& guest_rect,
171 const WebKit::WebInputEvent& event,
172 IPC::Message* reply_message) {
173 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
174 if (guest)
175 guest->HandleInputEvent(render_view_host, guest_rect, event, reply_message);
176 }
177
178 void BrowserPluginEmbedder::DestroyGuestByInstanceID(int instance_id) {
179 BrowserPluginGuest* guest = GetGuestByInstanceID(instance_id);
180 if (guest) {
181 WebContents* guest_web_contents = guest->web_contents();
182
183 GuestWebContentsMap::iterator guest_it = guest_web_contents_container_.find(
184 guest_web_contents);
185 DCHECK(guest_it != guest_web_contents_container_.end());
186
187 guest_web_contents_container_.erase(guest_it);
188 guests_by_instance_id_.erase(instance_id);
189
190 guest->Destroy();
191 }
192 }
193
194 void BrowserPluginEmbedder::DidCommitProvisionalLoadForFrame(
195 int64 frame_id,
196 bool is_main_frame,
197 const GURL& url,
198 PageTransition transition_type,
199 RenderViewHost* render_view_host) {
200 // Clean up guests that lie in the frame that we're navigating.
201 typedef std::set<WebContents*> GuestSet;
202 GuestSet guests_to_delete;
203 for (GuestWebContentsMap::const_iterator it =
204 guest_web_contents_container_.begin();
205 it != guest_web_contents_container_.end(); ++it) {
206 WebContents* web_contents = it->first;
207 if (it->second == frame_id) {
208 // TODO(lazyboy): If we allow browser tags to be nested, we need to take
209 // care of subframes inside this frame as well.
210 guests_to_delete.insert(web_contents);
211 }
212 }
213 for (GuestSet::const_iterator it = guests_to_delete.begin();
214 it != guests_to_delete.end(); ++it) {
215 int instance_id = static_cast<WebContentsImpl*>(*it)->
216 GetBrowserPluginGuest()->instance_id();
217 DestroyGuestByInstanceID(instance_id);
218 }
219 }
220
221 void BrowserPluginEmbedder::RenderViewDeleted(
222 RenderViewHost* render_view_host) {
223 DestroyGuests();
224 }
225
226 void BrowserPluginEmbedder::RenderViewGone(base::TerminationStatus status) {
227 DestroyGuests();
228 }
229
230 void BrowserPluginEmbedder::WebContentsVisiblitlyChanged(bool visible) {
231 // If the embedder is hidden we need to hide the guests as well.
232 for (GuestWebContentsMap::const_iterator it =
233 guest_web_contents_container_.begin();
234 it != guest_web_contents_container_.end(); ++it) {
235 WebContents* web_contents = it->first;
236 if (visible)
237 web_contents->WasShown();
238 else
239 web_contents->WasHidden();
240 }
241 }
242
243 void BrowserPluginEmbedder::PluginDestroyed(int instance_id) {
244 DestroyGuestByInstanceID(instance_id);
245 }
246
247 void BrowserPluginEmbedder::Observe(int type,
248 const NotificationSource& source,
249 const NotificationDetails& details) {
250 switch (type) {
251 case NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED: {
252 bool visible = *Details<bool>(details).ptr();
253 WebContentsVisiblitlyChanged(visible);
254 break;
255 }
256 default:
257 NOTREACHED() << "Unexpected notification type: " << type;
258 }
259 }
260
261 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698