diff options
Diffstat (limited to 'ppapi/proxy/ppb_file_chooser_proxy.cc')
-rw-r--r-- | ppapi/proxy/ppb_file_chooser_proxy.cc | 147 |
1 files changed, 69 insertions, 78 deletions
diff --git a/ppapi/proxy/ppb_file_chooser_proxy.cc b/ppapi/proxy/ppb_file_chooser_proxy.cc index 6307806..38bc058 100644 --- a/ppapi/proxy/ppb_file_chooser_proxy.cc +++ b/ppapi/proxy/ppb_file_chooser_proxy.cc @@ -9,23 +9,39 @@ #include "ppapi/c/dev/ppb_file_chooser_dev.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_proxy_private.h" +#include "ppapi/proxy/enter_proxy.h" #include "ppapi/proxy/host_dispatcher.h" #include "ppapi/proxy/plugin_dispatcher.h" #include "ppapi/proxy/plugin_resource.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/proxy/ppb_file_ref_proxy.h" #include "ppapi/proxy/serialized_var.h" +#include "ppapi/thunk/thunk.h" + +using ::ppapi::thunk::PPB_FileChooser_API; namespace pp { namespace proxy { -class FileChooser : public PluginResource { +class FileChooser : public PluginResource, + public PPB_FileChooser_API { public: FileChooser(const HostResource& resource); virtual ~FileChooser(); - virtual FileChooser* AsFileChooser(); + // ResourceObjectBase overrides. + virtual PPB_FileChooser_API* AsPPB_FileChooser_API() OVERRIDE; + + // PPB_FileChooser_API implementation. + virtual int32_t Show(PP_CompletionCallback callback) OVERRIDE; + virtual PP_Resource GetNextChosenFile() OVERRIDE; + + // Handles the choose complete notification from the host. + void ChooseComplete( + int32_t result_code, + const std::vector<PPBFileRef_CreateInfo>& chosen_files); + private: PP_CompletionCallback current_show_callback_; // All files returned by the current show callback that haven't yet been @@ -34,7 +50,6 @@ class FileChooser : public PluginResource { // has transferred to the plugin. std::queue<PP_Resource> file_queue_; - private: DISALLOW_COPY_AND_ASSIGN(FileChooser); }; @@ -62,73 +77,47 @@ FileChooser::~FileChooser() { } } -FileChooser* FileChooser::AsFileChooser() { +PPB_FileChooser_API* FileChooser::AsPPB_FileChooser_API() { return this; } -namespace { - -PP_Resource Create(PP_Instance instance, - const PP_FileChooserOptions_Dev* options) { - Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); - if (!dispatcher) - return 0; - - HostResource result; - dispatcher->Send(new PpapiHostMsg_PPBFileChooser_Create( - INTERFACE_ID_PPB_FILE_CHOOSER, instance, - options->mode, - options->accept_mime_types ? options->accept_mime_types : std::string(), - &result)); - - if (result.is_null()) - return 0; - linked_ptr<FileChooser> object(new FileChooser(result)); - return PluginResourceTracker::GetInstance()->AddResource(object); -} - -PP_Bool IsFileChooser(PP_Resource resource) { - FileChooser* object = PluginResource::GetAs<FileChooser>(resource); - return BoolToPPBool(!!object); -} - -int32_t Show(PP_Resource chooser, struct PP_CompletionCallback callback) { - FileChooser* object = PluginResource::GetAs<FileChooser>(chooser); - if (!object) - return PP_ERROR_BADRESOURCE; - Dispatcher* dispatcher = PluginDispatcher::GetForInstance(object->instance()); - if (!dispatcher) - return PP_ERROR_BADARGUMENT; - - if (object->current_show_callback_.func) +int32_t FileChooser::Show(PP_CompletionCallback callback) { + if (current_show_callback_.func) return PP_ERROR_INPROGRESS; // Can't show more than once. - object->current_show_callback_ = callback; - dispatcher->Send(new PpapiHostMsg_PPBFileChooser_Show( - INTERFACE_ID_PPB_FILE_CHOOSER, - object->host_resource())); + current_show_callback_ = callback; + GetDispatcher()->Send(new PpapiHostMsg_PPBFileChooser_Show( + INTERFACE_ID_PPB_FILE_CHOOSER, host_resource())); return PP_OK_COMPLETIONPENDING; } -PP_Resource GetNextChosenFile(PP_Resource chooser) { - FileChooser* object = PluginResource::GetAs<FileChooser>(chooser); - if (!object || object->file_queue_.empty()) +PP_Resource FileChooser::GetNextChosenFile() { + if (file_queue_.empty()) return 0; // Return the next resource in the queue. These resource have already been // addrefed (they're currently owned by the FileChooser) and returning them // transfers ownership of that reference to the plugin. - PP_Resource next = object->file_queue_.front(); - object->file_queue_.pop(); + PP_Resource next = file_queue_.front(); + file_queue_.pop(); return next; } -const PPB_FileChooser_Dev file_chooser_interface = { - &Create, - &IsFileChooser, - &Show, - &GetNextChosenFile -}; +void FileChooser::ChooseComplete( + int32_t result_code, + const std::vector<PPBFileRef_CreateInfo>& chosen_files) { + // Convert each of the passed in file infos to resources. These will be owned + // by the FileChooser object until they're passed to the plugin. + DCHECK(file_queue_.empty()); + for (size_t i = 0; i < chosen_files.size(); i++) + file_queue_.push(PPB_FileRef_Proxy::DeserializeFileRef(chosen_files[i])); + + // Notify the plugin of the new data. + PP_RunAndClearCompletionCallback(¤t_show_callback_, result_code); + // DANGER: May delete |this|! +} + +namespace { InterfaceProxy* CreateFileChooserProxy(Dispatcher* dispatcher, const void* target_interface) { @@ -148,7 +137,7 @@ PPB_FileChooser_Proxy::~PPB_FileChooser_Proxy() { const InterfaceProxy::Info* PPB_FileChooser_Proxy::GetInfo() { static const Info info = { - &file_chooser_interface, + ::ppapi::thunk::GetPPB_FileChooser_Thunk(), PPB_FILECHOOSER_DEV_INTERFACE, INTERFACE_ID_PPB_FILE_CHOOSER, false, @@ -157,6 +146,27 @@ const InterfaceProxy::Info* PPB_FileChooser_Proxy::GetInfo() { return &info; } +// static +PP_Resource PPB_FileChooser_Proxy::CreateProxyResource( + PP_Instance instance, + const PP_FileChooserOptions_Dev* options) { + Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); + if (!dispatcher) + return 0; + + HostResource result; + dispatcher->Send(new PpapiHostMsg_PPBFileChooser_Create( + INTERFACE_ID_PPB_FILE_CHOOSER, instance, + options->mode, + options->accept_mime_types ? options->accept_mime_types : std::string(), + &result)); + + if (result.is_null()) + return 0; + linked_ptr<FileChooser> object(new FileChooser(result)); + return PluginResourceTracker::GetInstance()->AddResource(object); +} + bool PPB_FileChooser_Proxy::OnMessageReceived(const IPC::Message& msg) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(PPB_FileChooser_Proxy, msg) @@ -197,30 +207,11 @@ void PPB_FileChooser_Proxy::OnMsgChooseComplete( const HostResource& chooser, int32_t result_code, const std::vector<PPBFileRef_CreateInfo>& chosen_files) { - PP_Resource plugin_resource = - PluginResourceTracker::GetInstance()->PluginResourceForHostResource( - chooser); - if (!plugin_resource) - return; - FileChooser* object = PluginResource::GetAs<FileChooser>(plugin_resource); - if (!object) - return; - - // Convert each of the passed in file infos to resources. These will be owned - // by the FileChooser object until they're passed to the plugin. - DCHECK(object->file_queue_.empty()); - for (size_t i = 0; i < chosen_files.size(); i++) { - object->file_queue_.push( - PPB_FileRef_Proxy::DeserializeFileRef(chosen_files[i])); + EnterPluginFromHostResource<PPB_FileChooser_API> enter(chooser); + if (enter.succeeded()) { + static_cast<FileChooser*>(enter.object())->ChooseComplete( + result_code, chosen_files); } - - // Notify the plugin of the new data. We have to swap out the callback - // because the plugin may trigger deleting the object from the callback, and - // the FileChooser object will attempt to call the callback in its destructor - // with the ABORTED status. - PP_RunAndClearCompletionCallback(&object->current_show_callback_, - result_code); - // DANGER: May delete |object|! } void PPB_FileChooser_Proxy::OnShowCallback(int32_t result, |