diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-15 21:22:31 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-12-15 21:22:31 +0000 |
commit | 8cc26a4c78767feaf47fa94af34471d63e3596e5 (patch) | |
tree | 24399869b26449df2a6a838796941c984106f4b2 | |
parent | b40a1f1acb4d3fa0c56a3706dd47a2ca8d471834 (diff) | |
download | chromium_src-8cc26a4c78767feaf47fa94af34471d63e3596e5.zip chromium_src-8cc26a4c78767feaf47fa94af34471d63e3596e5.tar.gz chromium_src-8cc26a4c78767feaf47fa94af34471d63e3596e5.tar.bz2 |
Implement in-process PPB_VarArrayBuffer_Dev.
+tony TBR for webkit/glue/webkit_glue.gypi
BUG=103435
TEST=N/A
TBR=tony
Review URL: http://codereview.chromium.org/8930010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@114700 0039d316-1c4b-4281-b951-d872f2087c98
33 files changed, 451 insertions, 59 deletions
diff --git a/chrome/test/ui/ppapi_uitest.cc b/chrome/test/ui/ppapi_uitest.cc index 48e072f..02a2f2e 100644 --- a/chrome/test/ui/ppapi_uitest.cc +++ b/chrome/test/ui/ppapi_uitest.cc @@ -425,11 +425,13 @@ TEST_PPAPI_IN_PROCESS(VarDeprecated) #endif TEST_PPAPI_IN_PROCESS(PostMessage_SendInInit) TEST_PPAPI_IN_PROCESS(PostMessage_SendingData) +TEST_PPAPI_IN_PROCESS(PostMessage_SendingArrayBuffer) TEST_PPAPI_IN_PROCESS(PostMessage_MessageEvent) TEST_PPAPI_IN_PROCESS(PostMessage_NoHandler) TEST_PPAPI_IN_PROCESS(PostMessage_ExtraParam) TEST_PPAPI_OUT_OF_PROCESS(PostMessage_SendInInit) TEST_PPAPI_OUT_OF_PROCESS(PostMessage_SendingData) +TEST_PPAPI_OUT_OF_PROCESS(DISABLED_PostMessage_SendingArrayBuffer) TEST_PPAPI_OUT_OF_PROCESS(PostMessage_MessageEvent) TEST_PPAPI_OUT_OF_PROCESS(PostMessage_NoHandler) TEST_PPAPI_OUT_OF_PROCESS(PostMessage_ExtraParam) diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi index 20157f2..8731cbf 100644 --- a/ppapi/ppapi_proxy.gypi +++ b/ppapi/ppapi_proxy.gypi @@ -40,6 +40,8 @@ 'proxy/interface_list.h', 'proxy/interface_proxy.cc', 'proxy/interface_proxy.h', + 'proxy/plugin_array_buffer_var.cc', + 'proxy/plugin_array_buffer_var.h', 'proxy/plugin_dispatcher.cc', 'proxy/plugin_dispatcher.h', 'proxy/plugin_globals.cc', diff --git a/ppapi/proxy/plugin_array_buffer_var.cc b/ppapi/proxy/plugin_array_buffer_var.cc new file mode 100644 index 0000000..d88ca7b --- /dev/null +++ b/ppapi/proxy/plugin_array_buffer_var.cc @@ -0,0 +1,31 @@ +// 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/plugin_array_buffer_var.h" + +#include <stdlib.h> + +#include <limits> + +namespace ppapi { + +PluginArrayBufferVar::PluginArrayBufferVar(uint32 size_in_bytes) + : buffer_(size_in_bytes) { +} + +PluginArrayBufferVar::~PluginArrayBufferVar() { +} + +void* PluginArrayBufferVar::Map() { + if (buffer_.empty()) + return NULL; + return &(buffer_[0]); +} + +uint32 PluginArrayBufferVar::ByteLength() { + return buffer_.size(); +} + +} // namespace ppapi + diff --git a/ppapi/proxy/plugin_array_buffer_var.h b/ppapi/proxy/plugin_array_buffer_var.h new file mode 100644 index 0000000..5e4d702 --- /dev/null +++ b/ppapi/proxy/plugin_array_buffer_var.h @@ -0,0 +1,36 @@ +// 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_PLUGIN_ARRAY_BUFFER_VAR_H_ +#define PPAPI_PROXY_PLUGIN_ARRAY_BUFFER_VAR_H_ + +#include <vector> + +#include "base/basictypes.h" +#include "ppapi/c/pp_stdint.h" +#include "ppapi/shared_impl/var.h" + +namespace ppapi { + +// Represents a plugin-side ArrayBufferVar. In the plugin process, it's +// owned as a vector. +class PluginArrayBufferVar : public ArrayBufferVar { + public: + explicit PluginArrayBufferVar(uint32 size_in_bytes); + virtual ~PluginArrayBufferVar(); + + // ArrayBufferVar implementation. + virtual void* Map() OVERRIDE; + virtual uint32 ByteLength() OVERRIDE; + + private: + // TODO(dmichael): Use shared memory for this. + std::vector<uint8> buffer_; + + DISALLOW_COPY_AND_ASSIGN(PluginArrayBufferVar); +}; + +} // namespace ppapi + +#endif // PPAPI_PROXY_PLUGIN_ARRAY_BUFFER_VAR_H_ diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc index 8ea25b1..a5f499a 100644 --- a/ppapi/proxy/plugin_var_tracker.cc +++ b/ppapi/proxy/plugin_var_tracker.cc @@ -7,6 +7,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/singleton.h" #include "ppapi/c/ppb_var.h" +#include "ppapi/proxy/plugin_array_buffer_var.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/proxy_object_var.h" @@ -156,6 +157,10 @@ int PluginVarTracker::GetTrackedWithNoReferenceCountForObject( return found->second.track_with_no_reference_count; } +ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { + return new PluginArrayBufferVar(size_in_bytes); +} + int32 PluginVarTracker::AddVarInternal(Var* var, AddVarRefMode mode) { // Normal adding. int32 new_id = VarTracker::AddVarInternal(var, mode); diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h index b6bb893..c2ede10 100644 --- a/ppapi/proxy/plugin_var_tracker.h +++ b/ppapi/proxy/plugin_var_tracker.h @@ -62,12 +62,13 @@ class PPAPI_PROXY_EXPORT PluginVarTracker : public VarTracker { int GetRefCountForObject(const PP_Var& plugin_object); int GetTrackedWithNoReferenceCountForObject(const PP_Var& plugin_object); - protected: + private: // VarTracker protected overrides. virtual int32 AddVarInternal(Var* var, AddVarRefMode mode) OVERRIDE; virtual void TrackedObjectGettingOneRef(VarMap::const_iterator iter) OVERRIDE; virtual void ObjectGettingZeroRef(VarMap::iterator iter) OVERRIDE; virtual bool DeleteObjectInfoIfNecessary(VarMap::iterator iter) OVERRIDE; + virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE; private: friend struct DefaultSingletonTraits<PluginVarTracker>; diff --git a/ppapi/proxy/proxy_object_var.cc b/ppapi/proxy/proxy_object_var.cc index 4a185e8..acd53f3 100644 --- a/ppapi/proxy/proxy_object_var.cc +++ b/ppapi/proxy/proxy_object_var.cc @@ -27,17 +27,6 @@ ProxyObjectVar* ProxyObjectVar::AsProxyObjectVar() { return this; } -PP_Var ProxyObjectVar::GetPPVar() { - int32 id = GetOrCreateVarID(); - if (!id) - return PP_MakeNull(); - - PP_Var result; - result.type = PP_VARTYPE_OBJECT; - result.value.as_id = id; - return result; -} - PP_VarType ProxyObjectVar::GetType() const { return PP_VARTYPE_OBJECT; } diff --git a/ppapi/proxy/proxy_object_var.h b/ppapi/proxy/proxy_object_var.h index e8d7aed..e9760f9 100644 --- a/ppapi/proxy/proxy_object_var.h +++ b/ppapi/proxy/proxy_object_var.h @@ -26,7 +26,6 @@ class ProxyObjectVar : public Var { // Var overrides. virtual ProxyObjectVar* AsProxyObjectVar() OVERRIDE; - virtual PP_Var GetPPVar() OVERRIDE; virtual PP_VarType GetType() const OVERRIDE; proxy::PluginDispatcher* dispatcher() const { return dispatcher_; } diff --git a/ppapi/proxy/serialized_var.cc b/ppapi/proxy/serialized_var.cc index 7a9eb6f..b892daf 100644 --- a/ppapi/proxy/serialized_var.cc +++ b/ppapi/proxy/serialized_var.cc @@ -152,12 +152,15 @@ void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const { // what looks like a valid empty string. m->WriteString(string_value_); break; + case PP_VARTYPE_ARRAY_BUFFER: + // TODO(dmichael): Proxy ArrayBuffer. + NOTIMPLEMENTED(); + break; case PP_VARTYPE_OBJECT: m->WriteInt64(var_.value.as_id); break; case PP_VARTYPE_ARRAY: case PP_VARTYPE_DICTIONARY: - case PP_VARTYPE_ARRAY_BUFFER: // TODO(brettw) when these are supported, implement this. NOTIMPLEMENTED(); break; diff --git a/ppapi/shared_impl/api_id.h b/ppapi/shared_impl/api_id.h index 73654b0..0813354 100644 --- a/ppapi/shared_impl/api_id.h +++ b/ppapi/shared_impl/api_id.h @@ -45,6 +45,7 @@ enum ApiID { API_ID_PPB_UDPSOCKET_PRIVATE, API_ID_PPB_URL_LOADER, API_ID_PPB_URL_RESPONSE_INFO, + API_ID_PPB_VAR_ARRAY_BUFFER, API_ID_PPB_VAR_DEPRECATED, API_ID_PPB_VIDEO_CAPTURE_DEV, API_ID_PPB_VIDEO_DECODER_DEV, diff --git a/ppapi/shared_impl/ppb_var_shared.cc b/ppapi/shared_impl/ppb_var_shared.cc index c548ba7..5549818 100644 --- a/ppapi/shared_impl/ppb_var_shared.cc +++ b/ppapi/shared_impl/ppb_var_shared.cc @@ -6,6 +6,7 @@ #include <limits> +#include "ppapi/c/dev/ppb_var_array_buffer_dev.h" #include "ppapi/c/ppb_var.h" #include "ppapi/c/pp_var.h" #include "ppapi/shared_impl/ppapi_globals.h" @@ -17,6 +18,10 @@ using ppapi::PpapiGlobals; using ppapi::StringVar; namespace ppapi { +namespace { + + +// PPB_Var methods ------------------------------------------------------------- void AddRefVar(PP_Var var) { ppapi::ProxyAutoLock lock; @@ -48,7 +53,6 @@ const char* VarToUtf8(PP_Var var, uint32_t* len) { return NULL; } -namespace { const PPB_Var var_interface = { &AddRefVar, &ReleaseVar, @@ -62,6 +66,35 @@ const PPB_Var_1_0 var_interface1_0 = { &VarFromUtf8_1_0, &VarToUtf8 }; + + +// PPB_VarArrayBuffer_Dev methods ---------------------------------------------- + +PP_Var CreateArrayBufferVar(uint32_t size_in_bytes) { + return PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( + size_in_bytes); +} + +uint32_t ByteLength(struct PP_Var array) { + ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array); + if (!buffer) + return 0; + return buffer->ByteLength(); +} + +void* Map(struct PP_Var array) { + ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(array); + if (!buffer) + return NULL; + return buffer->Map(); +} + +const PPB_VarArrayBuffer_Dev var_arraybuffer_interface = { + &CreateArrayBufferVar, + &ByteLength, + &Map +}; + } // namespace // static @@ -74,5 +107,10 @@ const PPB_Var_1_0* PPB_Var_Shared::GetVarInterface1_0() { return &var_interface1_0; } +// static +const PPB_VarArrayBuffer_Dev* PPB_Var_Shared::GetVarArrayBufferInterface() { + return &var_arraybuffer_interface; +} + } // namespace ppapi diff --git a/ppapi/shared_impl/ppb_var_shared.h b/ppapi/shared_impl/ppb_var_shared.h index dfdf472..5865d46 100644 --- a/ppapi/shared_impl/ppb_var_shared.h +++ b/ppapi/shared_impl/ppb_var_shared.h @@ -12,6 +12,7 @@ struct PP_Var; struct PPB_Var; struct PPB_Var_1_0; +struct PPB_VarArrayBuffer_Dev; namespace ppapi { @@ -19,6 +20,7 @@ class PPAPI_SHARED_EXPORT PPB_Var_Shared { public: static const PPB_Var* GetVarInterface(); static const PPB_Var_1_0* GetVarInterface1_0(); + static const PPB_VarArrayBuffer_Dev* GetVarArrayBufferInterface(); }; } // namespace ppapi diff --git a/ppapi/shared_impl/test_globals.h b/ppapi/shared_impl/test_globals.h index d5d1439..49f189f 100644 --- a/ppapi/shared_impl/test_globals.h +++ b/ppapi/shared_impl/test_globals.h @@ -12,6 +12,15 @@ namespace ppapi { +class TestVarTracker : public VarTracker { + public: + TestVarTracker() {} + virtual ~TestVarTracker() {} + virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) OVERRIDE { + return NULL; + } +}; + // Implementation of PpapiGlobals for tests that don't need either the host- or // plugin-specific implementations. class TestGlobals : public PpapiGlobals { @@ -28,7 +37,7 @@ class TestGlobals : public PpapiGlobals { private: ResourceTracker resource_tracker_; - VarTracker var_tracker_; + TestVarTracker var_tracker_; DISALLOW_COPY_AND_ASSIGN(TestGlobals); }; diff --git a/ppapi/shared_impl/var.cc b/ppapi/shared_impl/var.cc index 3bec5ce..60d439b 100644 --- a/ppapi/shared_impl/var.cc +++ b/ppapi/shared_impl/var.cc @@ -65,6 +65,10 @@ StringVar* Var::AsStringVar() { return NULL; } +ArrayBufferVar* Var::AsArrayBufferVar() { + return NULL; +} + NPObjectVar* Var::AsNPObjectVar() { return NULL; } @@ -73,6 +77,18 @@ ProxyObjectVar* Var::AsProxyObjectVar() { return NULL; } +PP_Var Var::GetPPVar() { + int32 id = GetOrCreateVarID(); + if (!id) + return PP_MakeNull(); + + PP_Var result; + result.type = GetType(); + result.padding = 0; + result.value.as_id = id; + return result; +} + int32 Var::GetExistingVarID() const { return var_id_; } @@ -112,18 +128,6 @@ StringVar* StringVar::AsStringVar() { return this; } -PP_Var StringVar::GetPPVar() { - int32 id = GetOrCreateVarID(); - if (!id) - return PP_MakeNull(); - - PP_Var result; - result.type = PP_VARTYPE_STRING; - result.padding = 0; - result.value.as_id = id; - return result; -} - PP_VarType StringVar::GetType() const { return PP_VARTYPE_STRING; } @@ -152,5 +156,32 @@ StringVar* StringVar::FromPPVar(PP_Var var) { return var_object->AsStringVar(); } +// ArrayBufferVar -------------------------------------------------------------- + +ArrayBufferVar::ArrayBufferVar() { +} + +ArrayBufferVar::~ArrayBufferVar() { +} + +ArrayBufferVar* ArrayBufferVar::AsArrayBufferVar() { + return this; +} + +PP_VarType ArrayBufferVar::GetType() const { + return PP_VARTYPE_ARRAY_BUFFER; +} + +// static +ArrayBufferVar* ArrayBufferVar::FromPPVar(PP_Var var) { + if (var.type != PP_VARTYPE_ARRAY_BUFFER) + return NULL; + scoped_refptr<Var> var_object( + PpapiGlobals::Get()->GetVarTracker()->GetVar(var)); + if (!var_object) + return NULL; + return var_object->AsArrayBufferVar(); +} + } // namespace ppapi diff --git a/ppapi/shared_impl/var.h b/ppapi/shared_impl/var.h index 49b9272..d41d00e 100644 --- a/ppapi/shared_impl/var.h +++ b/ppapi/shared_impl/var.h @@ -14,6 +14,7 @@ namespace ppapi { +class ArrayBufferVar; class NPObjectVar; class ProxyObjectVar; class StringVar; @@ -30,12 +31,13 @@ class PPAPI_SHARED_EXPORT Var : public base::RefCounted<Var> { static std::string PPVarToLogString(PP_Var var); virtual StringVar* AsStringVar(); + virtual ArrayBufferVar* AsArrayBufferVar(); virtual NPObjectVar* AsNPObjectVar(); virtual ProxyObjectVar* AsProxyObjectVar(); // Creates a PP_Var corresponding to this object. The return value will have // one reference addrefed on behalf of the caller. - virtual PP_Var GetPPVar() = 0; + PP_Var GetPPVar(); // Returns the type of this var. virtual PP_VarType GetType() const = 0; @@ -97,7 +99,6 @@ class PPAPI_SHARED_EXPORT StringVar : public Var { // Var override. virtual StringVar* AsStringVar() OVERRIDE; - virtual PP_Var GetPPVar() OVERRIDE; virtual PP_VarType GetType() const OVERRIDE; // Helper function to create a PP_Var of type string that contains a copy of @@ -119,6 +120,40 @@ class PPAPI_SHARED_EXPORT StringVar : public Var { DISALLOW_COPY_AND_ASSIGN(StringVar); }; +// ArrayBufferVar -------------------------------------------------------------- + +// Represents an array buffer Var. +// +// Note this is an abstract class. To create an appropriate concrete one, you +// need to use the VarTracker: +// VarArrayBuffer* buf = +// PpapiGlobals::Get()->GetVarTracker()->CreateArrayBuffer(size); +// +// Converting a PP_Var to an ArrayBufferVar: +// ArrayBufferVar* array = ArrayBufferVar::FromPPVar(var); +// if (!array) +// return false; // Not an ArrayBuffer or an invalid var. +// DoSomethingWithTheBuffer(array); +class PPAPI_SHARED_EXPORT ArrayBufferVar : public Var { + public: + ArrayBufferVar(); + virtual ~ArrayBufferVar(); + + virtual void* Map() = 0; + virtual uint32 ByteLength() = 0; + + // Var override. + virtual ArrayBufferVar* AsArrayBufferVar() OVERRIDE; + virtual PP_VarType GetType() const OVERRIDE; + + // Helper function that converts a PP_Var to an ArrayBufferVar. This will + // return NULL if the PP_Var is not of ArrayBuffer type. + static ArrayBufferVar* FromPPVar(PP_Var var); + + private: + DISALLOW_COPY_AND_ASSIGN(ArrayBufferVar); +}; + } // namespace ppapi #endif // PPAPI_SHARED_IMPL_VAR_H_ diff --git a/ppapi/shared_impl/var_tracker.cc b/ppapi/shared_impl/var_tracker.cc index d95a759..852d586 100644 --- a/ppapi/shared_impl/var_tracker.cc +++ b/ppapi/shared_impl/var_tracker.cc @@ -139,7 +139,14 @@ VarTracker::VarMap::const_iterator VarTracker::GetLiveVar( } bool VarTracker::IsVarTypeRefcounted(PP_VarType type) const { - return type == PP_VARTYPE_STRING || type == PP_VARTYPE_OBJECT; + return type >= PP_VARTYPE_STRING; +} + +PP_Var VarTracker::MakeArrayBufferPPVar(uint32 size_in_bytes) { + scoped_refptr<ArrayBufferVar> array_buffer(CreateArrayBuffer(size_in_bytes)); + if (!array_buffer) + return PP_MakeNull(); + return array_buffer->GetPPVar(); } void VarTracker::TrackedObjectGettingOneRef(VarMap::const_iterator obj) { diff --git a/ppapi/shared_impl/var_tracker.h b/ppapi/shared_impl/var_tracker.h index f91c209..a2debe0 100644 --- a/ppapi/shared_impl/var_tracker.h +++ b/ppapi/shared_impl/var_tracker.h @@ -8,11 +8,13 @@ #include "base/basictypes.h" #include "base/hash_tables.h" #include "base/memory/ref_counted.h" +#include "ppapi/c/pp_module.h" #include "ppapi/c/pp_var.h" #include "ppapi/shared_impl/ppapi_shared_export.h" namespace ppapi { +class ArrayBufferVar; class Var; // Tracks non-POD (refcounted) var objects held by a plugin. @@ -54,6 +56,10 @@ class PPAPI_SHARED_EXPORT VarTracker { bool ReleaseVar(int32 var_id); bool ReleaseVar(const PP_Var& var); + // Create a new array buffer of size |size_in_bytes|. Return a PP_Var that + // that references it and has an initial reference-count of 1. + PP_Var MakeArrayBufferPPVar(uint32 size_in_bytes); + protected: struct VarInfo { VarInfo(); @@ -126,6 +132,12 @@ class PPAPI_SHARED_EXPORT VarTracker { // Last assigned var ID. int32 last_var_id_; + private: + // Create and return a new ArrayBufferVar size_in_bytes bytes long. This is + // implemented by the Host and Plugin tracker separately, so that it can be + // a real WebKit ArrayBuffer on the host side. + virtual ArrayBufferVar* CreateArrayBuffer(uint32 size_in_bytes) = 0; + DISALLOW_COPY_AND_ASSIGN(VarTracker); }; diff --git a/ppapi/tests/all_c_includes.h b/ppapi/tests/all_c_includes.h index 3d30c6b..97fa532 100644 --- a/ppapi/tests/all_c_includes.h +++ b/ppapi/tests/all_c_includes.h @@ -29,6 +29,7 @@ #include "ppapi/c/dev/ppb_text_input_dev.h" #include "ppapi/c/dev/ppb_transport_dev.h" #include "ppapi/c/dev/ppb_url_util_dev.h" +#include "ppapi/c/dev/ppb_var_array_buffer_dev.h" #include "ppapi/c/dev/ppb_var_deprecated.h" #include "ppapi/c/dev/ppb_video_decoder_dev.h" #include "ppapi/c/dev/ppb_video_layer_dev.h" diff --git a/ppapi/tests/all_cpp_includes.h b/ppapi/tests/all_cpp_includes.h index 4323f51..ff408b0 100644 --- a/ppapi/tests/all_cpp_includes.h +++ b/ppapi/tests/all_cpp_includes.h @@ -28,6 +28,7 @@ #include "ppapi/cpp/dev/text_input_dev.h" #include "ppapi/cpp/dev/transport_dev.h" #include "ppapi/cpp/dev/url_util_dev.h" +#include "ppapi/cpp/dev/var_array_buffer_dev.h" #include "ppapi/cpp/dev/video_decoder_dev.h" #include "ppapi/cpp/dev/websocket_dev.h" #include "ppapi/cpp/dev/widget_client_dev.h" diff --git a/ppapi/tests/test_post_message.cc b/ppapi/tests/test_post_message.cc index 0f97b74..a86f310 100644 --- a/ppapi/tests/test_post_message.cc +++ b/ppapi/tests/test_post_message.cc @@ -8,7 +8,7 @@ #include "ppapi/c/dev/ppb_testing_dev.h" #include "ppapi/c/pp_var.h" -#include "ppapi/cpp/dev/scriptable_object_deprecated.h" +#include "ppapi/cpp/dev/var_array_buffer_dev.h" #include "ppapi/cpp/instance.h" #include "ppapi/cpp/var.h" #include "ppapi/tests/pp_thread.h" @@ -111,6 +111,7 @@ void TestPostMessage::RunTests(const std::string& filter) { // that was sent in Init above. RUN_TEST(SendInInit, filter); RUN_TEST(SendingData, filter); + RUN_TEST(SendingArrayBuffer, filter); RUN_TEST(MessageEvent, filter); RUN_TEST(NoHandler, filter); RUN_TEST(ExtraParam, filter); @@ -244,30 +245,90 @@ std::string TestPostMessage::TestSendingData() { PASS(); } +std::string TestPostMessage::TestSendingArrayBuffer() { + // Clean up after previous tests. This also swallows the message sent by Init + // if we didn't run the 'SendInInit' test. All tests other than 'SendInInit' + // should start with these. + WaitForMessages(); + ASSERT_TRUE(ClearListeners()); + + // Create a 100-byte array buffer with test_data[i] == i. + pp::VarArrayBuffer_Dev test_data(100u); + ASSERT_NE(NULL, test_data.Map()); + ASSERT_EQ(100u, test_data.ByteLength()); + unsigned char* buff = static_cast<unsigned char*>(test_data.Map()); + for (size_t i = 0; i < test_data.ByteLength(); ++i) + buff[i] = i; + + // Have the listener test some properties of the ArrayBuffer. + const char* const properties_to_check[] = { + "message_event.data.constructor.name === 'ArrayBuffer'", + "message_event.data.byteLength === 100", + "(new DataView(message_event.data)).getInt8(0) == 0", + "(new DataView(message_event.data)).getInt8(99) == 99", + NULL}; + for (size_t i = 0; properties_to_check[i]; ++i) { + ASSERT_TRUE(AddEchoingListener(properties_to_check[i])); + message_data_.clear(); + instance_->PostMessage(test_data); + ASSERT_EQ(message_data_.size(), 0); + ASSERT_EQ(WaitForMessages(), 1); + ASSERT_TRUE(message_data_.back().is_bool()); + if (!message_data_.back().AsBool()) + return std::string("Failed: ") + properties_to_check[i]; + ASSERT_TRUE(message_data_.back().AsBool()); + ASSERT_TRUE(ClearListeners()); + } + + // Set up the JavaScript message event listener to echo the data part of the + // message event back to us. + ASSERT_TRUE(AddEchoingListener("message_event.data")); + message_data_.clear(); + instance_->PostMessage(test_data); + // PostMessage is asynchronous, so we should not receive a response yet. + ASSERT_EQ(message_data_.size(), 0); + ASSERT_EQ(WaitForMessages(), 1); + ASSERT_TRUE(message_data_.back().is_array_buffer()); + pp::VarArrayBuffer_Dev received(message_data_.back()); + message_data_.clear(); + ASSERT_EQ(test_data.ByteLength(), received.ByteLength()); + unsigned char* received_buff = static_cast<unsigned char*>(received.Map()); + // The buffer should be copied, so this should be a distinct buffer. When + // 'transferrables' are implemented for PPAPI, we'll also want to test that + // we get the _same_ buffer back when it's transferred. + ASSERT_NE(buff, received_buff); + for (size_t i = 0; i < test_data.ByteLength(); ++i) + ASSERT_EQ(buff[i], received_buff[i]); + + ASSERT_TRUE(ClearListeners()); + + PASS(); +} + std::string TestPostMessage::TestMessageEvent() { // Set up the JavaScript message event listener to pass us some values from // the MessageEvent and make sure they match our expectations. WaitForMessages(); ASSERT_TRUE(ClearListeners()); - // Have the listener pass back the type of message_event and make sure it's - // "object". - ASSERT_TRUE(AddEchoingListener("typeof(message_event)")); + // Have the listener pass back the class name of message_event and make sure + // it's "MessageEvent". + ASSERT_TRUE(AddEchoingListener("message_event.constructor.name")); message_data_.clear(); instance_->PostMessage(pp::Var(kTestInt)); ASSERT_EQ(message_data_.size(), 0); ASSERT_EQ(WaitForMessages(), 1); ASSERT_TRUE(message_data_.back().is_string()); - ASSERT_EQ(message_data_.back().AsString(), "object"); + ASSERT_EQ(message_data_.back().AsString(), "MessageEvent"); ASSERT_TRUE(ClearListeners()); // Make sure all the non-data properties have the expected values. - bool success = AddEchoingListener("((message_event.origin == '')" - " && (message_event.lastEventId == '')" - " && (message_event.source == null)" - " && (message_event.ports.length == 0)" - " && (message_event.bubbles == false)" - " && (message_event.cancelable == false)" + bool success = AddEchoingListener("((message_event.origin === '')" + " && (message_event.lastEventId === '')" + " && (message_event.source === null)" + " && (message_event.ports.length === 0)" + " && (message_event.bubbles === false)" + " && (message_event.cancelable === false)" ")"); ASSERT_TRUE(success); message_data_.clear(); diff --git a/ppapi/tests/test_post_message.h b/ppapi/tests/test_post_message.h index b8e6499..8ba3e4e 100644 --- a/ppapi/tests/test_post_message.h +++ b/ppapi/tests/test_post_message.h @@ -52,6 +52,9 @@ class TestPostMessage : public TestCase { // in both directions. std::string TestSendingData(); + // Test sending ArrayBuffer vars in both directions. + std::string TestSendingArrayBuffer(); + // Test the MessageEvent object that JavaScript received to make sure it is // of the right type and has all the expected fields. std::string TestMessageEvent(); diff --git a/ppapi/thunk/enter.h b/ppapi/thunk/enter.h index 5d62173..e2c6938 100644 --- a/ppapi/thunk/enter.h +++ b/ppapi/thunk/enter.h @@ -94,7 +94,7 @@ class EnterFunction : subtle::LockOnEntry<lock_on_entry> { DISALLOW_COPY_AND_ASSIGN(EnterFunction); }; -// Like EnterResource but assumes the lock is already held. +// Like EnterFunction but assumes the lock is already held. template<typename FunctionsT> class EnterFunctionNoLock : public EnterFunction<FunctionsT, false> { public: diff --git a/ppapi/thunk/interfaces_ppb_public_dev.h b/ppapi/thunk/interfaces_ppb_public_dev.h index c3fb3e4..2aa7ea4 100644 --- a/ppapi/thunk/interfaces_ppb_public_dev.h +++ b/ppapi/thunk/interfaces_ppb_public_dev.h @@ -18,6 +18,7 @@ UNPROXIED_API(PPB_LayerCompositor) UNPROXIED_API(PPB_Scrollbar) PROXIED_API(PPB_TextInput) UNPROXIED_API(PPB_Transport) +UNPROXIED_API(PPB_VarArrayBuffer) PROXIED_API(PPB_VideoCapture) PROXIED_API(PPB_VideoDecoder) UNPROXIED_API(PPB_WebSocket) diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi index 98bf8b75..c2bbf38 100644 --- a/webkit/glue/webkit_glue.gypi +++ b/webkit/glue/webkit_glue.gypi @@ -231,6 +231,8 @@ '../plugins/ppapi/file_path.cc', '../plugins/ppapi/file_path.h', '../plugins/ppapi/fullscreen_container.h', + '../plugins/ppapi/host_array_buffer_var.cc', + '../plugins/ppapi/host_array_buffer_var.h', '../plugins/ppapi/host_globals.cc', '../plugins/ppapi/host_globals.h', '../plugins/ppapi/host_resource_tracker.cc', diff --git a/webkit/plugins/ppapi/host_array_buffer_var.cc b/webkit/plugins/ppapi/host_array_buffer_var.cc new file mode 100644 index 0000000..248ff85 --- /dev/null +++ b/webkit/plugins/ppapi/host_array_buffer_var.cc @@ -0,0 +1,34 @@ +// 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/host_array_buffer_var.h" + +using ppapi::ArrayBufferVar; +using WebKit::WebArrayBuffer; + +namespace webkit { +namespace ppapi { + +HostArrayBufferVar::HostArrayBufferVar(uint32 size_in_bytes) + : buffer_(WebArrayBuffer::create(size_in_bytes, 1 /* element_size */)) { +} + +HostArrayBufferVar::HostArrayBufferVar(const WebArrayBuffer& buffer) + : buffer_(buffer) { +} + +HostArrayBufferVar::~HostArrayBufferVar() { +} + +void* HostArrayBufferVar::Map() { + return buffer_.data(); +} + +uint32 HostArrayBufferVar::ByteLength() { + return buffer_.byteLength(); +} + +} // namespace ppapi +} // namespace webkit + diff --git a/webkit/plugins/ppapi/host_array_buffer_var.h b/webkit/plugins/ppapi/host_array_buffer_var.h new file mode 100644 index 0000000..aaccb34 --- /dev/null +++ b/webkit/plugins/ppapi/host_array_buffer_var.h @@ -0,0 +1,36 @@ +// 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_WEBKIT_PLUGINS_PPAPI_HOST_ARRAY_BUFFER_VAR_H_ +#define PPAPI_WEBKIT_PLUGINS_PPAPI_HOST_ARRAY_BUFFER_VAR_H_ + +#include "ppapi/shared_impl/var.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebArrayBuffer.h" + +namespace webkit { +namespace ppapi { + +// Represents a host-side ArrayBufferVar. +class HostArrayBufferVar : public ::ppapi::ArrayBufferVar { + public: + explicit HostArrayBufferVar(uint32 size_in_bytes); + explicit HostArrayBufferVar(const WebKit::WebArrayBuffer& buffer); + virtual ~HostArrayBufferVar(); + + // ArrayBufferVar implementation. + virtual void* Map() OVERRIDE; + virtual uint32 ByteLength() OVERRIDE; + + WebKit::WebArrayBuffer& webkit_buffer() { return buffer_; } + + private: + WebKit::WebArrayBuffer buffer_; + + DISALLOW_COPY_AND_ASSIGN(HostArrayBufferVar); +}; + +} // namespace ppapi +} // namespace webkit + +#endif // PPAPI_WEBKIT_PLUGINS_PPAPI_HOST_ARRAY_BUFFER_VAR_H_ diff --git a/webkit/plugins/ppapi/host_var_tracker.cc b/webkit/plugins/ppapi/host_var_tracker.cc index 0508d2c..51ba0e84 100644 --- a/webkit/plugins/ppapi/host_var_tracker.cc +++ b/webkit/plugins/ppapi/host_var_tracker.cc @@ -6,9 +6,11 @@ #include "base/logging.h" #include "ppapi/c/pp_var.h" +#include "webkit/plugins/ppapi/host_array_buffer_var.h" #include "webkit/plugins/ppapi/npobject_var.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" +using ppapi::ArrayBufferVar; using ppapi::NPObjectVar; namespace webkit { @@ -20,6 +22,10 @@ HostVarTracker::HostVarTracker() { HostVarTracker::~HostVarTracker() { } +ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) { + return new HostArrayBufferVar(size_in_bytes); +} + void HostVarTracker::AddNPObjectVar(NPObjectVar* object_var) { InstanceMap::iterator found_instance = instance_map_.find( object_var->pp_instance()); diff --git a/webkit/plugins/ppapi/host_var_tracker.h b/webkit/plugins/ppapi/host_var_tracker.h index a4344df..fb743fc 100644 --- a/webkit/plugins/ppapi/host_var_tracker.h +++ b/webkit/plugins/ppapi/host_var_tracker.h @@ -8,6 +8,7 @@ #include <map> #include "base/basictypes.h" +#include "base/compiler_specific.h" #include "base/gtest_prod_util.h" #include "base/hash_tables.h" #include "base/memory/linked_ptr.h" @@ -23,6 +24,7 @@ typedef struct NPObject NPObject; namespace ppapi { +class ArrayBufferVar; class NPObjectVar; class Var; } @@ -60,6 +62,10 @@ class HostVarTracker : public ::ppapi::VarTracker { void ForceFreeNPObjectsForInstance(PP_Instance instance); private: + // VarTracker implementation. + virtual ::ppapi::ArrayBufferVar* CreateArrayBuffer( + uint32 size_in_bytes) OVERRIDE; + typedef std::map<NPObject*, ::ppapi::NPObjectVar*> NPObjectToNPObjectVarMap; // Lists all known NPObjects, first indexed by the corresponding instance, diff --git a/webkit/plugins/ppapi/message_channel.cc b/webkit/plugins/ppapi/message_channel.cc index 1c3cd86..a6fafae 100644 --- a/webkit/plugins/ppapi/message_channel.cc +++ b/webkit/plugins/ppapi/message_channel.cc @@ -10,7 +10,9 @@ #include "base/bind.h" #include "base/logging.h" #include "base/message_loop.h" +#include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/var.h" +#include "ppapi/shared_impl/var_tracker.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebBindings.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebDOMMessageEvent.h" @@ -20,9 +22,12 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSerializedScriptValue.h" #include "v8/include/v8.h" +#include "webkit/plugins/ppapi/host_array_buffer_var.h" #include "webkit/plugins/ppapi/npapi_glue.h" #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" +using ppapi::ArrayBufferVar; +using ppapi::PpapiGlobals; using ppapi::StringVar; using WebKit::WebBindings; using WebKit::WebElement; @@ -84,10 +89,21 @@ bool PPVarToV8Value(PP_Var var, v8::Handle<v8::Value>* result) { *result = v8::String::New(value.c_str(), value.size()); break; } + case PP_VARTYPE_ARRAY_BUFFER: { + ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var); + if (!buffer) { + result->Clear(); + return false; + } + HostArrayBufferVar* host_buffer = + static_cast<HostArrayBufferVar*>(buffer); + *result = + v8::Local<v8::Value>::New(host_buffer->webkit_buffer().toV8Value()); + break; + } case PP_VARTYPE_OBJECT: case PP_VARTYPE_ARRAY: case PP_VARTYPE_DICTIONARY: - case PP_VARTYPE_ARRAY_BUFFER: // These are not currently supported. NOTIMPLEMENTED(); result->Clear(); @@ -100,8 +116,8 @@ bool PPVarToV8Value(PP_Var var, v8::Handle<v8::Value>* result) { // This currently just copies the value. For a string Var, the result is a // PP_Var with the a copy of |var|'s string contents and a reference count of 1. // -// TODO(dmichael): We need to do structured clone eventually to copy a object -// structure. The details and PPAPI changes for this are TBD. +// TODO(dmichael): Bypass this step for out-of-process plugins, since a copy +// happens already when the Var is serialized. PP_Var CopyPPVar(const PP_Var& var) { if (var.type == PP_VARTYPE_OBJECT) { // Objects are not currently supported. @@ -112,6 +128,15 @@ PP_Var CopyPPVar(const PP_Var& var) { if (!string) return PP_MakeUndefined(); return StringVar::StringToPPVar(string->value()); + } else if (var.type == PP_VARTYPE_ARRAY_BUFFER) { + ArrayBufferVar* buffer = ArrayBufferVar::FromPPVar(var); + if (!buffer) + return PP_MakeUndefined(); + PP_Var new_buffer_var = PpapiGlobals::Get()->GetVarTracker()-> + MakeArrayBufferPPVar(buffer->ByteLength()); + ArrayBufferVar* new_buffer = ArrayBufferVar::FromPPVar(new_buffer_var); + memcpy(new_buffer->Map(), buffer->Map(), buffer->ByteLength()); + return new_buffer_var; } else { return var; } @@ -302,7 +327,13 @@ MessageChannel::MessageChannel(PluginInstance* instance) void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { // Serialize the message data. v8::HandleScope scope; - v8::Handle<v8::Value> v8_val; + // Because V8 is probably not on the stack for Native->JS calls, we need to + // enter the appropriate context for the plugin. + v8::Local<v8::Context> context = + instance_->container()->element().document().frame()-> + mainWorldScriptContext(); + context->Enter(); + v8::Local<v8::Value> v8_val; if (!PPVarToV8Value(message_data, &v8_val)) { NOTREACHED(); return; @@ -310,6 +341,7 @@ void MessageChannel::PostMessageToJavaScript(PP_Var message_data) { WebSerializedScriptValue serialized_val = WebSerializedScriptValue::serialize(v8_val); + context->Exit(); MessageLoop::current()->PostTask( FROM_HERE, diff --git a/webkit/plugins/ppapi/npapi_glue.cc b/webkit/plugins/ppapi/npapi_glue.cc index 6b94d93..ed8d2cc 100644 --- a/webkit/plugins/ppapi/npapi_glue.cc +++ b/webkit/plugins/ppapi/npapi_glue.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/string_util.h" +#include "webkit/plugins/ppapi/host_array_buffer_var.h" #include "webkit/plugins/ppapi/host_globals.h" #include "webkit/plugins/ppapi/host_var_tracker.h" #include "webkit/plugins/ppapi/npobject_var.h" @@ -21,6 +22,7 @@ using ppapi::NPObjectVar; using ppapi::PpapiGlobals; using ppapi::StringVar; using ppapi::Var; +using WebKit::WebArrayBuffer; using WebKit::WebBindings; namespace webkit { @@ -73,6 +75,10 @@ bool PPVarToNPVariant(PP_Var var, NPVariant* result) { *result); break; } + // The following types are not supported for use with PPB_Var_Deprecated, + // because PPB_Var_Deprecated is only for trusted plugins, and the trusted + // plugins we have don't need these types. We can add support in the future + // if it becomes necessary. case PP_VARTYPE_ARRAY: case PP_VARTYPE_DICTIONARY: case PP_VARTYPE_ARRAY_BUFFER: @@ -133,6 +139,15 @@ PP_Var NPIdentifierToPPVar(NPIdentifier id) { PP_Var NPObjectToPPVar(PluginInstance* instance, NPObject* object) { DCHECK(object); + WebArrayBuffer buffer; + // TODO(dmichael): Should I protect against duplicate Vars representing the + // same array buffer? It's probably not worth the trouble, since it will only + // affect in-process plugins. + if (WebBindings::getArrayBuffer(object, &buffer)) { + scoped_refptr<HostArrayBufferVar> buffer_var( + new HostArrayBufferVar(buffer)); + return buffer_var->GetPPVar(); + } scoped_refptr<NPObjectVar> object_var( HostGlobals::Get()->host_var_tracker()->NPObjectVarForNPObject( instance->pp_instance(), object)); diff --git a/webkit/plugins/ppapi/npobject_var.cc b/webkit/plugins/ppapi/npobject_var.cc index 5a88176..09e9f3c 100644 --- a/webkit/plugins/ppapi/npobject_var.cc +++ b/webkit/plugins/ppapi/npobject_var.cc @@ -35,17 +35,6 @@ NPObjectVar* NPObjectVar::AsNPObjectVar() { return this; } -PP_Var NPObjectVar::GetPPVar() { - int32 id = GetOrCreateVarID(); - if (!id) - return PP_MakeNull(); - - PP_Var result; - result.type = PP_VARTYPE_OBJECT; - result.value.as_id = id; - return result; -} - PP_VarType NPObjectVar::GetType() const { return PP_VARTYPE_OBJECT; } diff --git a/webkit/plugins/ppapi/npobject_var.h b/webkit/plugins/ppapi/npobject_var.h index 83430f3..b4e4269 100644 --- a/webkit/plugins/ppapi/npobject_var.h +++ b/webkit/plugins/ppapi/npobject_var.h @@ -38,7 +38,6 @@ class NPObjectVar : public Var { // Var overrides. virtual NPObjectVar* AsNPObjectVar() OVERRIDE; - virtual PP_Var GetPPVar() OVERRIDE; virtual PP_VarType GetType() const OVERRIDE; // Returns the underlying NPObject corresponding to this NPObjectVar. diff --git a/webkit/plugins/ppapi/plugin_module.cc b/webkit/plugins/ppapi/plugin_module.cc index 6154817..3cb4c482 100644 --- a/webkit/plugins/ppapi/plugin_module.cc +++ b/webkit/plugins/ppapi/plugin_module.cc @@ -32,6 +32,7 @@ #include "ppapi/c/dev/ppb_text_input_dev.h" #include "ppapi/c/dev/ppb_transport_dev.h" #include "ppapi/c/dev/ppb_url_util_dev.h" +#include "ppapi/c/dev/ppb_var_array_buffer_dev.h" #include "ppapi/c/dev/ppb_var_deprecated.h" #include "ppapi/c/dev/ppb_video_capture_dev.h" #include "ppapi/c/dev/ppb_video_decoder_dev.h" @@ -336,6 +337,8 @@ const void* GetInterface(const char* name) { return ::ppapi::PPB_Var_Shared::GetVarInterface1_0(); if (strcmp(name, PPB_VAR_INTERFACE_1_1) == 0) return ::ppapi::PPB_Var_Shared::GetVarInterface(); + if (strcmp(name, PPB_VAR_ARRAY_BUFFER_DEV_INTERFACE) == 0) + return ::ppapi::PPB_Var_Shared::GetVarArrayBufferInterface(); #ifdef ENABLE_FLAPPER_HACKS if (strcmp(name, PPB_FLASH_NETCONNECTOR_INTERFACE) == 0) |