diff options
64 files changed, 1670 insertions, 831 deletions
diff --git a/ppapi/c/dev/ppb_cursor_control_dev.h b/ppapi/c/dev/ppb_cursor_control_dev.h index 104f6c5..8a51ac5 100644 --- a/ppapi/c/dev/ppb_cursor_control_dev.h +++ b/ppapi/c/dev/ppb_cursor_control_dev.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2010 The Chromium Authors. All rights reserved. +/* 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. */ @@ -14,7 +14,7 @@ #define PPB_CURSOR_CONTROL_DEV_INTERFACE "PPB_CursorControl(Dev);0.3" struct PPB_CursorControl_Dev { - // Set a cursor. If "type" is PP_CURSOR_TYPE_CUSTOM, then "custom_image" + // Set a cursor. If "type" is PP_CURSORTYPE_CUSTOM, then "custom_image" // must be an ImageData resource containing the cursor and "hot_spot" must // contain the offset within that image that refers to the cursor's position. PP_Bool (*SetCursor)(PP_Instance instance, diff --git a/ppapi/ppapi_shared_proxy.gypi b/ppapi/ppapi_shared_proxy.gypi index 8e62ae3..819f1ce 100644 --- a/ppapi/ppapi_shared_proxy.gypi +++ b/ppapi/ppapi_shared_proxy.gypi @@ -50,10 +50,9 @@ 'proxy/dispatcher.h', 'proxy/host_dispatcher.cc', 'proxy/host_dispatcher.h', + 'proxy/host_resource.h', 'proxy/host_var_serialization_rules.cc', 'proxy/host_var_serialization_rules.h', - 'proxy/image_data.cc', - 'proxy/image_data.h', 'proxy/interface_proxy.cc', 'proxy/interface_proxy.h', 'proxy/plugin_dispatcher.cc', diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi index dcb8578..9734827 100644 --- a/ppapi/ppapi_tests.gypi +++ b/ppapi/ppapi_tests.gypi @@ -267,8 +267,15 @@ 'sources': [ 'proxy/run_all_unittests.cc', + 'proxy/mock_resource.cc', + 'proxy/mock_resource.h', + 'proxy/plugin_resource_tracker_unittest.cc', 'proxy/plugin_var_tracker_unittest.cc', + 'proxy/ppapi_proxy_test.cc', + 'proxy/ppapi_proxy_test.h', + 'proxy/serialized_var_unittest.cc', + 'proxy/serialized_var_unittest.h', ], - }, + }, ], } diff --git a/ppapi/proxy/dispatcher.cc b/ppapi/proxy/dispatcher.cc index 0ae8e2e..f852c49 100644 --- a/ppapi/proxy/dispatcher.cc +++ b/ppapi/proxy/dispatcher.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "ipc/ipc_message.h" #include "ipc/ipc_sync_channel.h" +#include "ipc/ipc_test_sink.h" #include "ppapi/c/dev/ppb_buffer_dev.h" #include "ppapi/c/dev/ppb_char_set_dev.h" #include "ppapi/c/dev/ppb_cursor_control_dev.h" @@ -65,6 +66,7 @@ Dispatcher::Dispatcher(base::ProcessHandle remote_process_handle, GetInterfaceFunc local_get_interface) : pp_module_(0), remote_process_handle_(remote_process_handle), + test_sink_(NULL), disallow_trusted_interfaces_(false), // TODO(brettw) make this settable. local_get_interface_(local_get_interface), declared_supported_remote_interfaces_(false), @@ -87,6 +89,11 @@ bool Dispatcher::InitWithChannel(MessageLoop* ipc_message_loop, return true; } +void Dispatcher::InitWithTestSink(IPC::TestSink* test_sink) { + DCHECK(!test_sink_); + test_sink_ = test_sink; +} + bool Dispatcher::OnMessageReceived(const IPC::Message& msg) { // Control messages. if (msg.routing_id() == MSG_ROUTING_CONTROL) { @@ -157,6 +164,8 @@ const void* Dispatcher::GetProxiedInterface(const std::string& interface) { } bool Dispatcher::Send(IPC::Message* msg) { + if (test_sink_) + return test_sink_->Send(msg); return channel_->Send(msg); } diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h index 8ef243b..1aac12d 100644 --- a/ppapi/proxy/dispatcher.h +++ b/ppapi/proxy/dispatcher.h @@ -29,6 +29,7 @@ class WaitableEvent; namespace IPC { class SyncChannel; +class TestSink; } namespace pp { @@ -60,11 +61,17 @@ class Dispatcher : public IPC::Channel::Listener, ~Dispatcher(); + // You must call this function before anything else. Returns true on success. bool InitWithChannel(MessageLoop* ipc_message_loop, const IPC::ChannelHandle& channel_handle, bool is_client, base::WaitableEvent* shutdown_event); + // Alternative to InitWithChannel() for unit tests that want to send all + // messages sent via this dispatcher to the given test sink. The test sink + // must outlive this class. + void InitWithTestSink(IPC::TestSink* test_sink); + // Returns true if the dispatcher is on the plugin side, or false if it's the // browser side. virtual bool IsPlugin() const = 0; @@ -104,6 +111,7 @@ class Dispatcher : public IPC::Channel::Listener, // IPC::Channel::Listener implementation. virtual bool OnMessageReceived(const IPC::Message& msg); + // Will be NULL in some unit tests. IPC::SyncChannel* channel() const { return channel_.get(); } @@ -164,6 +172,13 @@ class Dispatcher : public IPC::Channel::Listener, PP_Module pp_module_; base::ProcessHandle remote_process_handle_; // See getter above. + + // When we're unit testing, this will indicate the sink for the messages to + // be deposited so they can be inspected by the test. When non-NULL, this + // indicates that the channel should not be used. + IPC::TestSink* test_sink_; + + // Will be null for some tests when there is a test_sink_. scoped_ptr<IPC::SyncChannel> channel_; bool disallow_trusted_interfaces_; diff --git a/ppapi/proxy/host_resource.h b/ppapi/proxy/host_resource.h new file mode 100644 index 0000000..badd2fd --- /dev/null +++ b/ppapi/proxy/host_resource.h @@ -0,0 +1,60 @@ +// 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_HOST_RESOURCE_H_ +#define PPAPI_PROXY_HOST_RESOURCE_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/pp_resource.h" + +namespace pp { +namespace proxy { + +// Represents a PP_Resource sent over the wire. This just wraps a PP_Resource. +// The point is to prevent mistakes where the wrong resource value is sent. +// Resource values are remapped in the plugin so that it can talk to multiple +// hosts. If all values were PP_Resource, it would be easy to forget to do +// this tranformation. +// +// All HostResources respresent IDs valid in the host. +class HostResource { + public: + HostResource() : instance_(0), host_resource_(0) { + } + + bool is_null() const { + return !host_resource_; + } + + // Sets and retrieves the internal PP_Resource which is valid for the host + // (a.k.a. renderer, as opposed to the plugin) process. + // + // DO NOT CALL THESE FUNCTIONS IN THE PLUGIN SIDE OF THE PROXY. The values + // will be invalid. See the class comment above. + void SetHostResource(PP_Instance instance, PP_Resource resource) { + instance_ = instance; + host_resource_ = resource; + } + PP_Resource host_resource() const { + return host_resource_; + } + + PP_Instance instance() const { return instance_; } + + // This object is used in maps so we need to provide this sorting operator. + bool operator<(const HostResource& other) const { + if (instance_ != other.instance_) + return instance_ < other.instance_; + return host_resource_ < other.host_resource_; + } + + private: + PP_Instance instance_; + PP_Resource host_resource_; +}; + +} // namespace proxy +} // namespace pp + +#endif // PPAPI_PROXY_HOST_RESOURCE_H_ diff --git a/ppapi/proxy/host_var_serialization_rules.cc b/ppapi/proxy/host_var_serialization_rules.cc index f6f00f7..2a1d0ee 100644 --- a/ppapi/proxy/host_var_serialization_rules.cc +++ b/ppapi/proxy/host_var_serialization_rules.cc @@ -62,7 +62,7 @@ PP_Var HostVarSerializationRules::ReceivePassRef(const PP_Var& var, } PP_Var HostVarSerializationRules::BeginSendPassRef(const PP_Var& var, - std::string* str_val) { + std::string* str_val) { // See PluginVarSerialization::ReceivePassRef for an example. We don't need // to do anything here other than convert the string. if (var.type == PP_VARTYPE_STRING) @@ -70,7 +70,8 @@ PP_Var HostVarSerializationRules::BeginSendPassRef(const PP_Var& var, return var; } -void HostVarSerializationRules::EndSendPassRef(const PP_Var& var) { +void HostVarSerializationRules::EndSendPassRef(const PP_Var& /* var */, + Dispatcher* /* dispatcher */) { // See PluginVarSerialization::ReceivePassRef for an example. We don't need // to do anything here. } diff --git a/ppapi/proxy/host_var_serialization_rules.h b/ppapi/proxy/host_var_serialization_rules.h index 2455c81..4fd39be 100644 --- a/ppapi/proxy/host_var_serialization_rules.h +++ b/ppapi/proxy/host_var_serialization_rules.h @@ -33,7 +33,7 @@ class HostVarSerializationRules : public VarSerializationRules { const std::string& str_val, Dispatcher* dispatcher); virtual PP_Var BeginSendPassRef(const PP_Var& var, std::string* str_val); - virtual void EndSendPassRef(const PP_Var& var); + virtual void EndSendPassRef(const PP_Var& var, Dispatcher* dispatcher); virtual void ReleaseObjectRef(const PP_Var& var); private: diff --git a/ppapi/proxy/image_data.cc b/ppapi/proxy/image_data.cc deleted file mode 100644 index 8042c38..0000000 --- a/ppapi/proxy/image_data.cc +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (c) 2010 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/image_data.h" - -#if defined(OS_LINUX) -#include <sys/shm.h> -#endif - -#if defined(OS_MACOSX) -#include <sys/stat.h> -#include <sys/mman.h> -#endif - -namespace pp { -namespace proxy { - -ImageData::ImageData(PP_Instance instance, - const PP_ImageDataDesc& desc, - ImageHandle handle) - : PluginResource(instance), - desc_(desc), - handle_(handle), - mapped_data_(NULL) { -} - -ImageData::~ImageData() { - Unmap(); -} - -ImageData* ImageData::AsImageData() { - return this; -} - -void* ImageData::Map() { -#if defined(OS_WIN) - NOTIMPLEMENTED(); - return NULL; -#elif defined(OS_MACOSX) - struct stat st; - if (fstat(handle_.fd, &st) != 0) - return NULL; - void* memory = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, - MAP_SHARED, handle_.fd, 0); - if (memory == MAP_FAILED) - return NULL; - mapped_data_ = memory; - return mapped_data_; -#else - int shmkey = handle_; - void* address = shmat(shmkey, NULL, 0); - // Mark for deletion in case we crash so the kernel will clean it up. - shmctl(shmkey, IPC_RMID, 0); - if (address == (void*)-1) - return NULL; - mapped_data_ = address; - return address; -#endif -} - -void ImageData::Unmap() { -#if defined(OS_WIN) - NOTIMPLEMENTED(); -#elif defined(OS_MACOSX) - if (mapped_data_) { - struct stat st; - if (fstat(handle_.fd, &st) == 0) - munmap(mapped_data_, st.st_size); - } -#else - if (mapped_data_) - shmdt(mapped_data_); -#endif - mapped_data_ = NULL; -} - -#if defined(OS_WIN) -const ImageHandle ImageData::NullHandle = NULL; -#elif defined(OS_MACOSX) -const ImageHandle ImageData::NullHandle = ImageHandle(); -#else -const ImageHandle ImageData::NullHandle = 0; -#endif - -ImageHandle ImageData::HandleFromInt(int32_t i) { -#if defined(OS_WIN) - return reinterpret_cast<ImageHandle>(i); -#elif defined(OS_MACOSX) - return ImageHandle(i, false); -#else - return static_cast<ImageHandle>(i); -#endif -} - -} // namespace proxy -} // namespace pp diff --git a/ppapi/proxy/image_data.h b/ppapi/proxy/image_data.h deleted file mode 100644 index 539a475..0000000 --- a/ppapi/proxy/image_data.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2010 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_IMAGE_DATA_H_ -#define PPAPI_PROXY_IMAGE_DATA_H_ - -#include "base/shared_memory.h" -#include "ppapi/c/pp_instance.h" -#include "ppapi/c/ppb_image_data.h" -#include "ppapi/proxy/plugin_resource.h" -#include "ppapi/proxy/serialized_structs.h" -#include "ppapi/shared_impl/image_data_impl.h" - -namespace pp { -namespace proxy { - -class ImageData : public PluginResource, - public pp::shared_impl::ImageDataImpl { - public: - ImageData(PP_Instance instance, - const PP_ImageDataDesc& desc, - ImageHandle handle); - virtual ~ImageData(); - - // Resource overrides. - virtual ImageData* AsImageData(); - - void* Map(); - void Unmap(); - - const PP_ImageDataDesc& desc() const { return desc_; } - - static const ImageHandle NullHandle; - static ImageHandle HandleFromInt(int32_t i); - - private: - PP_ImageDataDesc desc_; - ImageHandle handle_; - - void* mapped_data_; - - DISALLOW_COPY_AND_ASSIGN(ImageData); -}; - -} // namespace proxy -} // namespace pp - -#endif // PPAPI_PROXY_IMAGE_DATA_H_ diff --git a/ppapi/proxy/mock_resource.cc b/ppapi/proxy/mock_resource.cc new file mode 100644 index 0000000..21e5381 --- /dev/null +++ b/ppapi/proxy/mock_resource.cc @@ -0,0 +1,22 @@ +// Copyright (c) 2010 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/mock_resource.h" + +namespace pp { +namespace proxy { + +MockResource::MockResource(const HostResource& resource) + : PluginResource(resource) { +} + +MockResource::~MockResource() { +} + +MockResource* MockResource::AsMockResource() { + return this; +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/mock_resource.h b/ppapi/proxy/mock_resource.h new file mode 100644 index 0000000..7e38be1 --- /dev/null +++ b/ppapi/proxy/mock_resource.h @@ -0,0 +1,29 @@ +// 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_MOCK_RESOURCE_H_ +#define PPAPI_PROXY_MOCK_RESOURCE_H_ + +#include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/plugin_resource.h" + +namespace pp { +namespace proxy { + +class MockResource : public PluginResource { + public: + MockResource(const HostResource& resource); + virtual ~MockResource(); + + // Resource overrides. + virtual MockResource* AsMockResource(); + + private: + DISALLOW_COPY_AND_ASSIGN(MockResource); +}; + +} // namespace proxy +} // namespace pp + +#endif // PPAPI_PROXY_MOCK_RESOURCE_H_ diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc index 809ea40..83dadc6 100644 --- a/ppapi/proxy/plugin_resource.cc +++ b/ppapi/proxy/plugin_resource.cc @@ -7,7 +7,8 @@ namespace pp { namespace proxy { -PluginResource::PluginResource(PP_Instance instance) : instance_(instance) { +PluginResource::PluginResource(const HostResource& resource) + : host_resource_(resource) { } PluginResource::~PluginResource() { diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h index 8eee931..9fda1b5 100644 --- a/ppapi/proxy/plugin_resource.h +++ b/ppapi/proxy/plugin_resource.h @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource_tracker.h" @@ -18,6 +19,7 @@ F(Font) \ F(Graphics2D) \ F(ImageData) \ + F(MockResource) \ F(PrivateFontFile) \ F(URLLoader) \ F(URLRequestInfo)\ @@ -33,7 +35,7 @@ FOR_ALL_PLUGIN_RESOURCES(DECLARE_RESOURCE_CLASS) class PluginResource { public: - PluginResource(PP_Instance instance); + PluginResource(const HostResource& resource); virtual ~PluginResource(); // Returns NULL if the resource is invalid or is a different type. @@ -45,7 +47,12 @@ class PluginResource { template <typename T> T* Cast() { return NULL; } - PP_Instance instance() const { return instance_; } + PP_Instance instance() const { return host_resource_.instance(); } + + // Returns the host resource ID for sending to the host process. + const HostResource& host_resource() const { + return host_resource_; + } private: // Type-specific getters for individual resource types. These will return @@ -56,8 +63,11 @@ class PluginResource { FOR_ALL_PLUGIN_RESOURCES(DEFINE_TYPE_GETTER) #undef DEFINE_TYPE_GETTER - // Instance this resource is associated with. - PP_Instance instance_; + // The resource ID in the host that this object corresponds to. Inside the + // plugin we'll remap the resource IDs so we can have many host processes + // each independently generating resources (which may conflict) but the IDs + // in the plugin will all be unique. + HostResource host_resource_; DISALLOW_COPY_AND_ASSIGN(PluginResource); }; diff --git a/ppapi/proxy/plugin_resource_tracker.cc b/ppapi/proxy/plugin_resource_tracker.cc index f81a5f3..162f3f8 100644 --- a/ppapi/proxy/plugin_resource_tracker.cc +++ b/ppapi/proxy/plugin_resource_tracker.cc @@ -14,6 +14,13 @@ namespace pp { namespace proxy { +namespace { + +// When non-NULL, this object overrides the ResourceTrackerSingleton. +PluginResourceTracker* g_resource_tracker_override = NULL; + +} // namespace + PluginResourceTracker::ResourceInfo::ResourceInfo() : ref_count(0) { } @@ -39,14 +46,24 @@ PluginResourceTracker::ResourceInfo::operator=( return *this; } -PluginResourceTracker::PluginResourceTracker() { +// Start counting resources at a high number to avoid collisions with vars (to +// help debugging). +PluginResourceTracker::PluginResourceTracker() + : last_resource_id_(0x00100000) { } PluginResourceTracker::~PluginResourceTracker() { } // static +void PluginResourceTracker::SetInstanceForTest(PluginResourceTracker* tracker) { + g_resource_tracker_override = tracker; +} + +// static PluginResourceTracker* PluginResourceTracker::GetInstance() { + if (g_resource_tracker_override) + return g_resource_tracker_override; return Singleton<PluginResourceTracker>::get(); } @@ -58,37 +75,41 @@ PluginResource* PluginResourceTracker::GetResourceObject( return found->second.resource.get(); } -void PluginResourceTracker::AddResource(PP_Resource pp_resource, - linked_ptr<PluginResource> object) { - DCHECK(resource_map_.find(pp_resource) == resource_map_.end()); - resource_map_[pp_resource] = ResourceInfo(1, object); +PP_Resource PluginResourceTracker::AddResource( + linked_ptr<PluginResource> object) { + if (object->host_resource().is_null()) { + // Prevent adding null resources or GetResourceObject(0) will return a + // valid pointer! + NOTREACHED(); + return 0; + } + + PP_Resource plugin_resource = ++last_resource_id_; + DCHECK(resource_map_.find(plugin_resource) == resource_map_.end()); + resource_map_[plugin_resource] = ResourceInfo(1, object); + host_resource_map_[object->host_resource()] = plugin_resource; + return plugin_resource; } void PluginResourceTracker::AddRefResource(PP_Resource resource) { - resource_map_[resource].ref_count++; + ResourceMap::iterator found = resource_map_.find(resource); + if (found == resource_map_.end()) { + NOTREACHED(); + return; + } + found->second.ref_count++; } void PluginResourceTracker::ReleaseResource(PP_Resource resource) { ReleasePluginResourceRef(resource, true); } -bool PluginResourceTracker::PreparePreviouslyTrackedResource( - PP_Resource resource) { - ResourceMap::iterator found = resource_map_.find(resource); - if (found == resource_map_.end()) - return false; // We've not seen this resource before. - - // We have already seen this resource and the caller wants the plugin to - // have one more ref to the object (this function is called when retuning - // a resource). - // - // This is like the PluginVarTracker::ReceiveObjectPassRef. We do an AddRef - // in the plugin for the additional ref, and then a Release in the renderer - // because the code in the renderer addrefed on behalf of the caller. - found->second.ref_count++; - - SendReleaseResourceToHost(resource, found->second.resource.get()); - return true; +PP_Resource PluginResourceTracker::PluginResourceForHostResource( + const HostResource& resource) const { + HostResourceMap::const_iterator found = host_resource_map_.find(resource); + if (found == host_resource_map_.end()) + return 0; + return found->second; } void PluginResourceTracker::ReleasePluginResourceRef( @@ -99,8 +120,10 @@ void PluginResourceTracker::ReleasePluginResourceRef( return; found->second.ref_count--; if (found->second.ref_count == 0) { + PluginResource* plugin_resource = found->second.resource.get(); if (notify_browser_on_release) - SendReleaseResourceToHost(resource, found->second.resource.get()); + SendReleaseResourceToHost(resource, plugin_resource); + host_resource_map_.erase(plugin_resource->host_resource()); resource_map_.erase(found); } } @@ -112,7 +135,7 @@ void PluginResourceTracker::SendReleaseResourceToHost( PluginDispatcher::GetForInstance(resource->instance()); if (dispatcher) { dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource( - INTERFACE_ID_PPB_CORE, resource_id)); + INTERFACE_ID_PPB_CORE, resource->host_resource())); } else { NOTREACHED(); } diff --git a/ppapi/proxy/plugin_resource_tracker.h b/ppapi/proxy/plugin_resource_tracker.h index ba6ddb3..ee7ad96 100644 --- a/ppapi/proxy/plugin_resource_tracker.h +++ b/ppapi/proxy/plugin_resource_tracker.h @@ -6,12 +6,15 @@ #define PPAPI_PROXY_PLUGIN_RESOURCE_TRACKER_H_ #include <map> +#include <utility> #include "base/linked_ptr.h" #include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_stdint.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" +#include "ppapi/proxy/host_resource.h" template<typename T> struct DefaultSingletonTraits; @@ -23,6 +26,11 @@ class PluginResource; class PluginResourceTracker { public: + // Called by tests that want to specify a specific ResourceTracker. This + // allows them to use a unique one each time and avoids singletons sticking + // around across tests. + static void SetInstanceForTest(PluginResourceTracker* tracker); + // Returns the global singleton resource tracker for the plugin. static PluginResourceTracker* GetInstance(); @@ -30,38 +38,24 @@ class PluginResourceTracker { // there isn't one. PluginResource* GetResourceObject(PP_Resource pp_resource); - void AddResource(PP_Resource pp_resource, linked_ptr<PluginResource> object); + // Adds the given resource object to the tracked list, and returns the + // plugin-local PP_Resource ID that identifies the resource. Note that this + // PP_Resource is not valid to send to the host, use + // PluginResource.host_resource() to get that. + PP_Resource AddResource(linked_ptr<PluginResource> object); void AddRefResource(PP_Resource resource); void ReleaseResource(PP_Resource resource); - // Checks if the resource just returned from the renderer is already - // tracked by the plugin side and adjusts the refcounts if so. - // - // When the browser returns a PP_Resource, it could be a new one, in which - // case the proxy wants to create a corresponding object and call - // AddResource() on it. However, if the resouce is already known, then the - // refcount needs to be adjusted in both the plugin and the renderer side - // and no such object needs to be created. - // - // Returns true if the resource was previously known. The refcount will be - // fixed up such that it's ready to use by the plugin. A proxy can then - // just return the resource without doing any more work. - // - // Typical usage: - // - // PP_Resource result; - // dispatcher->Send(new MyMessage(..., &result)); - // if (PluginResourceTracker::GetInstance()-> - // PreparePreviouslyTrackedResource(result)) - // return result; - // ... create resource object ... - // PluginResourceTracker::GetInstance()->AddResource(result, object); - // return result; - bool PreparePreviouslyTrackedResource(PP_Resource resource); + // Given a host resource, maps it to an existing plugin resource ID if it + // exists, or returns 0 on failure. + PP_Resource PluginResourceForHostResource( + const HostResource& resource) const; private: friend struct DefaultSingletonTraits<PluginResourceTracker>; + friend class PluginResourceTrackerTest; + friend class PluginProxyTest; PluginResourceTracker(); ~PluginResourceTracker(); @@ -86,8 +80,19 @@ class PluginResourceTracker { void SendReleaseResourceToHost(PP_Resource resource_id, PluginResource* resource); + // Map of plugin resource IDs to the information tracking that resource. typedef std::map<PP_Resource, ResourceInfo> ResourceMap; ResourceMap resource_map_; + + // Map of host instance/resource pairs to a plugin resource ID. + typedef std::map<HostResource, PP_Resource> HostResourceMap; + HostResourceMap host_resource_map_; + + // Tracks the last ID we've sent out as a plugin resource so we don't send + // duplicates. + PP_Resource last_resource_id_; + + DISALLOW_COPY_AND_ASSIGN(PluginResourceTracker); }; } // namespace proxy diff --git a/ppapi/proxy/plugin_resource_tracker_unittest.cc b/ppapi/proxy/plugin_resource_tracker_unittest.cc new file mode 100644 index 0000000..4145a13 --- /dev/null +++ b/ppapi/proxy/plugin_resource_tracker_unittest.cc @@ -0,0 +1,75 @@ +// 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 "base/process.h" +#include "base/scoped_ptr.h" +#include "ppapi/proxy/mock_resource.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/ppapi_proxy_test.h" + +namespace pp { +namespace proxy { + +namespace { + +// Object so we know when a resource has been released. +class TrackedMockResource : public MockResource { + public: + TrackedMockResource(const HostResource& serialized) + : MockResource(serialized) { + tracked_alive_count++; + } + ~TrackedMockResource() { + tracked_alive_count--; + } + + static int tracked_alive_count; +}; + +int TrackedMockResource::tracked_alive_count = 0; + +} // namespace + +class PluginResourceTrackerTest : public PluginProxyTest { + public: + PluginResourceTrackerTest() {} + ~PluginResourceTrackerTest() {} + + PluginResourceTracker& tracker() { return tracker_; } + + private: + PluginResourceTracker tracker_; +}; + +TEST_F(PluginResourceTrackerTest, PluginResourceForHostResource) { + PP_Instance instance = 0x1234; + PP_Resource host_resource = 0x5678; + + HostResource serialized; + serialized.SetHostResource(instance, host_resource); + + // When we haven't added an object, the return value should be 0. + EXPECT_EQ(0, tracker().PluginResourceForHostResource(serialized)); + + EXPECT_EQ(0, TrackedMockResource::tracked_alive_count); + TrackedMockResource* object = new TrackedMockResource(serialized); + EXPECT_EQ(1, TrackedMockResource::tracked_alive_count); + PP_Resource plugin_resource = + tracker().AddResource(linked_ptr<PluginResource>(object)); + + // Now that the object has been added, the return value should be the plugin + // resource ID we already got. + EXPECT_EQ(plugin_resource, + tracker().PluginResourceForHostResource(serialized)); + + // Releasing the resource should have freed it. + tracker().ReleaseResource(plugin_resource); + EXPECT_EQ(0, TrackedMockResource::tracked_alive_count); + EXPECT_EQ(0, tracker().PluginResourceForHostResource(serialized)); +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/plugin_var_serialization_rules.cc b/ppapi/proxy/plugin_var_serialization_rules.cc index 7828587..a56e5b4 100644 --- a/ppapi/proxy/plugin_var_serialization_rules.cc +++ b/ppapi/proxy/plugin_var_serialization_rules.cc @@ -118,10 +118,14 @@ PP_Var PluginVarSerializationRules::BeginSendPassRef(const PP_Var& var, return var; } -void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var) { +void PluginVarSerializationRules::EndSendPassRef(const PP_Var& var, + Dispatcher* dispatcher) { // See BeginSendPassRef for an example of why we release our ref here. + // The var we have in our inner class has been converted to a host object + // by BeginSendPassRef. This means it's not a normal var valid in the plugin, + // so we need to use the special ReleaseHostObject. if (var.type == PP_VARTYPE_OBJECT) - var_tracker_->Release(var); + var_tracker_->ReleaseHostObject(dispatcher, var); } void PluginVarSerializationRules::ReleaseObjectRef(const PP_Var& var) { diff --git a/ppapi/proxy/plugin_var_serialization_rules.h b/ppapi/proxy/plugin_var_serialization_rules.h index 36e58e7..e073602 100644 --- a/ppapi/proxy/plugin_var_serialization_rules.h +++ b/ppapi/proxy/plugin_var_serialization_rules.h @@ -31,7 +31,7 @@ class PluginVarSerializationRules : public VarSerializationRules { const std::string& str_val, Dispatcher* dispatcher); virtual PP_Var BeginSendPassRef(const PP_Var& var, std::string* str_val); - virtual void EndSendPassRef(const PP_Var& var); + virtual void EndSendPassRef(const PP_Var& var, Dispatcher* dispatcher); virtual void ReleaseObjectRef(const PP_Var& var); private: diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc index 42370be..c079716 100644 --- a/ppapi/proxy/plugin_var_tracker.cc +++ b/ppapi/proxy/plugin_var_tracker.cc @@ -15,6 +15,9 @@ namespace proxy { namespace { +// When non-NULL, this object overrides the VarTrackerSingleton. +PluginVarTracker* var_tracker_override = NULL; + class RefCountedString : public base::RefCounted<RefCountedString> { public: RefCountedString() { @@ -64,7 +67,15 @@ PluginVarTracker::PluginVarTracker() : last_plugin_object_id_(0) { PluginVarTracker::~PluginVarTracker() { } +// static +void PluginVarTracker::SetInstanceForTest(PluginVarTracker* tracker) { + var_tracker_override = tracker; +} + +// static PluginVarTracker* PluginVarTracker::GetInstance() { + if (var_tracker_override) + return var_tracker_override; return Singleton<PluginVarTracker>::get(); } @@ -221,6 +232,24 @@ PP_Var PluginVarTracker::GetHostObject(const PP_Var& plugin_object) const { return ret; } +void PluginVarTracker::ReleaseHostObject(Sender* sender, + const PP_Var& host_object) { + // Convert the host object to a normal var valid in the plugin. + DCHECK(host_object.type == PP_VARTYPE_OBJECT); + HostVarToPluginVarMap::iterator found = host_var_to_plugin_var_.find( + HostVar(sender, host_object.value.as_id)); + if (found == host_var_to_plugin_var_.end()) { + NOTREACHED(); + return; + } + + // Now just release the object like normal. + PP_Var plugin_object; + plugin_object.type = PP_VARTYPE_OBJECT; + plugin_object.value.as_id = found->second; + Release(plugin_object); +} + int PluginVarTracker::GetRefCountForObject(const PP_Var& plugin_object) { PluginVarInfoMap::iterator found = plugin_var_info_.find( plugin_object.value.as_id); diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h index 02e83d5..21cd4594 100644 --- a/ppapi/proxy/plugin_var_tracker.h +++ b/ppapi/proxy/plugin_var_tracker.h @@ -44,6 +44,11 @@ class PluginVarTracker { // Dispatcher in this class, which makes it easy to unit test. typedef IPC::Channel::Sender Sender; + // Called by tests that want to specify a specific VarTracker. This allows + // them to use a unique one each time and avoids singletons sticking around + // across tests. + static void SetInstanceForTest(PluginVarTracker* tracker); + // Returns the global var tracker for the plugin object. static PluginVarTracker* GetInstance(); @@ -75,6 +80,10 @@ class PluginVarTracker { // should be a VARTYPE_OBJECT PP_Var GetHostObject(const PP_Var& plugin_object) const; + // Like Release() but the var is identified by its host object ID (as + // returned by GetHostObject). + void ReleaseHostObject(Sender* sender, const PP_Var& host_object); + // Retrieves the internal reference counts for testing. Returns 0 if we // know about the object but the corresponding value is 0, or -1 if the // given object ID isn't in our map. @@ -83,7 +92,7 @@ class PluginVarTracker { private: friend struct DefaultSingletonTraits<PluginVarTracker>; - friend class PluginVarTrackerTest; + friend class PluginProxyTest; // Represents a var as received from the host. struct HostVar { diff --git a/ppapi/proxy/plugin_var_tracker_unittest.cc b/ppapi/proxy/plugin_var_tracker_unittest.cc index 52f7168..25663f9 100644 --- a/ppapi/proxy/plugin_var_tracker_unittest.cc +++ b/ppapi/proxy/plugin_var_tracker_unittest.cc @@ -5,7 +5,7 @@ #include "ipc/ipc_test_sink.h" #include "ppapi/proxy/plugin_var_tracker.h" #include "ppapi/proxy/ppapi_messages.h" -#include "testing/gtest/include/gtest/gtest.h" +#include "ppapi/proxy/ppapi_proxy_test.h" namespace pp { namespace proxy { @@ -29,7 +29,7 @@ PP_Var MakeString(PluginVarTracker::VarID string_id) { } // namespace -class PluginVarTrackerTest : public testing::Test { +class PluginVarTrackerTest : public PluginProxyTest { public: PluginVarTrackerTest() {} @@ -37,7 +37,7 @@ class PluginVarTrackerTest : public testing::Test { // Asserts that there is a unique "release object" IPC message in the test // sink. This will return the var ID from the message or -1 if none found. PluginVarTracker::VarID GetObjectIDForUniqueReleaseObject() { - const IPC::Message* release_msg = sink_.GetUniqueMessageMatching( + const IPC::Message* release_msg = sink().GetUniqueMessageMatching( PpapiHostMsg_PPBVar_ReleaseObject::ID); if (!release_msg) return -1; @@ -46,25 +46,21 @@ class PluginVarTrackerTest : public testing::Test { PpapiHostMsg_PPBVar_ReleaseObject::Read(release_msg, &id); return id.a; } - - PluginVarTracker tracker_; - - IPC::TestSink sink_; }; TEST_F(PluginVarTrackerTest, Strings) { std::string str("Hello"); - PluginVarTracker::VarID str_id1 = tracker_.MakeString(str); + PluginVarTracker::VarID str_id1 = var_tracker().MakeString(str); EXPECT_NE(0, str_id1); - PluginVarTracker::VarID str_id2 = tracker_.MakeString( + PluginVarTracker::VarID str_id2 = var_tracker().MakeString( str.c_str(), static_cast<uint32_t>(str.size())); EXPECT_NE(0, str_id2); // Make sure the strings come out the other end. - std::string result = tracker_.GetString(MakeString(str_id1)); + std::string result = var_tracker().GetString(MakeString(str_id1)); EXPECT_EQ(str, result); - result = tracker_.GetString(MakeString(str_id2)); + result = var_tracker().GetString(MakeString(str_id2)); EXPECT_EQ(str, result); } @@ -73,43 +69,46 @@ TEST_F(PluginVarTrackerTest, GetHostObject) { // Round-trip through the tracker to make sure the host object comes out the // other end. - PP_Var plugin_object = tracker_.ReceiveObjectPassRef(host_object, &sink_); - PP_Var host_object2 = tracker_.GetHostObject(plugin_object); + PP_Var plugin_object = var_tracker().ReceiveObjectPassRef(host_object, + &sink()); + PP_Var host_object2 = var_tracker().GetHostObject(plugin_object); EXPECT_EQ(PP_VARTYPE_OBJECT, host_object2.type); EXPECT_EQ(host_object.value.as_id, host_object2.value.as_id); - tracker_.Release(plugin_object); + var_tracker().Release(plugin_object); } TEST_F(PluginVarTrackerTest, ReceiveObjectPassRef) { PP_Var host_object = MakeObject(12345); // Receive the object, we should have one ref and no messages. - PP_Var plugin_object = tracker_.ReceiveObjectPassRef(host_object, &sink_); - EXPECT_EQ(0u, sink_.message_count()); - EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_object)); + PP_Var plugin_object = var_tracker().ReceiveObjectPassRef(host_object, + &sink()); + EXPECT_EQ(0u, sink().message_count()); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); EXPECT_EQ(0, - tracker_.GetTrackedWithNoReferenceCountForObject(plugin_object)); + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_object)); // Receive the same object again, we should get the same plugin ID out. - PP_Var plugin_object2 = tracker_.ReceiveObjectPassRef(host_object, &sink_); + PP_Var plugin_object2 = var_tracker().ReceiveObjectPassRef(host_object, + &sink()); EXPECT_EQ(plugin_object.value.as_id, plugin_object2.value.as_id); - EXPECT_EQ(2, tracker_.GetRefCountForObject(plugin_object)); + EXPECT_EQ(2, var_tracker().GetRefCountForObject(plugin_object)); EXPECT_EQ(0, - tracker_.GetTrackedWithNoReferenceCountForObject(plugin_object)); + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_object)); // It should have sent one message to decerment the refcount in the host. // This is because it only maintains one host refcount for all references // in the plugin, but the host just sent the second one. EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject()); - sink_.ClearMessages(); + sink().ClearMessages(); // Release the object, one ref at a time. The second release should free // the tracking data and send a release message to the browser. - tracker_.Release(plugin_object); - EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_object)); - tracker_.Release(plugin_object); - EXPECT_EQ(-1, tracker_.GetRefCountForObject(plugin_object)); + var_tracker().Release(plugin_object); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + var_tracker().Release(plugin_object); + EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject()); } @@ -118,39 +117,43 @@ TEST_F(PluginVarTrackerTest, FreeTrackedAndReferencedObject) { PP_Var host_object = MakeObject(12345); // Phase one: First receive via a "pass ref", then a tracked with no ref. - PP_Var plugin_var = tracker_.ReceiveObjectPassRef(host_object, &sink_); - PP_Var plugin_var2 = tracker_.TrackObjectWithNoReference(host_object, &sink_); + PP_Var plugin_var = var_tracker().ReceiveObjectPassRef(host_object, &sink()); + PP_Var plugin_var2 = + var_tracker().TrackObjectWithNoReference(host_object, &sink()); EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id); - EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_var)); - EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var)); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_var)); + EXPECT_EQ(1, + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); // Free via the refcount, this should release the object to the browser but // maintain the tracked object. - tracker_.Release(plugin_var); - EXPECT_EQ(0, tracker_.GetRefCountForObject(plugin_var)); - EXPECT_EQ(1u, sink_.message_count()); + var_tracker().Release(plugin_var); + EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_var)); + EXPECT_EQ(1u, sink().message_count()); EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject()); // Now free via the tracked object, this should free it. - tracker_.StopTrackingObjectWithNoReference(plugin_var); - EXPECT_EQ(-1, tracker_.GetRefCountForObject(plugin_var)); + var_tracker().StopTrackingObjectWithNoReference(plugin_var); + EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_var)); // Phase two: Receive via a tracked, then get an addref. - sink_.ClearMessages(); - plugin_var = tracker_.TrackObjectWithNoReference(host_object, &sink_); - plugin_var2 = tracker_.ReceiveObjectPassRef(host_object, &sink_); + sink().ClearMessages(); + plugin_var = var_tracker().TrackObjectWithNoReference(host_object, &sink()); + plugin_var2 = var_tracker().ReceiveObjectPassRef(host_object, &sink()); EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id); - EXPECT_EQ(1, tracker_.GetRefCountForObject(plugin_var)); - EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var)); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_var)); + EXPECT_EQ(1, + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); // Free via the tracked object, this should have no effect. - tracker_.StopTrackingObjectWithNoReference(plugin_var); - EXPECT_EQ(0, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var)); - EXPECT_EQ(0u, sink_.message_count()); + var_tracker().StopTrackingObjectWithNoReference(plugin_var); + EXPECT_EQ(0, + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); + EXPECT_EQ(0u, sink().message_count()); // Now free via the refcount, this should delete it. - tracker_.Release(plugin_var); - EXPECT_EQ(-1, tracker_.GetRefCountForObject(plugin_var)); + var_tracker().Release(plugin_var); + EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_var)); EXPECT_EQ(host_object.value.as_id, GetObjectIDForUniqueReleaseObject()); } @@ -158,18 +161,24 @@ TEST_F(PluginVarTrackerTest, RecursiveTrackWithNoRef) { PP_Var host_object = MakeObject(12345); // Receive a tracked object twice. - PP_Var plugin_var = tracker_.TrackObjectWithNoReference(host_object, &sink_); - EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var)); - PP_Var plugin_var2 = tracker_.TrackObjectWithNoReference(host_object, &sink_); + PP_Var plugin_var = var_tracker().TrackObjectWithNoReference( + host_object, &sink()); + EXPECT_EQ(1, + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); + PP_Var plugin_var2 = var_tracker().TrackObjectWithNoReference(host_object, + &sink()); EXPECT_EQ(plugin_var.value.as_id, plugin_var2.value.as_id); - EXPECT_EQ(0, tracker_.GetRefCountForObject(plugin_var)); - EXPECT_EQ(2, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var)); + EXPECT_EQ(0, var_tracker().GetRefCountForObject(plugin_var)); + EXPECT_EQ(2, + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); // Now release those tracked items, the reference should be freed. - tracker_.StopTrackingObjectWithNoReference(plugin_var); - EXPECT_EQ(1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var)); - tracker_.StopTrackingObjectWithNoReference(plugin_var); - EXPECT_EQ(-1, tracker_.GetTrackedWithNoReferenceCountForObject(plugin_var)); + var_tracker().StopTrackingObjectWithNoReference(plugin_var); + EXPECT_EQ(1, + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); + var_tracker().StopTrackingObjectWithNoReference(plugin_var); + EXPECT_EQ(-1, + var_tracker().GetTrackedWithNoReferenceCountForObject(plugin_var)); } } // namespace proxy diff --git a/ppapi/proxy/ppapi_messages_internal.h b/ppapi/proxy/ppapi_messages_internal.h index 84a54fd..e949ad1 100644 --- a/ppapi/proxy/ppapi_messages_internal.h +++ b/ppapi/proxy/ppapi_messages_internal.h @@ -45,16 +45,12 @@ IPC_MESSAGE_CONTROL2(PpapiMsg_ExecuteCallback, // // The handler of this message should always close all of the handles passed // in, since some could be valid even in the error case. -IPC_MESSAGE_ROUTED5(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, - PP_Resource /* audio_id */, - int32_t /* result_code (will be != PP_OK on failure) */, - IPC::PlatformFileForTransit /* socket_handle */, - base::SharedMemoryHandle /* handle */, - int32_t /* length */) +IPC_MESSAGE_ROUTED1(PpapiMsg_PPBAudio_NotifyAudioStreamCreated, + pp::proxy::PPBAudio_NotifyAudioStreamCreated_Params); // PPB_Graphics2D. IPC_MESSAGE_ROUTED2(PpapiMsg_PPBGraphics2D_FlushACK, - PP_Resource /* graphics_2d */, + pp::proxy::HostResource /* graphics_2d */, int32_t /* pp_error */) // PPP_Class. @@ -130,7 +126,7 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiMsg_PPPInstance_HandleInputEvent, PP_Bool /* result */) IPC_SYNC_MESSAGE_ROUTED2_1(PpapiMsg_PPPInstance_HandleDocumentLoad, PP_Instance /* instance */, - PP_Resource /* url_loader */, + pp::proxy::HostResource /* url_loader */, PP_Bool /* result */) IPC_SYNC_MESSAGE_ROUTED1_1(PpapiMsg_PPPInstance_GetInstanceObject, PP_Instance /* instance */, @@ -139,14 +135,10 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiMsg_PPPInstance_GetInstanceObject, // PPB_URLLoader // (Messages from browser to plugin to notify it of changes in state.) -IPC_MESSAGE_ROUTED5(PpapiMsg_PPBURLLoader_UpdateProgress, - PP_Resource /* resource */, - int64 /* bytes_sent */, - int64 /* total_bytes_to_be_sent */, - int64 /* bytes_received */, - int64 /* total_bytes_to_be_received */) +IPC_MESSAGE_ROUTED1(PpapiMsg_PPBURLLoader_UpdateProgress, + pp::proxy::PPBURLLoader_UpdateProgress_Params /* params */) IPC_MESSAGE_ROUTED3(PpapiMsg_PPBURLLoader_ReadResponseBody_Ack, - PP_Resource /* loader */, + pp::proxy::HostResource /* loader */, int32 /* result */, std::string /* data */) @@ -159,10 +151,10 @@ IPC_MESSAGE_CONTROL1(PpapiHostMsg_PluginLoaded, // PPB_Audio. IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBAudio_Create, PP_Instance /* instance_id */, - PP_Resource /* config_id */, - PP_Resource /* result */) + pp::proxy::HostResource /* config_id */, + pp::proxy::HostResource /* result */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBAudio_StartOrStop, - PP_Resource /* audio_id */, + pp::proxy::HostResource /* audio_id */, bool /* play */) // PPB_AudioConfig. @@ -170,7 +162,7 @@ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBAudioConfig_Create, PP_Instance /* instance */, int32_t /* sample_rate */, uint32_t /* sample_frame_count */, - PP_Resource /* result */) + pp::proxy::HostResource /* result */) IPC_SYNC_MESSAGE_ROUTED2_1( PpapiHostMsg_PPBAudioConfig_RecommendSampleFrameCount, int32_t /* sample_rate */, @@ -181,12 +173,14 @@ IPC_SYNC_MESSAGE_ROUTED2_1( IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBBuffer_Create, PP_Instance /* instance */, uint32_t /* size */, - PP_Resource /* result_resource */, + pp::proxy::HostResource /* result_resource */, int32_t /* result_shm_handle */) // PPB_Core. -IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_AddRefResource, PP_Resource) -IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_ReleaseResource, PP_Resource) +IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_AddRefResource, + pp::proxy::HostResource) +IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBCore_ReleaseResource, + pp::proxy::HostResource) // PPB_CharSet. IPC_SYNC_MESSAGE_ROUTED4_2(PpapiHostMsg_PPBCharSet_UTF16ToCharSet, @@ -211,7 +205,7 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBCharSet_GetDefaultCharSet, IPC_SYNC_MESSAGE_ROUTED4_1(PpapiHostMsg_PPBCursorControl_SetCursor, PP_Instance /* instance */, int32_t /* type */, - PP_Resource /* custom_image */, + pp::proxy::HostResource /* custom_image */, PP_Point /* hot_spot */, PP_Bool /* result */) IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBCursorControl_LockCursor, @@ -282,7 +276,7 @@ IPC_SYNC_MESSAGE_ROUTED2_3( PpapiHostMsg_PPBFont_Create, PP_Instance /* instance */, pp::proxy::SerializedFontDescription /* in_description */, - PP_Resource /* result */, + pp::proxy::HostResource /* result */, pp::proxy::SerializedFontDescription /* out_description */, std::string /* out_metrics */) IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFont_DrawTextAt, @@ -290,20 +284,20 @@ IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBFont_DrawTextAt, pp::proxy::PPBFont_DrawTextAt_Params /* params */, PP_Bool /* result */) IPC_SYNC_MESSAGE_ROUTED4_1(PpapiHostMsg_PPBFont_MeasureText, - PP_Resource /* font */, + pp::proxy::HostResource /* font */, pp::proxy::SerializedVar /* text */, PP_Bool /* text_is_rtl */, PP_Bool /* override_direction */, int32_t /* result */) IPC_SYNC_MESSAGE_ROUTED5_1(PpapiHostMsg_PPBFont_CharacterOffsetForPixel, - PP_Resource /* font */, + pp::proxy::HostResource /* font */, pp::proxy::SerializedVar /* text */, PP_Bool /* text_is_rtl */, PP_Bool /* override_direction */, int32_t /* pixel_pos */, uint32_t /* result */) IPC_SYNC_MESSAGE_ROUTED5_1(PpapiHostMsg_PPBFont_PixelOffsetForCharacter, - PP_Resource /* font */, + pp::proxy::HostResource /* font */, pp::proxy::SerializedVar /* text */, PP_Bool /* text_is_rtl */, PP_Bool /* override_direction */, @@ -324,23 +318,23 @@ IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBGraphics2D_Create, PP_Instance /* instance */, PP_Size /* size */, PP_Bool /* is_always_opaque */, - PP_Resource /* result */) + pp::proxy::HostResource /* result */) IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBGraphics2D_PaintImageData, - PP_Resource /* graphics_2d */, - PP_Resource /* image_data */, + pp::proxy::HostResource /* graphics_2d */, + pp::proxy::HostResource /* image_data */, PP_Point /* top_left */, bool /* src_rect_specified */, PP_Rect /* src_rect */) IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBGraphics2D_Scroll, - PP_Resource /* graphics_2d */, + pp::proxy::HostResource /* graphics_2d */, bool /* clip_specified */, PP_Rect /* clip */, PP_Point /* amount */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBGraphics2D_ReplaceContents, - PP_Resource /* graphics_2d */, - PP_Resource /* image_data */) + pp::proxy::HostResource /* graphics_2d */, + pp::proxy::HostResource /* image_data */) IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBGraphics2D_Flush, - PP_Resource /* graphics_2d */) + pp::proxy::HostResource /* graphics_2d */) // PPB_ImageData. IPC_SYNC_MESSAGE_ROUTED4_3(PpapiHostMsg_PPBImageData_Create, @@ -348,7 +342,7 @@ IPC_SYNC_MESSAGE_ROUTED4_3(PpapiHostMsg_PPBImageData_Create, int32 /* format */, PP_Size /* size */, PP_Bool /* init_to_zero */, - PP_Resource /* result_resource */, + pp::proxy::HostResource /* result_resource */, std::string /* image_data_desc */, pp::proxy::ImageHandle /* result */) @@ -361,7 +355,7 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBInstance_GetOwnerElementObject, pp::proxy::SerializedVar /* result */) IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBInstance_BindGraphics, PP_Instance /* instance */, - PP_Resource /* device */, + pp::proxy::HostResource /* device */, PP_Bool /* result */) IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBInstance_IsFullFrame, PP_Instance /* instance */, @@ -377,19 +371,20 @@ IPC_SYNC_MESSAGE_ROUTED3_1( PP_Instance /* instance */, pp::proxy::SerializedFontDescription /* description */, int32_t /* charset */, - PP_Resource /* result */) + pp::proxy::HostResource /* result */) IPC_SYNC_MESSAGE_ROUTED2_1( PpapiHostMsg_PPBPDF_GetFontTableForPrivateFontFile, - PP_Resource /* font_file */, + pp::proxy::HostResource /* font_file */, uint32_t /* table */, std::string /* result */) // PPB_Testing. -IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBTesting_ReadImageData, - PP_Resource /* device_context_2d */, - PP_Resource /* image */, - PP_Point /* top_left */, - PP_Bool /* result */) +IPC_SYNC_MESSAGE_ROUTED3_1( + PpapiHostMsg_PPBTesting_ReadImageData, + pp::proxy::HostResource /* device_context_2d */, + pp::proxy::HostResource /* image */, + PP_Point /* top_left */, + PP_Bool /* result */) IPC_SYNC_MESSAGE_ROUTED0_1(PpapiHostMsg_PPBTesting_RunMessageLoop, bool /* dummy since there's no 0_0 variant */) IPC_MESSAGE_ROUTED0(PpapiHostMsg_PPBTesting_QuitMessageLoop) @@ -400,56 +395,57 @@ IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBTesting_GetLiveObjectsForInstance, // PPB_URLLoader. IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLLoader_Create, PP_Instance /* instance */, - PP_Resource /* result */) + pp::proxy::HostResource /* result */) IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBURLLoader_Open, - PP_Resource /* loader */, - PP_Resource /*request_info */, + pp::proxy::HostResource /* loader */, + pp::proxy::HostResource /*request_info */, uint32_t /* serialized_callback */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_FollowRedirect, - PP_Resource /* loader */, + pp::proxy::HostResource /* loader */, uint32_t /* serialized_callback */) -IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLLoader_GetResponseInfo, - PP_Resource /* loader */, - PP_Resource /* response_info_out */) +IPC_SYNC_MESSAGE_ROUTED1_1( + PpapiHostMsg_PPBURLLoader_GetResponseInfo, + pp::proxy::HostResource /* loader */, + pp::proxy::HostResource /* response_info_out */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_ReadResponseBody, - PP_Resource /* loader */, + pp::proxy::HostResource /* loader */, int32_t /* bytes_to_read */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLLoader_FinishStreamingToFile, - PP_Resource /* loader */, + pp::proxy::HostResource /* loader */, uint32_t /* serialized_callback */) IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoader_Close, - PP_Resource /* loader */) + pp::proxy::HostResource /* loader */) // PPB_URLLoaderTrusted. IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBURLLoaderTrusted_GrantUniversalAccess, - PP_Resource /* loader */) + pp::proxy::HostResource /* loader */) // PPB_URLRequestInfo. IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLRequestInfo_Create, PP_Instance /* instance */, - PP_Resource /* result */) + pp::proxy::HostResource /* result */) IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBURLRequestInfo_SetProperty, - PP_Resource /* request */, + pp::proxy::HostResource /* request */, int32_t /* property */, pp::proxy::SerializedVar /* value */) IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBURLRequestInfo_AppendDataToBody, - PP_Resource /* request */, + pp::proxy::HostResource /* request */, std::string /* data */) IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBURLRequestInfo_AppendFileToBody, - PP_Resource /* request */, - PP_Resource /* file_ref */, + pp::proxy::HostResource /* request */, + pp::proxy::HostResource /* file_ref */, int64_t /* start_offset */, int64_t /* number_of_bytes */, double /* expected_last_modified_time */) // PPB_URLResponseInfo. IPC_SYNC_MESSAGE_ROUTED2_1(PpapiHostMsg_PPBURLResponseInfo_GetProperty, - PP_Resource /* response */, + pp::proxy::HostResource /* response */, int32_t /* property */, pp::proxy::SerializedVar /* result */) IPC_SYNC_MESSAGE_ROUTED1_1(PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef, - PP_Resource /* response */, - PP_Resource /* file_ref_result */) + pp::proxy::HostResource /* response */, + pp::proxy::HostResource /* file_ref_result */) // PPB_Var. IPC_MESSAGE_ROUTED1(PpapiHostMsg_PPBVar_AddRefObject, diff --git a/ppapi/proxy/ppapi_param_traits.cc b/ppapi/proxy/ppapi_param_traits.cc index dbbc643..e38e9bf1 100644 --- a/ppapi/proxy/ppapi_param_traits.cc +++ b/ppapi/proxy/ppapi_param_traits.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -8,6 +8,7 @@ #include "ppapi/c/dev/pp_file_info_dev.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/serialized_var.h" @@ -180,6 +181,36 @@ bool ParamTraits<PP_Size>::Read(const Message* m, void** iter, param_type* r) { void ParamTraits<PP_Size>::Log(const param_type& p, std::string* l) { } +// PPBAudio_NotifyAudioStreamCreated_Params ------------------------------------ + +// static +void ParamTraits<pp::proxy::PPBAudio_NotifyAudioStreamCreated_Params>::Write( + Message* m, + const param_type& p) { + ParamTraits<pp::proxy::HostResource>::Write(m, p.audio_id); + ParamTraits<int32_t>::Write(m, p.result_code); + ParamTraits<PlatformFileForTransit>::Write(m, p.socket_handle); + ParamTraits<int32_t>::Write(m, p.length); +} + +// static +bool ParamTraits<pp::proxy::PPBAudio_NotifyAudioStreamCreated_Params>::Read( + const Message* m, + void** iter, + param_type* r) { + return + ParamTraits<pp::proxy::HostResource>::Read(m, iter, &r->audio_id) && + ParamTraits<int32_t>::Read(m, iter, &r->result_code) && + ParamTraits<PlatformFileForTransit>::Read(m, iter, &r->socket_handle) && + ParamTraits<int32_t>::Read(m, iter, &r->length); +} + +// static +void ParamTraits<pp::proxy::PPBAudio_NotifyAudioStreamCreated_Params>::Log( + const param_type& p, + std::string* l) { +} + // PPBFlash_DrawGlyphs_Params -------------------------------------------------- // static @@ -187,7 +218,7 @@ void ParamTraits<pp::proxy::PPBFlash_DrawGlyphs_Params>::Write( Message* m, const param_type& p) { ParamTraits<PP_Instance>::Write(m, p.instance); - ParamTraits<PP_Resource>::Write(m, p.pp_image_data); + ParamTraits<pp::proxy::HostResource>::Write(m, p.image_data); ParamTraits<pp::proxy::SerializedFontDescription>::Write(m, p.font_desc); ParamTraits<uint32_t>::Write(m, p.color); ParamTraits<PP_Point>::Write(m, p.position); @@ -212,7 +243,8 @@ bool ParamTraits<pp::proxy::PPBFlash_DrawGlyphs_Params>::Read( param_type* r) { return ParamTraits<PP_Instance>::Read(m, iter, &r->instance) && - ParamTraits<PP_Resource>::Read(m, iter, &r->pp_image_data) && + ParamTraits<pp::proxy::HostResource>::Read(m, iter, + &r->image_data) && ParamTraits<pp::proxy::SerializedFontDescription>::Read(m, iter, &r->font_desc) && ParamTraits<uint32_t>::Read(m, iter, &r->color) && @@ -244,8 +276,8 @@ void ParamTraits<pp::proxy::PPBFlash_DrawGlyphs_Params>::Log( void ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params>::Write( Message* m, const param_type& p) { - ParamTraits<PP_Resource>::Write(m, p.font); - ParamTraits<PP_Resource>::Write(m, p.image_data); + ParamTraits<pp::proxy::HostResource>::Write(m, p.font); + ParamTraits<pp::proxy::HostResource>::Write(m, p.image_data); ParamTraits<PP_Bool>::Write(m, p.text_is_rtl); ParamTraits<PP_Bool>::Write(m, p.override_direction); ParamTraits<PP_Point>::Write(m, p.position); @@ -261,8 +293,9 @@ bool ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params>::Read( void** iter, param_type* r) { return - ParamTraits<PP_Resource>::Read(m, iter, &r->font) && - ParamTraits<PP_Resource>::Read(m, iter, &r->image_data) && + ParamTraits<pp::proxy::HostResource>::Read(m, iter, &r->font) && + ParamTraits<pp::proxy::HostResource>::Read(m, iter, + &r->image_data) && ParamTraits<PP_Bool>::Read(m, iter, &r->text_is_rtl) && ParamTraits<PP_Bool>::Read(m, iter, &r->override_direction) && ParamTraits<PP_Point>::Read(m, iter, &r->position) && @@ -278,6 +311,40 @@ void ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params>::Log( std::string* l) { } +// PPBURLLoader_UpdateProgress_Params ------------------------------------------ + +// static +void ParamTraits<pp::proxy::PPBURLLoader_UpdateProgress_Params>::Write( + Message* m, + const param_type& p) { + ParamTraits<PP_Instance>::Write(m, p.instance); + ParamTraits<pp::proxy::HostResource>::Write(m, p.resource); + ParamTraits<int64_t>::Write(m, p.bytes_sent); + ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_sent); + ParamTraits<int64_t>::Write(m, p.bytes_received); + ParamTraits<int64_t>::Write(m, p.total_bytes_to_be_received); +} + +// static +bool ParamTraits<pp::proxy::PPBURLLoader_UpdateProgress_Params>::Read( + const Message* m, + void** iter, + param_type* r) { + return + ParamTraits<PP_Instance>::Read(m, iter, &r->instance) && + ParamTraits<pp::proxy::HostResource>::Read(m, iter, &r->resource) && + ParamTraits<int64_t>::Read(m, iter, &r->bytes_sent) && + ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_sent) && + ParamTraits<int64_t>::Read(m, iter, &r->bytes_received) && + ParamTraits<int64_t>::Read(m, iter, &r->total_bytes_to_be_received); +} + +// static +void ParamTraits<pp::proxy::PPBURLLoader_UpdateProgress_Params>::Log( + const param_type& p, + std::string* l) { +} + // SerializedDirEntry ---------------------------------------------------------- // static @@ -300,26 +367,6 @@ void ParamTraits<pp::proxy::SerializedDirEntry>::Log(const param_type& p, std::string* l) { } -// SerializedVar --------------------------------------------------------------- - -// static -void ParamTraits<pp::proxy::SerializedVar>::Write(Message* m, - const param_type& p) { - p.WriteToMessage(m); -} - -// static -bool ParamTraits<pp::proxy::SerializedVar>::Read(const Message* m, - void** iter, - param_type* r) { - return r->ReadFromMessage(m, iter); -} - -// static -void ParamTraits<pp::proxy::SerializedVar>::Log(const param_type& p, - std::string* l) { -} - // pp::proxy::SerializedFontDescription ---------------------------------------- // static @@ -358,6 +405,53 @@ void ParamTraits<pp::proxy::SerializedFontDescription>::Log( std::string* l) { } +// HostResource ---------------------------------------------------------- + +// static +void ParamTraits<pp::proxy::HostResource>::Write(Message* m, + const param_type& p) { + ParamTraits<PP_Instance>::Write(m, p.instance()); + ParamTraits<PP_Resource>::Write(m, p.host_resource()); +} + +// static +bool ParamTraits<pp::proxy::HostResource>::Read(const Message* m, + void** iter, + param_type* r) { + PP_Instance instance; + PP_Resource resource; + if (!ParamTraits<PP_Instance>::Read(m, iter, &instance) || + !ParamTraits<PP_Resource>::Read(m, iter, &resource)) + return false; + r->SetHostResource(instance, resource); + return true; +} + +// static +void ParamTraits<pp::proxy::HostResource>::Log(const param_type& p, + std::string* l) { +} + +// SerializedVar --------------------------------------------------------------- + +// static +void ParamTraits<pp::proxy::SerializedVar>::Write(Message* m, + const param_type& p) { + p.WriteToMessage(m); +} + +// static +bool ParamTraits<pp::proxy::SerializedVar>::Read(const Message* m, + void** iter, + param_type* r) { + return r->ReadFromMessage(m, iter); +} + +// static +void ParamTraits<pp::proxy::SerializedVar>::Log(const param_type& p, + std::string* l) { +} + // std::vector<SerializedVar> -------------------------------------------------- void ParamTraits< std::vector<pp::proxy::SerializedVar> >::Write( diff --git a/ppapi/proxy/ppapi_param_traits.h b/ppapi/proxy/ppapi_param_traits.h index fea2594d..3a7358d 100644 --- a/ppapi/proxy/ppapi_param_traits.h +++ b/ppapi/proxy/ppapi_param_traits.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -11,20 +11,24 @@ #include "ppapi/c/pp_input_event.h" #include "ppapi/c/pp_rect.h" #include "ppapi/c/pp_var.h" -#include "ppapi/proxy/serialized_var.h" // TODO(brettw) eraseme. struct PP_FileInfo_Dev; struct PP_ObjectProperty; namespace pp { namespace proxy { + +struct PPBAudio_NotifyAudioStreamCreated_Params; struct PPBFlash_DrawGlyphs_Params; struct PPBFont_DrawTextAt_Params; +struct PPBURLLoader_UpdateProgress_Params; struct SerializedDirEntry; struct SerializedFontDescription; +class HostResource; class SerializedVar; -} -} + +} // namespace proxy +} // namespace pp namespace IPC { @@ -84,6 +88,14 @@ struct ParamTraits<PP_Size> { static void Log(const param_type& p, std::string* l); }; +template<> struct ParamTraits< + pp::proxy::PPBAudio_NotifyAudioStreamCreated_Params> { + typedef pp::proxy::PPBAudio_NotifyAudioStreamCreated_Params param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + template<> struct ParamTraits<pp::proxy::PPBFlash_DrawGlyphs_Params> { typedef pp::proxy::PPBFlash_DrawGlyphs_Params param_type; @@ -101,6 +113,14 @@ struct ParamTraits<pp::proxy::PPBFont_DrawTextAt_Params> { }; template<> +struct ParamTraits<pp::proxy::PPBURLLoader_UpdateProgress_Params> { + typedef pp::proxy::PPBURLLoader_UpdateProgress_Params param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template<> struct ParamTraits<pp::proxy::SerializedDirEntry> { typedef pp::proxy::SerializedDirEntry param_type; static void Write(Message* m, const param_type& p); @@ -117,6 +137,14 @@ struct ParamTraits<pp::proxy::SerializedFontDescription> { }; template<> +struct ParamTraits<pp::proxy::HostResource> { + typedef pp::proxy::HostResource param_type; + static void Write(Message* m, const param_type& p); + static bool Read(const Message* m, void** iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + +template<> struct ParamTraits<pp::proxy::SerializedVar> { typedef pp::proxy::SerializedVar param_type; static void Write(Message* m, const param_type& p); diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc new file mode 100644 index 0000000..240860c --- /dev/null +++ b/ppapi/proxy/ppapi_proxy_test.cc @@ -0,0 +1,59 @@ +// 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/ppapi_proxy_test.h" + +#include "ppapi/c/pp_errors.h" + +namespace pp { +namespace proxy { + +namespace { + +const void* MockGetInterface(const char*) { + return NULL; +} + +int32_t MockInitModule(PP_Module, Dispatcher::GetInterfaceFunc) { + return PP_OK; +} + +void MockShutdownModuleFunc() { +} + +} // namespace + +PluginProxyTest::PluginProxyTest() { +} + +PluginProxyTest::~PluginProxyTest() { +} + +void PluginProxyTest::SetUp() { + // These must be first since the dispatcher set-up uses them. + PluginResourceTracker::SetInstanceForTest(&resource_tracker_); + PluginVarTracker::SetInstanceForTest(&var_tracker_); + + pp_instance_ = 0x1234; + plugin_dispatcher_.reset(new PluginDispatcher( + base::Process::Current().handle(), + &MockGetInterface, + &MockInitModule, + &MockShutdownModuleFunc)); + plugin_dispatcher_->InitWithTestSink(&sink_); + // When the plugin dispatcher is per-instance, this is the line to use: + // PluginDispatcher::SetForInstance(pp_instance_, plugin_dispatcher_.get()); + PluginDispatcher::SetGlobal(plugin_dispatcher_.get()); +} + +void PluginProxyTest::TearDown() { + PluginDispatcher::SetGlobal(NULL); + plugin_dispatcher_.reset(); + + PluginVarTracker::SetInstanceForTest(NULL); + PluginResourceTracker::SetInstanceForTest(NULL); +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/ppapi_proxy_test.h b/ppapi/proxy/ppapi_proxy_test.h new file mode 100644 index 0000000..a811080 --- /dev/null +++ b/ppapi/proxy/ppapi_proxy_test.h @@ -0,0 +1,46 @@ +// 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 "base/scoped_ptr.h" +#include "ipc/ipc_test_sink.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource_tracker.h" +#include "ppapi/proxy/plugin_var_tracker.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace pp { +namespace proxy { + +// Test harness for the plugin side of the proxy. +class PluginProxyTest : public testing::Test { + public: + PluginProxyTest(); + ~PluginProxyTest(); + + virtual void SetUp(); + virtual void TearDown(); + + // The instance ID associated with the plugin dispatcher. + PP_Instance pp_instance() const { return pp_instance_; } + + PluginDispatcher* plugin_dispatcher() { return plugin_dispatcher_.get(); } + + PluginResourceTracker& resource_tracker() { return resource_tracker_; } + PluginVarTracker& var_tracker() { return var_tracker_; } + + IPC::TestSink& sink() { return sink_; } + + private: + PluginResourceTracker resource_tracker_; + PluginVarTracker var_tracker_; + + PP_Instance pp_instance_; + scoped_ptr<PluginDispatcher> plugin_dispatcher_; + + IPC::TestSink sink_; +}; + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/ppb_audio_config_proxy.cc b/ppapi/proxy/ppb_audio_config_proxy.cc index 8bf62c3..d437694 100644 --- a/ppapi/proxy/ppb_audio_config_proxy.cc +++ b/ppapi/proxy/ppb_audio_config_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -14,10 +14,10 @@ namespace proxy { class AudioConfig : public PluginResource { public: - AudioConfig(PP_Instance instance, + AudioConfig(const HostResource& resource, PP_AudioSampleRate sample_rate, uint32_t sample_frame_count) - : PluginResource(instance), + : PluginResource(resource), sample_rate_(sample_rate), sample_frame_count_(sample_frame_count) { } @@ -41,19 +41,18 @@ namespace { PP_Resource CreateStereo16bit(PP_Instance instance, PP_AudioSampleRate sample_rate, uint32_t sample_frame_count) { - PP_Resource result = 0; + HostResource resource; PluginDispatcher::GetForInstance(instance)->Send( new PpapiHostMsg_PPBAudioConfig_Create( INTERFACE_ID_PPB_AUDIO_CONFIG, instance, static_cast<int32_t>(sample_rate), sample_frame_count, - &result)); - if (!result) + &resource)); + if (!resource.is_null()) return 0; linked_ptr<AudioConfig> object( - new AudioConfig(instance, sample_rate, sample_frame_count)); - PluginResourceTracker::GetInstance()->AddResource(result, object); - return result; + new AudioConfig(resource, sample_rate, sample_frame_count)); + return PluginResourceTracker::GetInstance()->AddResource(object); } uint32_t RecommendSampleFrameCount(PP_AudioSampleRate sample_rate, @@ -129,10 +128,11 @@ bool PPB_AudioConfig_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_AudioConfig_Proxy::OnMsgCreateStereo16Bit(PP_Instance instance, int32_t sample_rate, uint32_t sample_frame_count, - PP_Resource* result) { - *result = ppb_audio_config_target()->CreateStereo16Bit( - instance, static_cast<PP_AudioSampleRate>(sample_rate), - sample_frame_count); + HostResource* result) { + result->SetHostResource(instance, + ppb_audio_config_target()->CreateStereo16Bit( + instance, static_cast<PP_AudioSampleRate>(sample_rate), + sample_frame_count)); } void PPB_AudioConfig_Proxy::OnMsgRecommendSampleFrameCount( diff --git a/ppapi/proxy/ppb_audio_config_proxy.h b/ppapi/proxy/ppb_audio_config_proxy.h index c5ef56d..6492ae1 100644 --- a/ppapi/proxy/ppb_audio_config_proxy.h +++ b/ppapi/proxy/ppb_audio_config_proxy.h @@ -15,6 +15,8 @@ struct PPB_AudioConfig; namespace pp { namespace proxy { +class HostResource; + class PPB_AudioConfig_Proxy : public InterfaceProxy { public: PPB_AudioConfig_Proxy(Dispatcher* dispatcher, const void* target_interface); @@ -34,7 +36,7 @@ class PPB_AudioConfig_Proxy : public InterfaceProxy { void OnMsgCreateStereo16Bit(PP_Instance instance, int32_t sample_rate, uint32_t sample_frame_count, - PP_Resource* result); + HostResource* result); void OnMsgRecommendSampleFrameCount(int32_t sample_rate, uint32_t requested, uint32_t* result); diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc index 837637a..c1095cf 100644 --- a/ppapi/proxy/ppb_audio_proxy.cc +++ b/ppapi/proxy/ppb_audio_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -19,11 +19,11 @@ namespace proxy { class Audio : public PluginResource, public pp::shared_impl::AudioImpl { public: - Audio(PP_Instance instance, + Audio(const HostResource& audio_id, PP_Resource config_id, PPB_Audio_Callback callback, void* user_data) - : PluginResource(instance), + : PluginResource(audio_id), config_(config_id) { SetCallback(callback, user_data); PluginResourceTracker::GetInstance()->AddRefResource(config_); @@ -43,7 +43,7 @@ class Audio : public PluginResource, public pp::shared_impl::AudioImpl { SetStartPlaybackState(); PluginDispatcher::GetForInstance(instance())->Send( new PpapiHostMsg_PPBAudio_StartOrStop( - INTERFACE_ID_PPB_AUDIO, resource, true)); + INTERFACE_ID_PPB_AUDIO, host_resource(), true)); } void StopPlayback(PP_Resource resource) { @@ -51,7 +51,7 @@ class Audio : public PluginResource, public pp::shared_impl::AudioImpl { return; PluginDispatcher::GetForInstance(instance())->Send( new PpapiHostMsg_PPBAudio_StartOrStop( - INTERFACE_ID_PPB_AUDIO, resource, false)); + INTERFACE_ID_PPB_AUDIO, host_resource(), false)); SetStopPlaybackState(); } @@ -67,16 +67,19 @@ PP_Resource Create(PP_Instance instance_id, PP_Resource config_id, PPB_Audio_Callback callback, void* user_data) { - PP_Resource result; + PluginResource* config = PluginResourceTracker::GetInstance()-> + GetResourceObject(config_id); + if (!config) + return 0; + + HostResource result; PluginDispatcher::Get()->Send(new PpapiHostMsg_PPBAudio_Create( - INTERFACE_ID_PPB_AUDIO, instance_id, config_id, &result)); - if (!result) + INTERFACE_ID_PPB_AUDIO, instance_id, config->host_resource(), &result)); + if (result.is_null()) return 0; - linked_ptr<Audio> object(new Audio(instance_id, config_id, - callback, user_data)); - PluginResourceTracker::GetInstance()->AddResource(result, object); - return result; + linked_ptr<Audio> object(new Audio(result, config_id, callback, user_data)); + return PluginResourceTracker::GetInstance()->AddResource(object); } PP_Bool IsAudio(PP_Resource resource) { @@ -150,57 +153,61 @@ bool PPB_Audio_Proxy::OnMessageReceived(const IPC::Message& msg) { } void PPB_Audio_Proxy::OnMsgCreate(PP_Instance instance_id, - PP_Resource config_id, - PP_Resource* result) { + const HostResource& config_id, + HostResource* result) { const PPB_AudioTrusted* audio_trusted = reinterpret_cast<const PPB_AudioTrusted*>( dispatcher()->GetLocalInterface(PPB_AUDIO_TRUSTED_INTERFACE)); - if (!audio_trusted) { - *result = 0; + if (!audio_trusted) return; - } - *result = audio_trusted->CreateTrusted(instance_id); - if (!result) + result->SetHostResource(instance_id, + audio_trusted->CreateTrusted(instance_id)); + if (result->is_null()) return; CompletionCallback callback = callback_factory_.NewCallback( &PPB_Audio_Proxy::AudioChannelConnected, *result); - int32_t open_error = audio_trusted->Open(*result, config_id, + int32_t open_error = audio_trusted->Open(result->host_resource(), + config_id.host_resource(), callback.pp_completion_callback()); if (open_error != PP_ERROR_WOULDBLOCK) callback.Run(open_error); } -void PPB_Audio_Proxy::OnMsgStartOrStop(PP_Resource audio_id, bool play) { +void PPB_Audio_Proxy::OnMsgStartOrStop(const HostResource& audio_id, + bool play) { if (play) - ppb_audio_target()->StartPlayback(audio_id); + ppb_audio_target()->StartPlayback(audio_id.host_resource()); else - ppb_audio_target()->StopPlayback(audio_id); + ppb_audio_target()->StopPlayback(audio_id.host_resource()); } +// Processed in the plugin (message from host). void PPB_Audio_Proxy::OnMsgNotifyAudioStreamCreated( - PP_Resource audio_id, - int32_t result_code, - IPC::PlatformFileForTransit socket_handle, - base::SharedMemoryHandle handle, - uint32_t length) { - Audio* object = PluginResource::GetAs<Audio>(audio_id); - if (!object || result_code != PP_OK) { + const PPBAudio_NotifyAudioStreamCreated_Params& params) { + PP_Resource plugin_resource = + PluginResourceTracker::GetInstance()->PluginResourceForHostResource( + params.audio_id); + Audio* object = plugin_resource ? + PluginResource::GetAs<Audio>(plugin_resource) : NULL; + if (!object || params.result_code != PP_OK) { // The caller may still have given us these handles in the failure case. // The easiest way to clean these up is to just put them in the objects // and then close them. This failure case is not performance critical. base::SyncSocket temp_socket( - IPC::PlatformFileForTransitToPlatformFile(socket_handle)); - base::SharedMemory temp_mem(handle, false); + IPC::PlatformFileForTransitToPlatformFile(params.socket_handle)); + base::SharedMemory temp_mem(params.handle, false); return; } object->SetStreamInfo( - handle, length, IPC::PlatformFileForTransitToPlatformFile(socket_handle)); + params.handle, params.length, + IPC::PlatformFileForTransitToPlatformFile(params.socket_handle)); } -void PPB_Audio_Proxy::AudioChannelConnected(int32_t result, - PP_Resource resource) { +void PPB_Audio_Proxy::AudioChannelConnected( + int32_t result, + const HostResource& resource) { IPC::PlatformFileForTransit socket_handle = IPC::InvalidPlatformFileForTransit(); #if defined(OS_WIN) @@ -224,13 +231,18 @@ void PPB_Audio_Proxy::AudioChannelConnected(int32_t result, // inconvenient to clean up. Our IPC code will automatically handle this for // us, as long as the remote side always closes the handles it receives // (in OnMsgNotifyAudioStreamCreated), even in the failure case. + PPBAudio_NotifyAudioStreamCreated_Params params; + params.audio_id = resource; + params.result_code = result; + params.socket_handle = socket_handle; + params.handle = shared_memory; + params.length = shared_memory_length; dispatcher()->Send(new PpapiMsg_PPBAudio_NotifyAudioStreamCreated( - INTERFACE_ID_PPB_AUDIO, resource, result_code, socket_handle, - shared_memory, shared_memory_length)); + INTERFACE_ID_PPB_AUDIO, params)); } int32_t PPB_Audio_Proxy::GetAudioConnectedHandles( - PP_Resource resource, + const HostResource& resource, IPC::PlatformFileForTransit* foreign_socket_handle, base::SharedMemoryHandle* foreign_shared_memory_handle, uint32_t* shared_memory_length) { @@ -243,7 +255,8 @@ int32_t PPB_Audio_Proxy::GetAudioConnectedHandles( // Get the socket handle for signaling. int32_t socket_handle; - int32_t result = audio_trusted->GetSyncSocket(resource, &socket_handle); + int32_t result = audio_trusted->GetSyncSocket(resource.host_resource(), + &socket_handle); if (result != PP_OK) return result; @@ -265,8 +278,9 @@ int32_t PPB_Audio_Proxy::GetAudioConnectedHandles( // Get the shared memory for the buffer. // TODO(brettw) remove the reinterpret cast when the interface is updated. int shared_memory_handle; - result = audio_trusted->GetSharedMemory(resource, &shared_memory_handle, - shared_memory_length); + result = audio_trusted->GetSharedMemory(resource.host_resource(), + &shared_memory_handle, + shared_memory_length); if (result != PP_OK) return result; diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h index c77e3d6..7ac27f5 100644 --- a/ppapi/proxy/ppb_audio_proxy.h +++ b/ppapi/proxy/ppb_audio_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -21,6 +21,9 @@ struct PPB_Audio; namespace pp { namespace proxy { +struct PPBAudio_NotifyAudioStreamCreated_Params; +class HostResource; + class PPB_Audio_Proxy : public InterfaceProxy { public: PPB_Audio_Proxy(Dispatcher* dispatcher, const void* target_interface); @@ -38,19 +41,16 @@ class PPB_Audio_Proxy : public InterfaceProxy { private: // Plugin->renderer message handlers. void OnMsgCreate(PP_Instance instance_id, - PP_Resource config_id, - PP_Resource* result); - void OnMsgStartOrStop(PP_Resource audio_id, bool play); + const HostResource& config_id, + HostResource* result); + void OnMsgStartOrStop(const HostResource& audio_id, bool play); // Renderer->plugin message handlers. void OnMsgNotifyAudioStreamCreated( - PP_Resource audio_id, - int32_t result_code, - IPC::PlatformFileForTransit socket_handle, - base::SharedMemoryHandle shared_memory_handle, - uint32_t shared_memory_length); + const PPBAudio_NotifyAudioStreamCreated_Params& params); - void AudioChannelConnected(int32_t result, PP_Resource resource); + void AudioChannelConnected(int32_t result, + const HostResource& resource); // In the renderer, this is called in response to a stream created message. // It will retrieve the shared memory and socket handles and place them into @@ -61,7 +61,7 @@ class PPB_Audio_Proxy : public InterfaceProxy { // arguments may be written to, and others may be untouched, depending on // where the error occurred. int32_t GetAudioConnectedHandles( - PP_Resource resource, + const HostResource& resource, IPC::PlatformFileForTransit* foreign_socket_handle, base::SharedMemoryHandle* foreign_shared_memory_handle, uint32_t* shared_memory_length); diff --git a/ppapi/proxy/ppb_buffer_proxy.cc b/ppapi/proxy/ppb_buffer_proxy.cc index d224572..5125855 100644 --- a/ppapi/proxy/ppb_buffer_proxy.cc +++ b/ppapi/proxy/ppb_buffer_proxy.cc @@ -20,7 +20,9 @@ namespace proxy { class Buffer : public PluginResource { public: - Buffer(PP_Instance instance, int memory_handle, uint32_t size); + Buffer(const HostResource& resource, + int memory_handle, + uint32_t size); virtual ~Buffer(); // Resource overrides. @@ -40,8 +42,10 @@ class Buffer : public PluginResource { DISALLOW_COPY_AND_ASSIGN(Buffer); }; -Buffer::Buffer(PP_Instance instance, int memory_handle, uint32_t size) - : PluginResource(instance), +Buffer::Buffer(const HostResource& resource, + int memory_handle, + uint32_t size) + : PluginResource(resource), memory_handle_(memory_handle), size_(size), mapped_data_(NULL) { @@ -63,19 +67,18 @@ void Buffer::Unmap() { namespace { PP_Resource Create(PP_Instance instance, uint32_t size) { - PP_Resource result = 0; + HostResource result; int32_t shm_handle = -1; PluginDispatcher::GetForInstance(instance)->Send( new PpapiHostMsg_PPBBuffer_Create( INTERFACE_ID_PPB_BUFFER, instance, size, &result, &shm_handle)); - if (!result) + if (result.is_null()) return 0; - linked_ptr<Buffer> object(new Buffer(instance, static_cast<int>(shm_handle), - size)); - PluginResourceTracker::GetInstance()->AddResource(result, object); - return result; + linked_ptr<Buffer> object(new Buffer(result, + static_cast<int>(shm_handle), size)); + return PluginResourceTracker::GetInstance()->AddResource(object); } PP_Bool IsBuffer(PP_Resource resource) { @@ -144,9 +147,11 @@ bool PPB_Buffer_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_Buffer_Proxy::OnMsgCreate(PP_Instance instance, uint32_t size, - PP_Resource* result_resource, + HostResource* result_resource, int* result_shm_handle) { - *result_resource = ppb_buffer_target()->Create(instance, size); + result_resource->SetHostResource( + instance, + ppb_buffer_target()->Create(instance, size)); // TODO(brettw) set the shm handle from a trusted interface. *result_shm_handle = 0; } diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h index bec74f7..bc979a3 100644 --- a/ppapi/proxy/ppb_buffer_proxy.h +++ b/ppapi/proxy/ppb_buffer_proxy.h @@ -13,6 +13,8 @@ struct PPB_Buffer_Dev; namespace pp { namespace proxy { +class HostResource; + class PPB_Buffer_Proxy : public InterfaceProxy { public: PPB_Buffer_Proxy(Dispatcher* dispatcher, const void* target_interface); @@ -31,7 +33,7 @@ class PPB_Buffer_Proxy : public InterfaceProxy { // Message handlers. void OnMsgCreate(PP_Instance instance, uint32_t size, - PP_Resource* result_resource, + HostResource* result_resource, int* result_shm_handle); }; diff --git a/ppapi/proxy/ppb_core_proxy.cc b/ppapi/proxy/ppb_core_proxy.cc index b4afcb6..a9486c8 100644 --- a/ppapi/proxy/ppb_core_proxy.cc +++ b/ppapi/proxy/ppb_core_proxy.cc @@ -110,12 +110,12 @@ bool PPB_Core_Proxy::OnMessageReceived(const IPC::Message& msg) { return handled; } -void PPB_Core_Proxy::OnMsgAddRefResource(PP_Resource resource) { - ppb_core_target()->AddRefResource(resource); +void PPB_Core_Proxy::OnMsgAddRefResource(HostResource resource) { + ppb_core_target()->AddRefResource(resource.host_resource()); } -void PPB_Core_Proxy::OnMsgReleaseResource(PP_Resource resource) { - ppb_core_target()->ReleaseResource(resource); +void PPB_Core_Proxy::OnMsgReleaseResource(HostResource resource) { + ppb_core_target()->ReleaseResource(resource.host_resource()); } } // namespace proxy diff --git a/ppapi/proxy/ppb_core_proxy.h b/ppapi/proxy/ppb_core_proxy.h index ece12dc..0f8c58a 100644 --- a/ppapi/proxy/ppb_core_proxy.h +++ b/ppapi/proxy/ppb_core_proxy.h @@ -8,6 +8,7 @@ #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PPB_Core; @@ -31,8 +32,8 @@ class PPB_Core_Proxy : public InterfaceProxy { private: // Message handlers. - void OnMsgAddRefResource(PP_Resource resource); - void OnMsgReleaseResource(PP_Resource resource); + void OnMsgAddRefResource(HostResource resource); + void OnMsgReleaseResource(HostResource resource); }; } // namespace proxy diff --git a/ppapi/proxy/ppb_cursor_control_proxy.cc b/ppapi/proxy/ppb_cursor_control_proxy.cc index 75c3c3a..f1a89a2 100644 --- a/ppapi/proxy/ppb_cursor_control_proxy.cc +++ b/ppapi/proxy/ppb_cursor_control_proxy.cc @@ -1,11 +1,14 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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_cursor_control_proxy.h" +#include "ppapi/c/dev/pp_cursor_type_dev.h" #include "ppapi/c/dev/ppb_cursor_control_dev.h" #include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" namespace pp { @@ -21,11 +24,24 @@ PP_Bool SetCursor(PP_Instance instance_id, if (!dispatcher) return PP_FALSE; + // It's legal for the image ID to be null if the type is not custom. + HostResource cursor_image_resource; + if (type == PP_CURSORTYPE_CUSTOM) { + PluginResource* cursor_image = PluginResourceTracker::GetInstance()-> + GetResourceObject(custom_image_id); + if (!cursor_image || cursor_image->instance() != instance_id) + return PP_FALSE; + cursor_image_resource = cursor_image->host_resource(); + } else { + if (custom_image_id) + return PP_FALSE; // Image specified for a predefined type. + } + PP_Bool result = PP_FALSE; PP_Point empty_point = { 0, 0 }; dispatcher->Send(new PpapiHostMsg_PPBCursorControl_SetCursor( INTERFACE_ID_PPB_CURSORCONTROL, - instance_id, static_cast<int32_t>(type), custom_image_id, + instance_id, static_cast<int32_t>(type), cursor_image_resource, hot_spot ? *hot_spot : empty_point, &result)); return result; } @@ -121,11 +137,12 @@ bool PPB_CursorControl_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_CursorControl_Proxy::OnMsgSetCursor(PP_Instance instance, int32_t type, - PP_Resource custom_image, + HostResource custom_image, const PP_Point& hot_spot, PP_Bool* result) { *result = ppb_cursor_control_target()->SetCursor( - instance, static_cast<PP_CursorType_Dev>(type), custom_image, &hot_spot); + instance, static_cast<PP_CursorType_Dev>(type), + custom_image.host_resource(), &hot_spot); } void PPB_CursorControl_Proxy::OnMsgLockCursor(PP_Instance instance, diff --git a/ppapi/proxy/ppb_cursor_control_proxy.h b/ppapi/proxy/ppb_cursor_control_proxy.h index 033e6c1..00f82ac 100644 --- a/ppapi/proxy/ppb_cursor_control_proxy.h +++ b/ppapi/proxy/ppb_cursor_control_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -10,6 +10,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_point.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PPB_CursorControl_Dev; @@ -35,7 +36,7 @@ class PPB_CursorControl_Proxy : public InterfaceProxy { // Message handlers. void OnMsgSetCursor(PP_Instance instance, int32_t type, - PP_Resource custom_image, + HostResource custom_image, const PP_Point& hot_spot, PP_Bool* result); void OnMsgLockCursor(PP_Instance instance, diff --git a/ppapi/proxy/ppb_flash_proxy.cc b/ppapi/proxy/ppb_flash_proxy.cc index 014cea3..6ff1cb5 100644 --- a/ppapi/proxy/ppb_flash_proxy.cc +++ b/ppapi/proxy/ppb_flash_proxy.cc @@ -67,13 +67,22 @@ PP_Bool DrawGlyphs(PP_Instance instance, uint32_t glyph_count, const uint16_t glyph_indices[], const PP_Point glyph_advances[]) { - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + PluginResource* image_data = PluginResourceTracker::GetInstance()-> + GetResourceObject(pp_image_data); + if (!image_data) + return PP_FALSE; + // The instance parameter isn't strictly necessary but we check that it + // matches anyway. + if (image_data->instance() != instance) + return PP_FALSE; + + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( + image_data->instance()); if (!dispatcher) return PP_FALSE; PPBFlash_DrawGlyphs_Params params; - params.instance = instance, - params.pp_image_data = pp_image_data; + params.image_data = image_data->host_resource(); params.font_desc.SetFromPPFontDescription(dispatcher, *font_desc, true); params.color = color; params.position = position; @@ -305,8 +314,9 @@ void PPB_Flash_Proxy::OnMsgDrawGlyphs( return; *result = ppb_flash_target()->DrawGlyphs( - params.instance, params.pp_image_data, &font_desc, params.color, - params.position, params.clip, + 0, // Unused instance param. + params.image_data.host_resource(), &font_desc, + params.color, params.position, params.clip, const_cast<float(*)[3]>(params.transformation), static_cast<uint32_t>(params.glyph_indices.size()), const_cast<uint16_t*>(¶ms.glyph_indices[0]), diff --git a/ppapi/proxy/ppb_font_proxy.cc b/ppapi/proxy/ppb_font_proxy.cc index 5c9dfb9..1bbfcf0 100644 --- a/ppapi/proxy/ppb_font_proxy.cc +++ b/ppapi/proxy/ppb_font_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -14,7 +14,7 @@ namespace proxy { class Font : public PluginResource { public: - Font(PP_Instance instance); + Font(const HostResource& resource); virtual ~Font(); // PluginResource overrides. @@ -31,7 +31,7 @@ class Font : public PluginResource { DISALLOW_COPY_AND_ASSIGN(Font); }; -Font::Font(PP_Instance instance) : PluginResource(instance) { +Font::Font(const HostResource& resource) : PluginResource(resource) { memset(&desc_, 0, sizeof(PP_FontDescription_Dev)); desc_.face.type = PP_VARTYPE_UNDEFINED; memset(&metrics_, 0, sizeof(PP_FontMetrics_Dev)); @@ -52,17 +52,17 @@ PP_Resource Create(PP_Instance instance, SerializedFontDescription in_description; in_description.SetFromPPFontDescription(dispatcher, *description, true); - PP_Resource result; + HostResource result; SerializedFontDescription out_description; std::string out_metrics; dispatcher->Send(new PpapiHostMsg_PPBFont_Create( INTERFACE_ID_PPB_FONT, instance, in_description, &result, &out_description, &out_metrics)); - if (!result) + if (result.is_null()) return 0; // Failure creating font. - linked_ptr<Font> object(new Font(instance)); + linked_ptr<Font> object(new Font(result)); out_description.SetToPPFontDescription(dispatcher, object->desc_ptr(), true); // Convert the metrics, this is just serialized as a string of bytes. @@ -70,8 +70,7 @@ PP_Resource Create(PP_Instance instance, return 0; memcpy(&object->metrics(), out_metrics.data(), sizeof(PP_FontMetrics_Dev)); - PluginResourceTracker::GetInstance()->AddResource(result, object); - return result; + return PluginResourceTracker::GetInstance()->AddResource(object); } PP_Bool IsFont(PP_Resource resource) { @@ -102,13 +101,19 @@ PP_Bool DrawTextAt(PP_Resource font_id, uint32_t color, const PP_Rect* clip, PP_Bool image_data_is_opaque) { - Font* object = PluginResource::GetAs<Font>(font_id); - if (!object) + Font* font_object = PluginResource::GetAs<Font>(font_id); + if (!font_object) + return PP_FALSE; + PluginResource* image_object = PluginResourceTracker::GetInstance()-> + GetResourceObject(image_data); + if (!image_object) + return PP_FALSE; + if (font_object->instance() != image_object->instance()) return PP_FALSE; PPBFont_DrawTextAt_Params params; - params.font = font_id; - params.image_data = image_data; + params.font = font_object->host_resource(); + params.image_data = image_object->host_resource(); params.text_is_rtl = text->rtl; params.override_direction = text->override_direction; params.position = *position; @@ -122,7 +127,8 @@ PP_Bool DrawTextAt(PP_Resource font_id, } params.image_data_is_opaque = image_data_is_opaque; - Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); + Dispatcher* dispatcher = PluginDispatcher::GetForInstance( + image_object->instance()); PP_Bool result = PP_FALSE; if (dispatcher) { dispatcher->Send(new PpapiHostMsg_PPBFont_DrawTextAt( @@ -141,7 +147,7 @@ int32_t MeasureText(PP_Resource font_id, const PP_TextRun_Dev* text) { Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); int32_t result = 0; dispatcher->Send(new PpapiHostMsg_PPBFont_MeasureText( - INTERFACE_ID_PPB_FONT, font_id, + INTERFACE_ID_PPB_FONT, object->host_resource(), SerializedVarSendInput(dispatcher, text->text), text->rtl, text->override_direction, &result)); return result; @@ -157,7 +163,7 @@ uint32_t CharacterOffsetForPixel(PP_Resource font_id, Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); uint32_t result = 0; dispatcher->Send(new PpapiHostMsg_PPBFont_CharacterOffsetForPixel( - INTERFACE_ID_PPB_FONT, font_id, + INTERFACE_ID_PPB_FONT, object->host_resource(), SerializedVarSendInput(dispatcher, text->text), text->rtl, text->override_direction, pixel_position, &result)); return result; @@ -173,7 +179,7 @@ int32_t PixelOffsetForCharacter(PP_Resource font_id, Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); int32_t result = 0; dispatcher->Send(new PpapiHostMsg_PPBFont_PixelOffsetForCharacter( - INTERFACE_ID_PPB_FONT, font_id, + INTERFACE_ID_PPB_FONT, object->host_resource(), SerializedVarSendInput(dispatcher, text->text), text->rtl, text->override_direction, char_offset, &result)); return result; @@ -228,7 +234,7 @@ bool PPB_Font_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_Font_Proxy::OnMsgCreate( PP_Instance instance, const SerializedFontDescription& in_description, - PP_Resource* result, + HostResource* result, SerializedFontDescription* out_description, std::string* out_metrics) { // Convert the face name in the input description. @@ -241,11 +247,13 @@ void PPB_Font_Proxy::OnMsgCreate( memset(&out_pp_desc, 0, sizeof(PP_FontDescription_Dev)); out_pp_desc.face = PP_MakeUndefined(); - *result = ppb_font_target()->Create(instance, &in_pp_desc); - if (*result) { + result->SetHostResource(instance, + ppb_font_target()->Create(instance, &in_pp_desc)); + if (result->is_null()) { // Get the metrics and resulting description to return to the browser. PP_FontMetrics_Dev metrics; - if (ppb_font_target()->Describe(*result, &out_pp_desc, &metrics)) { + if (ppb_font_target()->Describe(result->host_resource(), &out_pp_desc, + &metrics)) { out_metrics->assign(reinterpret_cast<const char*>(&metrics), sizeof(PP_FontMetrics_Dev)); } @@ -264,12 +272,12 @@ void PPB_Font_Proxy::OnMsgDrawTextAt(SerializedVarReceiveInput text, run.rtl = params.text_is_rtl; run.override_direction = params.override_direction; - *result = ppb_font_target()->DrawTextAt(params.font, params.image_data, - &run, ¶ms.position, params.color, + *result = ppb_font_target()->DrawTextAt(params.font.host_resource(), + params.image_data.host_resource(), &run, ¶ms.position, params.color, params.clip_is_null ? NULL : ¶ms.clip, params.image_data_is_opaque); } -void PPB_Font_Proxy::OnMsgMeasureText(PP_Resource font, +void PPB_Font_Proxy::OnMsgMeasureText(HostResource font, SerializedVarReceiveInput text, PP_Bool text_is_rtl, PP_Bool override_direction, @@ -279,11 +287,11 @@ void PPB_Font_Proxy::OnMsgMeasureText(PP_Resource font, run.rtl = text_is_rtl; run.override_direction = override_direction; - *result = ppb_font_target()->MeasureText(font, &run); + *result = ppb_font_target()->MeasureText(font.host_resource(), &run); } void PPB_Font_Proxy::OnMsgCharacterOffsetForPixel( - PP_Resource font, + HostResource font, SerializedVarReceiveInput text, PP_Bool text_is_rtl, PP_Bool override_direction, @@ -294,11 +302,12 @@ void PPB_Font_Proxy::OnMsgCharacterOffsetForPixel( run.rtl = text_is_rtl; run.override_direction = override_direction; - *result = ppb_font_target()->CharacterOffsetForPixel(font, &run, pixel_pos); + *result = ppb_font_target()->CharacterOffsetForPixel(font.host_resource(), + &run, pixel_pos); } void PPB_Font_Proxy::OnMsgPixelOffsetForCharacter( - PP_Resource font, + HostResource font, SerializedVarReceiveInput text, PP_Bool text_is_rtl, PP_Bool override_direction, @@ -309,7 +318,8 @@ void PPB_Font_Proxy::OnMsgPixelOffsetForCharacter( run.rtl = text_is_rtl; run.override_direction = override_direction; - *result = ppb_font_target()->PixelOffsetForCharacter(font, &run, char_offset); + *result = ppb_font_target()->PixelOffsetForCharacter(font.host_resource(), + &run, char_offset); } } // namespace proxy diff --git a/ppapi/proxy/ppb_font_proxy.h b/ppapi/proxy/ppb_font_proxy.h index 322af80..1afe36f 100644 --- a/ppapi/proxy/ppb_font_proxy.h +++ b/ppapi/proxy/ppb_font_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PPB_Font_Dev; @@ -37,24 +38,24 @@ class PPB_Font_Proxy : public InterfaceProxy { // Message handlers. void OnMsgCreate(PP_Instance instance, const SerializedFontDescription& in_description, - PP_Resource* result, + HostResource* result, SerializedFontDescription* out_description, std::string* out_metrics); void OnMsgDrawTextAt(SerializedVarReceiveInput text, const PPBFont_DrawTextAt_Params& params, PP_Bool* result); - void OnMsgMeasureText(PP_Resource font, + void OnMsgMeasureText(HostResource font, SerializedVarReceiveInput text, PP_Bool text_is_rtl, PP_Bool override_direction, int32_t* result); - void OnMsgCharacterOffsetForPixel(PP_Resource font, + void OnMsgCharacterOffsetForPixel(HostResource font, SerializedVarReceiveInput text, PP_Bool text_is_rtl, PP_Bool override_direction, int32_t pixel_pos, uint32_t* result); - void OnMsgPixelOffsetForCharacter(PP_Resource font, + void OnMsgPixelOffsetForCharacter(HostResource font, SerializedVarReceiveInput text, PP_Bool text_is_rtl, PP_Bool override_direction, diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.cc b/ppapi/proxy/ppb_graphics_2d_proxy.cc index 143ec44..be98e1d 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.cc +++ b/ppapi/proxy/ppb_graphics_2d_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -21,14 +21,16 @@ namespace proxy { class Graphics2D : public PluginResource { public: - Graphics2D(PP_Instance instance, + Graphics2D(const HostResource& host_resource, const PP_Size& size, PP_Bool is_always_opaque) - : PluginResource(instance), + : PluginResource(host_resource), size_(size), is_always_opaque_(is_always_opaque), current_flush_callback_(PP_BlockUntilComplete()) { } + virtual ~Graphics2D() { + } // Resource overrides. virtual Graphics2D* AsGraphics2D() { return this; } @@ -65,16 +67,15 @@ PP_Resource Create(PP_Instance instance, if (!dispatcher) return PP_ERROR_BADARGUMENT; - PP_Resource result = 0; + HostResource result; dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Create( INTERFACE_ID_PPB_GRAPHICS_2D, instance, *size, is_always_opaque, &result)); - if (result) { - linked_ptr<Graphics2D> graphics_2d(new Graphics2D(instance, *size, - is_always_opaque)); - PluginResourceTracker::GetInstance()->AddResource(result, graphics_2d); - } - return result; + if (result.is_null()) + return 0; + linked_ptr<Graphics2D> graphics_2d(new Graphics2D(result, *size, + is_always_opaque)); + return PluginResourceTracker::GetInstance()->AddResource(graphics_2d); } PP_Bool IsGraphics2D(PP_Resource resource) { @@ -102,19 +103,27 @@ void PaintImageData(PP_Resource graphics_2d, PP_Resource image_data, const PP_Point* top_left, const PP_Rect* src_rect) { - Graphics2D* object = PluginResource::GetAs<Graphics2D>(graphics_2d); - if (!object) + Graphics2D* graphics_object = PluginResource::GetAs<Graphics2D>(graphics_2d); + if (!graphics_object) + return; + PluginResource* image_object = PluginResourceTracker::GetInstance()-> + GetResourceObject(image_data); + if (!image_object) return; + if (graphics_object->instance() != image_object->instance()) + return; + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - object->instance()); + graphics_object->instance()); if (!dispatcher) return; PP_Rect dummy; memset(&dummy, 0, sizeof(PP_Rect)); dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_PaintImageData( - INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, image_data, *top_left, - !!src_rect, src_rect ? *src_rect : dummy)); + INTERFACE_ID_PPB_GRAPHICS_2D, graphics_object->host_resource(), + image_object->host_resource(), *top_left, !!src_rect, + src_rect ? *src_rect : dummy)); } void Scroll(PP_Resource graphics_2d, @@ -131,21 +140,29 @@ void Scroll(PP_Resource graphics_2d, PP_Rect dummy; memset(&dummy, 0, sizeof(PP_Rect)); dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Scroll( - INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, !!clip_rect, - clip_rect ? *clip_rect : dummy, *amount)); + INTERFACE_ID_PPB_GRAPHICS_2D, object->host_resource(), + !!clip_rect, clip_rect ? *clip_rect : dummy, *amount)); } void ReplaceContents(PP_Resource graphics_2d, PP_Resource image_data) { - Graphics2D* object = PluginResource::GetAs<Graphics2D>(graphics_2d); - if (!object) + Graphics2D* graphics_object = PluginResource::GetAs<Graphics2D>(graphics_2d); + if (!graphics_object) + return; + PluginResource* image_object = PluginResourceTracker::GetInstance()-> + GetResourceObject(image_data); + if (!image_object) return; + if (graphics_object->instance() != image_object->instance()) + return; + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - object->instance()); + graphics_object->instance()); if (!dispatcher) return; dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_ReplaceContents( - INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, image_data)); + INTERFACE_ID_PPB_GRAPHICS_2D, graphics_object->host_resource(), + image_object->host_resource())); } int32_t Flush(PP_Resource graphics_2d, @@ -168,7 +185,7 @@ int32_t Flush(PP_Resource graphics_2d, object->set_current_flush_callback(callback); dispatcher->Send(new PpapiHostMsg_PPBGraphics2D_Flush( - INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d)); + INTERFACE_ID_PPB_GRAPHICS_2D, object->host_resource())); return PP_ERROR_WOULDBLOCK; } @@ -226,40 +243,42 @@ bool PPB_Graphics2D_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_Graphics2D_Proxy::OnMsgCreate(PP_Instance instance, const PP_Size& size, PP_Bool is_always_opaque, - PP_Resource* result) { - *result = ppb_graphics_2d_target()->Create( - instance, &size, is_always_opaque); + HostResource* result) { + result->SetHostResource(instance, ppb_graphics_2d_target()->Create( + instance, &size, is_always_opaque)); } -void PPB_Graphics2D_Proxy::OnMsgPaintImageData(PP_Resource graphics_2d, - PP_Resource image_data, - const PP_Point& top_left, - bool src_rect_specified, - const PP_Rect& src_rect) { +void PPB_Graphics2D_Proxy::OnMsgPaintImageData( + const HostResource& graphics_2d, + const HostResource& image_data, + const PP_Point& top_left, + bool src_rect_specified, + const PP_Rect& src_rect) { ppb_graphics_2d_target()->PaintImageData( - graphics_2d, image_data, &top_left, + graphics_2d.host_resource(), image_data.host_resource(), &top_left, src_rect_specified ? &src_rect : NULL); } -void PPB_Graphics2D_Proxy::OnMsgScroll(PP_Resource graphics_2d, +void PPB_Graphics2D_Proxy::OnMsgScroll(const HostResource& graphics_2d, bool clip_specified, const PP_Rect& clip, const PP_Point& amount) { - ppb_graphics_2d_target()->Scroll( - graphics_2d, - clip_specified ? &clip : NULL, &amount); + ppb_graphics_2d_target()->Scroll(graphics_2d.host_resource(), + clip_specified ? &clip : NULL, &amount); } -void PPB_Graphics2D_Proxy::OnMsgReplaceContents(PP_Resource graphics_2d, - PP_Resource image_data) { - ppb_graphics_2d_target()->ReplaceContents(graphics_2d, image_data); +void PPB_Graphics2D_Proxy::OnMsgReplaceContents( + const HostResource& graphics_2d, + const HostResource& image_data) { + ppb_graphics_2d_target()->ReplaceContents(graphics_2d.host_resource(), + image_data.host_resource()); } -void PPB_Graphics2D_Proxy::OnMsgFlush(PP_Resource graphics_2d) { +void PPB_Graphics2D_Proxy::OnMsgFlush(const HostResource& graphics_2d) { CompletionCallback callback = callback_factory_.NewCallback( &PPB_Graphics2D_Proxy::SendFlushACKToPlugin, graphics_2d); int32_t result = ppb_graphics_2d_target()->Flush( - graphics_2d, callback.pp_completion_callback()); + graphics_2d.host_resource(), callback.pp_completion_callback()); if (result != PP_ERROR_WOULDBLOCK) { // There was some error, so we won't get a flush callback. We need to now // issue the ACK to the plugin hears about the error. This will also clean @@ -268,9 +287,15 @@ void PPB_Graphics2D_Proxy::OnMsgFlush(PP_Resource graphics_2d) { } } -void PPB_Graphics2D_Proxy::OnMsgFlushACK(PP_Resource resource, +void PPB_Graphics2D_Proxy::OnMsgFlushACK(const HostResource& host_resource, int32_t pp_error) { - Graphics2D* object = PluginResource::GetAs<Graphics2D>(resource); + PP_Resource plugin_resource = + PluginResourceTracker::GetInstance()->PluginResourceForHostResource( + host_resource); + if (!plugin_resource) + return; + + Graphics2D* object = PluginResource::GetAs<Graphics2D>(plugin_resource); if (!object) { // The plugin has released the graphics 2D object so don't issue the // callback. @@ -284,8 +309,9 @@ void PPB_Graphics2D_Proxy::OnMsgFlushACK(PP_Resource resource, PP_RunCompletionCallback(&callback, pp_error); } -void PPB_Graphics2D_Proxy::SendFlushACKToPlugin(int32_t result, - PP_Resource graphics_2d) { +void PPB_Graphics2D_Proxy::SendFlushACKToPlugin( + int32_t result, + const HostResource& graphics_2d) { dispatcher()->Send(new PpapiMsg_PPBGraphics2D_FlushACK( INTERFACE_ID_PPB_GRAPHICS_2D, graphics_2d, result)); } diff --git a/ppapi/proxy/ppb_graphics_2d_proxy.h b/ppapi/proxy/ppb_graphics_2d_proxy.h index 96d3277..0e9400f 100644 --- a/ppapi/proxy/ppb_graphics_2d_proxy.h +++ b/ppapi/proxy/ppb_graphics_2d_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -13,6 +13,7 @@ #include "ppapi/c/pp_size.h" #include "ppapi/c/pp_var.h" #include "ppapi/cpp/completion_callback.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" @@ -42,25 +43,27 @@ class PPB_Graphics2D_Proxy : public InterfaceProxy { void OnMsgCreate(PP_Module module, const PP_Size& size, PP_Bool is_always_opaque, - PP_Resource* result); - void OnMsgPaintImageData(PP_Resource graphics_2d, - PP_Resource image_data, + HostResource* result); + void OnMsgPaintImageData(const HostResource& graphics_2d, + const HostResource& image_data, const PP_Point& top_left, bool src_rect_specified, const PP_Rect& src_rect); - void OnMsgScroll(PP_Resource graphics_2d, + void OnMsgScroll(const HostResource& graphics_2d, bool clip_specified, const PP_Rect& clip, const PP_Point& amount); - void OnMsgReplaceContents(PP_Resource graphics_2d, - PP_Resource image_data); - void OnMsgFlush(PP_Resource graphics_2d); + void OnMsgReplaceContents(const HostResource& graphics_2d, + const HostResource& image_data); + void OnMsgFlush(const HostResource& graphics_2d); // Renderer->plugin message handlers. - void OnMsgFlushACK(PP_Resource graphics_2d, int32_t pp_error); + void OnMsgFlushACK(const HostResource& graphics_2d, + int32_t pp_error); // Called in the renderer to send the given flush ACK to the plugin. - void SendFlushACKToPlugin(int32_t result, PP_Resource graphics_2d); + void SendFlushACKToPlugin(int32_t result, + const HostResource& graphics_2d); CompletionCallbackFactory<PPB_Graphics2D_Proxy, ProxyNonThreadSafeRefCount> callback_factory_; diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc index 386add9..18b4614 100644 --- a/ppapi/proxy/ppb_image_data_proxy.cc +++ b/ppapi/proxy/ppb_image_data_proxy.cc @@ -14,14 +14,128 @@ #include "ppapi/c/pp_errors.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/trusted/ppb_image_data_trusted.h" -#include "ppapi/proxy/image_data.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/shared_impl/image_data_impl.h" + +#if defined(OS_LINUX) +#include <sys/shm.h> +#elif defined(OS_MACOSX) +#include <sys/stat.h> +#include <sys/mman.h> +#endif namespace pp { namespace proxy { +class ImageData : public PluginResource, + public pp::shared_impl::ImageDataImpl { + public: + ImageData(const HostResource& resource, + const PP_ImageDataDesc& desc, + ImageHandle handle); + virtual ~ImageData(); + + // Resource overrides. + virtual ImageData* AsImageData(); + + void* Map(); + void Unmap(); + + const PP_ImageDataDesc& desc() const { return desc_; } + + static const ImageHandle NullHandle; + static ImageHandle HandleFromInt(int32_t i); + + private: + PP_ImageDataDesc desc_; + ImageHandle handle_; + + void* mapped_data_; + + DISALLOW_COPY_AND_ASSIGN(ImageData); +}; + +ImageData::ImageData(const HostResource& resource, + const PP_ImageDataDesc& desc, + ImageHandle handle) + : PluginResource(resource), + desc_(desc), + handle_(handle), + mapped_data_(NULL) { +} + +ImageData::~ImageData() { + Unmap(); +} + +ImageData* ImageData::AsImageData() { + return this; +} + +void* ImageData::Map() { +#if defined(OS_WIN) + NOTIMPLEMENTED(); + return NULL; +#elif defined(OS_MACOSX) + struct stat st; + if (fstat(handle_.fd, &st) != 0) + return NULL; + void* memory = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, handle_.fd, 0); + if (memory == MAP_FAILED) + return NULL; + mapped_data_ = memory; + return mapped_data_; +#else + int shmkey = handle_; + void* address = shmat(shmkey, NULL, 0); + // Mark for deletion in case we crash so the kernel will clean it up. + shmctl(shmkey, IPC_RMID, 0); + if (address == (void*)-1) + return NULL; + mapped_data_ = address; + return address; +#endif +} + +void ImageData::Unmap() { +#if defined(OS_WIN) + NOTIMPLEMENTED(); +#elif defined(OS_MACOSX) + if (mapped_data_) { + struct stat st; + if (fstat(handle_.fd, &st) == 0) + munmap(mapped_data_, st.st_size); + } +#else + if (mapped_data_) + shmdt(mapped_data_); +#endif + mapped_data_ = NULL; +} + +#if defined(OS_WIN) +const ImageHandle ImageData::NullHandle = NULL; +#elif defined(OS_MACOSX) +const ImageHandle ImageData::NullHandle = ImageHandle(); +#else +const ImageHandle ImageData::NullHandle = 0; +#endif + +ImageHandle ImageData::HandleFromInt(int32_t i) { +#if defined(OS_WIN) + return reinterpret_cast<ImageHandle>(i); +#elif defined(OS_MACOSX) + return ImageHandle(i, false); +#else + return static_cast<ImageHandle>(i); +#endif +} + namespace { PP_ImageDataFormat GetNativeImageDataFormat() { @@ -40,22 +154,22 @@ PP_Resource Create(PP_Instance instance, if (!dispatcher) return PP_ERROR_BADARGUMENT; - PP_Resource result = 0; + HostResource result; std::string image_data_desc; ImageHandle image_handle = ImageData::NullHandle; dispatcher->Send(new PpapiHostMsg_PPBImageData_Create( INTERFACE_ID_PPB_IMAGE_DATA, instance, format, *size, init_to_zero, &result, &image_data_desc, &image_handle)); - if (result && image_data_desc.size() == sizeof(PP_ImageDataDesc)) { - // We serialize the PP_ImageDataDesc just by copying to a string. - PP_ImageDataDesc desc; - memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); + if (result.is_null() || image_data_desc.size() != sizeof(PP_ImageDataDesc)) + return 0; - linked_ptr<ImageData> object(new ImageData(instance, desc, image_handle)); - PluginResourceTracker::GetInstance()->AddResource(result, object); - } - return result; + // We serialize the PP_ImageDataDesc just by copying to a string. + PP_ImageDataDesc desc; + memcpy(&desc, image_data_desc.data(), sizeof(PP_ImageDataDesc)); + + linked_ptr<ImageData> object(new ImageData(result, desc, image_handle)); + return PluginResourceTracker::GetInstance()->AddResource(object); } PP_Bool IsImageData(PP_Resource resource) { @@ -126,16 +240,16 @@ void PPB_ImageData_Proxy::OnMsgCreate(PP_Instance instance, int32_t format, const PP_Size& size, PP_Bool init_to_zero, - PP_Resource* result, + HostResource* result, std::string* image_data_desc, ImageHandle* result_image_handle) { - *result = ppb_image_data_target()->Create( + PP_Resource resource = ppb_image_data_target()->Create( instance, static_cast<PP_ImageDataFormat>(format), &size, init_to_zero); *result_image_handle = ImageData::NullHandle; - if (*result) { + if (resource) { // The ImageDesc is just serialized as a string. PP_ImageDataDesc desc; - if (ppb_image_data_target()->Describe(*result, &desc)) { + if (ppb_image_data_target()->Describe(resource, &desc)) { image_data_desc->resize(sizeof(PP_ImageDataDesc)); memcpy(&(*image_data_desc)[0], &desc, sizeof(PP_ImageDataDesc)); } @@ -147,9 +261,11 @@ void PPB_ImageData_Proxy::OnMsgCreate(PP_Instance instance, uint32_t byte_count = 0; if (trusted) { int32_t handle; - if (trusted->GetSharedMemory(*result, &handle, &byte_count) == PP_OK) + if (trusted->GetSharedMemory(resource, &handle, &byte_count) == PP_OK) *result_image_handle = ImageData::HandleFromInt(handle); } + + result->SetHostResource(instance, resource); } } diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h index 5a0d076..62f83fd 100644 --- a/ppapi/proxy/ppb_image_data_proxy.h +++ b/ppapi/proxy/ppb_image_data_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -7,19 +7,21 @@ #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_completion_callback.h" +#include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_module.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_size.h" #include "ppapi/c/pp_var.h" #include "ppapi/proxy/interface_proxy.h" -#include "ppapi/proxy/image_data.h" - +#include "ppapi/proxy/serialized_structs.h" struct PPB_ImageData; namespace pp { namespace proxy { +class HostResource; + class PPB_ImageData_Proxy : public InterfaceProxy { public: PPB_ImageData_Proxy(Dispatcher* dispatcher, const void* target_interface); @@ -42,7 +44,7 @@ class PPB_ImageData_Proxy : public InterfaceProxy { int32_t format, const PP_Size& size, PP_Bool init_to_zero, - PP_Resource* result, + HostResource* result, std::string* image_data_desc, ImageHandle* result_image_handle); }; diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index 8962292..d17e17b 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -7,6 +7,8 @@ #include "ppapi/c/pp_var.h" #include "ppapi/c/ppb_instance.h" #include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/serialized_var.h" @@ -42,9 +44,15 @@ PP_Bool BindGraphics(PP_Instance instance, PP_Resource device) { if (!dispatcher) return PP_FALSE; + PluginResource* object = + PluginResourceTracker::GetInstance()->GetResourceObject(device); + if (!object || object->instance() != instance) + return PP_FALSE; + PP_Bool result = PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBInstance_BindGraphics( - INTERFACE_ID_PPB_INSTANCE, instance, device, &result)); + INTERFACE_ID_PPB_INSTANCE, instance, object->host_resource(), + &result)); return result; } @@ -134,9 +142,10 @@ void PPB_Instance_Proxy::OnMsgGetOwnerElementObject( } void PPB_Instance_Proxy::OnMsgBindGraphics(PP_Instance instance, - PP_Resource device, + HostResource device, PP_Bool* result) { - *result = ppb_instance_target()->BindGraphics(instance, device); + *result = ppb_instance_target()->BindGraphics(instance, + device.host_resource()); } void PPB_Instance_Proxy::OnMsgIsFullFrame(PP_Instance instance, diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h index b01e9b0..4a73d5c 100644 --- a/ppapi/proxy/ppb_instance_proxy.h +++ b/ppapi/proxy/ppb_instance_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -8,6 +8,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PPB_Instance; @@ -40,7 +41,7 @@ class PPB_Instance_Proxy : public InterfaceProxy { void OnMsgGetOwnerElementObject(PP_Instance instance, SerializedVarReturnValue result); void OnMsgBindGraphics(PP_Instance instance, - PP_Resource device, + HostResource device, PP_Bool* result); void OnMsgIsFullFrame(PP_Instance instance, PP_Bool* result); void OnMsgExecuteScript(PP_Instance instance, diff --git a/ppapi/proxy/ppb_pdf_proxy.cc b/ppapi/proxy/ppb_pdf_proxy.cc index 7ad8326..e3c656f 100644 --- a/ppapi/proxy/ppb_pdf_proxy.cc +++ b/ppapi/proxy/ppb_pdf_proxy.cc @@ -22,7 +22,8 @@ namespace proxy { class PrivateFontFile : public PluginResource { public: - PrivateFontFile(PP_Instance instance) : PluginResource(instance) {} + PrivateFontFile(const HostResource& resource) : PluginResource(resource) { + } virtual ~PrivateFontFile() {} // Resource overrides. @@ -68,15 +69,14 @@ PP_Resource GetFontFileWithFallback( SerializedFontDescription desc; desc.SetFromPPFontDescription(dispatcher, *description, true); - PP_Resource result = 0; + HostResource result; dispatcher->Send(new PpapiHostMsg_PPBPDF_GetFontFileWithFallback( INTERFACE_ID_PPB_PDF, instance, desc, charset, &result)); - if (!result) + if (result.is_null()) return 0; - linked_ptr<PrivateFontFile> object(new PrivateFontFile(instance)); - PluginResourceTracker::GetInstance()->AddResource(result, object); - return result; + linked_ptr<PrivateFontFile> object(new PrivateFontFile(result)); + return PluginResourceTracker::GetInstance()->AddResource(object); } bool GetFontTableForPrivateFontFile(PP_Resource font_file, @@ -95,7 +95,7 @@ bool GetFontTableForPrivateFontFile(PP_Resource font_file, if (!contents) { std::string deserialized; dispatcher->Send(new PpapiHostMsg_PPBPDF_GetFontTableForPrivateFontFile( - INTERFACE_ID_PPB_PDF, font_file, table, &deserialized)); + INTERFACE_ID_PPB_PDF, object->host_resource(), table, &deserialized)); if (deserialized.empty()) return false; contents = object->AddFontTable(table, deserialized); @@ -149,26 +149,28 @@ void PPB_PDF_Proxy::OnMsgGetFontFileWithFallback( PP_Instance instance, const SerializedFontDescription& in_desc, int32_t charset, - PP_Resource* result) { + HostResource* result) { PP_FontDescription_Dev desc; in_desc.SetToPPFontDescription(dispatcher(), &desc, false); - *result = ppb_pdf_target()->GetFontFileWithFallback(instance, &desc, - static_cast<PP_PrivateFontCharset>(charset)); + result->SetHostResource(instance, + ppb_pdf_target()->GetFontFileWithFallback( + instance, &desc, static_cast<PP_PrivateFontCharset>(charset))); } -void PPB_PDF_Proxy::OnMsgGetFontTableForPrivateFontFile(PP_Resource font_file, - uint32_t table, - std::string* result) { +void PPB_PDF_Proxy::OnMsgGetFontTableForPrivateFontFile( + const HostResource& font_file, + uint32_t table, + std::string* result) { // TODO(brettw): It would be nice not to copy here. At least on Linux, // we can map the font file into shared memory and read it that way. uint32_t table_length = 0; if (!ppb_pdf_target()->GetFontTableForPrivateFontFile( - font_file, table, NULL, &table_length)) + font_file.host_resource(), table, NULL, &table_length)) return; result->resize(table_length); - ppb_pdf_target()->GetFontTableForPrivateFontFile(font_file, table, - const_cast<char*>(result->c_str()), &table_length); + ppb_pdf_target()->GetFontTableForPrivateFontFile(font_file.host_resource(), + table, const_cast<char*>(result->c_str()), &table_length); } } // namespace proxy diff --git a/ppapi/proxy/ppb_pdf_proxy.h b/ppapi/proxy/ppb_pdf_proxy.h index 071a493..c0da291 100644 --- a/ppapi/proxy/ppb_pdf_proxy.h +++ b/ppapi/proxy/ppb_pdf_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -6,6 +6,7 @@ #define PPAPI_PPB_PDF_PROXY_H_ #include "ppapi/c/pp_module.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PPB_PDF; @@ -34,8 +35,8 @@ class PPB_PDF_Proxy : public InterfaceProxy { void OnMsgGetFontFileWithFallback(PP_Module module, const SerializedFontDescription& desc, int32_t charset, - PP_Resource* result); - void OnMsgGetFontTableForPrivateFontFile(PP_Resource font_file, + HostResource* result); + void OnMsgGetFontTableForPrivateFontFile(const HostResource& font_file, uint32_t table, std::string* result); }; diff --git a/ppapi/proxy/ppb_testing_proxy.cc b/ppapi/proxy/ppb_testing_proxy.cc index fc9b9b6..b65bae7 100644 --- a/ppapi/proxy/ppb_testing_proxy.cc +++ b/ppapi/proxy/ppb_testing_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -6,8 +6,9 @@ #include "base/message_loop.h" #include "ppapi/c/dev/ppb_testing_dev.h" -#include "ppapi/proxy/image_data.h" #include "ppapi/proxy/plugin_dispatcher.h" +#include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" namespace pp { @@ -15,12 +16,19 @@ namespace proxy { namespace { -PP_Bool ReadImageData(PP_Resource device_context_2d, +PP_Bool ReadImageData(PP_Resource graphics_2d, PP_Resource image, const PP_Point* top_left) { - ImageData* image_object = PluginResource::GetAs<ImageData>(image); + PluginResource* image_object = PluginResourceTracker::GetInstance()-> + GetResourceObject(image); if (!image_object) return PP_FALSE; + PluginResource* graphics_2d_object = + PluginResourceTracker::GetInstance()->GetResourceObject(graphics_2d); + if (!graphics_2d_object || + image_object->instance() != graphics_2d_object->instance()) + return PP_FALSE; + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( image_object->instance()); if (!dispatcher) @@ -28,7 +36,8 @@ PP_Bool ReadImageData(PP_Resource device_context_2d, PP_Bool result = PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBTesting_ReadImageData( - INTERFACE_ID_PPB_TESTING, device_context_2d, image, *top_left, &result)); + INTERFACE_ID_PPB_TESTING, graphics_2d_object->host_resource(), + image_object->host_resource(), *top_left, &result)); return result; } @@ -95,12 +104,13 @@ bool PPB_Testing_Proxy::OnMessageReceived(const IPC::Message& msg) { return handled; } -void PPB_Testing_Proxy::OnMsgReadImageData(PP_Resource device_context_2d, - PP_Resource image, - const PP_Point& top_left, - PP_Bool* result) { +void PPB_Testing_Proxy::OnMsgReadImageData( + const HostResource& device_context_2d, + const HostResource& image, + const PP_Point& top_left, + PP_Bool* result) { *result = ppb_testing_target()->ReadImageData( - device_context_2d, image, &top_left); + device_context_2d.host_resource(), image.host_resource(), &top_left); } void PPB_Testing_Proxy::OnMsgRunMessageLoop(bool* dummy) { @@ -113,7 +123,7 @@ void PPB_Testing_Proxy::OnMsgQuitMessageLoop() { } void PPB_Testing_Proxy::OnMsgGetLiveObjectsForInstance(PP_Instance instance, - uint32_t* result) { + uint32_t* result) { *result = ppb_testing_target()->GetLiveObjectsForInstance(instance); } diff --git a/ppapi/proxy/ppb_testing_proxy.h b/ppapi/proxy/ppb_testing_proxy.h index a878329..9133a2d 100644 --- a/ppapi/proxy/ppb_testing_proxy.h +++ b/ppapi/proxy/ppb_testing_proxy.h @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PP_Point; @@ -32,8 +33,8 @@ class PPB_Testing_Proxy : public InterfaceProxy { private: // Message handlers. - void OnMsgReadImageData(PP_Resource device_context_2d, - PP_Resource image, + void OnMsgReadImageData(const HostResource& device_context_2d, + const HostResource& image, const PP_Point& top_left, PP_Bool* result); void OnMsgRunMessageLoop(bool* dummy); diff --git a/ppapi/proxy/ppb_url_loader_proxy.cc b/ppapi/proxy/ppb_url_loader_proxy.cc index 24e327e..e2786b6 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.cc +++ b/ppapi/proxy/ppb_url_loader_proxy.cc @@ -16,6 +16,7 @@ #include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource.h" +#include "ppapi/proxy/plugin_resource_tracker.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_url_response_info_proxy.h" @@ -28,12 +29,14 @@ namespace proxy { class URLLoader : public PluginResource { public: - URLLoader(PP_Instance instance); + URLLoader(const HostResource& resource); virtual ~URLLoader(); // Resource overrides. virtual URLLoader* AsURLLoader() { return this; } + PP_Resource GetResponseInfo(); + // Initialized to -1. Will be set to nonnegative values by the UpdateProgress // message when the values are known. int64_t bytes_sent_; @@ -46,32 +49,63 @@ class URLLoader : public PluginResource { PP_CompletionCallback current_read_callback_; char* current_read_buffer_; + // Cached copy of the response info. When nonzero, we're holding a reference + // to this resource. + PP_Resource response_info_; + private: DISALLOW_COPY_AND_ASSIGN(URLLoader); }; -URLLoader::URLLoader(PP_Instance instance) - : PluginResource(instance), +URLLoader::URLLoader(const HostResource& resource) + : PluginResource(resource), bytes_sent_(-1), total_bytes_to_be_sent_(-1), bytes_received_(-1), total_bytes_to_be_received_(-1), current_read_callback_(PP_MakeCompletionCallback(NULL, NULL)), - current_read_buffer_(NULL) { + current_read_buffer_(NULL), + response_info_(0) { } URLLoader::~URLLoader() { + if (response_info_) + PluginResourceTracker::GetInstance()->ReleaseResource(response_info_); +} + +PP_Resource URLLoader::GetResponseInfo() { + if (!response_info_) { + PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance()); + if (!dispatcher) + return 0; + + HostResource response_id; + dispatcher->Send(new PpapiHostMsg_PPBURLLoader_GetResponseInfo( + INTERFACE_ID_PPB_URL_LOADER, host_resource(), &response_id)); + if (response_id.is_null()) + return 0; + + response_info_ = PPB_URLResponseInfo_Proxy::CreateResponseForResource( + response_id); + } + + // The caller expects to get a ref, and we want to keep holding ours. + PluginResourceTracker::GetInstance()->AddRefResource(response_info_); + return response_info_; } namespace { -// Converts the given loader ID to the dispatcher associated with it, or NULL -// if it couldn't be found. -PluginDispatcher* DispatcherFromURLLoader(PP_Resource loader_id) { - URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); - if (!object) - return NULL; - return PluginDispatcher::GetForInstance(object->instance()); +// Converts the given loader ID to the dispatcher associated with it and the +// loader object. Returns true if the object was found. +bool RoutingDataFromURLLoader(PP_Resource loader_id, + URLLoader** loader_object, + PluginDispatcher** dispatcher) { + *loader_object = PluginResource::GetAs<URLLoader>(loader_id); + if (!*loader_object) + return false; + *dispatcher = PluginDispatcher::GetForInstance((*loader_object)->instance()); + return !!*dispatcher; } // Plugin PPB_URLLoader implmentation ------------------------------------------ @@ -81,12 +115,12 @@ PP_Resource Create(PP_Instance instance_id) { if (!dispatcher) return 0; - PP_Resource result = 0; + HostResource result; dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Create( INTERFACE_ID_PPB_URL_LOADER, instance_id, &result)); - if (result) - PPB_URLLoader_Proxy::TrackPluginResource(instance_id, result); - return result; + if (result.is_null()) + return 0; + return PPB_URLLoader_Proxy::TrackPluginResource(result); } PP_Bool IsURLLoader(PP_Resource resource) { @@ -97,24 +131,31 @@ PP_Bool IsURLLoader(PP_Resource resource) { int32_t Open(PP_Resource loader_id, PP_Resource request_id, PP_CompletionCallback callback) { - PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); - if (!dispatcher) + URLLoader* loader_object; + PluginDispatcher* dispatcher; + if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) + return PP_ERROR_BADRESOURCE; + PluginResource* request_object = + PluginResourceTracker::GetInstance()->GetResourceObject(request_id); + if (!request_object) return PP_ERROR_BADRESOURCE; dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Open( - INTERFACE_ID_PPB_URL_LOADER, loader_id, request_id, + INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource(), + request_object->host_resource(), dispatcher->callback_tracker().SendCallback(callback))); return PP_ERROR_WOULDBLOCK; } int32_t FollowRedirect(PP_Resource loader_id, PP_CompletionCallback callback) { - PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); - if (!dispatcher) + URLLoader* loader_object; + PluginDispatcher* dispatcher; + if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) return PP_ERROR_BADRESOURCE; dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FollowRedirect( - INTERFACE_ID_PPB_URL_LOADER, loader_id, + INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource(), dispatcher->callback_tracker().SendCallback(callback))); return PP_ERROR_WOULDBLOCK; } @@ -151,46 +192,21 @@ PP_Resource GetResponseInfo(PP_Resource loader_id) { URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); if (!object) return 0; - - // If we find that plugins are frequently requesting the response info, we - // can improve performance by caching the PP_Resource in the URLLoader - // object. This way we only have to do IPC for the first request. However, - // it seems that most plugins will only call this once so there's no use - // optimizing this case. - - PP_Resource result; - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - object->instance()); - if (!dispatcher) - return PP_ERROR_BADRESOURCE; - - dispatcher->Send(new PpapiHostMsg_PPBURLLoader_GetResponseInfo( - INTERFACE_ID_PPB_URL_LOADER, loader_id, &result)); - if (PluginResourceTracker::GetInstance()-> - PreparePreviouslyTrackedResource(result)) - return result; - - // Tell the response info to create a tracking object and add it to the - // resource tracker. - PPB_URLResponseInfo_Proxy::TrackPluginResource(object->instance(), result); - return result; + return object->GetResponseInfo(); } int32_t ReadResponseBody(PP_Resource loader_id, char* buffer, int32_t bytes_to_read, PP_CompletionCallback callback) { - URLLoader* object = PluginResource::GetAs<URLLoader>(loader_id); - if (!object) - return PP_ERROR_BADRESOURCE; - PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance( - object->instance()); - if (!dispatcher) + URLLoader* loader_object; + PluginDispatcher* dispatcher; + if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) return PP_ERROR_BADRESOURCE; if (!buffer) return PP_ERROR_BADARGUMENT; // Must specify an output buffer. - if (object->current_read_callback_.func) + if (loader_object->current_read_callback_.func) return PP_ERROR_INPROGRESS; // Can only have one request pending. // Currently we don't support sync calls to read. We'll need to revisit @@ -198,33 +214,36 @@ int32_t ReadResponseBody(PP_Resource loader_id, if (!callback.func) return PP_ERROR_BADARGUMENT; - object->current_read_callback_ = callback; - object->current_read_buffer_ = buffer; + loader_object->current_read_callback_ = callback; + loader_object->current_read_buffer_ = buffer; dispatcher->Send(new PpapiHostMsg_PPBURLLoader_ReadResponseBody( - INTERFACE_ID_PPB_URL_LOADER, loader_id, bytes_to_read)); + INTERFACE_ID_PPB_URL_LOADER, + loader_object->host_resource(), bytes_to_read)); return PP_ERROR_WOULDBLOCK; } int32_t FinishStreamingToFile(PP_Resource loader_id, PP_CompletionCallback callback) { - PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); - if (!dispatcher) + URLLoader* loader_object; + PluginDispatcher* dispatcher; + if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) return PP_ERROR_BADRESOURCE; dispatcher->Send(new PpapiHostMsg_PPBURLLoader_FinishStreamingToFile( - INTERFACE_ID_PPB_URL_LOADER, loader_id, + INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource(), dispatcher->callback_tracker().SendCallback(callback))); return PP_ERROR_WOULDBLOCK; } void Close(PP_Resource loader_id) { - PluginDispatcher* dispatcher = DispatcherFromURLLoader(loader_id); - if (!dispatcher) + URLLoader* loader_object; + PluginDispatcher* dispatcher; + if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) return; dispatcher->Send(new PpapiHostMsg_PPBURLLoader_Close( - INTERFACE_ID_PPB_URL_LOADER, loader_id)); + INTERFACE_ID_PPB_URL_LOADER, loader_object->host_resource())); } const PPB_URLLoader ppb_urlloader = { @@ -242,10 +261,15 @@ const PPB_URLLoader ppb_urlloader = { // Plugin URLLoaderTrusted implementation -------------------------------------- -void GrantUniversalAccess(PP_Resource loader) { - PluginDispatcher::Get()->Send( +void GrantUniversalAccess(PP_Resource loader_id) { + URLLoader* loader_object; + PluginDispatcher* dispatcher; + if (!RoutingDataFromURLLoader(loader_id, &loader_object, &dispatcher)) + return; + + dispatcher->Send( new PpapiHostMsg_PPBURLLoaderTrusted_GrantUniversalAccess( - INTERFACE_ID_PPB_URL_LOADER_TRUSTED, loader)); + INTERFACE_ID_PPB_URL_LOADER_TRUSTED, loader_object->host_resource())); } const PPB_URLLoaderTrusted ppb_urlloader_trusted = { @@ -258,7 +282,7 @@ const PPB_URLLoaderTrusted ppb_urlloader_trusted = { // PPB_URLLoader_Proxy --------------------------------------------------------- struct PPB_URLLoader_Proxy::ReadCallbackInfo { - PP_Resource pp_resource; + HostResource resource; std::string read_buffer; }; @@ -272,11 +296,10 @@ PPB_URLLoader_Proxy::~PPB_URLLoader_Proxy() { } // static -void PPB_URLLoader_Proxy::TrackPluginResource(PP_Instance instance, - PP_Resource url_loader_resource) { - linked_ptr<URLLoader> object(new URLLoader(instance)); - PluginResourceTracker::GetInstance()->AddResource(url_loader_resource, - object); +PP_Resource PPB_URLLoader_Proxy::TrackPluginResource( + const HostResource& url_loader_resource) { + linked_ptr<URLLoader> object(new URLLoader(url_loader_resource)); + return PluginResourceTracker::GetInstance()->AddResource(object); } const void* PPB_URLLoader_Proxy::GetSourceInterface() const { @@ -316,37 +339,38 @@ bool PPB_URLLoader_Proxy::OnMessageReceived(const IPC::Message& msg) { } void PPB_URLLoader_Proxy::OnMsgCreate(PP_Instance instance, - PP_Resource* result) { - *result = ppb_url_loader_target()->Create(instance); + HostResource* result) { + result->SetHostResource(instance, ppb_url_loader_target()->Create(instance)); } -void PPB_URLLoader_Proxy::OnMsgOpen(PP_Resource loader, - PP_Resource request_info, +void PPB_URLLoader_Proxy::OnMsgOpen(const HostResource& loader, + const HostResource& request_info, uint32_t serialized_callback) { PP_CompletionCallback callback = ReceiveCallback(serialized_callback); int32_t result = ppb_url_loader_target()->Open( - loader, request_info, callback); + loader.host_resource(), request_info.host_resource(), callback); if (result != PP_ERROR_WOULDBLOCK) PP_RunCompletionCallback(&callback, result); } void PPB_URLLoader_Proxy::OnMsgFollowRedirect( - PP_Resource loader, + const HostResource& loader, uint32_t serialized_callback) { PP_CompletionCallback callback = ReceiveCallback(serialized_callback); int32_t result = ppb_url_loader_target()->FollowRedirect( - loader, callback); + loader.host_resource(), callback); if (result != PP_ERROR_WOULDBLOCK) PP_RunCompletionCallback(&callback, result); } -void PPB_URLLoader_Proxy::OnMsgGetResponseInfo(PP_Resource loader, - PP_Resource* result) { - *result = ppb_url_loader_target()->GetResponseInfo(loader); +void PPB_URLLoader_Proxy::OnMsgGetResponseInfo(const HostResource& loader, + HostResource* result) { + result->SetHostResource(loader.instance(), + ppb_url_loader_target()->GetResponseInfo(loader.host_resource())); } void PPB_URLLoader_Proxy::OnMsgReadResponseBody( - PP_Resource loader, + const HostResource& loader, int32_t bytes_to_read) { // The plugin could be sending us malicious messages, don't accept negative // sizes. @@ -361,15 +385,16 @@ void PPB_URLLoader_Proxy::OnMsgReadResponseBody( // destroyed. Depending on the cleanup ordering, we may not need the weak // pointer here.) ReadCallbackInfo* info = new ReadCallbackInfo; - info->pp_resource = loader; + info->resource = loader; + // TODO(brettw) have a way to check for out-of-memory. info->read_buffer.resize(bytes_to_read); CompletionCallback callback = callback_factory_.NewCallback( &PPB_URLLoader_Proxy::OnReadCallback, info); int32_t result = ppb_url_loader_target()->ReadResponseBody( - loader, const_cast<char*>(info->read_buffer.c_str()), bytes_to_read, - callback.pp_completion_callback()); + loader.host_resource(), const_cast<char*>(info->read_buffer.c_str()), + bytes_to_read, callback.pp_completion_callback()); if (result != PP_ERROR_WOULDBLOCK) { // Send error (or perhaps success for synchronous reads) back to plugin. // The callback function is already set up to do this and also delete the @@ -379,45 +404,50 @@ void PPB_URLLoader_Proxy::OnMsgReadResponseBody( } void PPB_URLLoader_Proxy::OnMsgFinishStreamingToFile( - PP_Resource loader, + const HostResource& loader, uint32_t serialized_callback) { PP_CompletionCallback callback = ReceiveCallback(serialized_callback); int32_t result = ppb_url_loader_target()->FinishStreamingToFile( - loader, callback); + loader.host_resource(), callback); if (result != PP_ERROR_WOULDBLOCK) PP_RunCompletionCallback(&callback, result); } -void PPB_URLLoader_Proxy::OnMsgClose(PP_Resource loader) { - ppb_url_loader_target()->Close(loader); +void PPB_URLLoader_Proxy::OnMsgClose(const HostResource& loader) { + ppb_url_loader_target()->Close(loader.host_resource()); } +// Called in the Plugin. void PPB_URLLoader_Proxy::OnMsgUpdateProgress( - PP_Resource resource, - int64_t bytes_sent, - int64_t total_bytes_to_be_sent, - int64_t bytes_received, - int64_t total_bytes_to_be_received) { - URLLoader* object = PluginResource::GetAs<URLLoader>(resource); - if (!object) { - NOTREACHED(); + const PPBURLLoader_UpdateProgress_Params& params) { + PP_Resource plugin_resource = + PluginResourceTracker::GetInstance()->PluginResourceForHostResource( + params.resource); + if (!plugin_resource) + return; + URLLoader* object = PluginResource::GetAs<URLLoader>(plugin_resource); + if (!object) return; - } - - object->bytes_sent_ = bytes_sent; - object->total_bytes_to_be_sent_ = total_bytes_to_be_sent; - object->bytes_received_ = bytes_received; - object->total_bytes_to_be_received_ = total_bytes_to_be_received; -} -void PPB_URLLoader_Proxy::OnMsgReadResponseBodyAck(PP_Resource pp_resource, - int32 result, - const std::string& data) { - URLLoader* object = PluginResource::GetAs<URLLoader>(pp_resource); - if (!object) { - NOTREACHED(); + object->bytes_sent_ = params.bytes_sent; + object->total_bytes_to_be_sent_ = params.total_bytes_to_be_sent; + object->bytes_received_ = params.bytes_received; + object->total_bytes_to_be_received_ = params.total_bytes_to_be_received; +} + +// Called in the Plugin. +void PPB_URLLoader_Proxy::OnMsgReadResponseBodyAck( + const HostResource& host_resource, + int32 result, + const std::string& data) { + PP_Resource plugin_resource = + PluginResourceTracker::GetInstance()->PluginResourceForHostResource( + host_resource); + if (!plugin_resource) + return; + URLLoader* object = PluginResource::GetAs<URLLoader>(plugin_resource); + if (!object) return; - } if (!object->current_read_callback_.func || !object->current_read_buffer_) { NOTREACHED(); @@ -444,8 +474,7 @@ void PPB_URLLoader_Proxy::OnReadCallback(int32_t result, info->read_buffer.resize(bytes_read); dispatcher()->Send(new PpapiMsg_PPBURLLoader_ReadResponseBody_Ack( - INTERFACE_ID_PPB_URL_LOADER, info->pp_resource, - result, info->read_buffer)); + INTERFACE_ID_PPB_URL_LOADER, info->resource, result, info->read_buffer)); delete info; } @@ -480,8 +509,9 @@ bool PPB_URLLoaderTrusted_Proxy::OnMessageReceived(const IPC::Message& msg) { return handled; } -void PPB_URLLoaderTrusted_Proxy::OnMsgGrantUniversalAccess(PP_Resource loader) { - ppb_url_loader_trusted_target()->GrantUniversalAccess(loader); +void PPB_URLLoaderTrusted_Proxy::OnMsgGrantUniversalAccess( + const HostResource& loader) { + ppb_url_loader_trusted_target()->GrantUniversalAccess(loader.host_resource()); } } // namespace proxy diff --git a/ppapi/proxy/ppb_url_loader_proxy.h b/ppapi/proxy/ppb_url_loader_proxy.h index c05926a..49f49ea 100644 --- a/ppapi/proxy/ppb_url_loader_proxy.h +++ b/ppapi/proxy/ppb_url_loader_proxy.h @@ -12,6 +12,7 @@ #include "ppapi/c/pp_size.h" #include "ppapi/c/pp_var.h" #include "ppapi/cpp/completion_callback.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" #include "ppapi/proxy/proxy_non_thread_safe_ref_count.h" @@ -21,6 +22,8 @@ struct PPB_URLLoaderTrusted; namespace pp { namespace proxy { +struct PPBURLLoader_UpdateProgress_Params; + class PPB_URLLoader_Proxy : public InterfaceProxy { public: PPB_URLLoader_Proxy(Dispatcher* dispatcher, const void* target_interface); @@ -30,8 +33,8 @@ class PPB_URLLoader_Proxy : public InterfaceProxy { // they are also provided to PPP_Instance.OnMsgHandleDocumentLoad. This // function allows the proxy for DocumentLoad to create the correct plugin // proxied info for the given browser-supplied URLLoader resource ID. - static void TrackPluginResource(PP_Instance instance, - PP_Resource url_loader_resource); + static PP_Resource TrackPluginResource( + const HostResource& url_loader_resource); const PPB_URLLoader* ppb_url_loader_target() const { return reinterpret_cast<const PPB_URLLoader*>(target_interface()); @@ -48,27 +51,24 @@ class PPB_URLLoader_Proxy : public InterfaceProxy { // Plugin->renderer message handlers. void OnMsgCreate(PP_Instance instance, - PP_Resource* result); - void OnMsgOpen(PP_Resource loader, - PP_Resource request_info, + HostResource* result); + void OnMsgOpen(const HostResource& loader, + const HostResource& request_info, uint32_t serialized_callback); - void OnMsgFollowRedirect(PP_Resource loader, + void OnMsgFollowRedirect(const HostResource& loader, uint32_t serialized_callback); - void OnMsgGetResponseInfo(PP_Resource loader, - PP_Resource* result); - void OnMsgReadResponseBody(PP_Resource loader, + void OnMsgGetResponseInfo(const HostResource& loader, + HostResource* result); + void OnMsgReadResponseBody(const HostResource& loader, int32_t bytes_to_read); - void OnMsgFinishStreamingToFile(PP_Resource loader, + void OnMsgFinishStreamingToFile(const HostResource& loader, uint32_t serialized_callback); - void OnMsgClose(PP_Resource loader); + void OnMsgClose(const HostResource& loader); // Renderer->plugin message handlers. - void OnMsgUpdateProgress(PP_Resource resource, - int64_t bytes_sent, - int64_t total_bytes_to_be_sent, - int64_t bytes_received, - int64_t total_bytes_to_be_received); - void OnMsgReadResponseBodyAck(PP_Resource pp_resource, + void OnMsgUpdateProgress( + const PPBURLLoader_UpdateProgress_Params& params); + void OnMsgReadResponseBodyAck(const HostResource& pp_resource, int32_t result, const std::string& data); @@ -97,7 +97,7 @@ class PPB_URLLoaderTrusted_Proxy : public InterfaceProxy { private: // Plugin->renderer message handlers. - void OnMsgGrantUniversalAccess(PP_Resource loader); + void OnMsgGrantUniversalAccess(const HostResource& loader); }; } // namespace proxy diff --git a/ppapi/proxy/ppb_url_request_info_proxy.cc b/ppapi/proxy/ppb_url_request_info_proxy.cc index 9c98cfe..ecd7c3d 100644 --- a/ppapi/proxy/ppb_url_request_info_proxy.cc +++ b/ppapi/proxy/ppb_url_request_info_proxy.cc @@ -14,8 +14,10 @@ namespace proxy { class URLRequestInfo : public PluginResource { public: - URLRequestInfo(PP_Instance instance) : PluginResource(instance) {} - virtual ~URLRequestInfo() {} + URLRequestInfo(const HostResource& resource) : PluginResource(resource) { + } + virtual ~URLRequestInfo() { + } // Resource overrides. virtual URLRequestInfo* AsURLRequestInfo() { return this; } @@ -26,13 +28,16 @@ class URLRequestInfo : public PluginResource { namespace { -// Returns the dispatcher associated with the given URLRequestInfo, or NULL if -// none exists. -PluginDispatcher* DispatcherFromURLRequestInfo(PP_Resource resource) { - URLRequestInfo* object = PluginResource::GetAs<URLRequestInfo>(resource); - if (!object) - return NULL; - return PluginDispatcher::GetForInstance(object->instance()); +// Computes the dispatcher and request object for the given plugin resource, +// returning true on success. +bool DispatcherFromURLRequestInfo(PP_Resource resource, + PluginDispatcher** dispatcher, + URLRequestInfo** request_info) { + *request_info = PluginResource::GetAs<URLRequestInfo>(resource); + if (!*request_info) + return false; + *dispatcher = PluginDispatcher::GetForInstance((*request_info)->instance()); + return !!*dispatcher; } PP_Resource Create(PP_Instance instance) { @@ -40,14 +45,14 @@ PP_Resource Create(PP_Instance instance) { if (!dispatcher) return 0; - PP_Resource result; + HostResource result; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_Create( INTERFACE_ID_PPB_URL_REQUEST_INFO, instance, &result)); - if (result) { - linked_ptr<URLRequestInfo> object(new URLRequestInfo(instance)); - PluginResourceTracker::GetInstance()->AddResource(result, object); - } - return result; + if (result.is_null()) + return 0; + + linked_ptr<URLRequestInfo> object(new URLRequestInfo(result)); + return PluginResourceTracker::GetInstance()->AddResource(object); } PP_Bool IsURLRequestInfo(PP_Resource resource) { @@ -58,12 +63,13 @@ PP_Bool IsURLRequestInfo(PP_Resource resource) { PP_Bool SetProperty(PP_Resource request_id, PP_URLRequestProperty property, PP_Var var) { - PluginDispatcher* dispatcher = DispatcherFromURLRequestInfo(request_id); - if (!dispatcher) + PluginDispatcher* dispatcher; + URLRequestInfo* request_info; + if (!DispatcherFromURLRequestInfo(request_id, &dispatcher, &request_info)) return PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_SetProperty( - INTERFACE_ID_PPB_URL_REQUEST_INFO, request_id, + INTERFACE_ID_PPB_URL_REQUEST_INFO, request_info->host_resource(), static_cast<int32_t>(property), SerializedVarSendInput(dispatcher, var))); @@ -74,12 +80,14 @@ PP_Bool SetProperty(PP_Resource request_id, PP_Bool AppendDataToBody(PP_Resource request_id, const char* data, uint32_t len) { - PluginDispatcher* dispatcher = DispatcherFromURLRequestInfo(request_id); - if (!dispatcher) + PluginDispatcher* dispatcher; + URLRequestInfo* request_info; + if (!DispatcherFromURLRequestInfo(request_id, &dispatcher, &request_info)) return PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_AppendDataToBody( - INTERFACE_ID_PPB_URL_REQUEST_INFO, request_id, std::string(data, len))); + INTERFACE_ID_PPB_URL_REQUEST_INFO, request_info->host_resource(), + std::string(data, len))); // TODO(brettw) do some validation. We should be able to tell on the plugin // side whether the request will succeed or fail in the renderer. @@ -91,12 +99,18 @@ PP_Bool AppendFileToBody(PP_Resource request_id, int64_t start_offset, int64_t number_of_bytes, PP_Time expected_last_modified_time) { - PluginDispatcher* dispatcher = DispatcherFromURLRequestInfo(request_id); - if (!dispatcher) + PluginDispatcher* dispatcher; + URLRequestInfo* request_info; + if (!DispatcherFromURLRequestInfo(request_id, &dispatcher, &request_info)) + return PP_FALSE; + PluginResource* file_ref_object = + PluginResourceTracker::GetInstance()->GetResourceObject(file_ref_id); + if (!file_ref_object) return PP_FALSE; dispatcher->Send(new PpapiHostMsg_PPBURLRequestInfo_AppendFileToBody( - INTERFACE_ID_PPB_URL_REQUEST_INFO, request_id, file_ref_id, + INTERFACE_ID_PPB_URL_REQUEST_INFO, request_info->host_resource(), + file_ref_object->host_resource(), start_offset, number_of_bytes, expected_last_modified_time)); // TODO(brettw) do some validation. We should be able to tell on the plugin @@ -149,35 +163,36 @@ bool PPB_URLRequestInfo_Proxy::OnMessageReceived(const IPC::Message& msg) { void PPB_URLRequestInfo_Proxy::OnMsgCreate( PP_Instance instance, - PP_Resource* result) { - *result = ppb_url_request_info_target()->Create(instance); + HostResource* result) { + result->SetHostResource(instance, + ppb_url_request_info_target()->Create(instance)); } void PPB_URLRequestInfo_Proxy::OnMsgSetProperty( - PP_Resource request, + HostResource request, int32_t property, SerializedVarReceiveInput value) { - ppb_url_request_info_target()->SetProperty(request, + ppb_url_request_info_target()->SetProperty(request.host_resource(), static_cast<PP_URLRequestProperty>(property), value.Get(dispatcher())); } void PPB_URLRequestInfo_Proxy::OnMsgAppendDataToBody( - PP_Resource request, + HostResource request, const std::string& data) { - ppb_url_request_info_target()->AppendDataToBody(request, data.c_str(), - data.size()); + ppb_url_request_info_target()->AppendDataToBody(request.host_resource(), + data.c_str(), data.size()); } void PPB_URLRequestInfo_Proxy::OnMsgAppendFileToBody( - PP_Resource request, - PP_Resource file_ref, + HostResource request, + HostResource file_ref, int64_t start_offset, int64_t number_of_bytes, double expected_last_modified_time) { ppb_url_request_info_target()->AppendFileToBody( - request, file_ref, start_offset, number_of_bytes, - expected_last_modified_time); + request.host_resource(), file_ref.host_resource(), + start_offset, number_of_bytes, expected_last_modified_time); } } // namespace proxy diff --git a/ppapi/proxy/ppb_url_request_info_proxy.h b/ppapi/proxy/ppb_url_request_info_proxy.h index e317615..bfd4dba 100644 --- a/ppapi/proxy/ppb_url_request_info_proxy.h +++ b/ppapi/proxy/ppb_url_request_info_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PPB_URLRequestInfo; @@ -34,14 +35,14 @@ class PPB_URLRequestInfo_Proxy : public InterfaceProxy { private: // Message handlers. - void OnMsgCreate(PP_Instance instance, PP_Resource* result); - void OnMsgSetProperty(PP_Resource request, + void OnMsgCreate(PP_Instance instance, HostResource* result); + void OnMsgSetProperty(HostResource request, int32_t property, SerializedVarReceiveInput value); - void OnMsgAppendDataToBody(PP_Resource request, + void OnMsgAppendDataToBody(HostResource request, const std::string& data); - void OnMsgAppendFileToBody(PP_Resource request, - PP_Resource file_ref, + void OnMsgAppendFileToBody(HostResource request, + HostResource file_ref, int64_t start_offset, int64_t number_of_bytes, double expected_last_modified_time); diff --git a/ppapi/proxy/ppb_url_response_info_proxy.cc b/ppapi/proxy/ppb_url_response_info_proxy.cc index d9ddc20..9de374d 100644 --- a/ppapi/proxy/ppb_url_response_info_proxy.cc +++ b/ppapi/proxy/ppb_url_response_info_proxy.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -15,7 +15,9 @@ namespace proxy { class URLResponseInfo : public PluginResource { public: - URLResponseInfo(PP_Instance instance) : PluginResource(instance) {} + URLResponseInfo(const HostResource& resource) + : PluginResource(resource) { + } virtual ~URLResponseInfo() {} // Resource overrides. @@ -43,19 +45,19 @@ PP_Var GetProperty(PP_Resource response, PP_URLResponseProperty property) { ReceiveSerializedVarReturnValue result; dispatcher->Send(new PpapiHostMsg_PPBURLResponseInfo_GetProperty( - INTERFACE_ID_PPB_URL_RESPONSE_INFO, response, property, &result)); + INTERFACE_ID_PPB_URL_RESPONSE_INFO, object->host_resource(), property, + &result)); return result.Return(dispatcher); } PP_Resource GetBodyAsFileRef(PP_Resource response) { - PP_Resource result = 0; /* dispatcher->Send(new PpapiHostMsg_PPBURLResponseInfo_GetBodyAsFileRef( INTERFACE_ID_PPB_URL_RESPONSE_INFO, response, &result)); // TODO(brettw) when we have FileRef proxied, make an object from that // ref so we can track it properly and then uncomment this. */ - return result; + return 0; } const PPB_URLResponseInfo ppb_urlresponseinfo = { @@ -76,12 +78,10 @@ PPB_URLResponseInfo_Proxy::~PPB_URLResponseInfo_Proxy() { } // static -void PPB_URLResponseInfo_Proxy::TrackPluginResource( - PP_Instance instance, - PP_Resource response_resource) { - linked_ptr<URLResponseInfo> object(new URLResponseInfo(instance)); - PluginResourceTracker::GetInstance()->AddResource( - response_resource, object); +PP_Resource PPB_URLResponseInfo_Proxy::CreateResponseForResource( + const HostResource& resource) { + linked_ptr<URLResponseInfo> object(new URLResponseInfo(resource)); + return PluginResourceTracker::GetInstance()->AddResource(object); } const void* PPB_URLResponseInfo_Proxy::GetSourceInterface() const { @@ -106,17 +106,20 @@ bool PPB_URLResponseInfo_Proxy::OnMessageReceived(const IPC::Message& msg) { } void PPB_URLResponseInfo_Proxy::OnMsgGetProperty( - PP_Resource response, + HostResource response, int32_t property, SerializedVarReturnValue result) { result.Return(dispatcher(), ppb_url_response_info_target()->GetProperty( - response, static_cast<PP_URLResponseProperty>(property))); + response.host_resource(), static_cast<PP_URLResponseProperty>(property))); } void PPB_URLResponseInfo_Proxy::OnMsgGetBodyAsFileRef( - PP_Resource response, - PP_Resource* file_ref_result) { - *file_ref_result = ppb_url_response_info_target()->GetBodyAsFileRef(response); + HostResource response, + HostResource* file_ref_result) { + file_ref_result->SetHostResource( + response.instance(), + ppb_url_response_info_target()->GetBodyAsFileRef( + response.host_resource())); } } // namespace proxy diff --git a/ppapi/proxy/ppb_url_response_info_proxy.h b/ppapi/proxy/ppb_url_response_info_proxy.h index 079f3b7..0e1307f 100644 --- a/ppapi/proxy/ppb_url_response_info_proxy.h +++ b/ppapi/proxy/ppb_url_response_info_proxy.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -9,6 +9,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_module.h" #include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PPB_URLResponseInfo; @@ -24,11 +25,12 @@ class PPB_URLResponseInfo_Proxy : public InterfaceProxy { const void* target_interface); virtual ~PPB_URLResponseInfo_Proxy(); - // URLResponseInfo objects are actually returned by the URLLoader class. - // This function allows the URLLoader proxy to start the tracking of - // a response info object in the plugin. - static void TrackPluginResource(PP_Instance instance, - PP_Resource response_resource); + // URLResponseInfo objects are actually created and returned by the + // URLLoader. This function allows the URLLoader to convert a new + // HostResource representing a response info to a properly tracked + // URLReponseInfo PluginResource. Returns the plugin resource ID for the + // new resource. + static PP_Resource CreateResponseForResource(const HostResource& resource); const PPB_URLResponseInfo* ppb_url_response_info_target() const { return static_cast<const PPB_URLResponseInfo*>(target_interface()); @@ -41,11 +43,11 @@ class PPB_URLResponseInfo_Proxy : public InterfaceProxy { private: // Message handlers. - void OnMsgGetProperty(PP_Resource response, + void OnMsgGetProperty(HostResource response, int32_t property, SerializedVarReturnValue result); - void OnMsgGetBodyAsFileRef(PP_Resource response, - PP_Resource* file_ref_result); + void OnMsgGetBodyAsFileRef(HostResource response, + HostResource* file_ref_result); DISALLOW_COPY_AND_ASSIGN(PPB_URLResponseInfo_Proxy); }; diff --git a/ppapi/proxy/ppp_instance_proxy.cc b/ppapi/proxy/ppp_instance_proxy.cc index 3614c36..b2103a3 100644 --- a/ppapi/proxy/ppp_instance_proxy.cc +++ b/ppapi/proxy/ppp_instance_proxy.cc @@ -66,9 +66,11 @@ PP_Bool HandleInputEvent(PP_Instance instance, PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) { PP_Bool result = PP_FALSE; + HostResource serialized_loader; + serialized_loader.SetHostResource(instance, url_loader); HostDispatcher::GetForInstance(instance)->Send( new PpapiMsg_PPPInstance_HandleDocumentLoad(INTERFACE_ID_PPP_INSTANCE, - instance, url_loader, + instance, serialized_loader, &result)); return result; } @@ -180,11 +182,12 @@ void PPP_Instance_Proxy::OnMsgHandleInputEvent(PP_Instance instance, } void PPP_Instance_Proxy::OnMsgHandleDocumentLoad(PP_Instance instance, - PP_Resource url_loader, + const HostResource& url_loader, PP_Bool* result) { - PPB_URLLoader_Proxy::TrackPluginResource(instance, url_loader); + PP_Resource plugin_loader = + PPB_URLLoader_Proxy::TrackPluginResource(url_loader); *result = ppp_instance_target()->HandleDocumentLoad( - instance, url_loader); + instance, plugin_loader); } void PPP_Instance_Proxy::OnMsgGetInstanceObject( diff --git a/ppapi/proxy/ppp_instance_proxy.h b/ppapi/proxy/ppp_instance_proxy.h index 5d02fc8..8d68b79 100644 --- a/ppapi/proxy/ppp_instance_proxy.h +++ b/ppapi/proxy/ppp_instance_proxy.h @@ -11,6 +11,7 @@ #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_resource.h" #include "ppapi/c/pp_var.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/interface_proxy.h" struct PP_InputEvent; @@ -51,7 +52,7 @@ class PPP_Instance_Proxy : public InterfaceProxy { const PP_InputEvent& event, PP_Bool* result); void OnMsgHandleDocumentLoad(PP_Instance instance, - PP_Resource url_loader, + const HostResource& url_loader, PP_Bool* result); void OnMsgGetInstanceObject(PP_Instance instance, SerializedVarReturnValue result); diff --git a/ppapi/proxy/serialized_structs.cc b/ppapi/proxy/serialized_structs.cc index f744db9..576e31a 100644 --- a/ppapi/proxy/serialized_structs.cc +++ b/ppapi/proxy/serialized_structs.cc @@ -64,7 +64,6 @@ void SerializedFontDescription::SetToPPFontDescription( PPBFlash_DrawGlyphs_Params::PPBFlash_DrawGlyphs_Params() : instance(0), - pp_image_data(0), font_desc(), color(0) { } diff --git a/ppapi/proxy/serialized_structs.h b/ppapi/proxy/serialized_structs.h index 496fd3a..8b40042 100644 --- a/ppapi/proxy/serialized_structs.h +++ b/ppapi/proxy/serialized_structs.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// 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. @@ -10,11 +10,12 @@ #include "base/shared_memory.h" #include "build/build_config.h" +#include "ipc/ipc_platform_file.h" #include "ppapi/c/pp_bool.h" #include "ppapi/c/pp_instance.h" #include "ppapi/c/pp_point.h" #include "ppapi/c/pp_rect.h" -#include "ppapi/c/pp_resource.h" +#include "ppapi/proxy/host_resource.h" #include "ppapi/proxy/serialized_var.h" struct PP_FontDescription_Dev; @@ -74,8 +75,8 @@ struct SerializedDirEntry { // is a var, it's much more convenient to use the normal way of passing a // PP_Var. struct PPBFont_DrawTextAt_Params { - PP_Resource font; - PP_Resource image_data; + HostResource font; + HostResource image_data; PP_Bool text_is_rtl; PP_Bool override_direction; PP_Point position; @@ -90,7 +91,7 @@ struct PPBFlash_DrawGlyphs_Params { ~PPBFlash_DrawGlyphs_Params(); PP_Instance instance; - PP_Resource pp_image_data; + HostResource image_data; SerializedFontDescription font_desc; uint32_t color; PP_Point position; @@ -100,6 +101,23 @@ struct PPBFlash_DrawGlyphs_Params { std::vector<PP_Point> glyph_advances; }; +struct PPBAudio_NotifyAudioStreamCreated_Params { + pp::proxy::HostResource audio_id; + int32_t result_code; // Will be != PP_OK on failure + IPC::PlatformFileForTransit socket_handle; + base::SharedMemoryHandle handle; + int32_t length; +}; + +struct PPBURLLoader_UpdateProgress_Params { + PP_Instance instance; + pp::proxy::HostResource resource; + int64_t bytes_sent; + int64_t total_bytes_to_be_sent; + int64_t bytes_received; + int64_t total_bytes_to_be_received; +}; + #if defined(OS_WIN) typedef HANDLE ImageHandle; #elif defined(OS_MACOSX) diff --git a/ppapi/proxy/serialized_var.cc b/ppapi/proxy/serialized_var.cc index 5987ceb..a4888a0 100644 --- a/ppapi/proxy/serialized_var.cc +++ b/ppapi/proxy/serialized_var.cc @@ -19,7 +19,8 @@ namespace proxy { SerializedVar::Inner::Inner() : serialization_rules_(NULL), var_(PP_MakeUndefined()), - cleanup_mode_(CLEANUP_NONE) { + cleanup_mode_(CLEANUP_NONE), + dispatcher_for_end_send_pass_ref_(NULL) { #ifndef NDEBUG has_been_serialized_ = false; has_been_deserialized_ = false; @@ -29,7 +30,8 @@ SerializedVar::Inner::Inner() SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules) : serialization_rules_(serialization_rules), var_(PP_MakeUndefined()), - cleanup_mode_(CLEANUP_NONE) { + cleanup_mode_(CLEANUP_NONE), + dispatcher_for_end_send_pass_ref_(NULL) { #ifndef NDEBUG has_been_serialized_ = false; has_been_deserialized_ = false; @@ -40,7 +42,8 @@ SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules, const PP_Var& var) : serialization_rules_(serialization_rules), var_(var), - cleanup_mode_(CLEANUP_NONE) { + cleanup_mode_(CLEANUP_NONE), + dispatcher_for_end_send_pass_ref_(NULL) { #ifndef NDEBUG has_been_serialized_ = false; has_been_deserialized_ = false; @@ -50,7 +53,9 @@ SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules, SerializedVar::Inner::~Inner() { switch (cleanup_mode_) { case END_SEND_PASS_REF: - serialization_rules_->EndSendPassRef(var_); + DCHECK(dispatcher_for_end_send_pass_ref_); + serialization_rules_->EndSendPassRef(var_, + dispatcher_for_end_send_pass_ref_); break; case END_RECEIVE_CALLER_OWNED: serialization_rules_->EndReceiveCallerOwned(var_); @@ -204,6 +209,18 @@ bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m, void** iter) { return success; } +void SerializedVar::Inner::SetCleanupModeToEndSendPassRef( + Dispatcher* dispatcher) { + DCHECK(dispatcher); + DCHECK(!dispatcher_for_end_send_pass_ref_); + dispatcher_for_end_send_pass_ref_ = dispatcher; + cleanup_mode_ = END_SEND_PASS_REF; +} + +void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() { + cleanup_mode_ = END_RECEIVE_CALLER_OWNED; +} + // SerializedVar --------------------------------------------------------------- SerializedVar::SerializedVar() : inner_(new Inner) { @@ -339,7 +356,7 @@ PP_Var SerializedVarReceiveInput::Get(Dispatcher* dispatcher) { // Ensure that when the serialized var goes out of scope it cleans up the // stuff we're making in BeginReceiveCallerOwned. - serialized_.inner_->set_cleanup_mode(SerializedVar::END_RECEIVE_CALLER_OWNED); + serialized_.inner_->SetCleanupModeToEndReceiveCallerOwned(); serialized_.inner_->SetVar( serialized_.inner_->serialization_rules()->BeginReceiveCallerOwned( @@ -396,7 +413,7 @@ void SerializedVarReturnValue::Return(Dispatcher* dispatcher, dispatcher->serialization_rules()); // Var must clean up after our BeginSendPassRef call. - serialized_->inner_->set_cleanup_mode(SerializedVar::END_SEND_PASS_REF); + serialized_->inner_->SetCleanupModeToEndSendPassRef(dispatcher); serialized_->inner_->SetVar( dispatcher->serialization_rules()->BeginSendPassRef( @@ -408,7 +425,8 @@ void SerializedVarReturnValue::Return(Dispatcher* dispatcher, SerializedVarOutParam::SerializedVarOutParam(SerializedVar* serialized) : serialized_(serialized), - writable_var_(PP_MakeUndefined()) { + writable_var_(PP_MakeUndefined()), + dispatcher_(NULL) { } SerializedVarOutParam::~SerializedVarOutParam() { @@ -422,11 +440,12 @@ SerializedVarOutParam::~SerializedVarOutParam() { // Normally the current object will be created on the stack to wrap a // SerializedVar and won't have a scope around the actual IPC send. So we // need to tell the SerializedVar to do the begin/end send pass ref calls. - serialized_->inner_->set_cleanup_mode(SerializedVar::END_SEND_PASS_REF); + serialized_->inner_->SetCleanupModeToEndSendPassRef(dispatcher_); } } PP_Var* SerializedVarOutParam::OutParam(Dispatcher* dispatcher) { + dispatcher_ = dispatcher; serialized_->inner_->set_serialization_rules( dispatcher->serialization_rules()); return &writable_var_; @@ -468,6 +487,25 @@ PP_Var** SerializedVarVectorOutParam::ArrayOutParam(Dispatcher* dispatcher) { return &array_; } +SerializedVarTestConstructor::SerializedVarTestConstructor( + const PP_Var& pod_var) { + DCHECK(pod_var.type != PP_VARTYPE_STRING); + inner_->SetVar(pod_var); +} + +SerializedVarTestConstructor::SerializedVarTestConstructor( + const std::string& str) { + PP_Var string_var; + string_var.type = PP_VARTYPE_STRING; + string_var.value.as_id = 0; + inner_->SetVar(string_var); + *inner_->GetStringPtr() = str; +} + +SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var) + : SerializedVar(var) { +} + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/serialized_var.h b/ppapi/proxy/serialized_var.h index cf2d4d4..75ef494 100644 --- a/ppapi/proxy/serialized_var.h +++ b/ppapi/proxy/serialized_var.h @@ -39,7 +39,7 @@ class VarSerializationRules; // different combinations of reference counting for sending and receiving // objects and for dealing with strings // -// This makes SerializedVar complicate and easy to mess up. To make it +// This makes SerializedVar complicated and easy to mess up. To make it // reasonable to use all functions are protected and there are a use-specific // classes that encapsulate exactly one type of use in a way that typically // won't compile if you do the wrong thing. @@ -63,17 +63,6 @@ class VarSerializationRules; // behavior and will enforce that you don't do stupid things. class SerializedVar { public: - enum CleanupMode { - // The serialized var won't do anything special in the destructor (default). - CLEANUP_NONE, - - // The serialized var will call EndSendPassRef in the destructor. - END_SEND_PASS_REF, - - // The serialized var will call EndReceiveCallerOwned in the destructor. - END_RECEIVE_CALLER_OWNED - }; - SerializedVar(); ~SerializedVar(); @@ -90,6 +79,7 @@ class SerializedVar { friend class SerializedVarReturnValue; friend class SerializedVarOutParam; friend class SerializedVarSendInput; + friend class SerializedVarTestConstructor; friend class SerializedVarVectorReceiveInput; class Inner : public base::RefCounted<Inner> { @@ -106,8 +96,6 @@ class SerializedVar { serialization_rules_ = serialization_rules; } - void set_cleanup_mode(CleanupMode cm) { cleanup_mode_ = cm; } - // See outer class's declarations above. PP_Var GetVar() const; PP_Var GetIncompleteVar() const; @@ -118,7 +106,25 @@ class SerializedVar { void WriteToMessage(IPC::Message* m) const; bool ReadFromMessage(const IPC::Message* m, void** iter); + // Sets the cleanup mode. See the CleanupMode enum below. These functions + // are not just a simple setter in order to require that the appropriate + // data is set along with the corresponding mode. + void SetCleanupModeToEndSendPassRef(Dispatcher* dispatcher); + void SetCleanupModeToEndReceiveCallerOwned(); + private: + enum CleanupMode { + // The serialized var won't do anything special in the destructor + // (default). + CLEANUP_NONE, + + // The serialized var will call EndSendPassRef in the destructor. + END_SEND_PASS_REF, + + // The serialized var will call EndReceiveCallerOwned in the destructor. + END_RECEIVE_CALLER_OWNED + }; + // Rules for serializing and deserializing vars for this process type. // This may be NULL, but must be set before trying to serialize to IPC when // sending, or before converting back to a PP_Var when receiving. @@ -140,6 +146,10 @@ class SerializedVar { CleanupMode cleanup_mode_; + // The dispatcher saved for the call to EndSendPassRef for the cleanup. + // This is only valid when cleanup_mode == END_SEND_PASS_REF. + Dispatcher* dispatcher_for_end_send_pass_ref_; + #ifndef NDEBUG // When being sent or received over IPC, we should only be serialized or // deserialized once. These flags help us assert this is true. @@ -378,6 +388,8 @@ class SerializedVarOutParam { // This is the value actually written by the code and returned by OutParam. // We'll write this into serialized_ in our destructor. PP_Var writable_var_; + + Dispatcher* dispatcher_; }; // For returning an array of PP_Vars to the other side and transferring @@ -399,6 +411,30 @@ class SerializedVarVectorOutParam { PP_Var* array_; }; +// For tests that just want to construct a SerializedVar for giving it to one +// of the other classes. +class SerializedVarTestConstructor : public SerializedVar { + public: + // For POD-types and objects. + explicit SerializedVarTestConstructor(const PP_Var& pod_var); + + // For strings. + explicit SerializedVarTestConstructor(const std::string& str); +}; + +// For tests that want to read what's in a SerializedVar. +class SerializedVarTestReader : public SerializedVar { + public: + explicit SerializedVarTestReader(const SerializedVar& var); + + // The "incomplete" var is the one sent over the wire. Strings and object + // IDs have not yet been converted, so this is the thing that tests will + // actually want to check. + PP_Var GetIncompleteVar() const { return inner_->GetIncompleteVar(); } + + const std::string& GetString() const { return inner_->GetString(); } +}; + } // namespace proxy } // namespace pp diff --git a/ppapi/proxy/serialized_var_unittest.cc b/ppapi/proxy/serialized_var_unittest.cc new file mode 100644 index 0000000..3cc4e61 --- /dev/null +++ b/ppapi/proxy/serialized_var_unittest.cc @@ -0,0 +1,74 @@ +// 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/ppapi_proxy_test.h" + +#include "ppapi/proxy/serialized_var.h" + +namespace pp { +namespace proxy { + +namespace { + +PP_Var MakeStringVar(int64_t string_id) { + PP_Var ret; + ret.type = PP_VARTYPE_STRING; + ret.value.as_id = string_id; + return ret; +} + +PP_Var MakeObjectVar(int64_t object_id) { + PP_Var ret; + ret.type = PP_VARTYPE_OBJECT; + ret.value.as_id = object_id; + return ret; +} + +class SerializedVarTest : public PluginProxyTest { + public: + SerializedVarTest() {} +}; + +} // namespace + +// Tests output arguments. +TEST_F(SerializedVarTest, PluginSerializedVarOutParam) { + PP_Var host_object = MakeObjectVar(0x31337); + + // Start tracking this object in the plugin. + PP_Var plugin_object = var_tracker().ReceiveObjectPassRef( + host_object, plugin_dispatcher()); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + + { + SerializedVar sv; + { + // The "OutParam" does its work in its destructor, it will write the + // information to the SerializedVar we passed in the constructor. + SerializedVarOutParam out_param(&sv); + *out_param.OutParam(plugin_dispatcher()) = plugin_object; + } + + // The object should have transformed the plugin object back to the host + // object ID. Nothing in the var tracker should have changed yet, and no + // messages should have been sent. + SerializedVarTestReader reader(sv); + EXPECT_EQ(host_object.value.as_id, reader.GetIncompleteVar().value.as_id); + EXPECT_EQ(1, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(0u, sink().message_count()); + } + + // The out param should have done an "end send pass ref" on the plugin + // var serialization rules, which should have in turn released the reference + // in the var tracker. Since we only had one reference, this should have sent + // a release to the browser. + EXPECT_EQ(-1, var_tracker().GetRefCountForObject(plugin_object)); + EXPECT_EQ(1u, sink().message_count()); + + // We don't bother validating that message since it's nontrivial and the + // PluginVarTracker test has cases that cover that this message is correct. +} + +} // namespace proxy +} // namespace pp diff --git a/ppapi/proxy/var_serialization_rules.h b/ppapi/proxy/var_serialization_rules.h index f18b6f0..38698ae 100644 --- a/ppapi/proxy/var_serialization_rules.h +++ b/ppapi/proxy/var_serialization_rules.h @@ -73,10 +73,11 @@ class VarSerializationRules { // Prepares a var to be sent to the remote side. One local reference will // be passed to the remote side. Call Begin* before doing the send and End* // after doing the send. See SendCallerOwned for a description of the string. + // // The return value from BeginSendPassRef will be the var valid for the host - // process. + // process. This same value must be passed to EndSendPassRef. virtual PP_Var BeginSendPassRef(const PP_Var& var, std::string* str_val) = 0; - virtual void EndSendPassRef(const PP_Var& var) = 0; + virtual void EndSendPassRef(const PP_Var& var, Dispatcher* dispatcher) = 0; // --------------------------------------------------------------------------- |