summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authormichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-22 23:00:09 +0000
committermichaeln@google.com <michaeln@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-22 23:00:09 +0000
commitcc21fb5b4e675a86c8862b934aa8e100643e75e4 (patch)
treef5055650bc147382260bc397f417560c6090812e /chrome
parent5abb7f799f538318c702f0f26372b38464ab888a (diff)
downloadchromium_src-cc21fb5b4e675a86c8862b934aa8e100643e75e4.zip
chromium_src-cc21fb5b4e675a86c8862b934aa8e100643e75e4.tar.gz
chromium_src-cc21fb5b4e675a86c8862b934aa8e100643e75e4.tar.bz2
CPAPI gears drag drop and renderer IPC.
CPAPI (0.10) functions for gears drag drop; one to extract thedrag type/data given an NPObject *event, one to override thedrop effect (drag cursor). Gears drag drop API receives a browser event as an NPObject* sothe event is untrusted. Provide IPC calls to the renderer sogears can pass the event to renderer/V8 for checking, prior todrag type/data extraction, or the setting of the drop effect. Original patch by Noel Gordon via: http://codereview.chromium.org/99240 BUG=7995 TEST=none Review URL: http://codereview.chromium.org/112056 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16808 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/chrome_plugin_host.cc16
-rw-r--r--chrome/common/chrome_plugin_api.h35
-rw-r--r--chrome/common/plugin_messages_internal.h11
-rw-r--r--chrome/plugin/chrome_plugin_host.cc37
-rw-r--r--chrome/plugin/webplugin_proxy.cc52
-rw-r--r--chrome/plugin/webplugin_proxy.h10
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.cc105
-rw-r--r--chrome/renderer/webplugin_delegate_proxy.h6
8 files changed, 268 insertions, 4 deletions
diff --git a/chrome/browser/chrome_plugin_host.cc b/chrome/browser/chrome_plugin_host.cc
index 08ad7e7..a8b5b17 100644
--- a/chrome/browser/chrome_plugin_host.cc
+++ b/chrome/browser/chrome_plugin_host.cc
@@ -527,6 +527,20 @@ CPError STDCALL CPB_HandleCommand(
return CPERR_FAILURE;
}
+CPError STDCALL CPB_GetDragData(
+ CPID id, CPBrowsingContext context, struct NPObject* event, bool add_data,
+ int32* identity, int32* event_id, char** drag_type, char** drag_data) {
+ *identity = *event_id = 0;
+ NOTREACHED() << "Should not be called in the browser process.";
+ return CPERR_FAILURE;
+}
+
+CPError STDCALL CPB_SetDropEffect(
+ CPID id, CPBrowsingContext context, struct NPObject* event, int effect) {
+ NOTREACHED() << "Should not be called in the browser process.";
+ return CPERR_FAILURE;
+}
+
//
// Functions related to network interception
//
@@ -768,6 +782,8 @@ CPBrowserFuncs* GetCPBrowserFuncsForBrowser() {
browser_funcs.send_sync_message = CPB_SendSyncMessage;
browser_funcs.plugin_thread_async_call = CPB_PluginThreadAsyncCall;
browser_funcs.open_file_dialog = CPB_OpenFileDialog;
+ browser_funcs.get_drag_data = CPB_GetDragData;
+ browser_funcs.set_drop_effect = CPB_SetDropEffect;
request_funcs.size = sizeof(request_funcs);
request_funcs.start_request = CPR_StartRequest;
diff --git a/chrome/common/chrome_plugin_api.h b/chrome/common/chrome_plugin_api.h
index 384e9c2..c10985a 100644
--- a/chrome/common/chrome_plugin_api.h
+++ b/chrome/common/chrome_plugin_api.h
@@ -30,7 +30,7 @@ extern "C" {
// The current version of the API, used by the 'version' field of CPPluginFuncs
// and CPBrowserFuncs.
#define CP_MAJOR_VERSION 0
-#define CP_MINOR_VERSION 9
+#define CP_MINOR_VERSION 10
#define CP_VERSION ((CP_MAJOR_VERSION << 8) | (CP_MINOR_VERSION))
#define CP_GET_MAJOR_VERSION(version) ((version & 0xff00) >> 8)
@@ -414,6 +414,37 @@ typedef void (STDCALL *CPP_OnFileDialogResultFunc)(void *data,
const char **files,
uint32 files_len);
+// Asks the browser to verify that NPObject* 'event' is the current drag event
+// the browser is dispatching, and extract drag data from the event if so. On
+// success, returns the drag 'identity' (an up-counter that the browser chrome
+// increases each time a user drag enters a renderer tab), the drag 'event_id'
+// and the 'drag_type' being a utf8 encoded string with values "Files", "Text"
+// or "URL". If 'add_data' is true, also return the 'drag_data', again a utf8
+// encoded string with the data for the drag type. For drag type "Files", the
+// data is a backspace delimited list of file paths.
+//
+// The call fails with a CPError if 'event' is an invalid drag event, and sets
+// the 'identity' and 'event_id' to 0. Note: on success, non-NULL 'drag_type'
+// and 'drag_data' should be freed with CPB_Free() when done.
+typedef CPError (STDCALL *CPB_GetDragDataFunc)(
+ CPID id, CPBrowsingContext context, struct NPObject* event, bool add_data,
+ int32* identity, int32* event_id, char** drag_type, char** drag_data);
+
+// Asks the browser to verify that NPObject* 'event' is the current drag event
+// the browser is dispatching and show the requested drop 'effect' if so. The
+// browser displays drop effects during dragenter and dragover events, to give
+// user visible feedback (with a drag cursor, typically) to indicate whether a
+// subsequent drop event will succeed or not. The implementation supports the
+// so-called "copy" and "none" effects. When 'effect' is non-zero, the "copy"
+// effect is shown. Otherwise, the "none" effect is shown, which prevents the
+// subsequent drop event from succeeding. Returns CPError on failure, meaning
+// the 'event' is an invalid drag event.
+//
+// Note: 'effect' is int to allow for new effects in future. For example, the
+// HTML5-defined drop effects "move" and "link".
+typedef CPError (STDCALL *CPB_SetDropEffectFunc)(
+ CPID id, CPBrowsingContext context, struct NPObject* event, int effect);
+
// Function table for issuing requests using via the other side's network stack.
// For the plugin, this functions deal with issuing requests through the
// browser. For the browser, these functions deal with allowing the plugin to
@@ -488,6 +519,8 @@ typedef struct _CPBrowserFuncs {
CPB_SendSyncMessageFunc send_sync_message;
CPB_PluginThreadAsyncCallFunc plugin_thread_async_call;
CPB_OpenFileDialogFunc open_file_dialog;
+ CPB_GetDragDataFunc get_drag_data;
+ CPB_SetDropEffectFunc set_drop_effect;
} CPBrowserFuncs;
diff --git a/chrome/common/plugin_messages_internal.h b/chrome/common/plugin_messages_internal.h
index 20a21f6..80eac49 100644
--- a/chrome/common/plugin_messages_internal.h
+++ b/chrome/common/plugin_messages_internal.h
@@ -261,6 +261,17 @@ IPC_BEGIN_MESSAGES(PluginHost)
std::string /* json_arguments */,
std::string /* json_retval */)
+ IPC_SYNC_MESSAGE_ROUTED2_2(PluginHostMsg_GetDragData,
+ NPVariant_Param /* event */,
+ bool /* add_data */,
+ std::vector<NPVariant_Param> /* result_values */,
+ bool /* result_success */)
+
+ IPC_SYNC_MESSAGE_ROUTED2_1(PluginHostMsg_SetDropEffect,
+ NPVariant_Param /* event */,
+ int /* effect */,
+ bool /* result_success */)
+
IPC_MESSAGE_ROUTED1(PluginHostMsg_MissingPluginStatus,
int /* status */)
diff --git a/chrome/plugin/chrome_plugin_host.cc b/chrome/plugin/chrome_plugin_host.cc
index 992afcf..4874e41 100644
--- a/chrome/plugin/chrome_plugin_host.cc
+++ b/chrome/plugin/chrome_plugin_host.cc
@@ -313,6 +313,41 @@ CPError STDCALL CPB_ShowHtmlDialog(
return CPERR_FAILURE;
}
+CPError STDCALL CPB_GetDragData(
+ CPID id, CPBrowsingContext context, struct NPObject* event, bool add_data,
+ int32 *identity, int32 *event_id, char **drag_type, char **drag_data) {
+ CHECK(ChromePluginLib::IsPluginThread());
+
+ *identity = *event_id = 0;
+ WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(context);
+ if (!event || !webplugin)
+ return CPERR_INVALID_PARAMETER;
+
+ std::string type_str, data_str;
+ if (!webplugin->GetDragData(event, add_data,
+ identity, event_id, &type_str, &data_str)) {
+ return CPERR_FAILURE;
+ }
+
+ if (add_data)
+ *drag_data = CPB_StringDup(CPB_Alloc, data_str);
+ *drag_type = CPB_StringDup(CPB_Alloc, type_str);
+ return CPERR_SUCCESS;
+}
+
+CPError STDCALL CPB_SetDropEffect(
+ CPID id, CPBrowsingContext context, struct NPObject* event, int effect) {
+ CHECK(ChromePluginLib::IsPluginThread());
+
+ WebPluginProxy* webplugin = WebPluginProxy::FromCPBrowsingContext(context);
+ if (!event || !webplugin)
+ return CPERR_INVALID_PARAMETER;
+
+ if (webplugin->SetDropEffect(event, effect))
+ return CPERR_SUCCESS;
+ return CPERR_FAILURE;
+}
+
CPError STDCALL CPB_GetCommandLineArguments(
CPID id, CPBrowsingContext context, const char* url, char** arguments) {
CHECK(ChromePluginLib::IsPluginThread());
@@ -597,6 +632,8 @@ CPBrowserFuncs* GetCPBrowserFuncsForPlugin() {
browser_funcs.send_sync_message = CPB_SendSyncMessage;
browser_funcs.plugin_thread_async_call = CPB_PluginThreadAsyncCall;
browser_funcs.open_file_dialog = CPB_OpenFileDialog;
+ browser_funcs.get_drag_data = CPB_GetDragData;
+ browser_funcs.set_drop_effect = CPB_SetDropEffect;
browser_funcs.request_funcs = &request_funcs;
browser_funcs.response_funcs = &response_funcs;
diff --git a/chrome/plugin/webplugin_proxy.cc b/chrome/plugin/webplugin_proxy.cc
index 0075e79..2a84267 100644
--- a/chrome/plugin/webplugin_proxy.cc
+++ b/chrome/plugin/webplugin_proxy.cc
@@ -305,6 +305,58 @@ void WebPluginProxy::HandleURLRequest(const char *method,
Send(new PluginHostMsg_URLRequest(route_id_, params));
}
+bool WebPluginProxy::GetDragData(struct NPObject* event, bool add_data,
+ int32* identity, int32* event_id,
+ std::string* type, std::string* data) {
+ DCHECK(event);
+ NPObjectProxy* proxy = NPObjectProxy::GetProxy(event);
+ if (!proxy) // NPObject* event should have/be a renderer proxy.
+ return false;
+
+ NPVariant_Param event_param;
+ event_param.type = NPVARIANT_PARAM_OBJECT_POINTER;
+ event_param.npobject_pointer = proxy->npobject_ptr();
+ if (!event_param.npobject_pointer)
+ return false;
+
+ std::vector<NPVariant_Param> values;
+ bool success = false;
+ Send(new PluginHostMsg_GetDragData(route_id_, event_param, add_data,
+ &values, &success));
+ if (!success)
+ return false;
+
+ DCHECK(values.size() == 4);
+ DCHECK(values[0].type == NPVARIANT_PARAM_INT);
+ *identity = static_cast<int32>(values[0].int_value);
+ DCHECK(values[1].type == NPVARIANT_PARAM_INT);
+ *event_id = static_cast<int32>(values[1].int_value);
+ DCHECK(values[2].type == NPVARIANT_PARAM_STRING);
+ type->swap(values[2].string_value);
+ if (add_data && (values[3].type == NPVARIANT_PARAM_STRING))
+ data->swap(values[3].string_value);
+
+ return true;
+}
+
+bool WebPluginProxy::SetDropEffect(struct NPObject* event, int effect) {
+ DCHECK(event);
+ NPObjectProxy* proxy = NPObjectProxy::GetProxy(event);
+ if (!proxy) // NPObject* event should have/be a renderer proxy.
+ return false;
+
+ NPVariant_Param event_param;
+ event_param.type = NPVARIANT_PARAM_OBJECT_POINTER;
+ event_param.npobject_pointer = proxy->npobject_ptr();
+ if (!event_param.npobject_pointer)
+ return false;
+
+ bool success = false;
+ Send(new PluginHostMsg_SetDropEffect(route_id_, event_param, effect,
+ &success));
+ return success;
+}
+
void WebPluginProxy::Paint(const gfx::Rect& rect) {
#if defined(OS_WIN)
if (!windowless_hdc_)
diff --git a/chrome/plugin/webplugin_proxy.h b/chrome/plugin/webplugin_proxy.h
index 2822fa8..e5594f0 100644
--- a/chrome/plugin/webplugin_proxy.h
+++ b/chrome/plugin/webplugin_proxy.h
@@ -5,6 +5,8 @@
#ifndef CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__
#define CHROME_PLUGIN_PLUGIN_WEBPLUGIN_PROXY_H__
+#include <string>
+
#include "base/hash_tables.h"
#include "base/ref_counted.h"
#include "base/scoped_handle.h"
@@ -55,6 +57,14 @@ class WebPluginProxy : public WebPlugin {
void ShowModalHTMLDialog(const GURL& url, int width, int height,
const std::string& json_arguments,
std::string* json_retval);
+
+ // Called by gears over the CPAPI interface to verify that the given event is
+ // the current (javascript) drag event the browser is dispatching, and return
+ // the drag data, or control the drop effect (drag cursor), if so.
+ bool GetDragData(struct NPObject* event, bool add_data, int32* identity,
+ int32* event_id, std::string* type, std::string* data);
+ bool SetDropEffect(struct NPObject* event, int effect);
+
void OnMissingPluginStatus(int status);
// class-specific methods
diff --git a/chrome/renderer/webplugin_delegate_proxy.cc b/chrome/renderer/webplugin_delegate_proxy.cc
index 27f5422..86424eb 100644
--- a/chrome/renderer/webplugin_delegate_proxy.cc
+++ b/chrome/renderer/webplugin_delegate_proxy.cc
@@ -23,11 +23,15 @@
#include "chrome/common/render_messages.h"
#include "chrome/plugin/npobject_proxy.h"
#include "chrome/plugin/npobject_stub.h"
+#include "chrome/plugin/npobject_util.h"
#include "chrome/renderer/render_thread.h"
#include "chrome/renderer/render_view.h"
#include "googleurl/src/gurl.h"
#include "grit/generated_resources.h"
#include "net/base/mime_util.h"
+#include "webkit/api/public/WebDragData.h"
+#include "webkit/api/public/WebString.h"
+#include "webkit/api/public/WebVector.h"
#include "webkit/glue/webframe.h"
#include "webkit/glue/webkit_glue.h"
#include "webkit/glue/webplugin.h"
@@ -37,6 +41,11 @@
#include "chrome/common/gfx/emf.h"
#endif
+using WebKit::WebInputEvent;
+using WebKit::WebDragData;
+using WebKit::WebVector;
+using WebKit::WebString;
+
// Proxy for WebPluginResourceClient. The object owns itself after creation,
// deleting itself after its callback has been called.
class ResourceClientProxy : public WebPluginResourceClient {
@@ -339,6 +348,8 @@ void WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_MESSAGE_HANDLER(PluginHostMsg_GetCookies, OnGetCookies)
IPC_MESSAGE_HANDLER(PluginHostMsg_ShowModalHTMLDialog,
OnShowModalHTMLDialog)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_GetDragData, OnGetDragData);
+ IPC_MESSAGE_HANDLER(PluginHostMsg_SetDropEffect, OnSetDropEffect);
IPC_MESSAGE_HANDLER(PluginHostMsg_MissingPluginStatus,
OnMissingPluginStatus)
IPC_MESSAGE_HANDLER(PluginHostMsg_URLRequest, OnHandleURLRequest)
@@ -611,7 +622,7 @@ void WebPluginDelegateProxy::SetFocus() {
}
bool WebPluginDelegateProxy::HandleInputEvent(
- const WebKit::WebInputEvent& event,
+ const WebInputEvent& event,
WebCursor* cursor) {
bool handled;
// A windowless plugin can enter a modal loop in the context of a
@@ -727,6 +738,94 @@ void WebPluginDelegateProxy::OnShowModalHTMLDialog(
json_retval);
}
+static void EncodeDragData(const WebDragData& data, bool add_data,
+ NPVariant* drag_type, NPVariant* drag_data) {
+ const NPString* np_drag_type;
+ if (data.hasFileNames()) {
+ static const NPString kFiles = { "Files", 5 };
+ np_drag_type = &kFiles;
+ } else {
+ static const NPString kEmpty = { "" , 0 };
+ np_drag_type = &kEmpty;
+ add_data = false;
+ }
+
+ STRINGN_TO_NPVARIANT(np_drag_type->UTF8Characters,
+ np_drag_type->UTF8Length,
+ *drag_type);
+ if (!add_data) {
+ VOID_TO_NPVARIANT(*drag_data);
+ return;
+ }
+
+ WebVector<WebString> files;
+ data.fileNames(files);
+
+ static std::string utf8;
+ utf8.clear();
+ for (size_t i = 0; i < files.size(); ++i) {
+ static const char kBackspaceDelimiter('\b');
+ if (i != 0)
+ utf8.append(1, kBackspaceDelimiter);
+ utf8.append(UTF16ToUTF8(files[i]));
+ }
+
+ STRINGN_TO_NPVARIANT(utf8.data(), utf8.length(), *drag_data);
+}
+
+void WebPluginDelegateProxy::OnGetDragData(const NPVariant_Param& object,
+ bool add_data,
+ std::vector<NPVariant_Param>* values,
+ bool* success) {
+ DCHECK(values && success);
+ *success = false;
+
+ WebView* webview = NULL;
+ if (render_view_)
+ webview = render_view_->webview();
+ if (!webview)
+ return;
+
+ int event_id;
+ WebDragData data;
+ NPObject* event = reinterpret_cast<NPObject*>(object.npobject_pointer);
+ const int32 drag_id = webview->GetDragIdentity();
+ if (!drag_id || !webkit_glue::GetDragData(event, &event_id, &data))
+ return;
+
+ NPVariant results[4];
+ INT32_TO_NPVARIANT(drag_id, results[0]);
+ INT32_TO_NPVARIANT(event_id, results[1]);
+ EncodeDragData(data, add_data, &results[2], &results[3]);
+
+ for (size_t i = 0; i < arraysize(results); ++i) {
+ values->push_back(NPVariant_Param());
+ CreateNPVariantParam(results[i], NULL, &values->back(), false, NULL);
+ }
+
+ *success = true;
+}
+
+void WebPluginDelegateProxy::OnSetDropEffect(const NPVariant_Param& object,
+ int effect,
+ bool* success) {
+ DCHECK(success);
+ *success = false;
+
+ WebView* webview = NULL;
+ if (render_view_)
+ webview = render_view_->webview();
+ if (!webview)
+ return;
+
+ NPObject* event = reinterpret_cast<NPObject*>(object.npobject_pointer);
+ const int32 drag_id = webview->GetDragIdentity();
+ if (!drag_id || !webkit_glue::IsDragEvent(event))
+ return;
+
+ *success = webview->SetDropEffect(effect != 0);
+}
+
void WebPluginDelegateProxy::OnMissingPluginStatus(int status) {
if (render_view_)
render_view_->OnMissingPluginStatus(this, status);
@@ -826,8 +925,8 @@ void WebPluginDelegateProxy::OnCancelDocumentLoad() {
}
void WebPluginDelegateProxy::OnInitiateHTTPRangeRequest(
- const std::string& url, const std::string& range_info,
- intptr_t existing_stream, bool notify_needed, intptr_t notify_data) {
+ const std::string& url, const std::string& range_info,
+ intptr_t existing_stream, bool notify_needed, intptr_t notify_data) {
plugin_->InitiateHTTPRangeRequest(url.c_str(), range_info.c_str(),
existing_stream, notify_needed,
notify_data);
diff --git a/chrome/renderer/webplugin_delegate_proxy.h b/chrome/renderer/webplugin_delegate_proxy.h
index be7d6d7..b554aa9 100644
--- a/chrome/renderer/webplugin_delegate_proxy.h
+++ b/chrome/renderer/webplugin_delegate_proxy.h
@@ -6,6 +6,7 @@
#define CHROME_RENDERER_WEBPLUGIN_DELEGATE_PROXY_H__
#include <string>
+#include <vector>
#include "base/gfx/rect.h"
#include "base/gfx/native_widget_types.h"
@@ -19,6 +20,7 @@
class GURL;
struct NPObject;
class NPObjectStub;
+struct NPVariant_Param;
struct PluginHostMsg_URLRequest_Params;
class RenderView;
class SkBitmap;
@@ -126,6 +128,10 @@ class WebPluginDelegateProxy : public WebPluginDelegate,
void OnShowModalHTMLDialog(const GURL& url, int width, int height,
const std::string& json_arguments,
std::string* json_retval);
+ void OnGetDragData(const NPVariant_Param& event, bool add_data,
+ std::vector<NPVariant_Param>* values, bool* success);
+ void OnSetDropEffect(const NPVariant_Param& event, int effect,
+ bool* success);
void OnMissingPluginStatus(int status);
void OnGetCPBrowsingContext(uint32* context);
void OnCancelDocumentLoad();