This source file includes following definitions.
- Respond
- AllowedByDefault
- PermissionRequest
- PermissionRequest
- callback_
- RespondImpl
- DownloadRequest
- bridge_id_
- RespondImpl
- GeolocationRequest
- callback_
- RespondImpl
- MediaRequest
- instance_id_
- RespondImpl
- NewWindowRequest
- callback_
- RespondImpl
- JavaScriptDialogRequest
- PointerLockRequest
- RespondImpl
- PointerLockRequest
- WindowOpenDispositionToString
- JavaScriptMessageTypeToString
- RetrieveDownloadURLFromRequestId
- browser_plugin_guest_
- EmbedderWebContentsObserver
- WebContentsDestroyed
- WasShown
- WasHidden
- weak_ptr_factory_
- AddMessageToConsole
- DestroyUnattachedWindows
- LoadURLWithParams
- RespondToPermissionRequest
- RequestPermission
- CreateNewGuestWindow
- AsWeakPtr
- EmbedderDestroyed
- Destroy
- OnMessageReceivedFromEmbedder
- Initialize
- Create
- CreateWithOpener
- GetEmbedderRenderWidgetHostView
- UpdateVisibility
- CopyFromCompositingSurface
- ToGuestRect
- EmbedderVisibilityChanged
- AddNewContents
- CanDownload
- LoadProgressChanged
- CloseContents
- GetJavaScriptDialogManager
- OpenColorChooser
- HandleContextMenu
- HandleKeyboardEvent
- SetZoom
- FindReply
- OpenURLFromTab
- WebContentsCreated
- RendererUnresponsive
- RendererResponsive
- RunFileChooser
- ShouldFocusPageAfterCrash
- GetWebContents
- GetDamageBufferFromEmbedder
- SetDamageBuffer
- GetScreenCoordinates
- InAutoSizeBounds
- RequestNewWindowPermission
- UnlockMouseIfNecessary
- SendMessageToEmbedder
- DragSourceEndedAt
- EndSystemDrag
- SetDelegate
- AskEmbedderForGeolocationPermission
- RemoveBridgeID
- CancelGeolocationRequest
- SetGeolocationPermission
- SendQueuedMessages
- DidCommitProvisionalLoadForFrame
- DidStopLoading
- RenderViewReady
- RenderProcessGone
- AcknowledgeBufferPresent
- ShouldForwardToBrowserPluginGuest
- OnMessageReceived
- Attach
- OnCompositorFrameSwappedACK
- OnDragStatusUpdate
- OnExecuteEditCommand
- OnImeSetComposition
- OnImeConfirmComposition
- OnExtendSelectionAndDelete
- OnReclaimCompositorResources
- OnHandleInputEvent
- OnLockMouse
- OnLockMouseAck
- OnNavigateGuest
- OnPluginDestroyed
- OnResizeGuest
- OnSetFocus
- OnSetName
- OnSetSize
- OnSetEditCommandsForNextKeyEvent
- OnSetContentsOpaque
- OnSetVisibility
- OnSwapBuffersACK
- OnUnlockMouse
- OnUnlockMouseAck
- OnUpdateRectACK
- OnCopyFromCompositingSurfaceAck
- OnUpdateGeometry
- OnHasTouchEventHandlers
- OnSetCursor
- OnShowPopup
- OnShowWidget
- OnTakeFocus
- OnUpdateFrameName
- RequestMediaAccessPermission
- PreHandleGestureEvent
- RunJavaScriptDialog
- RunBeforeUnloadDialog
- HandleJavaScriptDialog
- CancelActiveAndPendingDialogs
- WebContentsDestroyed
- OnUpdateRect
- OnTextInputTypeChanged
- OnImeCancelComposition
- OnImeCompositionRangeChanged
- DidRetrieveDownloadURLFromRequestId
#include "content/browser/browser_plugin/browser_plugin_guest.h"
#include <algorithm>
#include "base/message_loop/message_loop.h"
#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_manager.h"
#include "content/browser/browser_plugin/browser_plugin_host_factory.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_widget_host_view_guest.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view_guest.h"
#include "content/common/browser_plugin/browser_plugin_constants.h"
#include "content/common/browser_plugin/browser_plugin_messages.h"
#include "content/common/content_constants_internal.h"
#include "content/common/drag_messages.h"
#include "content/common/gpu/gpu_messages.h"
#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/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"
#include "content/public/common/result_codes.h"
#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/platform/WebCursorInfo.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/surface/transport_dib.h"
#include "webkit/common/resource_type.h"
#if defined(OS_MACOSX)
#include "content/browser/browser_plugin/browser_plugin_popup_menu_helper_mac.h"
#endif
namespace content {
BrowserPluginHostFactory* BrowserPluginGuest::factory_ = NULL;
class BrowserPluginGuest::PermissionRequest :
public base::RefCounted<BrowserPluginGuest::PermissionRequest> {
public:
void Respond(bool should_allow, const std::string& user_input) {
if (!guest_)
return;
RespondImpl(should_allow, user_input);
}
virtual bool AllowedByDefault() const {
return false;
}
protected:
explicit PermissionRequest(const base::WeakPtr<BrowserPluginGuest>& guest)
: guest_(guest) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest"));
}
virtual ~PermissionRequest() {}
virtual void RespondImpl(bool should_allow,
const std::string& user_input) = 0;
friend class base::RefCounted<BrowserPluginGuest::PermissionRequest>;
base::WeakPtr<BrowserPluginGuest> guest_;
};
class BrowserPluginGuest::DownloadRequest : public PermissionRequest {
public:
DownloadRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
const base::Callback<void(bool)>& callback)
: PermissionRequest(guest),
callback_(callback) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Download"));
}
virtual void RespondImpl(bool should_allow,
const std::string& user_input) OVERRIDE {
callback_.Run(should_allow);
}
private:
virtual ~DownloadRequest() {}
base::Callback<void(bool)> callback_;
};
class BrowserPluginGuest::GeolocationRequest : public PermissionRequest {
public:
GeolocationRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
GeolocationCallback callback,
int bridge_id)
: PermissionRequest(guest),
callback_(callback),
bridge_id_(bridge_id) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Geolocation"));
}
virtual void RespondImpl(bool should_allow,
const std::string& user_input) OVERRIDE {
WebContents* web_contents = guest_->embedder_web_contents();
if (should_allow && web_contents) {
BrowserContext* browser_context = web_contents->GetBrowserContext();
if (browser_context) {
GeolocationPermissionContext* geolocation_context =
browser_context->GetGeolocationPermissionContext();
if (geolocation_context) {
base::Callback<void(bool)> geolocation_callback = base::Bind(
&BrowserPluginGuest::SetGeolocationPermission,
guest_,
callback_,
bridge_id_);
geolocation_context->RequestGeolocationPermission(
web_contents->GetRenderProcessHost()->GetID(),
web_contents->GetRoutingID(),
-1 ,
web_contents->GetLastCommittedURL(),
geolocation_callback);
return;
}
}
}
guest_->SetGeolocationPermission(callback_, bridge_id_, false);
}
private:
virtual ~GeolocationRequest() {}
base::Callback<void(bool)> callback_;
int bridge_id_;
};
class BrowserPluginGuest::MediaRequest : public PermissionRequest {
public:
MediaRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
const MediaStreamRequest& request,
const MediaResponseCallback& callback)
: PermissionRequest(guest),
request_(request),
callback_(callback) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.Media"));
}
virtual void RespondImpl(bool should_allow,
const std::string& user_input) OVERRIDE {
WebContentsImpl* web_contents = guest_->embedder_web_contents();
if (should_allow && web_contents) {
web_contents->RequestMediaAccessPermission(request_, callback_);
} else {
callback_.Run(MediaStreamDevices(),
MEDIA_DEVICE_INVALID_STATE,
scoped_ptr<MediaStreamUI>());
}
}
private:
virtual ~MediaRequest() {}
MediaStreamRequest request_;
MediaResponseCallback callback_;
};
class BrowserPluginGuest::NewWindowRequest : public PermissionRequest {
public:
NewWindowRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
int instance_id)
: PermissionRequest(guest),
instance_id_(instance_id) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.NewWindow"));
}
virtual void RespondImpl(bool should_allow,
const std::string& user_input) OVERRIDE {
int embedder_render_process_id =
guest_->embedder_web_contents()->GetRenderProcessHost()->GetID();
BrowserPluginGuest* guest =
guest_->GetWebContents()->GetBrowserPluginGuestManager()->
GetGuestByInstanceID(instance_id_, embedder_render_process_id);
if (!guest) {
VLOG(0) << "Guest not found. Instance ID: " << instance_id_;
return;
}
if (!should_allow)
guest->Destroy();
}
private:
virtual ~NewWindowRequest() {}
int instance_id_;
};
class BrowserPluginGuest::JavaScriptDialogRequest : public PermissionRequest {
public:
JavaScriptDialogRequest(const base::WeakPtr<BrowserPluginGuest>& guest,
const DialogClosedCallback& callback)
: PermissionRequest(guest),
callback_(callback) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.JSDialog"));
}
virtual void RespondImpl(bool should_allow,
const std::string& user_input) OVERRIDE {
callback_.Run(should_allow, base::UTF8ToUTF16(user_input));
}
private:
virtual ~JavaScriptDialogRequest() {}
DialogClosedCallback callback_;
};
class BrowserPluginGuest::PointerLockRequest : public PermissionRequest {
public:
explicit PointerLockRequest(const base::WeakPtr<BrowserPluginGuest>& guest)
: PermissionRequest(guest) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.PermissionRequest.PointerLock"));
}
virtual void RespondImpl(bool should_allow,
const std::string& user_input) OVERRIDE {
guest_->SendMessageToEmbedder(
new BrowserPluginMsg_SetMouseLock(guest_->instance_id(), should_allow));
}
private:
virtual ~PointerLockRequest() {}
};
namespace {
std::string WindowOpenDispositionToString(
WindowOpenDisposition window_open_disposition) {
switch (window_open_disposition) {
case IGNORE_ACTION:
return "ignore";
case SAVE_TO_DISK:
return "save_to_disk";
case CURRENT_TAB:
return "current_tab";
case NEW_BACKGROUND_TAB:
return "new_background_tab";
case NEW_FOREGROUND_TAB:
return "new_foreground_tab";
case NEW_WINDOW:
return "new_window";
case NEW_POPUP:
return "new_popup";
default:
NOTREACHED() << "Unknown Window Open Disposition";
return "ignore";
}
}
std::string JavaScriptMessageTypeToString(JavaScriptMessageType message_type) {
switch (message_type) {
case JAVASCRIPT_MESSAGE_TYPE_ALERT:
return "alert";
case JAVASCRIPT_MESSAGE_TYPE_CONFIRM:
return "confirm";
case JAVASCRIPT_MESSAGE_TYPE_PROMPT:
return "prompt";
default:
NOTREACHED() << "Unknown JavaScript Message Type.";
return "unknown";
}
}
static std::string RetrieveDownloadURLFromRequestId(
RenderViewHost* render_view_host,
int url_request_id) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
int render_process_id = render_view_host->GetProcess()->GetID();
GlobalRequestID global_id(render_process_id, url_request_id);
net::URLRequest* url_request =
ResourceDispatcherHostImpl::Get()->GetURLRequest(global_id);
if (url_request)
return url_request->url().possibly_invalid_spec();
return "";
}
}
class BrowserPluginGuest::EmbedderWebContentsObserver
: public WebContentsObserver {
public:
explicit EmbedderWebContentsObserver(BrowserPluginGuest* guest)
: WebContentsObserver(guest->embedder_web_contents()),
browser_plugin_guest_(guest) {
}
virtual ~EmbedderWebContentsObserver() {
}
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(EmbedderWebContentsObserver);
};
BrowserPluginGuest::BrowserPluginGuest(
int instance_id,
bool has_render_view,
WebContentsImpl* web_contents,
BrowserPluginGuest* opener)
: WebContentsObserver(web_contents),
embedder_web_contents_(NULL),
instance_id_(instance_id),
damage_buffer_sequence_id_(0),
damage_buffer_size_(0),
damage_buffer_scale_factor_(1.0f),
guest_device_scale_factor_(1.0f),
guest_hang_timeout_(
base::TimeDelta::FromMilliseconds(kHungRendererDelayMs)),
focused_(false),
mouse_locked_(false),
pending_lock_request_(false),
embedder_visible_(true),
auto_size_enabled_(false),
copy_request_id_(0),
next_permission_request_id_(browser_plugin::kInvalidPermissionRequestID),
has_render_view_(has_render_view),
last_seen_auto_size_enabled_(false),
is_in_destruction_(false),
last_text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
last_input_mode_(ui::TEXT_INPUT_MODE_DEFAULT),
last_can_compose_inline_(true),
weak_ptr_factory_(this) {
DCHECK(web_contents);
web_contents->SetDelegate(this);
if (opener)
opener_ = opener->AsWeakPtr();
GetWebContents()->GetBrowserPluginGuestManager()->AddGuest(instance_id_,
GetWebContents());
}
bool BrowserPluginGuest::AddMessageToConsole(WebContents* source,
int32 level,
const base::string16& message,
int32 line_no,
const base::string16& source_id) {
if (!delegate_)
return false;
delegate_->AddMessageToConsole(level, message, line_no, source_id);
return true;
}
void BrowserPluginGuest::DestroyUnattachedWindows() {
PendingWindowMap pending_new_windows(pending_new_windows_);
for (PendingWindowMap::const_iterator it = pending_new_windows.begin();
it != pending_new_windows.end(); ++it) {
it->first->Destroy();
}
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(
int request_id,
bool should_allow,
const std::string& user_input) {
RequestMap::iterator request_itr = permission_request_map_.find(request_id);
if (request_itr == permission_request_map_.end()) {
VLOG(0) << "Not a valid request ID.";
return;
}
request_itr->second->Respond(should_allow, user_input);
permission_request_map_.erase(request_itr);
}
int BrowserPluginGuest::RequestPermission(
BrowserPluginPermissionType permission_type,
scoped_refptr<BrowserPluginGuest::PermissionRequest> request,
const base::DictionaryValue& request_info) {
if (!delegate_) {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&BrowserPluginGuest::PermissionRequest::Respond,
request, false, ""));
return browser_plugin::kInvalidPermissionRequestID;
}
int request_id = ++next_permission_request_id_;
permission_request_map_[request_id] = request;
BrowserPluginGuestDelegate::PermissionResponseCallback callback =
base::Bind(&BrowserPluginGuest::RespondToPermissionRequest,
AsWeakPtr(),
request_id);
if (!delegate_->RequestPermission(
permission_type, request_info, callback, request->AllowedByDefault())) {
callback.Run(request->AllowedByDefault(), "");
return browser_plugin::kInvalidPermissionRequestID;
}
return request_id;
}
BrowserPluginGuest* BrowserPluginGuest::CreateNewGuestWindow(
const OpenURLParams& params) {
BrowserPluginGuestManager* guest_manager =
GetWebContents()->GetBrowserPluginGuestManager();
int instance_id = guest_manager->get_next_instance_id();
const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL();
BrowserPluginHostMsg_Attach_Params attach_params;
attach_params.storage_partition_id = site_url.query();
attach_params.persist_storage =
site_url.path().find("persist") != std::string::npos;
scoped_ptr<base::DictionaryValue> extra_params(
extra_attach_params_->DeepCopy());
BrowserPluginGuest* new_guest =
GetWebContents()->GetBrowserPluginGuestManager()->CreateGuest(
GetWebContents()->GetSiteInstance(), instance_id,
attach_params, extra_params.Pass());
new_guest->opener_ = AsWeakPtr();
pending_new_windows_.insert(
std::make_pair(new_guest, NewWindowInfo(params.url, std::string())));
RequestNewWindowPermission(params.disposition, gfx::Rect(),
params.user_gesture, new_guest->GetWebContents());
return new_guest;
}
base::WeakPtr<BrowserPluginGuest> BrowserPluginGuest::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
void BrowserPluginGuest::EmbedderDestroyed() {
embedder_web_contents_ = NULL;
if (delegate_)
delegate_->EmbedderDestroyed();
Destroy();
}
void BrowserPluginGuest::Destroy() {
is_in_destruction_ = true;
if (!attached() && opener())
opener()->pending_new_windows_.erase(this);
DestroyUnattachedWindows();
GetWebContents()->GetBrowserPluginGuestManager()->RemoveGuest(instance_id_);
delete GetWebContents();
}
bool BrowserPluginGuest::OnMessageReceivedFromEmbedder(
const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_BuffersSwappedACK,
OnSwapBuffersACK)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_CompositorFrameSwappedACK,
OnCompositorFrameSwappedACK)
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)
IPC_MESSAGE_HANDLER(BrowserPluginHostMsg_UpdateRect_ACK, OnUpdateRectACK)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void BrowserPluginGuest::Initialize(
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())
name_ = params.name;
auto_size_enabled_ = params.auto_size_params.enable;
max_auto_size_ = params.auto_size_params.max_size;
min_auto_size_ = params.auto_size_params.min_size;
embedder_web_contents_ = embedder_web_contents;
WebContentsViewGuest* new_view =
static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
new_view->OnGuestInitialized(embedder_web_contents->GetView());
RendererPreferences* renderer_prefs =
GetWebContents()->GetMutableRendererPrefs();
std::string guest_user_agent_override = renderer_prefs->user_agent_override;
*renderer_prefs = *embedder_web_contents_->GetMutableRendererPrefs();
renderer_prefs->user_agent_override = guest_user_agent_override;
renderer_prefs->report_frame_name_changes = true;
renderer_prefs->browser_handles_all_top_level_requests = false;
renderer_prefs->disable_client_blocked_error_page = true;
embedder_web_contents_observer_.reset(new EmbedderWebContentsObserver(this));
OnSetSize(instance_id_, params.auto_size_params, params.resize_guest_params);
int guest_routing_id =
GetWebContents()->CreateSwappedOutRenderView(
embedder_web_contents_->GetSiteInstance());
SendMessageToEmbedder(
new BrowserPluginMsg_GuestContentWindowReady(instance_id_,
guest_routing_id));
if (!params.src.empty()) {
OnNavigateGuest(instance_id_, params.src);
}
has_render_view_ = true;
WebPreferences prefs = GetWebContents()->GetWebkitPrefs();
prefs.navigate_on_drag_drop = false;
if (!embedder_web_contents_->
GetWebkitPrefs().accelerated_compositing_enabled) {
prefs.accelerated_compositing_enabled = false;
}
GetWebContents()->GetRenderViewHost()->UpdateWebkitPreferences(prefs);
if (static_cast<RenderViewHostImpl*>(
embedder_web_contents_->GetRenderViewHost())->input_method_active()) {
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
GetWebContents()->GetRenderViewHost());
guest_rvh->SetInputMethodActive(true);
}
const GURL& site_url = GetWebContents()->GetSiteInstance()->GetSiteURL();
BrowserPluginMsg_Attach_ACK_Params ack_params;
ack_params.storage_partition_id = site_url.query();
ack_params.persist_storage =
site_url.path().find("persist") != std::string::npos;
ack_params.name = name_;
SendMessageToEmbedder(
new BrowserPluginMsg_Attach_ACK(instance_id_, ack_params));
if (delegate_)
delegate_->DidAttach();
}
BrowserPluginGuest::~BrowserPluginGuest() {
while (!pending_messages_.empty()) {
delete pending_messages_.front();
pending_messages_.pop();
}
}
BrowserPluginGuest* BrowserPluginGuest::Create(
int instance_id,
SiteInstance* guest_site_instance,
WebContentsImpl* web_contents,
scoped_ptr<base::DictionaryValue> extra_params) {
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Create"));
BrowserPluginGuest* guest = NULL;
if (factory_) {
guest = factory_->CreateBrowserPluginGuest(instance_id, web_contents);
} else {
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(
guest_site_instance, web_contents, NULL, &delegate, extra_params.Pass());
guest->SetDelegate(delegate);
return guest;
}
BrowserPluginGuest* BrowserPluginGuest::CreateWithOpener(
int instance_id,
bool has_render_view,
WebContentsImpl* web_contents,
BrowserPluginGuest* opener) {
BrowserPluginGuest* guest =
new BrowserPluginGuest(
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);
return guest;
}
RenderWidgetHostView* BrowserPluginGuest::GetEmbedderRenderWidgetHostView() {
if (!attached())
return NULL;
return embedder_web_contents_->GetRenderWidgetHostView();
}
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));
}
gfx::Rect BrowserPluginGuest::ToGuestRect(const gfx::Rect& bounds) {
gfx::Rect guest_rect(bounds);
guest_rect.Offset(guest_window_rect_.OffsetFromOrigin());
return guest_rect;
}
void BrowserPluginGuest::EmbedderVisibilityChanged(bool visible) {
embedder_visible_ = visible;
UpdateVisibility();
}
void BrowserPluginGuest::AddNewContents(WebContents* source,
WebContents* new_contents,
WindowOpenDisposition disposition,
const gfx::Rect& initial_pos,
bool user_gesture,
bool* was_blocked) {
if (was_blocked)
*was_blocked = false;
RequestNewWindowPermission(disposition, initial_pos, user_gesture,
static_cast<WebContentsImpl*>(new_contents));
}
void BrowserPluginGuest::CanDownload(
RenderViewHost* render_view_host,
int request_id,
const std::string& request_method,
const base::Callback<void(bool)>& callback) {
BrowserThread::PostTaskAndReplyWithResult(
BrowserThread::IO, FROM_HERE,
base::Bind(&RetrieveDownloadURLFromRequestId,
render_view_host, request_id),
base::Bind(&BrowserPluginGuest::DidRetrieveDownloadURLFromRequestId,
weak_ptr_factory_.GetWeakPtr(),
request_method,
callback));
}
void BrowserPluginGuest::LoadProgressChanged(WebContents* contents,
double progress) {
if (delegate_)
delegate_->LoadProgressed(progress);
}
void BrowserPluginGuest::CloseContents(WebContents* source) {
if (!delegate_)
return;
delegate_->Close();
}
JavaScriptDialogManager* BrowserPluginGuest::GetJavaScriptDialogManager() {
return this;
}
ColorChooser* BrowserPluginGuest::OpenColorChooser(
WebContents* web_contents,
SkColor color,
const std::vector<ColorSuggestion>& suggestions) {
if (!embedder_web_contents_ || !embedder_web_contents_->GetDelegate())
return NULL;
return embedder_web_contents_->GetDelegate()->OpenColorChooser(
web_contents, color, suggestions);
}
bool BrowserPluginGuest::HandleContextMenu(const ContextMenuParams& params) {
return false;
}
void BrowserPluginGuest::HandleKeyboardEvent(
WebContents* source,
const NativeWebKeyboardEvent& event) {
if (!attached())
return;
if (UnlockMouseIfNecessary(event))
return;
if (delegate_ && delegate_->HandleKeyboardEvent(event))
return;
if (!embedder_web_contents_->GetDelegate())
return;
embedder_web_contents_->GetDelegate()->HandleKeyboardEvent(
web_contents(), event);
}
void BrowserPluginGuest::SetZoom(double zoom_factor) {
if (delegate_)
delegate_->SetZoom(zoom_factor);
}
void BrowserPluginGuest::FindReply(WebContents* contents,
int request_id,
int number_of_matches,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
if (!delegate_)
return;
delegate_->FindReply(request_id, number_of_matches,
ToGuestRect(selection_rect),
active_match_ordinal, final_update);
}
WebContents* BrowserPluginGuest::OpenURLFromTab(WebContents* source,
const OpenURLParams& params) {
if (!attached()) {
PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
if (it == opener()->pending_new_windows_.end())
return NULL;
const NewWindowInfo& old_target_url = it->second;
NewWindowInfo new_window_info(params.url, old_target_url.name);
new_window_info.changed = new_window_info.url != old_target_url.url;
it->second = new_window_info;
return NULL;
}
if (params.disposition == CURRENT_TAB) {
LoadURLWithParams(params.url, params.referrer, params.transition, source);
return source;
}
return CreateNewGuestWindow(params)->GetWebContents();
}
void BrowserPluginGuest::WebContentsCreated(WebContents* source_contents,
int opener_render_frame_id,
const base::string16& frame_name,
const GURL& target_url,
WebContents* new_contents) {
WebContentsImpl* new_contents_impl =
static_cast<WebContentsImpl*>(new_contents);
BrowserPluginGuest* guest = new_contents_impl->GetBrowserPluginGuest();
guest->opener_ = AsWeakPtr();
std::string guest_name = base::UTF16ToUTF8(frame_name);
guest->name_ = guest_name;
pending_new_windows_.insert(
std::make_pair(guest, NewWindowInfo(target_url, guest_name)));
}
void BrowserPluginGuest::RendererUnresponsive(WebContents* source) {
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Hung"));
if (!delegate_)
return;
delegate_->RendererUnresponsive();
}
void BrowserPluginGuest::RendererResponsive(WebContents* source) {
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Responsive"));
if (!delegate_)
return;
delegate_->RendererResponsive();
}
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);
}
bool BrowserPluginGuest::ShouldFocusPageAfterCrash() {
return false;
}
WebContentsImpl* BrowserPluginGuest::GetWebContents() {
return static_cast<WebContentsImpl*>(web_contents());
}
base::SharedMemory* BrowserPluginGuest::GetDamageBufferFromEmbedder(
const BrowserPluginHostMsg_ResizeGuest_Params& params) {
if (!attached()) {
LOG(WARNING) << "Attempting to map a damage buffer prior to attachment.";
return NULL;
}
#if defined(OS_WIN)
base::ProcessHandle handle =
embedder_web_contents_->GetRenderProcessHost()->GetHandle();
scoped_ptr<base::SharedMemory> shared_buf(
new base::SharedMemory(params.damage_buffer_handle, false, handle));
#elif defined(OS_POSIX)
scoped_ptr<base::SharedMemory> shared_buf(
new base::SharedMemory(params.damage_buffer_handle, false));
#endif
if (!shared_buf->Map(params.damage_buffer_size)) {
LOG(WARNING) << "Unable to map the embedder's damage buffer.";
return NULL;
}
return shared_buf.release();
}
void BrowserPluginGuest::SetDamageBuffer(
const BrowserPluginHostMsg_ResizeGuest_Params& params) {
damage_buffer_.reset(GetDamageBufferFromEmbedder(params));
DCHECK(!damage_buffer_ ||
*static_cast<unsigned int*>(damage_buffer_->memory()) == 0xdeadbeef);
damage_buffer_sequence_id_ = params.damage_buffer_sequence_id;
damage_buffer_size_ = params.damage_buffer_size;
damage_view_size_ = params.view_rect.size();
damage_buffer_scale_factor_ = params.scale_factor;
}
gfx::Point BrowserPluginGuest::GetScreenCoordinates(
const gfx::Point& relative_position) const {
gfx::Point screen_pos(relative_position);
screen_pos += guest_window_rect_.OffsetFromOrigin();
return screen_pos;
}
bool BrowserPluginGuest::InAutoSizeBounds(const gfx::Size& size) const {
return size.width() <= max_auto_size_.width() &&
size.height() <= max_auto_size_.height();
}
void BrowserPluginGuest::RequestNewWindowPermission(
WindowOpenDisposition disposition,
const gfx::Rect& initial_bounds,
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())
return;
const NewWindowInfo& new_window_info = it->second;
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kInitialHeight,
base::Value::CreateIntegerValue(initial_bounds.height()));
request_info.Set(browser_plugin::kInitialWidth,
base::Value::CreateIntegerValue(initial_bounds.width()));
request_info.Set(browser_plugin::kTargetURL,
base::Value::CreateStringValue(new_window_info.url.spec()));
request_info.Set(browser_plugin::kName,
base::Value::CreateStringValue(new_window_info.name));
request_info.Set(browser_plugin::kWindowID,
base::Value::CreateIntegerValue(guest->instance_id()));
request_info.Set(browser_plugin::kWindowOpenDisposition,
base::Value::CreateStringValue(
WindowOpenDispositionToString(disposition)));
RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_NEW_WINDOW,
new NewWindowRequest(weak_ptr_factory_.GetWeakPtr(),
guest->instance_id()),
request_info);
}
bool BrowserPluginGuest::UnlockMouseIfNecessary(
const NativeWebKeyboardEvent& event) {
if (!mouse_locked_)
return false;
embedder_web_contents()->GotResponseToLockMouseRequest(false);
return true;
}
void BrowserPluginGuest::SendMessageToEmbedder(IPC::Message* msg) {
if (!attached()) {
pending_messages_.push(msg);
return;
}
msg->set_routing_id(embedder_web_contents_->GetRoutingID());
embedder_web_contents_->Send(msg);
}
void BrowserPluginGuest::DragSourceEndedAt(int client_x, int client_y,
int screen_x, int screen_y, blink::WebDragOperation operation) {
web_contents()->GetRenderViewHost()->DragSourceEndedAt(client_x, client_y,
screen_x, screen_y, operation);
}
void BrowserPluginGuest::EndSystemDrag() {
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
GetWebContents()->GetRenderViewHost());
guest_rvh->DragSourceSystemDragEnded();
}
void BrowserPluginGuest::SetDelegate(BrowserPluginGuestDelegate* delegate) {
DCHECK(!delegate_);
delegate_.reset(delegate);
}
void BrowserPluginGuest::AskEmbedderForGeolocationPermission(
int bridge_id,
const GURL& requesting_frame,
const GeolocationCallback& callback) {
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kURL,
base::Value::CreateStringValue(requesting_frame.spec()));
int request_id =
RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_GEOLOCATION,
new GeolocationRequest(weak_ptr_factory_.GetWeakPtr(),
callback,
bridge_id),
request_info);
DCHECK(bridge_id_to_request_id_map_.find(bridge_id) ==
bridge_id_to_request_id_map_.end());
bridge_id_to_request_id_map_[bridge_id] = request_id;
}
int BrowserPluginGuest::RemoveBridgeID(int bridge_id) {
std::map<int, int>::iterator bridge_itr =
bridge_id_to_request_id_map_.find(bridge_id);
if (bridge_itr == bridge_id_to_request_id_map_.end())
return browser_plugin::kInvalidPermissionRequestID;
int request_id = bridge_itr->second;
bridge_id_to_request_id_map_.erase(bridge_itr);
return request_id;
}
void BrowserPluginGuest::CancelGeolocationRequest(int bridge_id) {
int request_id = RemoveBridgeID(bridge_id);
RequestMap::iterator request_itr = permission_request_map_.find(request_id);
if (request_itr == permission_request_map_.end())
return;
permission_request_map_.erase(request_itr);
}
void BrowserPluginGuest::SetGeolocationPermission(GeolocationCallback callback,
int bridge_id,
bool allowed) {
callback.Run(allowed);
RemoveBridgeID(bridge_id);
}
void BrowserPluginGuest::SendQueuedMessages() {
if (!attached())
return;
while (!pending_messages_.empty()) {
IPC::Message* message = pending_messages_.front();
pending_messages_.pop();
SendMessageToEmbedder(message);
}
}
void BrowserPluginGuest::DidCommitProvisionalLoadForFrame(
int64 frame_id,
const base::string16& frame_unique_name,
bool is_main_frame,
const GURL& url,
PageTransition transition_type,
RenderViewHost* render_view_host) {
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.DidNavigate"));
}
void BrowserPluginGuest::DidStopLoading(RenderViewHost* render_view_host) {
bool enable_dragdrop = delegate_ && delegate_->IsDragAndDropEnabled();
if (!enable_dragdrop) {
const char script[] = "window.addEventListener('dragstart', function() { "
" window.event.preventDefault(); "
"});";
render_view_host->GetMainFrame()->ExecuteJavaScript(
base::ASCIIToUTF16(script));
}
}
void BrowserPluginGuest::RenderViewReady() {
RenderViewHost* rvh = GetWebContents()->GetRenderViewHost();
CHECK(rvh->GetProcess()->IsGuest());
Send(new InputMsg_SetFocus(routing_id(), focused_));
UpdateVisibility();
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_);
}
void BrowserPluginGuest::RenderProcessGone(base::TerminationStatus status) {
SendMessageToEmbedder(new BrowserPluginMsg_GuestGone(instance_id()));
switch (status) {
case base::TERMINATION_STATUS_PROCESS_WAS_KILLED:
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Killed"));
break;
case base::TERMINATION_STATUS_PROCESS_CRASHED:
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Crashed"));
break;
case base::TERMINATION_STATUS_ABNORMAL_TERMINATION:
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.AbnormalDeath"));
break;
default:
break;
}
if (delegate_)
delegate_->GuestProcessGone(status);
}
void BrowserPluginGuest::AcknowledgeBufferPresent(
int route_id,
int gpu_host_id,
const gpu::Mailbox& mailbox,
uint32 sync_point) {
AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
ack_params.mailbox = mailbox;
ack_params.sync_point = sync_point;
RenderWidgetHostImpl::AcknowledgeBufferPresent(route_id,
gpu_host_id,
ack_params);
}
bool BrowserPluginGuest::ShouldForwardToBrowserPluginGuest(
const IPC::Message& message) {
switch (message.type()) {
case BrowserPluginHostMsg_BuffersSwappedACK::ID:
case BrowserPluginHostMsg_CompositorFrameSwappedACK::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:
return false;
}
}
bool BrowserPluginGuest::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(BrowserPluginGuest, message)
IPC_MESSAGE_HANDLER(ViewHostMsg_HasTouchEventHandlers,
OnHasTouchEventHandlers)
IPC_MESSAGE_HANDLER(ViewHostMsg_LockMouse, OnLockMouse)
IPC_MESSAGE_HANDLER(ViewHostMsg_SetCursor, OnSetCursor)
#if defined(OS_MACOSX)
IPC_MESSAGE_HANDLER(ViewHostMsg_ShowPopup, OnShowPopup)
#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)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
}
void BrowserPluginGuest::Attach(
WebContentsImpl* embedder_web_contents,
BrowserPluginHostMsg_Attach_Params params,
const base::DictionaryValue& extra_params) {
if (attached())
return;
extra_attach_params_.reset(extra_params.DeepCopy());
params.storage_partition_id.clear();
params.persist_storage = false;
params.src.clear();
if (has_render_view_) {
static_cast<RenderViewHostImpl*>(
GetWebContents()->GetRenderViewHost())->Init();
WebContentsViewGuest* new_view =
static_cast<WebContentsViewGuest*>(GetWebContents()->GetView());
new_view->CreateViewForWidget(web_contents()->GetRenderViewHost());
}
PendingWindowMap::iterator it = opener()->pending_new_windows_.find(this);
if (it != opener()->pending_new_windows_.end()) {
const NewWindowInfo& new_window_info = it->second;
if (new_window_info.changed || !has_render_view_)
params.src = it->second.url.spec();
} else {
NOTREACHED();
}
opener()->pending_new_windows_.erase(this);
if (!name_.empty())
params.name.clear();
Initialize(params, embedder_web_contents);
SendQueuedMessages();
RecordAction(base::UserMetricsAction("BrowserPlugin.Guest.Attached"));
}
void BrowserPluginGuest::OnCompositorFrameSwappedACK(
int instance_id,
const FrameHostMsg_CompositorFrameSwappedACK_Params& params) {
RenderWidgetHostImpl::SendSwapCompositorFrameAck(params.producing_route_id,
params.output_surface_id,
params.producing_host_id,
params.ack);
}
void BrowserPluginGuest::OnDragStatusUpdate(int instance_id,
blink::WebDragStatus drag_status,
const DropData& drop_data,
blink::WebDragOperationsMask mask,
const gfx::Point& location) {
RenderViewHost* host = GetWebContents()->GetRenderViewHost();
switch (drag_status) {
case blink::WebDragStatusEnter:
embedder_web_contents_->GetBrowserPluginEmbedder()->DragEnteredGuest(
this);
host->DragTargetDragEnter(drop_data, location, location, mask, 0);
break;
case blink::WebDragStatusOver:
host->DragTargetDragOver(location, location, mask, 0);
break;
case blink::WebDragStatusLeave:
embedder_web_contents_->GetBrowserPluginEmbedder()->DragLeftGuest(this);
host->DragTargetDragLeave();
break;
case blink::WebDragStatusDrop:
host->DragTargetDrop(location, location, 0);
EndSystemDrag();
break;
case blink::WebDragStatusUnknown:
NOTREACHED();
}
}
void BrowserPluginGuest::OnExecuteEditCommand(int instance_id,
const std::string& name) {
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(),
base::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(),
base::UTF8ToUTF16(text),
gfx::Range::InvalidRange(),
keep_selection));
}
void BrowserPluginGuest::OnExtendSelectionAndDelete(
int instance_id,
int before,
int after) {
RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
web_contents()->GetFocusedFrame());
if (rfh)
rfh->ExtendSelectionAndDelete(before, after);
}
void BrowserPluginGuest::OnReclaimCompositorResources(
int instance_id,
const FrameHostMsg_ReclaimCompositorResources_Params& params) {
RenderWidgetHostImpl::SendReclaimCompositorResources(params.route_id,
params.output_surface_id,
params.renderer_host_id,
params.ack);
}
void BrowserPluginGuest::OnHandleInputEvent(
int instance_id,
const gfx::Rect& guest_window_rect,
const blink::WebInputEvent* event) {
guest_window_rect_ = guest_window_rect;
if (embedder_web_contents_->GetRenderWidgetHostView()) {
guest_screen_rect_ = guest_window_rect;
guest_screen_rect_.Offset(
embedder_web_contents_->GetRenderWidgetHostView()->
GetViewBounds().OffsetFromOrigin());
}
RenderViewHostImpl* guest_rvh = static_cast<RenderViewHostImpl*>(
GetWebContents()->GetRenderViewHost());
if (blink::WebInputEvent::isMouseEventType(event->type)) {
guest_rvh->ForwardMouseEvent(
*static_cast<const blink::WebMouseEvent*>(event));
return;
}
if (event->type == blink::WebInputEvent::MouseWheel) {
guest_rvh->ForwardWheelEvent(
*static_cast<const blink::WebMouseWheelEvent*>(event));
return;
}
if (blink::WebInputEvent::isKeyboardEventType(event->type)) {
RenderViewHostImpl* embedder_rvh = static_cast<RenderViewHostImpl*>(
embedder_web_contents_->GetRenderViewHost());
if (!embedder_rvh->GetLastKeyboardEvent())
return;
NativeWebKeyboardEvent keyboard_event(
*embedder_rvh->GetLastKeyboardEvent());
guest_rvh->ForwardKeyboardEvent(keyboard_event);
return;
}
if (blink::WebInputEvent::isTouchEventType(event->type)) {
guest_rvh->ForwardTouchEventWithLatencyInfo(
*static_cast<const blink::WebTouchEvent*>(event),
ui::LatencyInfo());
return;
}
if (blink::WebInputEvent::isGestureEventType(event->type)) {
guest_rvh->ForwardGestureEvent(
*static_cast<const blink::WebGestureEvent*>(event));
return;
}
}
void BrowserPluginGuest::OnLockMouse(bool user_gesture,
bool last_unlocked_by_target,
bool privileged) {
if (pending_lock_request_) {
Send(new ViewMsg_LockMouse_ACK(routing_id(), false));
return;
}
pending_lock_request_ = true;
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kUserGesture,
base::Value::CreateBooleanValue(user_gesture));
request_info.Set(browser_plugin::kLastUnlockedBySelf,
base::Value::CreateBooleanValue(last_unlocked_by_target));
request_info.Set(browser_plugin::kURL,
base::Value::CreateStringValue(
web_contents()->GetLastCommittedURL().spec()));
RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_POINTER_LOCK,
new PointerLockRequest(weak_ptr_factory_.GetWeakPtr()),
request_info);
}
void BrowserPluginGuest::OnLockMouseAck(int instance_id, bool succeeded) {
Send(new ViewMsg_LockMouse_ACK(routing_id(), succeeded));
pending_lock_request_ = false;
if (succeeded)
mouse_locked_ = true;
}
void BrowserPluginGuest::OnNavigateGuest(
int instance_id,
const std::string& src) {
GURL url = delegate_ ? delegate_->ResolveURL(src) : GURL(src);
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 , url, error_type);
}
return;
}
GURL validated_url(url);
GetWebContents()->GetRenderProcessHost()->FilterURL(false, &validated_url);
LoadURLWithParams(validated_url, Referrer(), PAGE_TRANSITION_AUTO_TOPLEVEL,
GetWebContents());
}
void BrowserPluginGuest::OnPluginDestroyed(int instance_id) {
Destroy();
}
void BrowserPluginGuest::OnResizeGuest(
int instance_id,
const BrowserPluginHostMsg_ResizeGuest_Params& params) {
if (!params.size_changed)
return;
if (GetWebContents()->GetRenderViewHost()) {
RenderWidgetHostImpl* render_widget_host =
RenderWidgetHostImpl::From(GetWebContents()->GetRenderViewHost());
render_widget_host->ResetSizeAndRepaintPendingFlags();
if (guest_device_scale_factor_ != params.scale_factor) {
guest_device_scale_factor_ = params.scale_factor;
render_widget_host->NotifyScreenInfoChanged();
}
}
if (!auto_size_enabled_ && last_seen_auto_size_enabled_ &&
!params.view_rect.size().IsEmpty() && delegate_) {
delegate_->SizeChanged(last_seen_view_size_, params.view_rect.size());
last_seen_auto_size_enabled_ = false;
}
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()));
}
void BrowserPluginGuest::OnSetFocus(int instance_id, bool focused) {
focused_ = focused;
Send(new InputMsg_SetFocus(routing_id(), focused));
if (!focused && mouse_locked_)
OnUnlockMouse();
RenderWidgetHostViewPort* rwhv = RenderWidgetHostViewPort::FromRWHV(
web_contents()->GetRenderWidgetHostView());
if (rwhv) {
rwhv->TextInputTypeChanged(last_text_input_type_, last_input_mode_,
last_can_compose_inline_);
}
}
void BrowserPluginGuest::OnSetName(int instance_id, const std::string& name) {
if (name == name_)
return;
name_ = name;
Send(new ViewMsg_SetName(routing_id(), name));
}
void BrowserPluginGuest::OnSetSize(
int instance_id,
const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
bool old_auto_size_enabled = auto_size_enabled_;
gfx::Size old_max_size = max_auto_size_;
gfx::Size old_min_size = min_auto_size_;
auto_size_enabled_ = auto_size_params.enable;
max_auto_size_ = auto_size_params.max_size;
min_auto_size_ = auto_size_params.min_size;
if (auto_size_enabled_ && (!old_auto_size_enabled ||
(old_max_size != max_auto_size_) ||
(old_min_size != min_auto_size_))) {
RecordAction(
base::UserMetricsAction("BrowserPlugin.Guest.EnableAutoResize"));
GetWebContents()->GetRenderViewHost()->EnableAutoResize(
min_auto_size_, max_auto_size_);
Send(new ViewMsg_Repaint(routing_id(), max_auto_size_));
} else if (!auto_size_enabled_ && old_auto_size_enabled) {
GetWebContents()->GetRenderViewHost()->DisableAutoResize(
resize_guest_params.view_rect.size());
}
OnResizeGuest(instance_id_, resize_guest_params);
}
void BrowserPluginGuest::OnSetEditCommandsForNextKeyEvent(
int instance_id,
const std::vector<EditCommand>& edit_commands) {
Send(new InputMsg_SetEditCommandsForNextKeyEvent(routing_id(),
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_)
GetWebContents()->WasShown();
else
GetWebContents()->WasHidden();
}
void BrowserPluginGuest::OnSwapBuffersACK(
int instance_id,
const FrameHostMsg_BuffersSwappedACK_Params& params) {
AcknowledgeBufferPresent(params.gpu_route_id, params.gpu_host_id,
params.mailbox, params.sync_point);
#if defined(OS_MACOSX) || defined(OS_WIN)
RenderWidgetHostImpl* render_widget_host =
RenderWidgetHostImpl::From(GetWebContents()->GetRenderViewHost());
render_widget_host->AcknowledgeSwapBuffersToRenderer();
#endif
}
void BrowserPluginGuest::OnUnlockMouse() {
SendMessageToEmbedder(
new BrowserPluginMsg_SetMouseLock(instance_id(), false));
}
void BrowserPluginGuest::OnUnlockMouseAck(int instance_id) {
if (mouse_locked_)
Send(new ViewMsg_MouseLockLost(routing_id()));
mouse_locked_ = false;
}
void BrowserPluginGuest::OnUpdateRectACK(
int instance_id,
bool needs_ack,
const BrowserPluginHostMsg_AutoSize_Params& auto_size_params,
const BrowserPluginHostMsg_ResizeGuest_Params& resize_guest_params) {
if (needs_ack)
Send(new ViewMsg_UpdateRect_ACK(routing_id()));
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) {
guest_window_rect_ = view_rect;
RenderViewHostImpl* rvh = static_cast<RenderViewHostImpl*>(
GetWebContents()->GetRenderViewHost());
if (rvh)
rvh->SendScreenRects();
}
void BrowserPluginGuest::OnHasTouchEventHandlers(bool accept) {
SendMessageToEmbedder(
new BrowserPluginMsg_ShouldAcceptTouchEvents(instance_id(), accept));
}
void BrowserPluginGuest::OnSetCursor(const WebCursor& cursor) {
SendMessageToEmbedder(new BrowserPluginMsg_SetCursor(instance_id(), cursor));
}
#if defined(OS_MACOSX)
void BrowserPluginGuest::OnShowPopup(
const ViewHostMsg_ShowPopup_Params& params) {
gfx::Rect translated_bounds(params.bounds);
translated_bounds.Offset(guest_window_rect_.OffsetFromOrigin());
BrowserPluginPopupMenuHelper popup_menu_helper(
embedder_web_contents_->GetRenderViewHost(),
GetWebContents()->GetRenderViewHost());
popup_menu_helper.ShowPopupMenu(translated_bounds,
params.item_height,
params.item_font_size,
params.selected_item,
params.popup_items,
params.right_aligned,
params.allow_multiple_selection);
}
#endif
void BrowserPluginGuest::OnShowWidget(int route_id,
const gfx::Rect& initial_pos) {
GetWebContents()->ShowCreatedWidget(route_id, initial_pos);
}
void BrowserPluginGuest::OnTakeFocus(bool reverse) {
SendMessageToEmbedder(
new BrowserPluginMsg_AdvanceFocus(instance_id(), reverse));
}
void BrowserPluginGuest::OnUpdateFrameName(int frame_id,
bool is_top_level,
const std::string& name) {
if (!is_top_level)
return;
name_ = name;
SendMessageToEmbedder(new BrowserPluginMsg_UpdatedName(instance_id_, name));
}
void BrowserPluginGuest::RequestMediaAccessPermission(
WebContents* web_contents,
const MediaStreamRequest& request,
const MediaResponseCallback& callback) {
base::DictionaryValue request_info;
request_info.Set(
browser_plugin::kURL,
base::Value::CreateStringValue(request.security_origin.spec()));
RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_MEDIA,
new MediaRequest(weak_ptr_factory_.GetWeakPtr(),
request,
callback),
request_info);
}
bool BrowserPluginGuest::PreHandleGestureEvent(
WebContents* source, const blink::WebGestureEvent& event) {
return event.type == blink::WebGestureEvent::GesturePinchBegin ||
event.type == blink::WebGestureEvent::GesturePinchUpdate ||
event.type == blink::WebGestureEvent::GesturePinchEnd;
}
void BrowserPluginGuest::RunJavaScriptDialog(
WebContents* web_contents,
const GURL& origin_url,
const std::string& accept_lang,
JavaScriptMessageType javascript_message_type,
const base::string16& message_text,
const base::string16& default_prompt_text,
const DialogClosedCallback& callback,
bool* did_suppress_message) {
base::DictionaryValue request_info;
request_info.Set(
browser_plugin::kDefaultPromptText,
base::Value::CreateStringValue(base::UTF16ToUTF8(default_prompt_text)));
request_info.Set(
browser_plugin::kMessageText,
base::Value::CreateStringValue(base::UTF16ToUTF8(message_text)));
request_info.Set(
browser_plugin::kMessageType,
base::Value::CreateStringValue(
JavaScriptMessageTypeToString(javascript_message_type)));
request_info.Set(
browser_plugin::kURL,
base::Value::CreateStringValue(origin_url.spec()));
RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_JAVASCRIPT_DIALOG,
new JavaScriptDialogRequest(weak_ptr_factory_.GetWeakPtr(),
callback),
request_info);
}
void BrowserPluginGuest::RunBeforeUnloadDialog(
WebContents* web_contents,
const base::string16& message_text,
bool is_reload,
const DialogClosedCallback& callback) {
callback.Run(true, base::string16());
}
bool BrowserPluginGuest::HandleJavaScriptDialog(
WebContents* web_contents,
bool accept,
const base::string16* prompt_override) {
return false;
}
void BrowserPluginGuest::CancelActiveAndPendingDialogs(
WebContents* web_contents) {
}
void BrowserPluginGuest::WebContentsDestroyed(WebContents* web_contents) {
}
void BrowserPluginGuest::OnUpdateRect(
const ViewHostMsg_UpdateRect_Params& params) {
BrowserPluginMsg_UpdateRect_Params relay_params;
relay_params.view_size = params.view_size;
relay_params.scale_factor = params.scale_factor;
relay_params.is_resize_ack = ViewHostMsg_UpdateRect_Flags::is_resize_ack(
params.flags);
relay_params.needs_ack = params.needs_ack;
bool size_changed = last_seen_view_size_ != params.view_size;
gfx::Size old_size = last_seen_view_size_;
last_seen_view_size_ = params.view_size;
if ((auto_size_enabled_ || last_seen_auto_size_enabled_) &&
size_changed && delegate_) {
delegate_->SizeChanged(old_size, last_seen_view_size_);
}
last_seen_auto_size_enabled_ = auto_size_enabled_;
if (!params.needs_ack || !damage_buffer_) {
relay_params.damage_buffer_sequence_id = 0;
SendMessageToEmbedder(
new BrowserPluginMsg_UpdateRect(instance_id(), relay_params));
return;
}
if (((auto_size_enabled_ && InAutoSizeBounds(params.view_size)) ||
(params.view_size == damage_view_size())) &&
params.scale_factor == damage_buffer_scale_factor()) {
TransportDIB* dib = GetWebContents()->GetRenderProcessHost()->
GetTransportDIB(params.bitmap);
if (dib) {
size_t guest_damage_buffer_size =
#if defined(OS_WIN)
params.bitmap_rect.width() *
params.bitmap_rect.height() * 4;
#else
dib->size();
#endif
size_t embedder_damage_buffer_size = damage_buffer_size_;
void* guest_memory = dib->memory();
void* embedder_memory = damage_buffer_->memory();
size_t size = std::min(guest_damage_buffer_size,
embedder_damage_buffer_size);
memcpy(embedder_memory, guest_memory, size);
}
}
relay_params.damage_buffer_sequence_id = damage_buffer_sequence_id_;
relay_params.bitmap_rect = params.bitmap_rect;
relay_params.scroll_delta = params.scroll_delta;
relay_params.scroll_rect = params.scroll_rect;
relay_params.copy_rects = params.copy_rects;
SendMessageToEmbedder(
new BrowserPluginMsg_UpdateRect(instance_id(), relay_params));
}
void BrowserPluginGuest::OnTextInputTypeChanged(ui::TextInputType type,
ui::TextInputMode input_mode,
bool can_compose_inline) {
last_text_input_type_ = type;
last_input_mode_ = input_mode;
last_can_compose_inline_ = 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,
const std::string& url) {
if (url.empty()) {
callback.Run(false);
return;
}
base::DictionaryValue request_info;
request_info.Set(browser_plugin::kRequestMethod,
base::Value::CreateStringValue(request_method));
request_info.Set(browser_plugin::kURL, base::Value::CreateStringValue(url));
RequestPermission(BROWSER_PLUGIN_PERMISSION_TYPE_DOWNLOAD,
new DownloadRequest(weak_ptr_factory_.GetWeakPtr(),
callback),
request_info);
}
}