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

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

Issue 9609008: Implemented Browser Plugin (NOT FOR REVIEW) (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: New BrowserPluginSerializationRules. Removed unnecessary changes to VarTracker 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 "base/atomic_sequence_num.h"
8 #include "base/lazy_instance.h"
9 #include "content/browser/renderer_host/render_view_host_impl.h"
10 #include "content/browser/web_contents/web_contents_impl.h"
11 #include "content/common/browser_plugin_messages.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "content/public/browser/notification_details.h"
14 #include "content/public/browser/notification_source.h"
15 #include "content/public/browser/notification_types.h"
16 #include "content/public/browser/render_process_host.h"
17 #include "content/public/browser/render_widget_host.h"
18 #include "content/public/browser/render_widget_host_view.h"
19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/site_instance.h"
21 #include "content/public/browser/web_contents.h"
22 #include "ppapi/proxy/ppapi_messages.h"
23
24 namespace content {
25
26 BrowserPluginHost::BrowserPluginHost(
27 WebContentsImpl* web_contents)
28 : WebContentsObserver(web_contents),
29 embedder_(NULL),
30 instance_id_(0) {
31 registrar_.Add(this,
32 NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
33 Source<RenderViewHost>(
34 web_contents->GetRenderViewHost()));
35 }
36
37 BrowserPluginHost::~BrowserPluginHost() {
38 }
39
40 BrowserPluginHost* BrowserPluginHost::GetGuestByContainerID(int container_id) {
41 ContainerInstanceMap::const_iterator it =
42 guests_by_container_id_.find(container_id);
43 if (it != guests_by_container_id_.end())
44 return it->second;
45 return NULL;
46 }
47
48 void BrowserPluginHost::RegisterContainerInstance(
49 int container_id,
50 BrowserPluginHost* observer) {
51 DCHECK(guests_by_container_id_.find(container_id) ==
52 guests_by_container_id_.end());
53 guests_by_container_id_[container_id] = observer;
54 }
55
56 bool BrowserPluginHost::OnMessageReceived(const IPC::Message& message) {
57 bool handled = true;
58 IPC_BEGIN_MESSAGE_MAP(BrowserPluginHost, message)
59 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ConnectToChannel,
60 OnConnectToChannel)
61 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateFromEmbedder,
62 OnNavigateFromEmbedder)
63 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateFromGuest,
64 OnNavigateFromGuest)
65 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_MapInstance,
66 OnMapInstance)
67 IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ResizeGuest, OnResizeGuest)
68 IPC_MESSAGE_UNHANDLED(handled = false)
69 IPC_END_MESSAGE_MAP()
70 return handled;
71 }
72
73 void BrowserPluginHost::OnResizeGuest(int width, int height) {
74 // Tell the RenderWidgetHostView to adjust its size.
75 web_contents()->GetRenderViewHost()->GetView()->SetSize(
76 gfx::Size(width, height));
77 }
78
79 void BrowserPluginHost::OnNavigateFromEmbedder(
80 int instance_id,
81 long long frame_id,
82 const std::string& src,
83 const gfx::Size& size) {
84 BrowserPluginHost* guest_observer = GetGuestByContainerID(instance_id);
85 WebContentsImpl* guest_web_contents =
86 guest_observer ?
87 static_cast<WebContentsImpl*>(guest_observer->web_contents()): NULL;
88 if (!guest_observer) {
89 GURL url(src);
90 guest_web_contents =
91 static_cast<WebContentsImpl*>(
92 WebContents::Create(
93 web_contents()->GetBrowserContext(),
94 web_contents()->GetSiteInstance(),
95 MSG_ROUTING_NONE,
96 NULL, // base WebContents
97 NULL // session storage namespace
98 ));
99 guest_observer =
100 guest_web_contents->browser_plugin_host();
101 guest_observer->set_embedder(static_cast<WebContentsImpl*>(web_contents()));
102 guest_observer->set_instance_id(instance_id);
103 guest_observer->set_url(url);
104 guest_observer->set_initial_size(size);
105 RegisterContainerInstance(instance_id, guest_observer);
106 AddGuest(guest_web_contents, frame_id);
107 }
108
109 // TODO(fsamuel): Set the WebContentsDelegate here.
110 guest_observer->web_contents()->GetController().LoadURL(
111 guest_observer->url(),
112 Referrer(),
113 PAGE_TRANSITION_HOME_PAGE,
114 std::string());
115 }
116
117 void BrowserPluginHost::OnNavigateFromGuest(
118 PP_Instance instance,
119 const std::string& src) {
120 GURL url(src);
121 web_contents()->GetController().LoadURL(
122 url,
123 Referrer(),
124 PAGE_TRANSITION_HOME_PAGE,
125 std::string());
126 }
127
128 void BrowserPluginHost::OnMapInstance(int container_id, PP_Instance instance) {
129 BrowserPluginHost* guest_observer = GetGuestByContainerID(container_id);
130 WebContentsImpl* guest_web_contents =
131 static_cast<WebContentsImpl*>(guest_observer->web_contents());
132 RenderViewHost* rvh = guest_web_contents->GetPendingRenderViewHost() ?
133 guest_web_contents->GetPendingRenderViewHost() :
134 guest_web_contents->GetRenderViewHost();
135 // TODO(fsamuel): This is wrong. The current size of the plugin container
136 // might not be equal to initial size on subsequent navigations.
137 // BrowserPluginHost_MapInstance should also report the current size of
138 // the container to the browser process.
139 rvh->GetView()->SetSize(guest_observer->initial_size());
140
141 rvh->Send(new BrowserPluginMsg_CompleteNavigation(
142 rvh->GetRoutingID(),
143 instance));
144 }
145
146 void BrowserPluginHost::OnConnectToChannel(
147 const IPC::ChannelHandle& channel_handle) {
148 DCHECK(embedder());
149 WebContentsImpl* embedder_web_contents =
150 static_cast<WebContentsImpl*>(web_contents());
151 RenderViewHost* rvh =
152 embedder_web_contents->GetPendingRenderViewHost() ?
153 embedder_web_contents->GetPendingRenderViewHost() :
154 embedder_web_contents->GetRenderViewHost();
155 // Tell the BrowserPlugin in the embedder that we're done and that it can
156 // begin using the guest renderer.
157 embedder()->GetRenderProcessHost()->Send(
158 new BrowserPluginMsg_LoadGuest(
159 instance_id(),
160 rvh->GetProcess()->GetID(),
161 channel_handle));
162 }
163
164 void BrowserPluginHost::AddGuest(WebContentsImpl* guest, int64 frame_id) {
165 guests_[guest] = frame_id;
166 }
167
168 void BrowserPluginHost::RemoveGuest(WebContentsImpl* guest) {
169 guests_.erase(guest);
170 }
171
172 void BrowserPluginHost::DestroyGuests() {
173 for (GuestMap::const_iterator it = guests_.begin();
174 it != guests_.end(); ++it) {
175 WebContentsImpl* web_contents = it->first;
176 delete web_contents;
177 }
178 guests_.clear();
179 guests_by_container_id_.clear();
180 }
181
182 void BrowserPluginHost::DidCommitProvisionalLoadForFrame(
183 int64 frame_id,
184 bool is_main_frame,
185 const GURL& url,
186 PageTransition transition_type) {
187 typedef std::set<WebContentsImpl*> GuestSet;
188 GuestSet guests_to_delete;
189 for (GuestMap::const_iterator it = guests_.begin();
190 it != guests_.end(); ++it) {
191 WebContentsImpl* web_contents = it->first;
192 if (it->second == frame_id) {
193 guests_to_delete.insert(web_contents);
194 }
195 }
196 for (GuestSet::const_iterator it = guests_to_delete.begin();
197 it != guests_to_delete.end(); ++it) {
198 delete *it;
199 guests_.erase(*it);
200 }
201 }
202
203 void BrowserPluginHost::RenderViewDeleted(RenderViewHost* render_view_host) {
204 DestroyGuests();
205 }
206
207 void BrowserPluginHost::RenderViewGone(base::TerminationStatus status) {
208 DestroyGuests();
209 }
210
211 void BrowserPluginHost::WebContentsDestroyed(WebContents* web_contents) {
212 DestroyGuests();
213 }
214
215 void BrowserPluginHost::Observe(
216 int type,
217 const NotificationSource& source,
218 const NotificationDetails& details) {
219 DCHECK(type == NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED);
220 bool visible = *Details<bool>(details).ptr();
221
222 // If the embedder is hidden we need to hide the guests as well.
223 for (GuestMap::const_iterator it = guests_.begin();
224 it != guests_.end(); ++it) {
225 WebContentsImpl* web_contents = it->first;
226 if (visible)
227 web_contents->ShowContents();
228 else
229 web_contents->HideContents();
230 }
231 }
232
233 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698