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

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

Powered by Google App Engine
This is Rietveld 408576698