summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-11 20:20:56 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-11 20:20:56 +0000
commitd38c5740cdfada7281f07a201dc01417511220a5 (patch)
treecc80698c750862160a74dff6ce4d20131cf585ec
parentc8d7021f04a3430705fc7ccd9672fc83d6533caf (diff)
downloadchromium_src-d38c5740cdfada7281f07a201dc01417511220a5.zip
chromium_src-d38c5740cdfada7281f07a201dc01417511220a5.tar.gz
chromium_src-d38c5740cdfada7281f07a201dc01417511220a5.tar.bz2
Add a console interface for logging to the JS console from a PPAPI plugin.
TEST=manual Review URL: http://codereview.chromium.org/6667010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77852 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ppapi/c/dev/ppb_console_dev.h45
-rw-r--r--ppapi/example/example.cc42
-rw-r--r--ppapi/ppapi_cpp.gypi1
-rw-r--r--ppapi/ppapi_shared_proxy.gypi2
-rw-r--r--ppapi/proxy/dispatcher.cc2
-rw-r--r--ppapi/proxy/interface_id.h1
-rw-r--r--ppapi/proxy/ppapi_messages_internal.h11
-rw-r--r--ppapi/proxy/ppb_console_proxy.cc103
-rw-r--r--ppapi/proxy/ppb_console_proxy.h48
-rw-r--r--ppapi/tests/all_c_includes.h1
-rw-r--r--webkit/glue/webkit_glue.gypi2
-rw-r--r--webkit/plugins/ppapi/plugin_module.cc4
-rw-r--r--webkit/plugins/ppapi/ppb_console_impl.cc86
-rw-r--r--webkit/plugins/ppapi/ppb_console_impl.h23
-rw-r--r--webkit/plugins/ppapi/var.cc33
-rw-r--r--webkit/plugins/ppapi/var.h3
16 files changed, 385 insertions, 22 deletions
diff --git a/ppapi/c/dev/ppb_console_dev.h b/ppapi/c/dev/ppb_console_dev.h
new file mode 100644
index 0000000..da51dbe
--- /dev/null
+++ b/ppapi/c/dev/ppb_console_dev.h
@@ -0,0 +1,45 @@
+/* Copyright (c) 2011 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 PPAPI_C_DEV_PPB_CONSOLE_DEV_H_
+#define PPAPI_C_DEV_PPB_CONSOLE_DEV_H_
+
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/c/pp_var.h"
+
+#define PPB_CONSOLE_DEV_INTERFACE "PPB_Console(Dev);0.1"
+
+typedef enum {
+ PP_LOGLEVEL_TIP = 0,
+ PP_LOGLEVEL_LOG,
+ PP_LOGLEVEL_WARNING,
+ PP_LOGLEVEL_ERROR
+} PP_LogLevel_Dev;
+
+struct PPB_Console_Dev {
+ /**
+ * Logs the given message to the JavaScript console associated with the
+ * given plugin instance with the given logging level. The name of the plugin
+ * issuing the log message will be automatically prepended to the message.
+ * The value may be any type of Var.
+ */
+ void (*Log)(PP_Instance instance, PP_LogLevel_Dev level, struct PP_Var value);
+
+ /**
+ * Logs a message to the console with the given source information rather
+ * than using the internal PPAPI plugin name. The name must be a string var.
+ *
+ * The regular log function will automatically prepend the name of your
+ * plugin to the message as the "source" of the message. Some plugins may
+ * wish to override this. For example, if your plugin is a Python
+ * interpreter, you would want log messages to contain the source .py file
+ * doing the log statement rather than have "python" show up in the console.
+ */
+ void (*LogWithSource)(PP_Instance instance,
+ PP_LogLevel_Dev level,
+ struct PP_Var source,
+ struct PP_Var value);
+};
+
+#endif // PPAPI_C_DEV_PPB_CONSOLE_DEV_H_
diff --git a/ppapi/example/example.cc b/ppapi/example/example.cc
index dc0230c..5529391 100644
--- a/ppapi/example/example.cc
+++ b/ppapi/example/example.cc
@@ -11,6 +11,7 @@
#include <algorithm>
+#include "ppapi/c/dev/ppb_console_dev.h"
#include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_input_event.h"
@@ -175,6 +176,14 @@ class MyInstance : public pp::Instance, public MyFetcherClient {
return true;
}
+ void Log(PP_LogLevel_Dev level, const pp::Var& value) {
+ const PPB_Console_Dev* console = reinterpret_cast<const PPB_Console_Dev*>(
+ pp::Module::Get()->GetBrowserInterface(PPB_CONSOLE_DEV_INTERFACE));
+ if (!console)
+ return;
+ console->Log(pp_instance(), level, value.pp_var());
+ }
+
virtual bool HandleDocumentLoad(const pp::URLLoader& loader) {
fetcher_ = new MyFetcher();
fetcher_->StartWithOpenedLoader(loader, this);
@@ -184,7 +193,7 @@ class MyInstance : public pp::Instance, public MyFetcherClient {
virtual bool HandleInputEvent(const PP_InputEvent& event) {
switch (event.type) {
case PP_INPUTEVENT_TYPE_MOUSEDOWN:
- //SayHello();
+ SayHello();
return true;
case PP_INPUTEVENT_TYPE_MOUSEMOVE:
return true;
@@ -242,6 +251,7 @@ class MyInstance : public pp::Instance, public MyFetcherClient {
}
virtual void DidChangeView(const pp::Rect& position, const pp::Rect& clip) {
+ Log(PP_LOGLEVEL_LOG, "DidChangeView");
if (position.size().width() == width_ &&
position.size().height() == height_)
return; // We don't care about the position, only the size.
@@ -342,18 +352,6 @@ class MyInstance : public pp::Instance, public MyFetcherClient {
}
private:
- void Log(const pp::Var& var) {
- pp::Var doc = GetWindowObject().GetProperty("document");
- if (console_.is_undefined()) {
- pp::Var body = doc.GetProperty("body");
- console_ = doc.Call("createElement", "pre");
- console_.GetProperty("style").SetProperty("backgroundColor", "lightgray");
- body.Call("appendChild", console_);
- }
- console_.Call("appendChild", doc.Call("createTextNode", var));
- console_.Call("appendChild", doc.Call("createTextNode", "\n"));
- }
-
void SayHello() {
pp::Var window = GetWindowObject();
pp::Var doc = window.GetProperty("document");
@@ -362,20 +360,20 @@ class MyInstance : public pp::Instance, public MyFetcherClient {
pp::Var obj(this, new MyScriptableObject(this));
// Our object should have its toString method called.
- Log("Testing MyScriptableObject::toString():");
- Log(obj);
+ Log(PP_LOGLEVEL_LOG, "Testing MyScriptableObject::toString():");
+ Log(PP_LOGLEVEL_LOG, obj);
// body.appendChild(body) should throw an exception
- Log("\nCalling body.appendChild(body):");
+ Log(PP_LOGLEVEL_LOG, "Calling body.appendChild(body):");
pp::Var exception;
body.Call("appendChild", body, &exception);
- Log(exception);
+ Log(PP_LOGLEVEL_LOG, exception);
- Log("\nEnumeration of window properties:");
+ Log(PP_LOGLEVEL_LOG, "Enumeration of window properties:");
std::vector<pp::Var> props;
window.GetAllPropertyNames(&props);
for (size_t i = 0; i < props.size(); ++i)
- Log(props[i]);
+ Log(PP_LOGLEVEL_LOG, props[i]);
pp::Var location = window.GetProperty("location");
pp::Var href = location.GetProperty("href");
@@ -387,11 +385,11 @@ class MyInstance : public pp::Instance, public MyFetcherClient {
}
void DidFetch(bool success, const std::string& data) {
- Log("\nDownloaded location.href:");
+ Log(PP_LOGLEVEL_LOG, "Downloaded location.href:");
if (success) {
- Log(data);
+ Log(PP_LOGLEVEL_LOG, data);
} else {
- Log("Failed to download.");
+ Log(PP_LOGLEVEL_ERROR, "Failed to download.");
}
delete fetcher_;
fetcher_ = NULL;
diff --git a/ppapi/ppapi_cpp.gypi b/ppapi/ppapi_cpp.gypi
index 0724961..adcf01a 100644
--- a/ppapi/ppapi_cpp.gypi
+++ b/ppapi/ppapi_cpp.gypi
@@ -51,6 +51,7 @@
'c/dev/ppb_char_set_dev.h',
'c/dev/ppb_context_3d_dev.h',
'c/dev/ppb_context_3d_trusted_dev.h',
+ 'c/dev/ppb_console_dev.h',
'c/dev/ppb_cursor_control_dev.h',
'c/dev/ppb_directory_reader_dev.h',
'c/dev/ppb_file_chooser_dev.h',
diff --git a/ppapi/ppapi_shared_proxy.gypi b/ppapi/ppapi_shared_proxy.gypi
index 8c8a047..fb823e2 100644
--- a/ppapi/ppapi_shared_proxy.gypi
+++ b/ppapi/ppapi_shared_proxy.gypi
@@ -81,6 +81,8 @@
'proxy/ppb_buffer_proxy.h',
'proxy/ppb_char_set_proxy.cc',
'proxy/ppb_char_set_proxy.h',
+ 'proxy/ppb_console_proxy.cc',
+ 'proxy/ppb_console_proxy.h',
'proxy/ppb_context_3d_proxy.cc',
'proxy/ppb_context_3d_proxy.h',
'proxy/ppb_core_proxy.cc',
diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc
index 391a882..156374d 100644
--- a/ppapi/proxy/dispatcher.cc
+++ b/ppapi/proxy/dispatcher.cc
@@ -47,6 +47,7 @@
#include "ppapi/proxy/ppb_audio_proxy.h"
#include "ppapi/proxy/ppb_buffer_proxy.h"
#include "ppapi/proxy/ppb_char_set_proxy.h"
+#include "ppapi/proxy/ppb_console_proxy.h"
#include "ppapi/proxy/ppb_context_3d_proxy.h"
#include "ppapi/proxy/ppb_core_proxy.h"
#include "ppapi/proxy/ppb_cursor_control_proxy.h"
@@ -105,6 +106,7 @@ InterfaceList::InterfaceList() {
AddPPB(PPB_Audio_Proxy::GetInfo());
AddPPB(PPB_Buffer_Proxy::GetInfo());
AddPPB(PPB_CharSet_Proxy::GetInfo());
+ AddPPB(PPB_Console_Proxy::GetInfo());
AddPPB(PPB_Context3D_Proxy::GetInfo());
AddPPB(PPB_Core_Proxy::GetInfo());
AddPPB(PPB_CursorControl_Proxy::GetInfo());
diff --git a/ppapi/proxy/interface_id.h b/ppapi/proxy/interface_id.h
index 5cf4ac3..ceeb7b3 100644
--- a/ppapi/proxy/interface_id.h
+++ b/ppapi/proxy/interface_id.h
@@ -17,6 +17,7 @@ enum InterfaceID {
INTERFACE_ID_PPB_AUDIO_CONFIG,
INTERFACE_ID_PPB_BUFFER,
INTERFACE_ID_PPB_CHAR_SET,
+ INTERFACE_ID_PPB_CONSOLE,
INTERFACE_ID_PPB_CONTEXT_3D,
INTERFACE_ID_PPB_CORE,
INTERFACE_ID_PPB_CURSORCONTROL,
diff --git a/ppapi/proxy/ppapi_messages_internal.h b/ppapi/proxy/ppapi_messages_internal.h
index 375e7d5..a417426 100644
--- a/ppapi/proxy/ppapi_messages_internal.h
+++ b/ppapi/proxy/ppapi_messages_internal.h
@@ -216,6 +216,17 @@ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBBuffer_Create,
pp::proxy::HostResource /* result_resource */,
int32_t /* result_shm_handle */)
+// PPB_Console.
+IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBConsole_Log,
+ PP_Instance /* instance */,
+ int /* log_level */,
+ pp::proxy::SerializedVar /* value */)
+IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBConsole_LogWithSource,
+ PP_Instance /* instance */,
+ int /* log_level */,
+ pp::proxy::SerializedVar /* soruce */,
+ pp::proxy::SerializedVar /* value */)
+
// PPB_Context3D.
IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBContext3D_Create,
PP_Instance /* instance */,
diff --git a/ppapi/proxy/ppb_console_proxy.cc b/ppapi/proxy/ppb_console_proxy.cc
new file mode 100644
index 0000000..a04aacc
--- /dev/null
+++ b/ppapi/proxy/ppb_console_proxy.cc
@@ -0,0 +1,103 @@
+// Copyright (c) 2011 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 "ppapi/proxy/ppb_console_proxy.h"
+
+#include "ppapi/c/dev/ppb_console_dev.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
+#include "ppapi/proxy/ppapi_messages.h"
+
+namespace pp {
+namespace proxy {
+
+namespace {
+
+void Log(PP_Instance instance, PP_LogLevel_Dev level, PP_Var value) {
+ PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
+ if (!dispatcher)
+ return;
+ dispatcher->Send(new PpapiHostMsg_PPBConsole_Log(
+ INTERFACE_ID_PPB_CONSOLE, instance, static_cast<int>(level),
+ SerializedVarSendInput(dispatcher, value)));
+}
+
+void LogWithSource(PP_Instance instance,
+ PP_LogLevel_Dev level,
+ const PP_Var source,
+ const PP_Var value) {
+ PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
+ if (!dispatcher)
+ return;
+ dispatcher->Send(new PpapiHostMsg_PPBConsole_LogWithSource(
+ INTERFACE_ID_PPB_CONSOLE, instance, static_cast<int>(level),
+ SerializedVarSendInput(dispatcher, source),
+ SerializedVarSendInput(dispatcher, value)));
+}
+
+const PPB_Console_Dev console_interface = {
+ &Log,
+ &LogWithSource
+};
+
+InterfaceProxy* CreateConsoleProxy(Dispatcher* dispatcher,
+ const void* target_interface) {
+ return new PPB_Console_Proxy(dispatcher, target_interface);
+}
+
+} // namespace
+
+PPB_Console_Proxy::PPB_Console_Proxy(Dispatcher* dispatcher,
+ const void* target_interface)
+ : InterfaceProxy(dispatcher, target_interface) {
+}
+
+PPB_Console_Proxy::~PPB_Console_Proxy() {
+}
+
+// static
+const InterfaceProxy::Info* PPB_Console_Proxy::GetInfo() {
+ static const Info info = {
+ &console_interface,
+ PPB_CONSOLE_DEV_INTERFACE,
+ INTERFACE_ID_PPB_CONSOLE,
+ false,
+ &CreateConsoleProxy,
+ };
+ return &info;
+}
+
+bool PPB_Console_Proxy::OnMessageReceived(const IPC::Message& msg) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(PPB_Console_Proxy, msg)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBConsole_Log,
+ OnMsgLog)
+ IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBConsole_LogWithSource,
+ OnMsgLogWithSource)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void PPB_Console_Proxy::OnMsgLog(PP_Instance instance,
+ int log_level,
+ SerializedVarReceiveInput value) {
+ ppb_console_target()->Log(instance,
+ static_cast<PP_LogLevel_Dev>(log_level),
+ value.Get(dispatcher()));
+}
+
+void PPB_Console_Proxy::OnMsgLogWithSource(PP_Instance instance,
+ int log_level,
+ SerializedVarReceiveInput source,
+ SerializedVarReceiveInput value) {
+ ppb_console_target()->LogWithSource(
+ instance,
+ static_cast<PP_LogLevel_Dev>(log_level),
+ source.Get(dispatcher()),
+ value.Get(dispatcher()));
+}
+
+} // namespace proxy
+} // namespace pp
+
diff --git a/ppapi/proxy/ppb_console_proxy.h b/ppapi/proxy/ppb_console_proxy.h
new file mode 100644
index 0000000..af1c9e0
--- /dev/null
+++ b/ppapi/proxy/ppb_console_proxy.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2011 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 PPAPI_PROXY_PPB_CONSOLE_PROXY_H_
+#define PPAPI_PROXY_PPB_CONSOLE_PROXY_H_
+
+#include "base/basictypes.h"
+#include "ppapi/c/pp_instance.h"
+#include "ppapi/proxy/interface_proxy.h"
+#include "ppapi/proxy/serialized_var.h"
+
+struct PPB_Console_Dev;
+
+namespace pp {
+namespace proxy {
+
+class PPB_Console_Proxy : public InterfaceProxy {
+ public:
+ PPB_Console_Proxy(Dispatcher* dispatcher, const void* target_interface);
+ virtual ~PPB_Console_Proxy();
+
+ static const Info* GetInfo();
+
+ const PPB_Console_Dev* ppb_console_target() const {
+ return static_cast<const PPB_Console_Dev*>(target_interface());
+ }
+
+ // InterfaceProxy implementation.
+ virtual bool OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ // Message handlers.
+ void OnMsgLog(PP_Instance instance,
+ int log_level,
+ SerializedVarReceiveInput value);
+ void OnMsgLogWithSource(PP_Instance instance,
+ int log_level,
+ SerializedVarReceiveInput source,
+ SerializedVarReceiveInput value);
+
+ DISALLOW_COPY_AND_ASSIGN(PPB_Console_Proxy);
+};
+
+} // namespace proxy
+} // namespace pp
+
+#endif // PPAPI_PROXY_PPB_CONSOLE_PROXY_H_
diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h
index 86c2925..09ca217 100644
--- a/ppapi/tests/all_c_includes.h
+++ b/ppapi/tests/all_c_includes.h
@@ -15,6 +15,7 @@
#include "ppapi/c/dev/pp_video_dev.h"
#include "ppapi/c/dev/ppb_buffer_dev.h"
#include "ppapi/c/dev/ppb_char_set_dev.h"
+#include "ppapi/c/dev/ppb_console_dev.h"
#include "ppapi/c/dev/ppb_context_3d_dev.h"
#include "ppapi/c/dev/ppb_context_3d_trusted_dev.h"
#include "ppapi/c/dev/ppb_cursor_control_dev.h"
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index 83395d3..1dc4664 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -283,6 +283,8 @@
'../plugins/ppapi/ppb_buffer_impl.h',
'../plugins/ppapi/ppb_char_set_impl.cc',
'../plugins/ppapi/ppb_char_set_impl.h',
+ '../plugins/ppapi/ppb_console_impl.cc',
+ '../plugins/ppapi/ppb_console_impl.h',
'../plugins/ppapi/ppb_context_3d_impl.cc',
'../plugins/ppapi/ppb_context_3d_impl.h',
'../plugins/ppapi/ppb_cursor_control_impl.cc',
diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc
index 0ea2859..02d1276 100644
--- a/webkit/plugins/ppapi/plugin_module.cc
+++ b/webkit/plugins/ppapi/plugin_module.cc
@@ -16,6 +16,7 @@
#include "ppapi/c/dev/ppb_char_set_dev.h"
#include "ppapi/c/dev/ppb_context_3d_dev.h"
#include "ppapi/c/dev/ppb_context_3d_trusted_dev.h"
+#include "ppapi/c/dev/ppb_console_dev.h"
#include "ppapi/c/dev/ppb_cursor_control_dev.h"
#include "ppapi/c/dev/ppb_directory_reader_dev.h"
#include "ppapi/c/dev/ppb_file_io_dev.h"
@@ -65,6 +66,7 @@
#include "webkit/plugins/ppapi/ppb_audio_impl.h"
#include "webkit/plugins/ppapi/ppb_buffer_impl.h"
#include "webkit/plugins/ppapi/ppb_char_set_impl.h"
+#include "webkit/plugins/ppapi/ppb_console_impl.h"
#include "webkit/plugins/ppapi/ppb_cursor_control_impl.h"
#include "webkit/plugins/ppapi/ppb_directory_reader_impl.h"
#include "webkit/plugins/ppapi/ppb_file_chooser_impl.h"
@@ -230,6 +232,8 @@ const void* GetInterface(const char* name) {
return PPB_CharSet_Impl::GetInterface();
if (strcmp(name, PPB_CLASS_INTERFACE) == 0)
return VarObjectClass::GetInterface();
+ if (strcmp(name, PPB_CONSOLE_DEV_INTERFACE) == 0)
+ return PPB_Console_Impl::GetInterface();
if (strcmp(name, PPB_CORE_INTERFACE) == 0)
return &core_interface;
if (strcmp(name, PPB_CURSOR_CONTROL_DEV_INTERFACE) == 0)
diff --git a/webkit/plugins/ppapi/ppb_console_impl.cc b/webkit/plugins/ppapi/ppb_console_impl.cc
new file mode 100644
index 0000000..3ca773c
--- /dev/null
+++ b/webkit/plugins/ppapi/ppb_console_impl.cc
@@ -0,0 +1,86 @@
+// Copyright (c) 2011 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 "webkit/plugins/ppapi/ppb_console_impl.h"
+
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "ppapi/c/dev/ppb_console_dev.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
+#include "webkit/plugins/ppapi/plugin_module.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+#include "webkit/plugins/ppapi/resource_tracker.h"
+#include "webkit/plugins/ppapi/var.h"
+
+using WebKit::WebConsoleMessage;
+using WebKit::WebString;
+
+namespace webkit {
+namespace ppapi {
+
+namespace {
+
+void LogWithSource(PP_Instance instance_id,
+ PP_LogLevel_Dev level,
+ PP_Var source,
+ PP_Var value) {
+ PluginInstance* instance = ResourceTracker::Get()->GetInstance(instance_id);
+ if (!instance)
+ return;
+
+ // Convert the log level, defaulting to error.
+ WebConsoleMessage::Level web_level;
+ switch (level) {
+ case PP_LOGLEVEL_TIP:
+ web_level = WebConsoleMessage::LevelTip;
+ break;
+ case PP_LOGLEVEL_LOG:
+ web_level = WebConsoleMessage::LevelLog;
+ break;
+ case PP_LOGLEVEL_WARNING:
+ web_level = WebConsoleMessage::LevelWarning;
+ break;
+ case PP_LOGLEVEL_ERROR:
+ default:
+ web_level = WebConsoleMessage::LevelError;
+ break;
+ }
+
+ // Format is the "<source>: <value>". The source defaults to the module name
+ // if the source isn't a string or is empty.
+ std::string message;
+ if (source.type == PP_VARTYPE_STRING)
+ message = Var::PPVarToLogString(source);
+ if (message.empty())
+ message = instance->module()->name();
+ message.append(": ");
+ message.append(Var::PPVarToLogString(value));
+
+ instance->container()->element().document().frame()->addMessageToConsole(
+ WebConsoleMessage(web_level, WebString(UTF8ToUTF16(message))));
+}
+
+void Log(PP_Instance instance, PP_LogLevel_Dev level, PP_Var value) {
+ LogWithSource(instance, level, PP_MakeUndefined(), value);
+}
+
+const PPB_Console_Dev ppb_console = {
+ &Log,
+ &LogWithSource
+};
+
+} // namespace
+
+// static
+const struct PPB_Console_Dev* PPB_Console_Impl::GetInterface() {
+ return &ppb_console;
+}
+
+} // namespace ppapi
+} // namespace webkit
+
diff --git a/webkit/plugins/ppapi/ppb_console_impl.h b/webkit/plugins/ppapi/ppb_console_impl.h
new file mode 100644
index 0000000..2d47587
--- /dev/null
+++ b/webkit/plugins/ppapi/ppb_console_impl.h
@@ -0,0 +1,23 @@
+// Copyright (c) 2011 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 WEBKIT_PLUGINS_PPAPI_PPB_CONSOLE_IMPL_H_
+#define WEBKIT_PLUGINS_PPAPI_PPB_CONSOLE_IMPL_H_
+
+struct PPB_Console_Dev;
+
+namespace webkit {
+namespace ppapi {
+
+class PPB_Console_Impl {
+ public:
+ // Returns a pointer to the interface implementing PPB_Console_Dev that is
+ // exposed to the plugin.
+ static const PPB_Console_Dev* GetInterface();
+};
+
+} // namespace ppapi
+} // namespace webkit
+
+#endif // WEBKIT_PLUGINS_PPAPI_PPB_CONSOLE_IMPL_H_
diff --git a/webkit/plugins/ppapi/var.cc b/webkit/plugins/ppapi/var.cc
index b8071ed..097c613 100644
--- a/webkit/plugins/ppapi/var.cc
+++ b/webkit/plugins/ppapi/var.cc
@@ -8,6 +8,7 @@
#include "base/logging.h"
#include "base/scoped_ptr.h"
+#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/ppb_var.h"
@@ -724,6 +725,38 @@ PP_Var Var::NPIdentifierToPPVar(PluginModule* module, NPIdentifier id) {
}
// static
+std::string Var::PPVarToLogString(PP_Var var) {
+ switch (var.type) {
+ case PP_VARTYPE_UNDEFINED:
+ return "[Undefined]";
+ case PP_VARTYPE_NULL:
+ return "[Null]";
+ case PP_VARTYPE_BOOL:
+ return var.value.as_bool ? "[True]" : "[False]";
+ case PP_VARTYPE_INT32:
+ return base::IntToString(var.value.as_int);
+ case PP_VARTYPE_DOUBLE:
+ return base::DoubleToString(var.value.as_double);
+ case PP_VARTYPE_STRING: {
+ scoped_refptr<StringVar> string(StringVar::FromPPVar(var));
+ if (!string)
+ return "[Invalid string]";
+
+ // Since this is for logging, escape NULLs.
+ std::string result = string->value();
+ std::string null;
+ null.push_back(0);
+ ReplaceSubstringsAfterOffset(&result, 0, null, "\\0");
+ return result;
+ }
+ case PP_VARTYPE_OBJECT:
+ return "[Object]";
+ default:
+ return "[Invalid var]";
+ }
+}
+
+// static
void Var::PluginAddRefPPVar(PP_Var var) {
if (var.type == PP_VARTYPE_STRING || var.type == PP_VARTYPE_OBJECT) {
if (!ResourceTracker::Get()->AddRefVar(static_cast<int32>(var.value.as_id)))
diff --git a/webkit/plugins/ppapi/var.h b/webkit/plugins/ppapi/var.h
index 4571698..0a17585 100644
--- a/webkit/plugins/ppapi/var.h
+++ b/webkit/plugins/ppapi/var.h
@@ -54,6 +54,9 @@ class Var : public base::RefCounted<Var> {
// given module. A returned string will have a reference count of 1.
static PP_Var NPIdentifierToPPVar(PluginModule* module, NPIdentifier id);
+ // Returns a string representing the given var for logging purposes.
+ static std::string PPVarToLogString(PP_Var var);
+
// Provides access to the manual refcounting of a PP_Var from the plugin's
// perspective. This is different than the AddRef/Release on this scoped
// object. This uses the ResourceTracker, which keeps a separate "plugin