summaryrefslogtreecommitdiffstats
path: root/chromium/content/browser/browser_plugin
diff options
context:
space:
mode:
authorAndras Becsi <andras.becsi@digia.com>2014-03-18 13:16:26 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-03-20 15:55:39 +0100
commit3f0f86b0caed75241fa71c95a5d73bc0164348c5 (patch)
tree92b9fb00f2e9e90b0be2262093876d4f43b6cd13 /chromium/content/browser/browser_plugin
parente90d7c4b152c56919d963987e2503f9909a666d2 (diff)
Update to new stable branch 1750
This also includes an updated ninja and chromium dependencies needed on Windows. Change-Id: Icd597d80ed3fa4425933c9f1334c3c2e31291c42 Reviewed-by: Zoltan Arvai <zarvai@inf.u-szeged.hu> Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
Diffstat (limited to 'chromium/content/browser/browser_plugin')
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.cc59
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_embedder.h12
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.cc455
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest.h191
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest_helper.cc55
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest_helper.h59
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest_manager.cc118
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_guest_manager.h11
-rw-r--r--chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc335
-rw-r--r--chromium/content/browser/browser_plugin/test_browser_plugin_guest.cc56
-rw-r--r--chromium/content/browser/browser_plugin/test_browser_plugin_guest.h19
-rw-r--r--chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc10
-rw-r--r--chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h7
13 files changed, 849 insertions, 538 deletions
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
index 1f673ba520f..18bfc25c3b4 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.cc
@@ -8,6 +8,7 @@
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
+#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
@@ -16,11 +17,13 @@
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/native_web_keyboard_event.h"
+#include "content/public/browser/render_view_host.h"
#include "content/public/browser/user_metrics.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
#include "net/base/escape.h"
+#include "ui/events/keycodes/keyboard_codes.h"
namespace content {
@@ -78,15 +81,58 @@ void BrowserPluginEmbedder::GetRenderViewHostAtPosition(
++next_get_render_view_request_id_;
}
+bool BrowserPluginEmbedder::DidSendScreenRectsCallback(
+ BrowserPluginGuest* guest) {
+ static_cast<RenderViewHostImpl*>(
+ guest->GetWebContents()->GetRenderViewHost())->SendScreenRects();
+ // Not handled => Iterate over all guests.
+ return false;
+}
+
void BrowserPluginEmbedder::DidSendScreenRects() {
- GetBrowserPluginGuestManager()->DidSendScreenRects(
- static_cast<WebContentsImpl*>(web_contents()));
+ WebContentsImpl* embedder =
+ static_cast<WebContentsImpl*>(web_contents());
+ GetBrowserPluginGuestManager()->ForEachGuest(embedder, base::Bind(
+ &BrowserPluginEmbedder::DidSendScreenRectsCallback,
+ base::Unretained(this)));
+}
+
+bool BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback(
+ const NativeWebKeyboardEvent& event,
+ BrowserPluginGuest* guest) {
+ return guest->UnlockMouseIfNecessary(event);
}
bool BrowserPluginEmbedder::HandleKeyboardEvent(
const NativeWebKeyboardEvent& event) {
- return GetBrowserPluginGuestManager()->UnlockMouseIfNecessary(
- static_cast<WebContentsImpl*>(web_contents()), event);
+ if ((event.type != blink::WebInputEvent::RawKeyDown) ||
+ (event.windowsKeyCode != ui::VKEY_ESCAPE) ||
+ (event.modifiers & blink::WebInputEvent::InputModifiers)) {
+ return false;
+ }
+
+ WebContentsImpl* embedder =
+ static_cast<WebContentsImpl*>(web_contents());
+ return GetBrowserPluginGuestManager()->ForEachGuest(embedder, base::Bind(
+ &BrowserPluginEmbedder::UnlockMouseIfNecessaryCallback,
+ base::Unretained(this),
+ event));
+}
+
+bool BrowserPluginEmbedder::SetZoomLevelCallback(
+ double level, BrowserPluginGuest* guest) {
+ guest->GetWebContents()->SetZoomLevel(level);
+ // Not handled => Iterate over all guests.
+ return false;
+}
+
+void BrowserPluginEmbedder::SetZoomLevel(double level) {
+ WebContentsImpl* embedder =
+ static_cast<WebContentsImpl*>(web_contents());
+ GetBrowserPluginGuestManager()->ForEachGuest(embedder, base::Bind(
+ &BrowserPluginEmbedder::SetZoomLevelCallback,
+ base::Unretained(this),
+ level));
}
void BrowserPluginEmbedder::RenderProcessGone(base::TerminationStatus status) {
@@ -109,7 +155,7 @@ bool BrowserPluginEmbedder::OnMessageReceived(const IPC::Message& message) {
}
void BrowserPluginEmbedder::DragSourceEndedAt(int client_x, int client_y,
- int screen_x, int screen_y, WebKit::WebDragOperation operation) {
+ int screen_x, int screen_y, blink::WebDragOperation operation) {
if (guest_started_drag_.get()) {
gfx::Point guest_offset =
guest_started_drag_->GetScreenCoordinates(gfx::Point());
@@ -177,7 +223,6 @@ void BrowserPluginEmbedder::OnAttach(
GetBrowserPluginGuestManager()->GetGuestByInstanceID(
instance_id, web_contents()->GetRenderProcessHost()->GetID());
-
if (guest) {
// There is an implicit order expectation here:
// 1. The content embedder is made aware of the attachment.
@@ -203,7 +248,7 @@ void BrowserPluginEmbedder::OnAttach(
guest->GetWebContents(),
web_contents(),
extra_params);
- guest->Initialize(static_cast<WebContentsImpl*>(web_contents()), params);
+ guest->Initialize(params, static_cast<WebContentsImpl*>(web_contents()));
}
}
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
index 52610632f59..107fa618686 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -67,12 +67,15 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
factory_ = factory;
}
+ // Sets the zoom level for all guests within this embedder.
+ void SetZoomLevel(double level);
+
// WebContentsObserver implementation.
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
void DragSourceEndedAt(int client_x, int client_y, int screen_x,
- int screen_y, WebKit::WebDragOperation operation);
+ int screen_y, blink::WebDragOperation operation);
void DragSourceMovedTo(int client_x, int client_y,
int screen_x, int screen_y);
@@ -98,6 +101,13 @@ class CONTENT_EXPORT BrowserPluginEmbedder : public WebContentsObserver {
BrowserPluginGuestManager* GetBrowserPluginGuestManager();
+ bool DidSendScreenRectsCallback(BrowserPluginGuest* guest);
+
+ bool SetZoomLevelCallback(double level, BrowserPluginGuest* guest);
+
+ bool UnlockMouseIfNecessaryCallback(const NativeWebKeyboardEvent& event,
+ BrowserPluginGuest* guest);
+
// Message handlers.
void OnAllocateInstanceID(int request_id);
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
index 19e7eba3d44..9668d227c51 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.cc
@@ -10,7 +10,6 @@
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/browser_plugin/browser_plugin_embedder.h"
-#include "content/browser/browser_plugin/browser_plugin_guest_helper.h"
#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
#include "content/browser/browser_thread_impl.h"
@@ -28,15 +27,16 @@
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/port/browser/render_view_host_delegate_view.h"
+#include "content/port/browser/render_widget_host_view_port.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/geolocation_permission_context.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
+#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/resource_request_details.h"
#include "content/public/browser/user_metrics.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/drop_data.h"
#include "content/public/common/media_stream_request.h"
@@ -44,7 +44,7 @@
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "net/url_request/url_request.h"
-#include "third_party/WebKit/public/web/WebCursorInfo.h"
+#include "third_party/WebKit/public/platform/WebCursorInfo.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/surface/transport_dib.h"
#include "webkit/common/resource_type.h"
@@ -64,6 +64,9 @@ class BrowserPluginGuest::PermissionRequest :
public base::RefCounted<BrowserPluginGuest::PermissionRequest> {
public:
virtual void Respond(bool should_allow, const std::string& user_input) = 0;
+ virtual bool AllowedByDefault() const {
+ return false;
+ }
protected:
PermissionRequest() {
RecordAction(UserMetricsAction("BrowserPlugin.Guest.PermissionRequest"));
@@ -193,7 +196,7 @@ class BrowserPluginGuest::NewWindowRequest : public PermissionRequest {
guest_->GetWebContents()->GetBrowserPluginGuestManager()->
GetGuestByInstanceID(instance_id_, embedder_render_process_id);
if (!guest) {
- LOG(INFO) << "Guest not found. Instance ID: " << instance_id_;
+ VLOG(0) << "Guest not found. Instance ID: " << instance_id_;
return;
}
@@ -213,8 +216,7 @@ class BrowserPluginGuest::JavaScriptDialogRequest : public PermissionRequest {
JavaScriptDialogRequest(const DialogClosedCallback& callback)
: callback_(callback) {
RecordAction(
- UserMetricsAction(
- "BrowserPlugin.Guest.PermissionRequest.JavaScriptDialog"));
+ UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.JSDialog"));
}
virtual void Respond(bool should_allow,
@@ -247,8 +249,6 @@ class BrowserPluginGuest::PointerLockRequest : public PermissionRequest {
};
namespace {
-const size_t kNumMaxOutstandingPermissionRequests = 1024;
-
std::string WindowOpenDispositionToString(
WindowOpenDisposition window_open_disposition) {
switch (window_open_disposition) {
@@ -298,40 +298,46 @@ static std::string RetrieveDownloadURLFromRequestId(
ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
if (url_request)
return url_request->url().possibly_invalid_spec();
- return std::string();
+ return "";
}
} // namespace
-class BrowserPluginGuest::EmbedderRenderViewHostObserver
- : public RenderViewHostObserver {
+class BrowserPluginGuest::EmbedderWebContentsObserver
+ : public WebContentsObserver {
public:
- explicit EmbedderRenderViewHostObserver(BrowserPluginGuest* guest)
- : RenderViewHostObserver(
- guest->embedder_web_contents()->GetRenderViewHost()),
+ explicit EmbedderWebContentsObserver(BrowserPluginGuest* guest)
+ : WebContentsObserver(guest->embedder_web_contents()),
browser_plugin_guest_(guest) {
}
- virtual ~EmbedderRenderViewHostObserver() {
+ virtual ~EmbedderWebContentsObserver() {
}
- // RenderViewHostObserver:
- virtual void RenderViewHostDestroyed(
- RenderViewHost* render_view_host) OVERRIDE {
+ // WebContentsObserver:
+ virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE {
browser_plugin_guest_->EmbedderDestroyed();
}
+ virtual void WasShown() OVERRIDE {
+ browser_plugin_guest_->EmbedderVisibilityChanged(true);
+ }
+
+ virtual void WasHidden() OVERRIDE {
+ browser_plugin_guest_->EmbedderVisibilityChanged(false);
+ }
+
private:
BrowserPluginGuest* browser_plugin_guest_;
- DISALLOW_COPY_AND_ASSIGN(EmbedderRenderViewHostObserver);
+ DISALLOW_COPY_AND_ASSIGN(EmbedderWebContentsObserver);
};
BrowserPluginGuest::BrowserPluginGuest(
int instance_id,
+ bool has_render_view,
WebContentsImpl* web_contents,
- BrowserPluginGuest* opener,
- bool has_render_view)
+ BrowserPluginGuest* opener)
: WebContentsObserver(web_contents),
weak_ptr_factory_(this),
embedder_web_contents_(NULL),
@@ -346,6 +352,7 @@ BrowserPluginGuest::BrowserPluginGuest(
mouse_locked_(false),
pending_lock_request_(false),
embedder_visible_(true),
+ copy_request_id_(0),
next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID),
has_render_view_(has_render_view),
last_seen_auto_size_enabled_(false),
@@ -360,9 +367,9 @@ BrowserPluginGuest::BrowserPluginGuest(
bool BrowserPluginGuest::AddMessageToConsole(WebContents* source,
int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) {
+ const base::string16& source_id) {
if (!delegate_)
return false;
@@ -382,7 +389,22 @@ void BrowserPluginGuest::DestroyUnattachedWindows() {
}
// All pending windows should be removed from the set after Destroy() is
// called on all of them.
- DCHECK_EQ(0ul, pending_new_windows_.size());
+ DCHECK(pending_new_windows_.empty());
+}
+
+void BrowserPluginGuest::LoadURLWithParams(const GURL& url,
+ const Referrer& referrer,
+ PageTransition transition_type,
+ WebContents* web_contents) {
+ NavigationController::LoadURLParams load_url_params(url);
+ load_url_params.referrer = referrer;
+ load_url_params.transition_type = transition_type;
+ load_url_params.extra_headers = std::string();
+ if (delegate_ && delegate_->IsOverridingUserAgent()) {
+ load_url_params.override_user_agent =
+ NavigationController::UA_OVERRIDE_TRUE;
+ }
+ web_contents->GetController().LoadURLWithParams(load_url_params);
}
void BrowserPluginGuest::RespondToPermissionRequest(
@@ -391,7 +413,7 @@ void BrowserPluginGuest::RespondToPermissionRequest(
const std::string& user_input) {
RequestMap::iterator request_itr = permission_request_map_.find(request_id);
if (request_itr == permission_request_map_.end()) {
- LOG(INFO) << "Not a valid request ID.";
+ VLOG(0) << "Not a valid request ID.";
return;
}
request_itr->second->Respond(should_allow, user_input);
@@ -415,9 +437,12 @@ int BrowserPluginGuest::RequestPermission(
AsWeakPtr(),
request_id);
// If BrowserPluginGuestDelegate hasn't handled the permission then we simply
- // reject it immediately.
- if (!delegate_->RequestPermission(permission_type, request_info, callback))
- callback.Run(false, "");
+ // perform the default action (which is one of allow or reject) immediately.
+ if (!delegate_->RequestPermission(
+ permission_type, request_info, callback, request->AllowedByDefault())) {
+ callback.Run(request->AllowedByDefault(), "");
+ return browser_plugin::kInvalidPermissionRequestID;
+ }
return request_id;
}
@@ -454,11 +479,8 @@ BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow(
std::make_pair(new_guest, NewWindowInfo(params.url, std::string())));
// Request permission to show the new window.
- RequestNewWindowPermission(
- new_guest->GetWebContents(),
- params.disposition,
- gfx::Rect(),
- params.user_gesture);
+ RequestNewWindowPermission(params.disposition, gfx::Rect(),
+ params.user_gesture, new_guest->GetWebContents());
return new_guest;
}
@@ -487,21 +509,33 @@ bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
OnSwapBuffersACK)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameACK,
OnCompositorFrameACK)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CopyFromCompositingSurfaceAck,
+ OnCopyFromCompositingSurfaceAck)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_DragStatusUpdate,
OnDragStatusUpdate)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExecuteEditCommand,
OnExecuteEditCommand)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ExtendSelectionAndDelete,
+ OnExtendSelectionAndDelete)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_HandleInputEvent,
OnHandleInputEvent)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ImeConfirmComposition,
+ OnImeConfirmComposition)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ImeSetComposition,
+ OnImeSetComposition)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_LockMouse_ACK, OnLockMouseAck)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_NavigateGuest, OnNavigateGuest)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_PluginDestroyed, OnPluginDestroyed)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ReclaimCompositorResources,
+ OnReclaimCompositorResources)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_ResizeGuest, OnResizeGuest)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetAutoSize, OnSetSize)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent,
OnSetEditCommandsForNextKeyEvent)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetFocus, OnSetFocus)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetName, OnSetName)
+ IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetContentsOpaque,
+ OnSetContentsOpaque)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_SetVisibility, OnSetVisibility)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UnlockMouse_ACK, OnUnlockMouseAck)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateGeometry, OnUpdateGeometry)
@@ -512,10 +546,11 @@ bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
}
void BrowserPluginGuest::Initialize(
- WebContentsImpl* embedder_web_contents,
- const BrowserPluginHostMsg_Attach_Params& params) {
+ const BrowserPluginHostMsg_Attach_Params& params,
+ WebContentsImpl* embedder_web_contents) {
focused_ = params.focused;
guest_visible_ = params.visible;
+ guest_opaque_ = params.opaque;
guest_window_rect_ = params.resize_guest_params.view_rect;
if (!params.name.empty())
@@ -532,11 +567,9 @@ void BrowserPluginGuest::Initialize(
static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
new_view->OnGuestInitialized(embedder_web_contents->GetView());
- // |render_view_host| manages the ownership of this BrowserPluginGuestHelper.
- new BrowserPluginGuestHelper(this, GetWebContents()->GetRenderViewHost());
-
RendererPreferences* renderer_prefs =
GetWebContents()->GetMutableRendererPrefs();
+ std::string guest_user_agent_override = renderer_prefs->user_agent_override;
// Copy renderer preferences (and nothing else) from the embedder's
// WebContents to the guest.
//
@@ -544,6 +577,7 @@ void BrowserPluginGuest::Initialize(
// values for caret blinking interval, colors related to selection and
// focus.
*renderer_prefs = *embedder_web_contents_->GetMutableRendererPrefs();
+ renderer_prefs->user_agent_override = guest_user_agent_override;
// We would like the guest to report changes to frame names so that we can
// update the BrowserPlugin's corresponding 'name' attribute.
@@ -555,14 +589,7 @@ void BrowserPluginGuest::Initialize(
// Disable "client blocked" error page for browser plugin.
renderer_prefs->disable_client_blocked_error_page = true;
- // Listen to embedder visibility changes so that the guest is in a 'shown'
- // state if both the embedder is visible and the BrowserPlugin is marked as
- // visible.
- notification_registrar_.Add(
- this, NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED,
- Source<WebContents>(embedder_web_contents_));
-
- embedder_rvh_observer_.reset(new EmbedderRenderViewHostObserver(this));
+ embedder_web_contents_observer_.reset(new EmbedderWebContentsObserver(this));
OnSetSize(instance_id_, params.auto_size_params, params.resize_guest_params);
@@ -575,8 +602,10 @@ void BrowserPluginGuest::Initialize(
new BrowserPluginMsg_GuestContentWindowReady(instance_id_,
guest_routing_id));
- if (!params.src.empty())
+ if (!params.src.empty()) {
+ // params.src will be validated in BrowserPluginGuest::OnNavigateGuest.
OnNavigateGuest(instance_id_, params.src);
+ }
has_render_view_ = true;
@@ -606,6 +635,9 @@ void BrowserPluginGuest::Initialize(
ack_params.name = name_;
SendMessageToEmbedder(
new BrowserPluginMsg_Attach_ACK(instance_id_, ack_params));
+
+ if (delegate_)
+ delegate_->DidAttach();
}
BrowserPluginGuest::~BrowserPluginGuest() {
@@ -618,6 +650,7 @@ BrowserPluginGuest::~BrowserPluginGuest() {
// static
BrowserPluginGuest* BrowserPluginGuest::Create(
int instance_id,
+ SiteInstance* guest_site_instance,
WebContentsImpl* web_contents,
scoped_ptr<base::DictionaryValue> extra_params) {
RecordAction(UserMetricsAction("BrowserPlugin.Guest.Create"));
@@ -625,13 +658,13 @@ BrowserPluginGuest* BrowserPluginGuest::Create(
if (factory_) {
guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents);
} else {
- guest = new BrowserPluginGuest(instance_id, web_contents, NULL, false);
+ guest = new BrowserPluginGuest(instance_id, false, web_contents, NULL);
}
guest->extra_attach_params_.reset(extra_params->DeepCopy());
web_contents->SetBrowserPluginGuest(guest);
BrowserPluginGuestDelegate* delegate = NULL;
GetContentClient()->browser()->GuestWebContentsCreated(
- web_contents, NULL, &delegate, extra_params.Pass());
+ guest_site_instance, web_contents, NULL, &delegate, extra_params.Pass());
guest->SetDelegate(delegate);
return guest;
}
@@ -639,15 +672,16 @@ BrowserPluginGuest* BrowserPluginGuest::Create(
// static
BrowserPluginGuest* BrowserPluginGuest::CreateWithOpener(
int instance_id,
+ bool has_render_view,
WebContentsImpl* web_contents,
- BrowserPluginGuest* opener,
- bool has_render_view) {
+ BrowserPluginGuest* opener) {
BrowserPluginGuest* guest =
new BrowserPluginGuest(
- instance_id, web_contents, opener, has_render_view);
+ instance_id, has_render_view, web_contents, opener);
web_contents->SetBrowserPluginGuest(guest);
BrowserPluginGuestDelegate* delegate = NULL;
GetContentClient()->browser()->GuestWebContentsCreated(
+ opener->GetWebContents()->GetSiteInstance(),
web_contents, opener->GetWebContents(), &delegate,
scoped_ptr<base::DictionaryValue>());
guest->SetDelegate(delegate);
@@ -662,6 +696,16 @@ void BrowserPluginGuest::UpdateVisibility() {
OnSetVisibility(instance_id_, visible());
}
+void BrowserPluginGuest::CopyFromCompositingSurface(
+ gfx::Rect src_subrect,
+ gfx::Size dst_size,
+ const base::Callback<void(bool, const SkBitmap&)>& callback) {
+ copy_request_callbacks_.insert(std::make_pair(++copy_request_id_, callback));
+ SendMessageToEmbedder(
+ new BrowserPluginMsg_CopyFromCompositingSurface(instance_id(),
+ copy_request_id_, src_subrect, dst_size));
+}
+
// screen.
gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) {
gfx::Rect guest_rect(bounds);
@@ -669,20 +713,9 @@ gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) {
return guest_rect;
}
-void BrowserPluginGuest::Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- switch (type) {
- case NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED: {
- DCHECK_EQ(Source<WebContents>(source).ptr(), embedder_web_contents_);
- embedder_visible_ = *Details<bool>(details).ptr();
- UpdateVisibility();
- break;
- }
- default:
- NOTREACHED() << "Unexpected notification sent.";
- break;
- }
+void BrowserPluginGuest::EmbedderVisibilityChanged(bool visible) {
+ embedder_visible_ = visible;
+ UpdateVisibility();
}
void BrowserPluginGuest::AddNewContents(WebContents* source,
@@ -693,8 +726,8 @@ void BrowserPluginGuest::AddNewContents(WebContents* source,
bool* was_blocked) {
if (was_blocked)
*was_blocked = false;
- RequestNewWindowPermission(static_cast<WebContentsImpl*>(new_contents),
- disposition, initial_pos, user_gesture);
+ RequestNewWindowPermission(disposition, initial_pos, user_gesture,
+ static_cast<WebContentsImpl*>(new_contents));
}
void BrowserPluginGuest::CanDownload(
@@ -702,12 +735,6 @@ void BrowserPluginGuest::CanDownload(
int request_id,
const std::string& request_method,
const base::Callback<void(bool)>& callback) {
- if (permission_request_map_.size() >= kNumMaxOutstandingPermissionRequests) {
- // Deny the download request.
- callback.Run(false);
- return;
- }
-
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::IO, FROM_HERE,
base::Bind(&RetrieveDownloadURLFromRequestId,
@@ -754,6 +781,9 @@ void BrowserPluginGuest::HandleKeyboardEvent(
if (delegate_ && delegate_->HandleKeyboardEvent(event))
return;
+ if (!embedder_web_contents_->GetDelegate())
+ return;
+
// Send the unhandled keyboard events back to the embedder to reprocess them.
// TODO(fsamuel): This introduces the possibility of out-of-order keyboard
// events because the guest may be arbitrarily delayed when responding to
@@ -783,8 +813,7 @@ WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source,
}
if (params.disposition == CURRENT_TAB) {
// This can happen for cross-site redirects.
- source->GetController().LoadURL(
- params.url, params.referrer, params.transition, std::string());
+ LoadURLWithParams(params.url, params.referrer, params.transition, source);
return source;
}
@@ -793,7 +822,7 @@ WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source,
void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents,
int64 source_frame_id,
- const string16& frame_name,
+ const base::string16& frame_name,
const GURL& target_url,
WebContents* new_contents) {
WebContentsImpl* new_contents_impl =
@@ -825,6 +854,12 @@ void BrowserPluginGuest::RendererResponsive(WebContents* source) {
void BrowserPluginGuest::RunFileChooser(WebContents* web_contents,
const FileChooserParams& params) {
+ if (!attached())
+ return;
+
+ if (!embedder_web_contents_->GetDelegate())
+ return;
+
embedder_web_contents_->GetDelegate()->RunFileChooser(web_contents, params);
}
@@ -886,10 +921,10 @@ bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const {
}
void BrowserPluginGuest::RequestNewWindowPermission(
- WebContentsImpl* new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_bounds,
- bool user_gesture) {
+ bool user_gesture,
+ WebContentsImpl* new_contents) {
BrowserPluginGuest* guest = new_contents->GetBrowserPluginGuest();
PendingWindowMap::iterator it = pending_new_windows_.find(guest);
if (it == pending_new_windows_.end())
@@ -940,7 +975,7 @@ void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) {
}
void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y,
- int screen_x, int screen_y, WebKit::WebDragOperation operation) {
+ int screen_x, int screen_y, blink::WebDragOperation operation) {
web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y,
screen_x, screen_y, operation);
}
@@ -956,9 +991,9 @@ void BrowserPluginGuest::EndSystemDrag() {
GetWebContents()->GetRenderViewHost());
guest_rvh->DragSourceSystemDragEnded();
// Issue a MouseUp event to get out of a selection state.
- WebKit::WebMouseEvent mouse_event;
- mouse_event.type = WebKit::WebInputEvent::MouseUp;
- mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
+ blink::WebMouseEvent mouse_event;
+ mouse_event.type = blink::WebInputEvent::MouseUp;
+ mouse_event.button = blink::WebMouseEvent::ButtonLeft;
guest_rvh->ForwardMouseEvent(mouse_event);
}
@@ -971,12 +1006,6 @@ void BrowserPluginGuest::AskEmbedderForGeolocationPermission(
int bridge_id,
const GURL& requesting_frame,
const GeolocationCallback& callback) {
- if (permission_request_map_.size() >= kNumMaxOutstandingPermissionRequests) {
- // Deny the geolocation request.
- callback.Run(false);
- return;
- }
-
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kURL,
base::Value::CreateStringValue(requesting_frame.spec()));
@@ -1031,6 +1060,7 @@ void BrowserPluginGuest::SendQueuedMessages() {
void BrowserPluginGuest::DidCommitProvisionalLoadForFrame(
int64 frame_id,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
@@ -1047,23 +1077,26 @@ void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) {
const char script[] = "window.addEventListener('dragstart', function() { "
" window.event.preventDefault(); "
"});";
- render_view_host->ExecuteJavascriptInWebFrame(string16(),
+ render_view_host->ExecuteJavascriptInWebFrame(base::string16(),
ASCIIToUTF16(script));
}
}
void BrowserPluginGuest::RenderViewReady() {
+ RenderViewHost* rvh = GetWebContents()->GetRenderViewHost();
+ // The guest RenderView should always live in a guest process.
+ CHECK(rvh->GetProcess()->IsGuest());
// TODO(fsamuel): Investigate whether it's possible to update state earlier
// here (see http://crbug.com/158151).
Send(new InputMsg_SetFocus(routing_id(), focused_));
UpdateVisibility();
- RenderViewHost* rvh = GetWebContents()->GetRenderViewHost();
if (auto_size_enabled_)
rvh->EnableAutoResize(min_auto_size_, max_auto_size_);
else
rvh->DisableAutoResize(damage_view_size_);
Send(new ViewMsg_SetName(routing_id(), name_));
+ OnSetContentsOpaque(instance_id_, guest_opaque_);
RenderWidgetHostImpl::From(rvh)->
set_hung_renderer_delay_ms(guest_hang_timeout_);
@@ -1110,26 +1143,31 @@ bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(
switch (message.type()) {
case BrowserPluginHostMsg_BuffersSwappedACK::ID:
case BrowserPluginHostMsg_CompositorFrameACK::ID:
+ case BrowserPluginHostMsg_CopyFromCompositingSurfaceAck::ID:
case BrowserPluginHostMsg_DragStatusUpdate::ID:
case BrowserPluginHostMsg_ExecuteEditCommand::ID:
+ case BrowserPluginHostMsg_ExtendSelectionAndDelete::ID:
case BrowserPluginHostMsg_HandleInputEvent::ID:
+ case BrowserPluginHostMsg_ImeConfirmComposition::ID:
+ case BrowserPluginHostMsg_ImeSetComposition::ID:
case BrowserPluginHostMsg_LockMouse_ACK::ID:
case BrowserPluginHostMsg_NavigateGuest::ID:
case BrowserPluginHostMsg_PluginDestroyed::ID:
+ case BrowserPluginHostMsg_ReclaimCompositorResources::ID:
case BrowserPluginHostMsg_ResizeGuest::ID:
case BrowserPluginHostMsg_SetAutoSize::ID:
case BrowserPluginHostMsg_SetEditCommandsForNextKeyEvent::ID:
case BrowserPluginHostMsg_SetFocus::ID:
case BrowserPluginHostMsg_SetName::ID:
+ case BrowserPluginHostMsg_SetContentsOpaque::ID:
case BrowserPluginHostMsg_SetVisibility::ID:
case BrowserPluginHostMsg_UnlockMouse_ACK::ID:
case BrowserPluginHostMsg_UpdateGeometry::ID:
case BrowserPluginHostMsg_UpdateRect_ACK::ID:
return true;
default:
- break;
+ return false;
}
- return false;
}
bool BrowserPluginGuest::OnMessageReceived(const IPC::Message& message) {
@@ -1147,6 +1185,14 @@ bool BrowserPluginGuest::OnMessageReceived(const IPC::Message& message) {
#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowWidget, OnShowWidget)
IPC_MESSAGE_HANDLER(ViewHostMsg_TakeFocus, OnTakeFocus)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_TextInputTypeChanged,
+ OnTextInputTypeChanged)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCancelComposition,
+ OnImeCancelComposition)
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_ImeCompositionRangeChanged,
+ OnImeCompositionRangeChanged)
+#endif
IPC_MESSAGE_HANDLER(ViewHostMsg_UnlockMouse, OnUnlockMouse)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFrameName, OnUpdateFrameName)
IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateRect, OnUpdateRect)
@@ -1170,7 +1216,7 @@ void BrowserPluginGuest::Attach(
params.src.clear();
// If a RenderView has already been created for this new window, then we need
- // to initialize the browser-side state now so that the RenderViewHostManager
+ // to initialize the browser-side state now so that the RenderFrameHostManager
// does not create a new RenderView on navigation.
if (has_render_view_) {
static_cast<RenderViewHostImpl*>(
@@ -1203,7 +1249,7 @@ void BrowserPluginGuest::Attach(
if (!name_.empty())
params.name.clear();
- Initialize(embedder_web_contents, params);
+ Initialize(params, embedder_web_contents);
SendQueuedMessages();
@@ -1223,29 +1269,29 @@ void BrowserPluginGuest::OnCompositorFrameACK(
}
void BrowserPluginGuest::OnDragStatusUpdate(int instance_id,
- WebKit::WebDragStatus drag_status,
+ blink::WebDragStatus drag_status,
const DropData& drop_data,
- WebKit::WebDragOperationsMask mask,
+ blink::WebDragOperationsMask mask,
const gfx::Point& location) {
RenderViewHost* host = GetWebContents()->GetRenderViewHost();
switch (drag_status) {
- case WebKit::WebDragStatusEnter:
+ case blink::WebDragStatusEnter:
embedder_web_contents_->GetBrowserPluginEmbedder()->DragEnteredGuest(
this);
host->DragTargetDragEnter(drop_data, location, location, mask, 0);
break;
- case WebKit::WebDragStatusOver:
+ case blink::WebDragStatusOver:
host->DragTargetDragOver(location, location, mask, 0);
break;
- case WebKit::WebDragStatusLeave:
+ case blink::WebDragStatusLeave:
embedder_web_contents_->GetBrowserPluginEmbedder()->DragLeftGuest(this);
host->DragTargetDragLeave();
break;
- case WebKit::WebDragStatusDrop:
+ case blink::WebDragStatusDrop:
host->DragTargetDrop(location, location, 0);
EndSystemDrag();
break;
- case WebKit::WebDragStatusUnknown:
+ case blink::WebDragStatusUnknown:
NOTREACHED();
}
}
@@ -1255,10 +1301,50 @@ void BrowserPluginGuest::OnExecuteEditCommand(int instance_id,
Send(new InputMsg_ExecuteEditCommand(routing_id(), name, std::string()));
}
+void BrowserPluginGuest::OnImeSetComposition(
+ int instance_id,
+ const std::string& text,
+ const std::vector<blink::WebCompositionUnderline>& underlines,
+ int selection_start,
+ int selection_end) {
+ Send(new ViewMsg_ImeSetComposition(routing_id(),
+ UTF8ToUTF16(text), underlines,
+ selection_start, selection_end));
+}
+
+void BrowserPluginGuest::OnImeConfirmComposition(
+ int instance_id,
+ const std::string& text,
+ bool keep_selection) {
+ Send(new ViewMsg_ImeConfirmComposition(routing_id(),
+ UTF8ToUTF16(text),
+ gfx::Range::InvalidRange(),
+ keep_selection));
+}
+
+void BrowserPluginGuest::OnExtendSelectionAndDelete(
+ int instance_id,
+ int before,
+ int after) {
+ Send(new ViewMsg_ExtendSelectionAndDelete(routing_id(), before, after));
+}
+
+void BrowserPluginGuest::OnReclaimCompositorResources(
+ int instance_id,
+ int route_id,
+ uint32 output_surface_id,
+ int renderer_host_id,
+ const cc::CompositorFrameAck& ack) {
+ RenderWidgetHostImpl::SendReclaimCompositorResources(route_id,
+ output_surface_id,
+ renderer_host_id,
+ ack);
+}
+
void BrowserPluginGuest::OnHandleInputEvent(
int instance_id,
const gfx::Rect& guest_window_rect,
- const WebKit::WebInputEvent* event) {
+ const blink::WebInputEvent* event) {
guest_window_rect_ = guest_window_rect;
// If the embedder's RWHV is destroyed then that means that the embedder's
// window has been closed but the embedder's WebContents has not yet been
@@ -1273,19 +1359,19 @@ void BrowserPluginGuest::OnHandleInputEvent(
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
GetWebContents()->GetRenderViewHost());
- if (WebKit::WebInputEvent::isMouseEventType(event->type)) {
+ if (blink::WebInputEvent::isMouseEventType(event->type)) {
guest_rvh->ForwardMouseEvent(
- *static_cast<const WebKit::WebMouseEvent*>(event));
+ *static_cast<const blink::WebMouseEvent*>(event));
return;
}
- if (event->type == WebKit::WebInputEvent::MouseWheel) {
+ if (event->type == blink::WebInputEvent::MouseWheel) {
guest_rvh->ForwardWheelEvent(
- *static_cast<const WebKit::WebMouseWheelEvent*>(event));
+ *static_cast<const blink::WebMouseWheelEvent*>(event));
return;
}
- if (WebKit::WebInputEvent::isKeyboardEventType(event->type)) {
+ if (blink::WebInputEvent::isKeyboardEventType(event->type)) {
RenderViewHostImpl* embedder_rvh = static_cast<RenderViewHostImpl*>(
embedder_web_contents_->GetRenderViewHost());
if (!embedder_rvh->GetLastKeyboardEvent())
@@ -1296,16 +1382,16 @@ void BrowserPluginGuest::OnHandleInputEvent(
return;
}
- if (WebKit::WebInputEvent::isTouchEventType(event->type)) {
+ if (blink::WebInputEvent::isTouchEventType(event->type)) {
guest_rvh->ForwardTouchEventWithLatencyInfo(
- *static_cast<const WebKit::WebTouchEvent*>(event),
+ *static_cast<const blink::WebTouchEvent*>(event),
ui::LatencyInfo());
return;
}
- if (WebKit::WebInputEvent::isGestureEventType(event->type)) {
+ if (blink::WebInputEvent::isGestureEventType(event->type)) {
guest_rvh->ForwardGestureEvent(
- *static_cast<const WebKit::WebGestureEvent*>(event));
+ *static_cast<const blink::WebGestureEvent*>(event));
return;
}
}
@@ -1313,9 +1399,7 @@ void BrowserPluginGuest::OnHandleInputEvent(
void BrowserPluginGuest::OnLockMouse(bool user_gesture,
bool last_unlocked_by_target,
bool privileged) {
- if (pending_lock_request_ ||
- (permission_request_map_.size() >=
- kNumMaxOutstandingPermissionRequests)) {
+ if (pending_lock_request_) {
// Immediately reject the lock because only one pointerLock may be active
// at a time.
Send(new ViewMsg_LockMouse_ACK(routing_id(), false));
@@ -1346,39 +1430,45 @@ void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) {
void BrowserPluginGuest::OnNavigateGuest(
int instance_id,
const std::string& src) {
- GURL url(src);
+ GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src);
// We do not load empty urls in web_contents.
// If a guest sets empty src attribute after it has navigated to some
// non-empty page, the action is considered no-op. This empty src navigation
// should never be sent to BrowserPluginGuest (browser process).
DCHECK(!src.empty());
- if (!src.empty()) {
- // Do not allow navigating a guest to schemes other than known safe schemes.
- // This will block the embedder trying to load unwanted schemes, e.g.
- // chrome://settings.
- bool scheme_is_blocked =
- (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme(
- url.scheme()) &&
- !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme(
- url.scheme())) ||
- url.SchemeIs(kJavaScriptScheme);
- if (scheme_is_blocked || !url.is_valid()) {
- if (delegate_) {
- std::string error_type;
- RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::", &error_type);
- delegate_->LoadAbort(true /* is_top_level */, url, error_type);
- }
- return;
- }
+ if (src.empty())
+ return;
- // As guests do not swap processes on navigation, only navigations to
- // normal web URLs are supported. No protocol handlers are installed for
- // other schemes (e.g., WebUI or extensions), and no permissions or bindings
- // can be granted to the guest process.
- GetWebContents()->GetController().LoadURL(url, Referrer(),
- PAGE_TRANSITION_AUTO_TOPLEVEL,
- std::string());
+ // Do not allow navigating a guest to schemes other than known safe schemes.
+ // This will block the embedder trying to load unwanted schemes, e.g.
+ // chrome://settings.
+ bool scheme_is_blocked =
+ (!ChildProcessSecurityPolicyImpl::GetInstance()->IsWebSafeScheme(
+ url.scheme()) &&
+ !ChildProcessSecurityPolicyImpl::GetInstance()->IsPseudoScheme(
+ url.scheme())) ||
+ url.SchemeIs(kJavaScriptScheme);
+ if (scheme_is_blocked || !url.is_valid()) {
+ if (delegate_) {
+ std::string error_type;
+ base::RemoveChars(net::ErrorToString(net::ERR_ABORTED), "net::",
+ &error_type);
+ delegate_->LoadAbort(true /* is_top_level */, url, error_type);
+ }
+ return;
}
+
+ GURL validated_url(url);
+ RenderViewHost::FilterURL(
+ GetWebContents()->GetRenderProcessHost(),
+ false,
+ &validated_url);
+ // As guests do not swap processes on navigation, only navigations to
+ // normal web URLs are supported. No protocol handlers are installed for
+ // other schemes (e.g., WebUI or extensions), and no permissions or bindings
+ // can be granted to the guest process.
+ LoadURLWithParams(validated_url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL,
+ GetWebContents());
}
void BrowserPluginGuest::OnPluginDestroyed(int instance_id) {
@@ -1413,15 +1503,10 @@ void BrowserPluginGuest::OnResizeGuest(
}
// Invalid damage buffer means we are in HW compositing mode,
// so just resize the WebContents and repaint if needed.
- if (!base::SharedMemory::IsHandleValid(params.damage_buffer_handle)) {
- if (!params.view_rect.size().IsEmpty())
- GetWebContents()->GetView()->SizeContents(params.view_rect.size());
- if (params.repaint)
- Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size()));
- return;
- }
- SetDamageBuffer(params);
- GetWebContents()->GetView()->SizeContents(params.view_rect.size());
+ if (base::SharedMemory::IsHandleValid(params.damage_buffer_handle))
+ SetDamageBuffer(params);
+ if (!params.view_rect.size().IsEmpty())
+ GetWebContents()->GetView()->SizeContents(params.view_rect.size());
if (params.repaint)
Send(new ViewMsg_Repaint(routing_id(), params.view_rect.size()));
}
@@ -1480,6 +1565,18 @@ void BrowserPluginGuest::OnSetEditCommandsForNextKeyEvent(
edit_commands));
}
+void BrowserPluginGuest::OnSetContentsOpaque(int instance_id, bool opaque) {
+ guest_opaque_ = opaque;
+
+ SkBitmap background;
+ if (!guest_opaque_) {
+ background.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
+ unsigned int color = 0;
+ background.setPixels(&color);
+ }
+ Send(new ViewMsg_SetBackground(routing_id(), background));
+}
+
void BrowserPluginGuest::OnSetVisibility(int instance_id, bool visible) {
guest_visible_ = visible;
if (embedder_visible_ && guest_visible_)
@@ -1529,6 +1626,18 @@ void BrowserPluginGuest::OnUpdateRectACK(
OnSetSize(instance_id_, auto_size_params, resize_guest_params);
}
+void BrowserPluginGuest::OnCopyFromCompositingSurfaceAck(
+ int instance_id,
+ int request_id,
+ const SkBitmap& bitmap) {
+ CHECK(copy_request_callbacks_.count(request_id));
+ if (!copy_request_callbacks_.count(request_id))
+ return;
+ const CopyRequestCallback& callback = copy_request_callbacks_[request_id];
+ callback.Run(!bitmap.empty() && !bitmap.isNull(), bitmap);
+ copy_request_callbacks_.erase(request_id);
+}
+
void BrowserPluginGuest::OnUpdateGeometry(int instance_id,
const gfx::Rect& view_rect) {
// The plugin has moved within the embedder without resizing or the
@@ -1591,12 +1700,6 @@ void BrowserPluginGuest::RequestMediaAccessPermission(
WebContents* web_contents,
const MediaStreamRequest& request,
const MediaResponseCallback& callback) {
- if (permission_request_map_.size() >= kNumMaxOutstandingPermissionRequests) {
- // Deny the media request.
- callback.Run(MediaStreamDevices(), scoped_ptr<MediaStreamUI>());
- return;
- }
-
base::DictionaryValue request_info;
request_info.Set(
browser_plugin::kURL,
@@ -1612,15 +1715,10 @@ void BrowserPluginGuest::RunJavaScriptDialog(
const GURL& origin_url,
const std::string& accept_lang,
JavaScriptMessageType javascript_message_type,
- const string16& message_text,
- const string16& default_prompt_text,
+ const base::string16& message_text,
+ const base::string16& default_prompt_text,
const DialogClosedCallback& callback,
bool* did_suppress_message) {
- if (permission_request_map_.size() >= kNumMaxOutstandingPermissionRequests) {
- // Cancel the dialog.
- callback.Run(false, string16());
- return;
- }
base::DictionaryValue request_info;
request_info.Set(
browser_plugin::kDefaultPromptText,
@@ -1643,18 +1741,18 @@ void BrowserPluginGuest::RunJavaScriptDialog(
void BrowserPluginGuest::RunBeforeUnloadDialog(
WebContents* web_contents,
- const string16& message_text,
+ const base::string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) {
// This is called if the guest has a beforeunload event handler.
// This callback allows navigation to proceed.
- callback.Run(true, string16());
+ callback.Run(true, base::string16());
}
bool BrowserPluginGuest::HandleJavaScriptDialog(
WebContents* web_contents,
bool accept,
- const string16* prompt_override) {
+ const base::string16* prompt_override) {
return false;
}
@@ -1729,6 +1827,29 @@ void BrowserPluginGuest::OnUpdateRect(
new BrowserPluginMsg_UpdateRect(instance_id(), relay_params));
}
+void BrowserPluginGuest::OnTextInputTypeChanged(ui::TextInputType type,
+ ui::TextInputMode input_mode,
+ bool can_compose_inline) {
+ RenderWidgetHostViewPort::FromRWHV(
+ web_contents()->GetRenderWidgetHostView())->TextInputTypeChanged(
+ type, input_mode, can_compose_inline);
+}
+
+void BrowserPluginGuest::OnImeCancelComposition() {
+ RenderWidgetHostViewPort::FromRWHV(
+ web_contents()->GetRenderWidgetHostView())->ImeCancelComposition();
+}
+
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA)
+void BrowserPluginGuest::OnImeCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds) {
+ RenderWidgetHostViewPort::FromRWHV(
+ web_contents()->GetRenderWidgetHostView())->ImeCompositionRangeChanged(
+ range, character_bounds);
+}
+#endif
+
void BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId(
const std::string& request_method,
const base::Callback<void(bool)>& callback,
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest.h b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
index 0101ff7118d..46c95a40da8 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest.h
@@ -6,12 +6,9 @@
// renderer channel. A BrowserPlugin (a WebPlugin) is on the embedder
// renderer side of browser <--> embedder renderer communication.
//
-// BrowserPluginGuest lives on the UI thread of the browser process. It has a
-// helper, BrowserPluginGuestHelper, which is a RenderViewHostObserver. The
-// helper object intercepts messages (ViewHostMsg_*) directed at the browser
-// process and redirects them to this class. Any messages about the guest render
-// process that the embedder might be interested in receiving should be listened
-// for here.
+// BrowserPluginGuest lives on the UI thread of the browser process. Any
+// messages about the guest render process that the embedder might be interested
+// in receiving should be listened for here.
//
// BrowserPluginGuest is a WebContentsDelegate and WebContentsObserver for the
// guest WebContents. BrowserPluginGuest operates under the assumption that the
@@ -33,15 +30,15 @@
#include "content/port/common/input_event_ack_state.h"
#include "content/public/browser/browser_plugin_guest_delegate.h"
#include "content/public/browser/javascript_dialog_manager.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/render_view_host_observer.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/browser_plugin_permission_type.h"
+#include "third_party/WebKit/public/web/WebCompositionUnderline.h"
#include "third_party/WebKit/public/web/WebDragOperation.h"
#include "third_party/WebKit/public/web/WebDragStatus.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/base/ime/text_input_mode.h"
+#include "ui/base/ime/text_input_type.h"
#include "ui/gfx/rect.h"
#include "ui/surface/transport_dib.h"
@@ -59,10 +56,14 @@ namespace cc {
class CompositorFrameAck;
}
-namespace WebKit {
+namespace blink {
class WebInputEvent;
}
+namespace gfx {
+class Range;
+}
+
namespace content {
class BrowserPluginHostFactory;
@@ -70,6 +71,7 @@ class BrowserPluginEmbedder;
class BrowserPluginGuestManager;
class RenderProcessHost;
class RenderWidgetHostView;
+class SiteInstance;
struct DropData;
struct MediaStreamRequest;
@@ -85,7 +87,6 @@ struct MediaStreamRequest;
// which means it can share storage and can script this guest.
class CONTENT_EXPORT BrowserPluginGuest
: public JavaScriptDialogManager,
- public NotificationObserver,
public WebContentsDelegate,
public WebContentsObserver,
public base::SupportsWeakPtr<BrowserPluginGuest> {
@@ -93,21 +94,32 @@ class CONTENT_EXPORT BrowserPluginGuest
typedef base::Callback<void(bool)> GeolocationCallback;
virtual ~BrowserPluginGuest();
+ // The WebContents passed into the factory method here has not been
+ // initialized yet and so it does not yet hold a SiteInstance.
+ // BrowserPluginGuest must be constructed and installed into a WebContents
+ // prior to its initialization because WebContents needs to determine what
+ // type of WebContentsView to construct on initialization. The content
+ // embedder needs to be aware of |guest_site_instance| on the guest's
+ // construction and so we pass it in here.
static BrowserPluginGuest* Create(
int instance_id,
+ SiteInstance* guest_site_instance,
WebContentsImpl* web_contents,
scoped_ptr<base::DictionaryValue> extra_params);
static BrowserPluginGuest* CreateWithOpener(
int instance_id,
+ bool has_render_view,
WebContentsImpl* web_contents,
- BrowserPluginGuest* opener,
- bool has_render_view);
+ BrowserPluginGuest* opener);
- // Called when the embedder RenderViewHost is destroyed to give the
+ // Called when the embedder WebContents is destroyed to give the
// BrowserPluginGuest an opportunity to clean up after itself.
void EmbedderDestroyed();
+ // Called when the embedder WebContents changes visibility.
+ void EmbedderVisibilityChanged(bool visible);
+
// Destroys the guest WebContents and all its associated state, including
// this BrowserPluginGuest, and its new unattached windows.
void Destroy();
@@ -116,20 +128,10 @@ class CONTENT_EXPORT BrowserPluginGuest
// within an embedder.
int instance_id() const { return instance_id_; }
- // Overrides factory for testing. Default (NULL) value indicates regular
- // (non-test) environment.
- static void set_factory_for_testing(BrowserPluginHostFactory* factory) {
- BrowserPluginGuest::factory_ = factory;
- }
-
bool OnMessageReceivedFromEmbedder(const IPC::Message& message);
- void Initialize(WebContentsImpl* embedder_web_contents,
- const BrowserPluginHostMsg_Attach_Params& params);
-
- void set_guest_hang_timeout_for_testing(const base::TimeDelta& timeout) {
- guest_hang_timeout_ = timeout;
- }
+ void Initialize(const BrowserPluginHostMsg_Attach_Params& params,
+ WebContentsImpl* embedder_web_contents);
WebContentsImpl* embedder_web_contents() const {
return embedder_web_contents_;
@@ -149,14 +151,15 @@ class CONTENT_EXPORT BrowserPluginGuest
void UpdateVisibility();
- // NotificationObserver implementation.
- virtual void Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) OVERRIDE;
+ void CopyFromCompositingSurface(
+ gfx::Rect src_subrect,
+ gfx::Size dst_size,
+ const base::Callback<void(bool, const SkBitmap&)>& callback);
// WebContentsObserver implementation.
virtual void DidCommitProvisionalLoadForFrame(
int64 frame_id,
+ const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
@@ -170,9 +173,9 @@ class CONTENT_EXPORT BrowserPluginGuest
// WebContentsDelegate implementation.
virtual bool AddMessageToConsole(WebContents* source,
int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) OVERRIDE;
+ const base::string16& source_id) OVERRIDE;
// If a new window is created with target="_blank" and rel="noreferrer", then
// this method is called, indicating that the new WebContents is ready to be
// attached.
@@ -198,7 +201,7 @@ class CONTENT_EXPORT BrowserPluginGuest
const OpenURLParams& params) OVERRIDE;
virtual void WebContentsCreated(WebContents* source_contents,
int64 source_frame_id,
- const string16& frame_name,
+ const base::string16& frame_name,
const GURL& target_url,
WebContents* new_contents) OVERRIDE;
virtual void RendererUnresponsive(WebContents* source) OVERRIDE;
@@ -217,18 +220,19 @@ class CONTENT_EXPORT BrowserPluginGuest
const GURL& origin_url,
const std::string& accept_lang,
JavaScriptMessageType javascript_message_type,
- const string16& message_text,
- const string16& default_prompt_text,
+ const base::string16& message_text,
+ const base::string16& default_prompt_text,
const DialogClosedCallback& callback,
bool* did_suppress_message) OVERRIDE;
virtual void RunBeforeUnloadDialog(
WebContents* web_contents,
- const string16& message_text,
+ const base::string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) OVERRIDE;
- virtual bool HandleJavaScriptDialog(WebContents* web_contents,
- bool accept,
- const string16* prompt_override) OVERRIDE;
+ virtual bool HandleJavaScriptDialog(
+ WebContents* web_contents,
+ bool accept,
+ const base::string16* prompt_override) OVERRIDE;
virtual void CancelActiveAndPendingDialogs(
WebContents* web_contents) OVERRIDE;
virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
@@ -249,7 +253,7 @@ class CONTENT_EXPORT BrowserPluginGuest
virtual void SendMessageToEmbedder(IPC::Message* msg);
// Returns whether the guest is attached to an embedder.
- bool attached() const { return !!embedder_web_contents_; }
+ bool attached() const { return embedder_web_contents_ != NULL; }
// Attaches this BrowserPluginGuest to the provided |embedder_web_contents|
// and initializes the guest with the provided |params|. Attaching a guest
@@ -281,7 +285,7 @@ class CONTENT_EXPORT BrowserPluginGuest
gfx::Rect ToGuestRect(const gfx::Rect& rect);
void DragSourceEndedAt(int client_x, int client_y, int screen_x,
- int screen_y, WebKit::WebDragOperation operation);
+ int screen_y, blink::WebDragOperation operation);
void DragSourceMovedTo(int client_x, int client_y,
int screen_x, int screen_y);
@@ -296,8 +300,14 @@ class CONTENT_EXPORT BrowserPluginGuest
bool should_allow,
const std::string& user_input);
+ // Overrides factory for testing. Default (NULL) value indicates regular
+ // (non-test) environment.
+ static void set_factory_for_testing(BrowserPluginHostFactory* factory) {
+ BrowserPluginGuest::factory_ = factory;
+ }
+
private:
- class EmbedderRenderViewHostObserver;
+ class EmbedderWebContentsObserver;
friend class TestBrowserPluginGuest;
class DownloadRequest;
@@ -309,15 +319,36 @@ class CONTENT_EXPORT BrowserPluginGuest
class PermissionRequest;
class PointerLockRequest;
+ // Tracks the name, and target URL of the new window and whether or not it has
+ // changed since the WebContents has been created and before the new window
+ // has been attached to a BrowserPlugin. Once the first navigation commits, we
+ // no longer track this information.
+ struct NewWindowInfo {
+ bool changed;
+ GURL url;
+ std::string name;
+ NewWindowInfo(const GURL& url, const std::string& name) :
+ changed(false),
+ url(url),
+ name(name) {}
+ };
+
+ // BrowserPluginGuest is a WebContentsObserver of |web_contents| and
+ // |web_contents| has to stay valid for the lifetime of BrowserPluginGuest.
BrowserPluginGuest(int instance_id,
+ bool has_render_view,
WebContentsImpl* web_contents,
- BrowserPluginGuest* opener,
- bool has_render_view);
+ BrowserPluginGuest* opener);
// Destroy unattached new windows that have been opened by this
// BrowserPluginGuest.
void DestroyUnattachedWindows();
+ void LoadURLWithParams(const GURL& url,
+ const Referrer& referrer,
+ PageTransition transition_type,
+ WebContents* web_contents);
+
// Bridge IDs correspond to a geolocation request. This method will remove
// the bookkeeping for a particular geolocation request associated with the
// provided |bridge_id|. It returns the request ID of the geolocation request.
@@ -344,10 +375,10 @@ class CONTENT_EXPORT BrowserPluginGuest
bool InAutoSizeBounds(const gfx::Size& size) const;
- void RequestNewWindowPermission(WebContentsImpl* new_contents,
- WindowOpenDisposition disposition,
+ void RequestNewWindowPermission(WindowOpenDisposition disposition,
const gfx::Rect& initial_bounds,
- bool user_gesture);
+ bool user_gesture,
+ WebContentsImpl* new_contents);
// Message handlers for messages from embedder.
@@ -356,24 +387,34 @@ class CONTENT_EXPORT BrowserPluginGuest
uint32 output_surface_id,
int renderer_host_id,
const cc::CompositorFrameAck& ack);
-
+ void OnCopyFromCompositingSurfaceAck(int instance_id,
+ int request_id,
+ const SkBitmap& bitmap);
// Handles drag events from the embedder.
// When dragging, the drag events go to the embedder first, and if the drag
// happens on the browser plugin, then the plugin sends a corresponding
// drag-message to the guest. This routes the drag-message to the guest
// renderer.
void OnDragStatusUpdate(int instance_id,
- WebKit::WebDragStatus drag_status,
+ blink::WebDragStatus drag_status,
const DropData& drop_data,
- WebKit::WebDragOperationsMask drag_mask,
+ blink::WebDragOperationsMask drag_mask,
const gfx::Point& location);
// Instructs the guest to execute an edit command decoded in the embedder.
void OnExecuteEditCommand(int instance_id,
const std::string& command);
+
+ // Returns compositor resources reclaimed in the embedder to the guest.
+ void OnReclaimCompositorResources(int instance_id,
+ int route_id,
+ uint32 output_surface_id,
+ int renderer_host_id,
+ const cc::CompositorFrameAck& ack);
+
// Overriden in tests.
virtual void OnHandleInputEvent(int instance_id,
const gfx::Rect& guest_window_rect,
- const WebKit::WebInputEvent* event);
+ const blink::WebInputEvent* event);
void OnLockMouse(bool user_gesture,
bool last_unlocked_by_target,
bool privileged);
@@ -397,6 +438,7 @@ class CONTENT_EXPORT BrowserPluginGuest
void OnSetEditCommandsForNextKeyEvent(
int instance_id,
const std::vector<EditCommand>& edit_commands);
+ void OnSetContentsOpaque(int instance_id, bool opaque);
// The guest WebContents is visible if both its embedder is visible and
// the browser plugin element is visible. If either one is not then the
// WebContents is marked as hidden. A hidden WebContents will consume
@@ -428,12 +470,33 @@ class CONTENT_EXPORT BrowserPluginGuest
const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params);
+ void OnTextInputTypeChanged(ui::TextInputType type,
+ ui::TextInputMode input_mode,
+ bool can_compose_inline);
+ void OnImeSetComposition(
+ int instance_id,
+ const std::string& text,
+ const std::vector<blink::WebCompositionUnderline>& underlines,
+ int selection_start,
+ int selection_end);
+ void OnImeConfirmComposition(
+ int instance_id,
+ const std::string& text,
+ bool keep_selection);
+ void OnExtendSelectionAndDelete(int instance_id, int before, int after);
+ // Overridden in tests.
+ virtual void OnImeCancelComposition();
+#if defined(OS_MACOSX) || defined(OS_WIN) || defined(USE_AURA)
+ void OnImeCompositionRangeChanged(
+ const gfx::Range& range,
+ const std::vector<gfx::Rect>& character_bounds);
+#endif
// Message handlers for messages from guest.
void OnDragStopped();
void OnHandleInputEventAck(
- WebKit::WebInputEvent::Type event_type,
+ blink::WebInputEvent::Type event_type,
InputEventAckState ack_result);
void OnHasTouchEventHandlers(bool accept);
void OnSetCursor(const WebCursor& cursor);
@@ -471,8 +534,7 @@ class CONTENT_EXPORT BrowserPluginGuest
// Static factory instance (always NULL for non-test).
static BrowserPluginHostFactory* factory_;
- NotificationRegistrar notification_registrar_;
- scoped_ptr<EmbedderRenderViewHostObserver> embedder_rvh_observer_;
+ scoped_ptr<EmbedderWebContentsObserver> embedder_web_contents_observer_;
WebContentsImpl* embedder_web_contents_;
std::map<int, int> bridge_id_to_request_id_map_;
@@ -494,25 +556,20 @@ class CONTENT_EXPORT BrowserPluginGuest
bool mouse_locked_;
bool pending_lock_request_;
bool guest_visible_;
+ bool guest_opaque_;
bool embedder_visible_;
std::string name_;
bool auto_size_enabled_;
gfx::Size max_auto_size_;
gfx::Size min_auto_size_;
- // Tracks the name, and target URL of the new window and whether or not it has
- // changed since the WebContents has been created and before the new window
- // has been attached to a BrowserPlugin. Once the first navigation commits, we
- // no longer track this information.
- struct NewWindowInfo {
- bool changed;
- GURL url;
- std::string name;
- NewWindowInfo(const GURL& url, const std::string& name) :
- changed(false),
- url(url),
- name(name) {}
- };
+ // Each copy-request is identified by a unique number. The unique number is
+ // used to keep track of the right callback.
+ int copy_request_id_;
+ typedef base::Callback<void(bool, const SkBitmap&)> CopyRequestCallback;
+ typedef std::map<int, const CopyRequestCallback> CopyRequestMap;
+ CopyRequestMap copy_request_callbacks_;
+
typedef std::map<BrowserPluginGuest*, NewWindowInfo> PendingWindowMap;
PendingWindowMap pending_new_windows_;
base::WeakPtr<BrowserPluginGuest> opener_;
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest_helper.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest_helper.cc
deleted file mode 100644
index ee18b6e92e3..00000000000
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest_helper.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/browser_plugin/browser_plugin_guest_helper.h"
-
-#include "content/browser/browser_plugin/browser_plugin_guest.h"
-#include "content/common/drag_messages.h"
-#include "content/common/view_messages.h"
-#include "content/public/browser/render_view_host.h"
-
-namespace content {
-
-BrowserPluginGuestHelper::BrowserPluginGuestHelper(
- BrowserPluginGuest* guest,
- RenderViewHost* render_view_host)
- : RenderViewHostObserver(render_view_host),
- guest_(guest) {
-}
-
-BrowserPluginGuestHelper::~BrowserPluginGuestHelper() {
-}
-
-bool BrowserPluginGuestHelper::OnMessageReceived(
- const IPC::Message& message) {
- if (ShouldForwardToBrowserPluginGuest(message))
- return guest_->OnMessageReceived(message);
- return false;
-}
-
-// static
-bool BrowserPluginGuestHelper::ShouldForwardToBrowserPluginGuest(
- const IPC::Message& message) {
- switch (message.type()) {
- case DragHostMsg_StartDragging::ID:
- case DragHostMsg_TargetDrop_ACK::ID:
- case ViewHostMsg_HasTouchEventHandlers::ID:
- case ViewHostMsg_SetCursor::ID:
- #if defined(OS_MACOSX)
- case ViewHostMsg_ShowPopup::ID:
- #endif
- case ViewHostMsg_ShowWidget::ID:
- case ViewHostMsg_TakeFocus::ID:
- case ViewHostMsg_UpdateFrameName::ID:
- case ViewHostMsg_UpdateRect::ID:
- case ViewHostMsg_LockMouse::ID:
- case ViewHostMsg_UnlockMouse::ID:
- return true;
- default:
- break;
- }
- return false;
-}
-
-} // namespace content
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest_helper.h b/chromium/content/browser/browser_plugin/browser_plugin_guest_helper.h
deleted file mode 100644
index dfe2e321691..00000000000
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest_helper.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_HELPER_H_
-#define CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_HELPER_H_
-
-#include "content/port/common/input_event_ack_state.h"
-#include "content/public/browser/render_view_host_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "third_party/WebKit/public/web/WebDragOperation.h"
-#include "third_party/WebKit/public/web/WebInputEvent.h"
-
-class WebCursor;
-#if defined(OS_MACOSX)
-struct ViewHostMsg_ShowPopup_Params;
-#endif
-struct ViewHostMsg_UpdateRect_Params;
-
-namespace gfx {
-class Size;
-}
-
-namespace content {
-class BrowserPluginGuest;
-class RenderViewHost;
-
-// Helper for BrowserPluginGuest.
-//
-// The purpose of this class is to intercept messages from the guest RenderView
-// before they are handled by the standard message handlers in the browser
-// process. This permits overriding standard behavior with BrowserPlugin-
-// specific behavior.
-//
-// The lifetime of this class is managed by the associated RenderViewHost. A
-// BrowserPluginGuestHelper is created whenever a BrowserPluginGuest is created.
-class BrowserPluginGuestHelper : public RenderViewHostObserver {
- public:
- BrowserPluginGuestHelper(BrowserPluginGuest* guest,
- RenderViewHost* render_view_host);
- virtual ~BrowserPluginGuestHelper();
-
- protected:
- // RenderViewHostObserver implementation.
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-
- private:
- // Returns whether a message should be forward to the helper's associated
- // BrowserPluginGuest.
- static bool ShouldForwardToBrowserPluginGuest(const IPC::Message& message);
-
- BrowserPluginGuest* guest_;
-
- DISALLOW_COPY_AND_ASSIGN(BrowserPluginGuestHelper);
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_BROWSER_PLUGIN_BROWSER_PLUGIN_GUEST_HELPER_H_
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.cc b/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.cc
index 6c86331b0fe..ed91c1f51ad 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.cc
@@ -4,7 +4,6 @@
#include "content/browser/browser_plugin/browser_plugin_guest_manager.h"
-#include "base/command_line.h"
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
@@ -13,11 +12,10 @@
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/content_export.h"
#include "content/public/browser/user_metrics.h"
-#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"
#include "content/public/common/url_constants.h"
+#include "content/public/common/url_utils.h"
#include "net/base/escape.h"
-#include "ui/events/keycodes/keyboard_codes.h"
namespace content {
@@ -43,7 +41,8 @@ BrowserPluginGuest* BrowserPluginGuestManager::CreateGuest(
int instance_id,
const BrowserPluginHostMsg_Attach_Params& params,
scoped_ptr<base::DictionaryValue> extra_params) {
- SiteInstance* guest_site_instance = NULL;
+ RenderProcessHost* embedder_process_host =
+ embedder_site_instance->GetProcess();
// Validate that the partition id coming from the renderer is valid UTF-8,
// since we depend on this in other parts of the code, such as FilePath
// creation. If the validation fails, treat it as a bad message and kill the
@@ -51,50 +50,44 @@ BrowserPluginGuest* BrowserPluginGuestManager::CreateGuest(
if (!IsStringUTF8(params.storage_partition_id)) {
content::RecordAction(UserMetricsAction("BadMessageTerminate_BPGM"));
base::KillProcess(
- embedder_site_instance->GetProcess()->GetHandle(),
+ embedder_process_host->GetHandle(),
content::RESULT_CODE_KILLED_BAD_MESSAGE, false);
return NULL;
}
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- if (command_line.HasSwitch(switches::kSitePerProcess)) {
- // When --site-per-process is specified, the behavior of BrowserPlugin
- // as <webview> is broken and we use it for rendering out-of-process
- // iframes instead. We use the src URL sent by the renderer to find the
- // right process in which to place this instance.
- // Note: Since BrowserPlugin doesn't support cross-process navigation,
- // the instance will stay in the initially assigned process, regardless
- // of the site it is navigated to.
- // TODO(nasko): Fix this, and such that cross-process navigations are
- // supported.
- guest_site_instance =
- embedder_site_instance->GetRelatedSiteInstance(GURL(params.src));
- } else {
- const std::string& host = embedder_site_instance->GetSiteURL().host();
-
- std::string url_encoded_partition = net::EscapeQueryParamValue(
- params.storage_partition_id, false);
- // The SiteInstance of a given webview tag is based on the fact that it's
- // a guest process in addition to which platform application the tag
- // belongs to and what storage partition is in use, rather than the URL
- // that the tag is being navigated to.
- GURL guest_site(
- base::StringPrintf("%s://%s/%s?%s", chrome::kGuestScheme,
- host.c_str(),
- params.persist_storage ? "persist" : "",
- url_encoded_partition.c_str()));
-
- // If we already have a webview tag in the same app using the same storage
- // partition, we should use the same SiteInstance so the existing tag and
- // the new tag can script each other.
- guest_site_instance = GetGuestSiteInstance(guest_site);
- if (!guest_site_instance) {
- // Create the SiteInstance in a new BrowsingInstance, which will ensure
- // that webview tags are also not allowed to send messages across
- // different partitions.
- guest_site_instance = SiteInstance::CreateForURL(
- embedder_site_instance->GetBrowserContext(), guest_site);
- }
+ // We usually require BrowserPlugins to be hosted by a storage isolated
+ // extension. We treat WebUI pages as a special case if they host the
+ // BrowserPlugin in a component extension iframe. In that case, we use the
+ // iframe's URL to determine the extension.
+ const GURL& embedder_site_url = embedder_site_instance->GetSiteURL();
+ GURL validated_frame_url(params.embedder_frame_url);
+ RenderViewHost::FilterURL(
+ embedder_process_host, false, &validated_frame_url);
+ const std::string& host = content::HasWebUIScheme(embedder_site_url) ?
+ validated_frame_url.host() : embedder_site_url.host();
+
+ std::string url_encoded_partition = net::EscapeQueryParamValue(
+ params.storage_partition_id, false);
+ // The SiteInstance of a given webview tag is based on the fact that it's
+ // a guest process in addition to which platform application the tag
+ // belongs to and what storage partition is in use, rather than the URL
+ // that the tag is being navigated to.
+ GURL guest_site(base::StringPrintf("%s://%s/%s?%s",
+ kGuestScheme,
+ host.c_str(),
+ params.persist_storage ? "persist" : "",
+ url_encoded_partition.c_str()));
+
+ // If we already have a webview tag in the same app using the same storage
+ // partition, we should use the same SiteInstance so the existing tag and
+ // the new tag can script each other.
+ SiteInstance* guest_site_instance = GetGuestSiteInstance(guest_site);
+ if (!guest_site_instance) {
+ // Create the SiteInstance in a new BrowsingInstance, which will ensure
+ // that webview tags are also not allowed to send messages across
+ // different partitions.
+ guest_site_instance = SiteInstance::CreateForURL(
+ embedder_site_instance->GetBrowserContext(), guest_site);
}
return WebContentsImpl::CreateGuest(
@@ -233,40 +226,17 @@ void BrowserPluginGuestManager::OnUnhandledSwapBuffersACK(
sync_point);
}
-void BrowserPluginGuestManager::DidSendScreenRects(
- WebContentsImpl* embedder_web_contents) {
- // TODO(lazyboy): Generalize iterating over guest instances and performing
- // actions on the guests.
+bool BrowserPluginGuestManager::ForEachGuest(
+ WebContentsImpl* embedder_web_contents, const GuestCallback& callback) {
for (GuestInstanceMap::iterator it =
guest_web_contents_by_instance_id_.begin();
- it != guest_web_contents_by_instance_id_.end(); ++it) {
+ it != guest_web_contents_by_instance_id_.end(); ++it) {
BrowserPluginGuest* guest = it->second->GetBrowserPluginGuest();
- if (embedder_web_contents == guest->embedder_web_contents()) {
- static_cast<RenderViewHostImpl*>(
- guest->GetWebContents()->GetRenderViewHost())->SendScreenRects();
- }
- }
-}
+ if (embedder_web_contents != guest->embedder_web_contents())
+ continue;
-bool BrowserPluginGuestManager::UnlockMouseIfNecessary(
- WebContentsImpl* embedder_web_contents,
- const NativeWebKeyboardEvent& event) {
- if ((event.type != WebKit::WebInputEvent::RawKeyDown) ||
- (event.windowsKeyCode != ui::VKEY_ESCAPE) ||
- (event.modifiers & WebKit::WebInputEvent::InputModifiers)) {
- return false;
- }
-
- // TODO(lazyboy): Generalize iterating over guest instances and performing
- // actions on the guests.
- for (GuestInstanceMap::iterator it =
- guest_web_contents_by_instance_id_.begin();
- it != guest_web_contents_by_instance_id_.end(); ++it) {
- BrowserPluginGuest* guest = it->second->GetBrowserPluginGuest();
- if (embedder_web_contents == guest->embedder_web_contents()) {
- if (guest->UnlockMouseIfNecessary(event))
- return true;
- }
+ if (callback.Run(guest))
+ return true;
}
return false;
}
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.h b/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.h
index a657bfa7a67..5f3b3b9c686 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.h
+++ b/chromium/content/browser/browser_plugin/browser_plugin_guest_manager.h
@@ -36,8 +36,10 @@ class RenderWidgetHostImpl;
class SiteInstance;
class WebContents;
class WebContentsImpl;
-struct NativeWebKeyboardEvent;
+// WARNING: All APIs should be guarded with a process ID check like
+// CanEmbedderAccessInstanceIDMaybeKill, to prevent abuse by normal renderer
+// processes.
class CONTENT_EXPORT BrowserPluginGuestManager :
public base::SupportsUserData::Data {
public:
@@ -83,10 +85,9 @@ class CONTENT_EXPORT BrowserPluginGuestManager :
bool CanEmbedderAccessInstanceIDMaybeKill(int embedder_render_process_id,
int instance_id) const;
- void DidSendScreenRects(WebContentsImpl* embedder_web_contents);
-
- bool UnlockMouseIfNecessary(WebContentsImpl* embedder_web_contents_,
- const NativeWebKeyboardEvent& event);
+ typedef base::Callback<bool(BrowserPluginGuest*)> GuestCallback;
+ bool ForEachGuest(WebContentsImpl* embedder_web_contents,
+ const GuestCallback& callback);
void OnMessageReceived(const IPC::Message& message, int render_process_id);
diff --git a/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc b/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
index d49f169f05f..9e48a49647d 100644
--- a/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
+++ b/chromium/content/browser/browser_plugin/browser_plugin_host_browsertest.cc
@@ -18,11 +18,12 @@
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/view_messages.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
-#include "content/public/browser/render_view_host_observer.h"
#include "content/public/browser/render_widget_host_view.h"
+#include "content/public/browser/web_contents_observer.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/drop_data.h"
#include "content/public/common/url_constants.h"
@@ -38,31 +39,16 @@
#include "net/test/spawned_test_server/spawned_test_server.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
-using WebKit::WebInputEvent;
-using WebKit::WebMouseEvent;
+using blink::WebInputEvent;
+using blink::WebMouseEvent;
using content::BrowserPluginEmbedder;
using content::BrowserPluginGuest;
using content::BrowserPluginHostFactory;
using content::WebContentsImpl;
-namespace {
-
const char kHTMLForGuest[] =
"data:text/html,<html><body>hello world</body></html>";
-const char kHTMLForGuestBusyLoop[] =
- "data:text/html,<html><head><script type=\"text/javascript\">"
- "function PauseMs(timems) {"
- " document.title = \"start\";"
- " var date = new Date();"
- " var currDate = null;"
- " do {"
- " currDate = new Date();"
- " } while (currDate - date < timems)"
- "}"
- "function StartPauseMs(timems) {"
- " setTimeout(function() { PauseMs(timems); }, 0);"
- "}"
- "</script></head><body></body></html>";
+
const char kHTMLForGuestTouchHandler[] =
"data:text/html,<html><body><div id=\"touch\">With touch</div></body>"
"<script type=\"text/javascript\">"
@@ -76,11 +62,7 @@ const char kHTMLForGuestTouchHandler[] =
" handler);"
"}"
"</script></html>";
-const char kHTMLForGuestWithTitle[] =
- "data:text/html,"
- "<html><head><title>%s</title></head>"
- "<body>hello world</body>"
- "</html>";
+
const char kHTMLForGuestAcceptDrag[] =
"data:text/html,<html><body>"
"<script>"
@@ -92,6 +74,7 @@ const char kHTMLForGuestAcceptDrag[] =
" ondrop=\"dropped();\">"
"</textarea>"
"</body></html>";
+
const char kHTMLForGuestWithSize[] =
"data:text/html,"
"<html>"
@@ -100,12 +83,6 @@ const char kHTMLForGuestWithSize[] =
"</body>"
"</html>";
-std::string GetHTMLForGuestWithTitle(const std::string& title) {
- return base::StringPrintf(kHTMLForGuestWithTitle, title.c_str());
-}
-
-} // namespace
-
namespace content {
// Test factory for creating test instances of BrowserPluginEmbedder and
@@ -169,9 +146,9 @@ class TestShortHangTimeoutGuestFactory : public TestBrowserPluginHostFactory {
public:
virtual BrowserPluginGuest* CreateBrowserPluginGuest(
int instance_id, WebContentsImpl* web_contents) OVERRIDE {
- BrowserPluginGuest* guest =
+ TestBrowserPluginGuest* guest =
new TestBrowserPluginGuest(instance_id, web_contents);
- guest->set_guest_hang_timeout_for_testing(TestTimeouts::tiny_timeout());
+ guest->set_guest_hang_timeout(TestTimeouts::tiny_timeout());
return guest;
}
@@ -193,16 +170,15 @@ class TestShortHangTimeoutGuestFactory : public TestBrowserPluginHostFactory {
// A transparent observer that can be used to verify that a RenderViewHost
// received a specific message.
-class RenderViewHostMessageObserver : public RenderViewHostObserver {
+class MessageObserver : public WebContentsObserver {
public:
- RenderViewHostMessageObserver(RenderViewHost* host,
- uint32 message_id)
- : RenderViewHostObserver(host),
+ MessageObserver(WebContents* web_contents, uint32 message_id)
+ : WebContentsObserver(web_contents),
message_id_(message_id),
message_received_(false) {
}
- virtual ~RenderViewHostMessageObserver() {}
+ virtual ~MessageObserver() {}
void WaitUntilMessageReceived() {
if (message_received_)
@@ -230,7 +206,7 @@ class RenderViewHostMessageObserver : public RenderViewHostObserver {
uint32 message_id_;
bool message_received_;
- DISALLOW_COPY_AND_ASSIGN(RenderViewHostMessageObserver);
+ DISALLOW_COPY_AND_ASSIGN(MessageObserver);
};
class BrowserPluginHostTest : public ContentBrowserTest {
@@ -411,7 +387,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AdvanceFocus) {
StartBrowserPluginTest(kEmbedderURL, kGuestURL, false, std::string());
SimulateMouseClick(test_embedder()->web_contents(), 0,
- WebKit::WebMouseEvent::ButtonLeft);
+ blink::WebMouseEvent::ButtonLeft);
BrowserPluginHostTest::SimulateTabKeyPress(test_embedder()->web_contents());
// Wait until we focus into the guest.
test_guest()->WaitForFocus();
@@ -445,7 +421,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderChangedAfterSwap) {
GURL test_https_url(https_server.GetURL(
"files/browser_plugin_title_change.html"));
content::WindowedNotificationObserver swap_observer(
- content::NOTIFICATION_WEB_CONTENTS_SWAPPED,
+ content::NOTIFICATION_RENDER_VIEW_HOST_CHANGED,
content::Source<WebContents>(test_embedder()->web_contents()));
NavigateToURL(shell(), test_https_url);
swap_observer.Wait();
@@ -463,7 +439,13 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderChangedAfterSwap) {
// This test opens two pages in http and there is no RenderViewHost swap,
// therefore the embedder created on first page navigation stays the same in
// web_contents.
-IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderSameAfterNav) {
+// Failing flakily on Windows: crbug.com/308405
+#if defined(OS_WIN)
+#define MAYBE_EmbedderSameAfterNav DISABLED_EmbedderSameAfterNav
+#else
+#define MAYBE_EmbedderSameAfterNav EmbedderSameAfterNav
+#endif
+IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_EmbedderSameAfterNav) {
const char kEmbedderURL[] = "/browser_plugin_embedder.html";
StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true, std::string());
WebContentsImpl* embedder_web_contents = test_embedder()->web_contents();
@@ -472,13 +454,13 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, EmbedderSameAfterNav) {
// does not happen and existing embedder doesn't change in web_contents.
GURL test_url_new(embedded_test_server()->GetURL(
"/browser_plugin_title_change.html"));
- const string16 expected_title = ASCIIToUTF16("done");
+ const base::string16 expected_title = ASCIIToUTF16("done");
content::TitleWatcher title_watcher(shell()->web_contents(), expected_title);
NavigateToURL(shell(), test_url_new);
- LOG(INFO) << "Start waiting for title";
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ VLOG(0) << "Start waiting for title";
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
- LOG(INFO) << "Done navigating to second page";
+ VLOG(0) << "Done navigating to second page";
TestBrowserPluginEmbedder* test_embedder_after_nav =
static_cast<TestBrowserPluginEmbedder*>(
@@ -527,8 +509,8 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, AcceptTouchEvents) {
// Install the touch handler in the guest. This should cause the embedder to
// start listening for touch events too.
- RenderViewHostMessageObserver observer(rvh,
- ViewHostMsg_HasTouchEventHandlers::ID);
+ MessageObserver observer(test_embedder()->web_contents(),
+ ViewHostMsg_HasTouchEventHandlers::ID);
ExecuteSyncJSFunction(test_guest()->web_contents()->GetRenderViewHost(),
"InstallTouchHandler();");
observer.WaitUntilMessageReceived();
@@ -555,26 +537,26 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadEmbedder) {
// the page has successfully reloaded when it goes back to 'embedder'
// in the next step.
{
- const string16 expected_title = ASCIIToUTF16("modified");
+ const base::string16 expected_title = ASCIIToUTF16("modified");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
ExecuteSyncJSFunction(rvh,
base::StringPrintf("SetTitle('%s');", "modified"));
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
// Reload the embedder page, and verify that the reload was successful.
// Then navigate the guest to verify that the browser process does not crash.
{
- const string16 expected_title = ASCIIToUTF16("embedder");
+ const base::string16 expected_title = ASCIIToUTF16("embedder");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
test_embedder()->web_contents()->GetController().Reload(false);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
ExecuteSyncJSFunction(
@@ -596,8 +578,9 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, ReloadEmbedder) {
}
}
-// Always failing in the win7_aura try bot. See http://crbug.com/181107.
-#if defined(OS_WIN) && defined(USE_AURA)
+// Always failing in the win7_aura try bot. See http://crbug.com/181107.
+// Times out on the Mac. See http://crbug.com/297576.
+#if (defined(OS_WIN) && defined(USE_AURA)) || defined(OS_MACOSX)
#define MAYBE_AcceptDragEvents DISABLED_AcceptDragEvents
#else
#define MAYBE_AcceptDragEvents AcceptDragEvents
@@ -636,17 +619,17 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, MAYBE_AcceptDragEvents) {
// This should trigger appropriate messages from the embedder to the guest,
// and end with a drop on the guest. The guest changes title when a drop
// happens.
- const string16 expected_title = ASCIIToUTF16("DROPPED");
+ const base::string16 expected_title = ASCIIToUTF16("DROPPED");
content::TitleWatcher title_watcher(test_guest()->web_contents(),
expected_title);
rvh->DragTargetDragEnter(drop_data, gfx::Point(start_x, start_y),
- gfx::Point(start_x, start_y), WebKit::WebDragOperationEvery, 0);
+ gfx::Point(start_x, start_y), blink::WebDragOperationEvery, 0);
rvh->DragTargetDragOver(gfx::Point(end_x, end_y), gfx::Point(end_x, end_y),
- WebKit::WebDragOperationEvery, 0);
+ blink::WebDragOperationEvery, 0);
rvh->DragTargetDrop(gfx::Point(end_x, end_y), gfx::Point(end_x, end_y), 0);
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
@@ -668,7 +651,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PostMessage) {
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
- const string16 expected_title = ASCIIToUTF16("main guest");
+ const base::string16 expected_title = ASCIIToUTF16("main guest");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
@@ -679,7 +662,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, PostMessage) {
// The title will be updated to "main guest" at the last stage of the
// process described above.
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
}
@@ -696,7 +679,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) {
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
test_embedder()->web_contents()->GetRenderViewHost());
{
- const string16 expected_title = ASCIIToUTF16("main guest");
+ const base::string16 expected_title = ASCIIToUTF16("main guest");
content::TitleWatcher title_watcher(test_embedder()->web_contents(),
expected_title);
@@ -705,7 +688,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) {
// The title will be updated to "main guest" at the last stage of the
// process described above.
- string16 actual_title = title_watcher.WaitAndGetTitle();
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
}
{
@@ -721,7 +704,7 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DISABLED_PostMessageToIFrame) {
base::StringPrintf(
"CreateChildFrame('%s');", test_url.spec().c_str()));
- string16 actual_title = ready_watcher.WaitAndGetTitle();
+ base::string16 actual_title = ready_watcher.WaitAndGetTitle();
EXPECT_EQ(ASCIIToUTF16("ready"), actual_title);
content::TitleWatcher iframe_watcher(test_embedder()->web_contents(),
@@ -823,10 +806,234 @@ IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, DoNotCrashOnInvalidNavigation) {
// should be blocked because the scheme isn't web-safe or a pseudo-scheme.
ExecuteSyncJSFunction(
test_embedder()->web_contents()->GetRenderViewHost(),
- base::StringPrintf("SetSrc('%s://abc123');",
- chrome::kGuestScheme));
+ base::StringPrintf("SetSrc('%s://abc123');", kGuestScheme));
EXPECT_TRUE(delegate->load_aborted());
EXPECT_TRUE(delegate->load_aborted_url().is_valid());
}
+// Tests involving the threaded compositor.
+class BrowserPluginThreadedCompositorTest : public BrowserPluginHostTest {
+ public:
+ BrowserPluginThreadedCompositorTest() {}
+ virtual ~BrowserPluginThreadedCompositorTest() {}
+
+ protected:
+ virtual void SetUpCommandLine(CommandLine* cmd) OVERRIDE {
+ BrowserPluginHostTest::SetUpCommandLine(cmd);
+ cmd->AppendSwitch(switches::kEnableThreadedCompositing);
+
+ // http://crbug.com/327035
+ cmd->AppendSwitch(switches::kDisableDelegatedRenderer);
+ }
+};
+
+static void CompareSkBitmaps(const SkBitmap& expected_bitmap,
+ const SkBitmap& bitmap) {
+ EXPECT_EQ(expected_bitmap.width(), bitmap.width());
+ if (expected_bitmap.width() != bitmap.width())
+ return;
+ EXPECT_EQ(expected_bitmap.height(), bitmap.height());
+ if (expected_bitmap.height() != bitmap.height())
+ return;
+ EXPECT_EQ(expected_bitmap.config(), bitmap.config());
+ if (expected_bitmap.config() != bitmap.config())
+ return;
+
+ SkAutoLockPixels expected_bitmap_lock(expected_bitmap);
+ SkAutoLockPixels bitmap_lock(bitmap);
+ int fails = 0;
+ const int kAllowableError = 2;
+ for (int i = 0; i < bitmap.width() && fails < 10; ++i) {
+ for (int j = 0; j < bitmap.height() && fails < 10; ++j) {
+ SkColor expected_color = expected_bitmap.getColor(i, j);
+ SkColor color = bitmap.getColor(i, j);
+ int expected_alpha = SkColorGetA(expected_color);
+ int alpha = SkColorGetA(color);
+ int expected_red = SkColorGetR(expected_color);
+ int red = SkColorGetR(color);
+ int expected_green = SkColorGetG(expected_color);
+ int green = SkColorGetG(color);
+ int expected_blue = SkColorGetB(expected_color);
+ int blue = SkColorGetB(color);
+ EXPECT_NEAR(expected_alpha, alpha, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ EXPECT_NEAR(expected_red, red, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ EXPECT_NEAR(expected_green, green, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ EXPECT_NEAR(expected_blue, blue, kAllowableError)
+ << "expected_color: " << std::hex << expected_color
+ << " color: " << color
+ << " Failed at " << std::dec << i << ", " << j
+ << " Failure " << ++fails;
+ }
+ }
+ EXPECT_LT(fails, 10);
+}
+
+static void CompareSkBitmapAndRun(const base::Closure& callback,
+ const SkBitmap& expected_bitmap,
+ bool *result,
+ bool succeed,
+ const SkBitmap& bitmap) {
+ *result = succeed;
+ if (succeed)
+ CompareSkBitmaps(expected_bitmap, bitmap);
+ callback.Run();
+}
+
+// http://crbug.com/171744
+#if defined(OS_MACOSX)
+#define MAYBE_GetBackingStore DISABLED_GetBackingStore
+#else
+#define MAYBE_GetBackingStore GetBackingStore
+#endif
+IN_PROC_BROWSER_TEST_F(BrowserPluginThreadedCompositorTest,
+ MAYBE_GetBackingStore) {
+ const char kEmbedderURL[] = "/browser_plugin_embedder.html";
+ const char kHTMLForGuest[] =
+ "data:text/html,<html><style>body { background-color: red; }</style>"
+ "<body></body></html>";
+ StartBrowserPluginTest(kEmbedderURL, kHTMLForGuest, true,
+ std::string("SetSize(50, 60);"));
+
+ WebContentsImpl* guest_contents = test_guest()->web_contents();
+ RenderWidgetHostImpl* guest_widget_host =
+ RenderWidgetHostImpl::From(guest_contents->GetRenderViewHost());
+
+ SkBitmap expected_bitmap;
+ expected_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 50, 60);
+ expected_bitmap.allocPixels();
+ expected_bitmap.eraseARGB(255, 255, 0, 0); // #f00
+ bool result = false;
+ while (!result) {
+ base::RunLoop loop;
+ guest_widget_host->CopyFromBackingStore(gfx::Rect(),
+ guest_widget_host->GetView()->GetViewBounds().size(),
+ base::Bind(&CompareSkBitmapAndRun, loop.QuitClosure(), expected_bitmap,
+ &result));
+ loop.Run();
+ }
+}
+
+// Tests input method.
+IN_PROC_BROWSER_TEST_F(BrowserPluginHostTest, InputMethod) {
+ const char kEmbedderURL[] = "/browser_plugin_embedder.html";
+ const char kGuestHTML[] = "data:text/html,"
+ "<html><body><input id=\"input1\">"
+ "<input id=\"input2\"></body>"
+ "<script>"
+ "var i = document.getElementById(\"input1\");"
+ "i.oninput = function() {"
+ " document.title = i.value;"
+ "}"
+ "</script>"
+ "</html>";
+ StartBrowserPluginTest(kEmbedderURL, kGuestHTML, true,
+ "document.getElementById(\"plugin\").focus();");
+
+ RenderViewHostImpl* embedder_rvh = static_cast<RenderViewHostImpl*>(
+ test_embedder()->web_contents()->GetRenderViewHost());
+ RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
+ test_guest()->web_contents()->GetRenderViewHost());
+
+ std::vector<blink::WebCompositionUnderline> underlines;
+
+ // An input field in browser plugin guest gets focus and given some user
+ // input via IME.
+ {
+ ExecuteSyncJSFunction(guest_rvh,
+ "document.getElementById('input1').focus();");
+ string16 expected_title = UTF8ToUTF16("InputTest123");
+ content::TitleWatcher title_watcher(test_guest()->web_contents(),
+ expected_title);
+ embedder_rvh->Send(
+ new ViewMsg_ImeSetComposition(
+ test_embedder()->web_contents()->GetRoutingID(),
+ expected_title,
+ underlines,
+ 12, 12));
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
+ EXPECT_EQ(expected_title, actual_title);
+ }
+ // A composition is committed via IME.
+ {
+ string16 expected_title = UTF8ToUTF16("InputTest456");
+ content::TitleWatcher title_watcher(test_guest()->web_contents(),
+ expected_title);
+ embedder_rvh->Send(
+ new ViewMsg_ImeConfirmComposition(
+ test_embedder()->web_contents()->GetRoutingID(),
+ expected_title,
+ gfx::Range(),
+ true));
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
+ EXPECT_EQ(expected_title, actual_title);
+ }
+ // IME composition starts, but focus moves out, then the composition will
+ // be committed and get cancel msg.
+ {
+ ExecuteSyncJSFunction(guest_rvh,
+ "document.getElementById('input1').value = '';");
+ string16 composition = UTF8ToUTF16("InputTest789");
+ content::TitleWatcher title_watcher(test_guest()->web_contents(),
+ composition);
+ embedder_rvh->Send(
+ new ViewMsg_ImeSetComposition(
+ test_embedder()->web_contents()->GetRoutingID(),
+ composition,
+ underlines,
+ 12, 12));
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
+ EXPECT_EQ(composition, actual_title);
+ // Moving focus causes IME cancel, and the composition will be committed
+ // in input1, not in input2.
+ ExecuteSyncJSFunction(guest_rvh,
+ "document.getElementById('input2').focus();");
+ test_guest()->WaitForImeCancel();
+ scoped_ptr<base::Value> value =
+ content::ExecuteScriptAndGetValue(
+ guest_rvh, "document.getElementById('input1').value");
+ std::string result;
+ ASSERT_TRUE(value->GetAsString(&result));
+ EXPECT_EQ(UTF16ToUTF8(composition), result);
+ }
+ // Tests ExtendSelectionAndDelete message works in browser_plugin.
+ {
+ // Set 'InputTestABC' in input1 and put caret at 6 (after 'T').
+ ExecuteSyncJSFunction(guest_rvh,
+ "var i = document.getElementById('input1');"
+ "i.focus();"
+ "i.value = 'InputTestABC';"
+ "i.selectionStart=6;"
+ "i.selectionEnd=6;");
+ string16 expected_value = UTF8ToUTF16("InputABC");
+ content::TitleWatcher title_watcher(test_guest()->web_contents(),
+ expected_value);
+ // Delete 'Test' in 'InputTestABC', as the caret is after 'T':
+ // delete before 1 character ('T') and after 3 characters ('est').
+ embedder_rvh->Send(
+ new ViewMsg_ExtendSelectionAndDelete(
+ test_embedder()->web_contents()->GetRoutingID(),
+ 1, 3));
+ base::string16 actual_title = title_watcher.WaitAndGetTitle();
+ EXPECT_EQ(expected_value, actual_title);
+ scoped_ptr<base::Value> value =
+ content::ExecuteScriptAndGetValue(
+ guest_rvh, "document.getElementById('input1').value");
+ std::string actual_value;
+ ASSERT_TRUE(value->GetAsString(&actual_value));
+ EXPECT_EQ(UTF16ToUTF8(expected_value), actual_value);
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/browser_plugin/test_browser_plugin_guest.cc b/chromium/content/browser/browser_plugin/test_browser_plugin_guest.cc
index a6e62a3ba55..91ba2909d21 100644
--- a/chromium/content/browser/browser_plugin/test_browser_plugin_guest.cc
+++ b/chromium/content/browser/browser_plugin/test_browser_plugin_guest.cc
@@ -8,7 +8,6 @@
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
-#include "content/public/browser/notification_types.h"
namespace content {
@@ -17,7 +16,7 @@ class BrowserPluginGuest;
TestBrowserPluginGuest::TestBrowserPluginGuest(
int instance_id,
WebContentsImpl* web_contents)
- : BrowserPluginGuest(instance_id, web_contents, NULL, false),
+ : BrowserPluginGuest(instance_id, false, web_contents, NULL),
update_rect_count_(0),
damage_buffer_call_count_(0),
exit_observed_(false),
@@ -28,12 +27,9 @@ TestBrowserPluginGuest::TestBrowserPluginGuest(
set_damage_buffer_observed_(false),
input_observed_(false),
load_stop_observed_(false),
+ ime_cancel_observed_(false),
waiting_for_damage_buffer_with_size_(false),
last_damage_buffer_size_(gfx::Size()) {
- // Listen to visibility changes so that a test can wait for these changes.
- notification_registrar_.Add(this,
- NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED,
- Source<WebContents>(web_contents));
}
TestBrowserPluginGuest::~TestBrowserPluginGuest() {
@@ -43,24 +39,6 @@ WebContentsImpl* TestBrowserPluginGuest::web_contents() const {
return static_cast<WebContentsImpl*>(BrowserPluginGuest::web_contents());
}
-void TestBrowserPluginGuest::Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- switch (type) {
- case NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED: {
- bool visible = *Details<bool>(details).ptr();
- if (!visible) {
- was_hidden_observed_ = true;
- if (was_hidden_message_loop_runner_.get())
- was_hidden_message_loop_runner_->Quit();
- }
- return;
- }
- }
-
- BrowserPluginGuest::Observe(type, source, details);
-}
-
void TestBrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) {
if (msg->type() == BrowserPluginMsg_UpdateRect::ID) {
update_rect_count_++;
@@ -106,7 +84,7 @@ void TestBrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) {
exit_observed_ = true;
if (status != base::TERMINATION_STATUS_NORMAL_TERMINATION &&
status != base::TERMINATION_STATUS_STILL_RUNNING)
- LOG(INFO) << "Guest crashed status: " << status;
+ VLOG(0) << "Guest crashed status: " << status;
if (crash_message_loop_runner_.get())
crash_message_loop_runner_->Quit();
BrowserPluginGuest::RenderProcessGone(status);
@@ -115,7 +93,7 @@ void TestBrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) {
void TestBrowserPluginGuest::OnHandleInputEvent(
int instance_id,
const gfx::Rect& guest_window_rect,
- const WebKit::WebInputEvent* event) {
+ const blink::WebInputEvent* event) {
BrowserPluginGuest::OnHandleInputEvent(instance_id,
guest_window_rect,
event);
@@ -204,6 +182,17 @@ void TestBrowserPluginGuest::WaitForViewSize(const gfx::Size& view_size) {
last_view_size_observed_ = gfx::Size();
}
+void TestBrowserPluginGuest::WaitForImeCancel() {
+ if (ime_cancel_observed_) {
+ ime_cancel_observed_ = false;
+ return;
+ }
+
+ ime_cancel_message_loop_runner_ = new MessageLoopRunner();
+ ime_cancel_message_loop_runner_->Run();
+ ime_cancel_observed_ = false;
+}
+
void TestBrowserPluginGuest::OnSetFocus(int instance_id, bool focused) {
if (focused) {
focus_observed_ = true;
@@ -247,4 +236,19 @@ void TestBrowserPluginGuest::DidStopLoading(
load_stop_message_loop_runner_->Quit();
}
+void TestBrowserPluginGuest::OnImeCancelComposition() {
+ if (!ime_cancel_observed_) {
+ ime_cancel_observed_ = true;
+ if (ime_cancel_message_loop_runner_.get())
+ ime_cancel_message_loop_runner_->Quit();
+ }
+ BrowserPluginGuest::OnImeCancelComposition();
+}
+
+void TestBrowserPluginGuest::WasHidden() {
+ was_hidden_observed_ = true;
+ if (was_hidden_message_loop_runner_.get())
+ was_hidden_message_loop_runner_->Quit();
+}
+
} // namespace content
diff --git a/chromium/content/browser/browser_plugin/test_browser_plugin_guest.h b/chromium/content/browser/browser_plugin/test_browser_plugin_guest.h
index 7fccb002388..1ef7f0dbecf 100644
--- a/chromium/content/browser/browser_plugin/test_browser_plugin_guest.h
+++ b/chromium/content/browser/browser_plugin/test_browser_plugin_guest.h
@@ -27,21 +27,20 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
WebContentsImpl* web_contents() const;
- // NotificationObserver method override.
- virtual void Observe(int type,
- const NotificationSource& source,
- const NotificationDetails& details) OVERRIDE;
-
// Overridden methods from BrowserPluginGuest to intercept in test objects.
virtual void RenderProcessGone(base::TerminationStatus status) OVERRIDE;
virtual void OnHandleInputEvent(int instance_id,
const gfx::Rect& guest_window_rect,
- const WebKit::WebInputEvent* event) OVERRIDE;
+ const blink::WebInputEvent* event) OVERRIDE;
virtual void OnSetFocus(int instance_id, bool focused) OVERRIDE;
virtual void OnTakeFocus(bool reverse) OVERRIDE;
virtual void SetDamageBuffer(
const BrowserPluginHostMsg_ResizeGuest_Params& params) OVERRIDE;
virtual void DidStopLoading(RenderViewHost* render_view_host) OVERRIDE;
+ virtual void OnImeCancelComposition() OVERRIDE;
+
+ // Overridden from WebContentsObserver.
+ virtual void WasHidden() OVERRIDE;
// Test utilities to wait for a event we are interested in.
// Waits until UpdateRect message is sent from the guest, meaning it is
@@ -66,6 +65,12 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
void WaitForLoadStop();
// Waits until UpdateRect with a particular |view_size| is observed.
void WaitForViewSize(const gfx::Size& view_size);
+ // Waits until IME cancellation is observed.
+ void WaitForImeCancel();
+
+ void set_guest_hang_timeout(const base::TimeDelta& timeout) {
+ guest_hang_timeout_ = timeout;
+ }
private:
// Overridden methods from BrowserPluginGuest to intercept in test objects.
@@ -81,6 +86,7 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
bool set_damage_buffer_observed_;
bool input_observed_;
bool load_stop_observed_;
+ bool ime_cancel_observed_;
gfx::Size last_view_size_observed_;
gfx::Size expected_auto_view_size_;
@@ -99,6 +105,7 @@ class TestBrowserPluginGuest : public BrowserPluginGuest {
scoped_refptr<MessageLoopRunner> input_message_loop_runner_;
scoped_refptr<MessageLoopRunner> load_stop_message_loop_runner_;
scoped_refptr<MessageLoopRunner> auto_view_size_message_loop_runner_;
+ scoped_refptr<MessageLoopRunner> ime_cancel_message_loop_runner_;
DISALLOW_COPY_AND_ASSIGN(TestBrowserPluginGuest);
};
diff --git a/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc b/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc
index 28c27b7578e..59ae63555d9 100644
--- a/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc
+++ b/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.cc
@@ -20,9 +20,9 @@ void TestBrowserPluginGuestDelegate::ResetStates() {
void TestBrowserPluginGuestDelegate::AddMessageToConsole(
int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) {
+ const base::string16& source_id) {
}
void TestBrowserPluginGuestDelegate::Close() {
@@ -53,10 +53,12 @@ void TestBrowserPluginGuestDelegate::RendererUnresponsive() {
bool TestBrowserPluginGuestDelegate::RequestPermission(
BrowserPluginPermissionType permission_type,
const base::DictionaryValue& request_info,
- const PermissionResponseCallback& callback) {
+ const PermissionResponseCallback& callback,
+ bool allowed_by_default) {
return BrowserPluginGuestDelegate::RequestPermission(permission_type,
request_info,
- callback);
+ callback,
+ allowed_by_default);
}
void TestBrowserPluginGuestDelegate::SizeChanged(const gfx::Size& old_size,
diff --git a/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h b/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h
index b6e7e9079f3..4bfae4c622f 100644
--- a/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h
+++ b/chromium/content/browser/browser_plugin/test_browser_plugin_guest_delegate.h
@@ -22,9 +22,9 @@ class TestBrowserPluginGuestDelegate : public BrowserPluginGuestDelegate {
private:
// Overridden from BrowserPluginGuestDelegate:
virtual void AddMessageToConsole(int32 level,
- const string16& message,
+ const base::string16& message,
int32 line_no,
- const string16& source_id) OVERRIDE;
+ const base::string16& source_id) OVERRIDE;
virtual void Close() OVERRIDE;
virtual void GuestProcessGone(base::TerminationStatus status) OVERRIDE;
virtual bool HandleKeyboardEvent(
@@ -37,7 +37,8 @@ class TestBrowserPluginGuestDelegate : public BrowserPluginGuestDelegate {
virtual bool RequestPermission(
BrowserPluginPermissionType permission_type,
const base::DictionaryValue& request_info,
- const PermissionResponseCallback& callback) OVERRIDE;
+ const PermissionResponseCallback& callback,
+ bool allowed_by_default) OVERRIDE;
virtual void SizeChanged(const gfx::Size& old_size,
const gfx::Size& new_size) OVERRIDE;