124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Copyright (c) 2012 The Chromium Authors. All rights reserved. 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// Use of this source code is governed by a BSD-style license that can be 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// found in the LICENSE file. 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// A BrowserPluginGuest is the browser side of a browser <--> embedder 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// renderer channel. A BrowserPlugin (a WebPlugin) is on the embedder 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// renderer side of browser <--> embedder renderer communication. 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// BrowserPluginGuest lives on the UI thread of the browser process. Any 10d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea// messages about the guest render process that the embedder might be interested 11d891f9b872103235cfd2ed452c6f14a4394d9b3aDaniel Malea// in receiving should be listened for here. 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// BrowserPluginGuest is a WebContentsObserver for the guest WebContents. 1424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// BrowserPluginGuest operates under the assumption that the guest will be 1524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// accessible through only one RenderViewHost for the lifetime of 1624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the guest WebContents. Thus, cross-process navigation is not supported. 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 18b4a4728ce4abd61a2d5be9ae925e1a81d56e4b5dEli Friedman#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_ 19b4a4728ce4abd61a2d5be9ae925e1a81d56e4b5dEli Friedman#define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_ 2024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <map> 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <queue> 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/compiler_specific.h" 2524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/memory/linked_ptr.h" 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/memory/weak_ptr.h" 2724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "base/values.h" 28238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton#include "content/common/edit_command.h" 29da26bd203cbb104291b39891febf7481794f205fJim Ingham#include "content/common/input/input_event_ack_state.h" 3024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "content/public/browser/browser_plugin_guest_delegate.h" 3124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "content/public/browser/web_contents_observer.h" 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "third_party/WebKit/public/web/WebCompositionUnderline.h" 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "third_party/WebKit/public/web/WebDragOperation.h" 3424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "third_party/WebKit/public/web/WebDragStatus.h" 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "third_party/WebKit/public/web/WebInputEvent.h" 3624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "ui/base/ime/text_input_mode.h" 37dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata#include "ui/base/ime/text_input_type.h" 38dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata#include "ui/gfx/rect.h" 39dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 40dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granataclass SkBitmap; 41dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatastruct BrowserPluginHostMsg_Attach_Params; 42dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatastruct BrowserPluginHostMsg_ResizeGuest_Params; 43dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatastruct FrameHostMsg_CompositorFrameSwappedACK_Params; 44dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatastruct FrameHostMsg_ReclaimCompositorResources_Params; 45dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata#if defined(OS_MACOSX) 46dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatastruct FrameHostMsg_ShowPopup_Params; 47dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata#endif 48dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 49dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatanamespace blink { 50dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granataclass WebInputEvent; 51dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata} // namespace blink 52dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 53dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatanamespace cc { 54dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granataclass CompositorFrame; 55dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata} // namespace cc 56dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 57dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatanamespace gfx { 58dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granataclass Range; 59dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata} // namespace gfx 60dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 61dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatanamespace content { 62dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 63ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molendaclass BrowserPluginGuestManager; 64ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molendaclass RenderViewHostImpl; 65ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molendaclass RenderWidgetHost; 66ba065cab7acc8ef7fbedc27af5d18c3a694a084aJason Molendaclass RenderWidgetHostView; 67dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granataclass SiteInstance; 68dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granatastruct DropData; 69dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 70dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// A browser plugin guest provides functionality for WebContents to operate in 71dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// the guest role and implements guest-specific overrides for ViewHostMsg_* 72dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// messages. 73dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// 74dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// When a guest is initially created, it is in an unattached state. That is, 75dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// it is not visible anywhere and has no embedder WebContents assigned. 76dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// A BrowserPluginGuest is said to be "attached" if it has an embedder. 77dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// A BrowserPluginGuest can also create a new unattached guest via 78dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// CreateNewWindow. The newly created guest will live in the same partition, 79dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata// which means it can share storage and can script this guest. 80dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granataclass CONTENT_EXPORT BrowserPluginGuest : public WebContentsObserver { 8124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner public: 82da26bd203cbb104291b39891febf7481794f205fJim Ingham virtual ~BrowserPluginGuest(); 8324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 84dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // The WebContents passed into the factory method here has not been 85dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // initialized yet and so it does not yet hold a SiteInstance. 86dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // BrowserPluginGuest must be constructed and installed into a WebContents 87dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // prior to its initialization because WebContents needs to determine what 88dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // type of WebContentsView to construct on initialization. The content 89dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // embedder needs to be aware of |guest_site_instance| on the guest's 90dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // construction and so we pass it in here. 91dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata static BrowserPluginGuest* Create(WebContentsImpl* web_contents, 92dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata BrowserPluginGuestDelegate* delegate); 93dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata 94dcb36c76090fdbf52f020bdd3fada62e0cffcc8dEnrico Granata // Returns whether the given WebContents is a BrowserPlugin guest. 95238c0a1e7b733cee539258faa656159c63f9e893Greg Clayton static bool IsGuest(WebContentsImpl* web_contents); 9624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 9724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner // Returns whether the given RenderviewHost is a BrowserPlugin guest. 9824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner static bool IsGuest(RenderViewHostImpl* render_view_host); 9924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 100 // Returns a WeakPtr to this BrowserPluginGuest. 101 base::WeakPtr<BrowserPluginGuest> AsWeakPtr(); 102 103 // Sets the focus state of the current RenderWidgetHostView. 104 void SetFocus(RenderWidgetHost* rwh, bool focused); 105 106 // Sets the lock state of the pointer. Returns true if |allowed| is true and 107 // the mouse has been successfully locked. 108 bool LockMouse(bool allowed); 109 110 // Return true if the mouse is locked. 111 bool mouse_locked() const { return mouse_locked_; } 112 113 // Called when the embedder WebContents changes visibility. 114 void EmbedderVisibilityChanged(bool visible); 115 116 // Destroys the guest WebContents and all its associated state, including 117 // this BrowserPluginGuest, and its new unattached windows. 118 void Destroy(); 119 120 // Creates a new guest WebContentsImpl with the provided |params| with |this| 121 // as the |opener|. 122 WebContentsImpl* CreateNewGuestWindow( 123 const WebContents::CreateParams& params); 124 125 // Returns the identifier that uniquely identifies a browser plugin guest 126 // within an embedder. 127 int browser_plugin_instance_id() const { return browser_plugin_instance_id_; } 128 129 bool OnMessageReceivedFromEmbedder(const IPC::Message& message); 130 131 WebContentsImpl* embedder_web_contents() const { 132 return embedder_web_contents_; 133 } 134 135 // Returns the embedder's RenderWidgetHostView if it is available. 136 // Returns NULL otherwise. 137 RenderWidgetHostView* GetEmbedderRenderWidgetHostView(); 138 139 bool focused() const { return focused_; } 140 bool visible() const { return guest_visible_; } 141 bool is_in_destruction() { return is_in_destruction_; } 142 143 void UpdateVisibility(); 144 145 void CopyFromCompositingSurface( 146 gfx::Rect src_subrect, 147 gfx::Size dst_size, 148 const base::Callback<void(bool, const SkBitmap&)>& callback); 149 150 BrowserPluginGuestManager* GetBrowserPluginGuestManager() const; 151 152 // WebContentsObserver implementation. 153 virtual void DidCommitProvisionalLoadForFrame( 154 RenderFrameHost* render_frame_host, 155 const GURL& url, 156 ui::PageTransition transition_type) OVERRIDE; 157 158 virtual void RenderViewReady() OVERRIDE; 159 virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE; 160 virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; 161 virtual bool OnMessageReceived(const IPC::Message& message, 162 RenderFrameHost* render_frame_host) OVERRIDE; 163 164 // Exposes the protected web_contents() from WebContentsObserver. 165 WebContentsImpl* GetWebContents() const; 166 167 gfx::Point GetScreenCoordinates(const gfx::Point& relative_position) const; 168 169 // Helper to send messages to embedder. This methods fills the message with 170 // the correct routing id. 171 void SendMessageToEmbedder(IPC::Message* msg); 172 173 // Returns whether the guest is attached to an embedder. 174 bool attached() const { return embedder_web_contents_ != NULL; } 175 176 // Attaches this BrowserPluginGuest to the provided |embedder_web_contents| 177 // and initializes the guest with the provided |params|. Attaching a guest 178 // to an embedder implies that this guest's lifetime is no longer managed 179 // by its opener, and it can begin loading resources. 180 void Attach(int browser_plugin_instance_id, 181 WebContentsImpl* embedder_web_contents, 182 const BrowserPluginHostMsg_Attach_Params& params); 183 184 // Returns whether BrowserPluginGuest is interested in receiving the given 185 // |message|. 186 static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message); 187 188 void DragSourceEndedAt(int client_x, int client_y, int screen_x, 189 int screen_y, blink::WebDragOperation operation); 190 191 // Called when the drag started by this guest ends at an OS-level. 192 void EndSystemDrag(); 193 194 void RespondToPermissionRequest(int request_id, 195 bool should_allow, 196 const std::string& user_input); 197 198 void PointerLockPermissionResponse(bool allow); 199 200 void SwapCompositorFrame(uint32 output_surface_id, 201 int host_process_id, 202 int host_routing_id, 203 scoped_ptr<cc::CompositorFrame> frame); 204 205 void SetContentsOpaque(bool opaque); 206 207 private: 208 class EmbedderWebContentsObserver; 209 210 // BrowserPluginGuest is a WebContentsObserver of |web_contents| and 211 // |web_contents| has to stay valid for the lifetime of BrowserPluginGuest. 212 BrowserPluginGuest(bool has_render_view, 213 WebContentsImpl* web_contents, 214 BrowserPluginGuestDelegate* delegate); 215 216 void WillDestroy(); 217 218 void Initialize(int browser_plugin_instance_id, 219 const BrowserPluginHostMsg_Attach_Params& params, 220 WebContentsImpl* embedder_web_contents); 221 222 bool InAutoSizeBounds(const gfx::Size& size) const; 223 224 // Message handlers for messages from embedder. 225 226 void OnCompositorFrameSwappedACK( 227 int instance_id, 228 const FrameHostMsg_CompositorFrameSwappedACK_Params& params); 229 void OnCopyFromCompositingSurfaceAck(int instance_id, 230 int request_id, 231 const SkBitmap& bitmap); 232 // Handles drag events from the embedder. 233 // When dragging, the drag events go to the embedder first, and if the drag 234 // happens on the browser plugin, then the plugin sends a corresponding 235 // drag-message to the guest. This routes the drag-message to the guest 236 // renderer. 237 void OnDragStatusUpdate(int instance_id, 238 blink::WebDragStatus drag_status, 239 const DropData& drop_data, 240 blink::WebDragOperationsMask drag_mask, 241 const gfx::Point& location); 242 // Instructs the guest to execute an edit command decoded in the embedder. 243 void OnExecuteEditCommand(int instance_id, 244 const std::string& command); 245 246 // Returns compositor resources reclaimed in the embedder to the guest. 247 void OnReclaimCompositorResources( 248 int instance_id, 249 const FrameHostMsg_ReclaimCompositorResources_Params& params); 250 251 void OnLockMouse(bool user_gesture, 252 bool last_unlocked_by_target, 253 bool privileged); 254 void OnLockMouseAck(int instance_id, bool succeeded); 255 void OnPluginDestroyed(int instance_id); 256 // Resizes the guest's web contents. 257 void OnResizeGuest( 258 int instance_id, const BrowserPluginHostMsg_ResizeGuest_Params& params); 259 void OnSetFocus(int instance_id, bool focused); 260 // Sets the name of the guest so that other guests in the same partition can 261 // access it. 262 void OnSetName(int instance_id, const std::string& name); 263 // Updates the size state of the guest. 264 void OnSetEditCommandsForNextKeyEvent( 265 int instance_id, 266 const std::vector<EditCommand>& edit_commands); 267 // The guest WebContents is visible if both its embedder is visible and 268 // the browser plugin element is visible. If either one is not then the 269 // WebContents is marked as hidden. A hidden WebContents will consume 270 // fewer GPU and CPU resources. 271 // 272 // When every WebContents in a RenderProcessHost is hidden, it will lower 273 // the priority of the process (see RenderProcessHostImpl::WidgetHidden). 274 // 275 // It will also send a message to the guest renderer process to cleanup 276 // resources such as dropping back buffers and adjusting memory limits (if in 277 // compositing mode, see CCLayerTreeHost::setVisible). 278 // 279 // Additionally, it will slow down Javascript execution and garbage 280 // collection. See RenderThreadImpl::IdleHandler (executed when hidden) and 281 // RenderThreadImpl::IdleHandlerInForegroundTab (executed when visible). 282 void OnSetVisibility(int instance_id, bool visible); 283 void OnUnlockMouse(); 284 void OnUnlockMouseAck(int instance_id); 285 void OnUpdateGeometry(int instance_id, const gfx::Rect& view_rect); 286 287 void OnTextInputTypeChanged(ui::TextInputType type, 288 ui::TextInputMode input_mode, 289 bool can_compose_inline); 290 void OnImeSetComposition( 291 int instance_id, 292 const std::string& text, 293 const std::vector<blink::WebCompositionUnderline>& underlines, 294 int selection_start, 295 int selection_end); 296 void OnImeConfirmComposition( 297 int instance_id, 298 const std::string& text, 299 bool keep_selection); 300 void OnExtendSelectionAndDelete(int instance_id, int before, int after); 301 void OnImeCancelComposition(); 302#if defined(OS_MACOSX) || defined(USE_AURA) 303 void OnImeCompositionRangeChanged( 304 const gfx::Range& range, 305 const std::vector<gfx::Rect>& character_bounds); 306#endif 307 308 // Message handlers for messages from guest. 309 void OnHandleInputEventAck( 310 blink::WebInputEvent::Type event_type, 311 InputEventAckState ack_result); 312 void OnHasTouchEventHandlers(bool accept); 313#if defined(OS_MACOSX) 314 // On MacOS X popups are painted by the browser process. We handle them here 315 // so that they are positioned correctly. 316 void OnShowPopup(RenderFrameHost* render_frame_host, 317 const FrameHostMsg_ShowPopup_Params& params); 318#endif 319 void OnShowWidget(int route_id, const gfx::Rect& initial_pos); 320 void OnTakeFocus(bool reverse); 321 void OnUpdateFrameName(int frame_id, 322 bool is_top_level, 323 const std::string& name); 324 325 // Forwards all messages from the |pending_messages_| queue to the embedder. 326 void SendQueuedMessages(); 327 328 scoped_ptr<EmbedderWebContentsObserver> embedder_web_contents_observer_; 329 WebContentsImpl* embedder_web_contents_; 330 331 // An identifier that uniquely identifies a browser plugin within an embedder. 332 int browser_plugin_instance_id_; 333 float guest_device_scale_factor_; 334 gfx::Rect guest_window_rect_; 335 bool focused_; 336 bool mouse_locked_; 337 bool pending_lock_request_; 338 bool guest_visible_; 339 bool embedder_visible_; 340 341 // Each copy-request is identified by a unique number. The unique number is 342 // used to keep track of the right callback. 343 int copy_request_id_; 344 typedef base::Callback<void(bool, const SkBitmap&)> CopyRequestCallback; 345 typedef std::map<int, const CopyRequestCallback> CopyRequestMap; 346 CopyRequestMap copy_request_callbacks_; 347 348 // Indicates that this BrowserPluginGuest has associated renderer-side state. 349 // This is used to determine whether or not to create a new RenderView when 350 // this guest is attached. A BrowserPluginGuest would have renderer-side state 351 // prior to attachment if it is created via a call to window.open and 352 // maintains a JavaScript reference to its opener. 353 bool has_render_view_; 354 355 // Last seen size of guest contents (by SwapCompositorFrame). 356 gfx::Size last_seen_view_size_; 357 // Last seen size of BrowserPlugin (by OnResizeGuest). 358 gfx::Size last_seen_browser_plugin_size_; 359 360 bool is_in_destruction_; 361 362 // Text input type states. 363 ui::TextInputType last_text_input_type_; 364 ui::TextInputMode last_input_mode_; 365 bool last_can_compose_inline_; 366 367 // This is a queue of messages that are destined to be sent to the embedder 368 // once the guest is attached to a particular embedder. 369 std::deque<linked_ptr<IPC::Message> > pending_messages_; 370 371 BrowserPluginGuestDelegate* const delegate_; 372 373 // Weak pointer used to ask GeolocationPermissionContext about geolocation 374 // permission. 375 base::WeakPtrFactory<BrowserPluginGuest> weak_ptr_factory_; 376 377 DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuest); 378}; 379 380} // namespace content 381 382#endif // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_H_ 383