summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-14 15:43:42 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-14 15:43:42 +0000
commiteccf8031b30e3f8cf85b1e0dc82e69966afa30d5 (patch)
tree6c10625135c1fd95eb316fdbf496c5a5ee220c6e
parent1c7fa0a26fed6f48fbb2a7fe5724c5f9143610ff (diff)
downloadchromium_src-eccf8031b30e3f8cf85b1e0dc82e69966afa30d5.zip
chromium_src-eccf8031b30e3f8cf85b1e0dc82e69966afa30d5.tar.gz
chromium_src-eccf8031b30e3f8cf85b1e0dc82e69966afa30d5.tar.bz2
This implements the PPB_FileChooser resource as a new-style IPC-only resource.
Note that the new file name is file_chooser_resource in the proxy. I decided to drop the ppb_ prefix for the "new-style" files to help differentiate them, and also because it's technically wrong. PPB is an interface, and a resource "object" may support multiple interfaces. I think FooResource is easier to type and read. Review URL: https://chromiumcodereview.appspot.com/10544089 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@146737 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/content_renderer.gypi5
-rw-r--r--content/content_tests.gypi6
-rw-r--r--content/renderer/pepper/content_renderer_pepper_host_factory.cc26
-rw-r--r--content/renderer/pepper/content_renderer_pepper_host_factory.h12
-rw-r--r--content/renderer/pepper/pepper_file_chooser_host.cc176
-rw-r--r--content/renderer/pepper/pepper_file_chooser_host.h68
-rw-r--r--content/renderer/pepper/pepper_file_chooser_host_browsertest.cc175
-rw-r--r--content/renderer/pepper/pepper_in_process_resource_creation.cc19
-rw-r--r--content/renderer/pepper/pepper_in_process_resource_creation.h9
-rw-r--r--content/renderer/pepper/pepper_instance_state_accessor.h33
-rw-r--r--content/renderer/pepper/pepper_instance_state_accessor_impl.cc50
-rw-r--r--content/renderer/pepper/pepper_instance_state_accessor_impl.h45
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.cc47
-rw-r--r--content/renderer/pepper/pepper_plugin_delegate_impl.h5
-rw-r--r--ppapi/host/dispatch_host_message.h78
-rw-r--r--ppapi/ppapi_host.gypi1
-rw-r--r--ppapi/ppapi_proxy.gypi6
-rw-r--r--ppapi/ppapi_tests.gypi1
-rw-r--r--ppapi/proxy/file_chooser_resource.cc149
-rw-r--r--ppapi/proxy/file_chooser_resource.h89
-rw-r--r--ppapi/proxy/file_chooser_resource_unittest.cc140
-rw-r--r--ppapi/proxy/host_dispatcher.cc5
-rw-r--r--ppapi/proxy/interface_list.cc1
-rw-r--r--ppapi/proxy/plugin_dispatcher.cc17
-rw-r--r--ppapi/proxy/plugin_dispatcher.h5
-rw-r--r--ppapi/proxy/plugin_resource.cc52
-rw-r--r--ppapi/proxy/plugin_resource.h64
-rw-r--r--ppapi/proxy/ppapi_messages.h32
-rw-r--r--ppapi/proxy/ppapi_proxy_test.cc1
-rw-r--r--ppapi/proxy/ppapi_proxy_test.h17
-rw-r--r--ppapi/proxy/ppb_file_chooser_proxy.cc311
-rw-r--r--ppapi/proxy/ppb_file_chooser_proxy.h75
-rw-r--r--ppapi/proxy/ppb_file_ref_proxy.cc1
-rw-r--r--ppapi/proxy/ppb_file_ref_proxy.h11
-rw-r--r--ppapi/proxy/resource_creation_proxy.cc6
-rw-r--r--ppapi/shared_impl/ppb_file_ref_shared.cc1
-rw-r--r--ppapi/thunk/interfaces_ppb_private.h4
-rw-r--r--ppapi/thunk/interfaces_ppb_public_dev.h5
-rw-r--r--webkit/glue/webkit_glue.gypi2
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.cc6
-rw-r--r--webkit/plugins/ppapi/mock_plugin_delegate.h3
-rw-r--r--webkit/plugins/ppapi/plugin_delegate.h7
-rw-r--r--webkit/plugins/ppapi/ppb_file_chooser_impl.cc288
-rw-r--r--webkit/plugins/ppapi/ppb_file_chooser_impl.h114
-rw-r--r--webkit/plugins/ppapi/ppb_file_chooser_impl_unittest.cc39
-rw-r--r--webkit/plugins/ppapi/ppb_file_ref_impl.h4
-rw-r--r--webkit/plugins/ppapi/resource_creation_impl.cc8
-rw-r--r--webkit/plugins/ppapi/resource_creation_impl.h4
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
49 files changed, 1296 insertions, 928 deletions
diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi
index 0dc741e..570e48c 100644
--- a/content/content_renderer.gypi
+++ b/content/content_renderer.gypi
@@ -145,12 +145,17 @@
'renderer/notification_provider.h',
'renderer/paint_aggregator.cc',
'renderer/paint_aggregator.h',
+ 'renderer/pepper/pepper_instance_state_accessor.h',
+ 'renderer/pepper/pepper_instance_state_accessor_impl.cc',
+ 'renderer/pepper/pepper_instance_state_accessor_impl.h',
'renderer/pepper/content_renderer_pepper_host_factory.cc',
'renderer/pepper/content_renderer_pepper_host_factory.h',
'renderer/pepper/pepper_broker_impl.cc',
'renderer/pepper/pepper_broker_impl.h',
'renderer/pepper/pepper_device_enumeration_event_handler.cc',
'renderer/pepper/pepper_device_enumeration_event_handler.h',
+ 'renderer/pepper/pepper_file_chooser_host.cc',
+ 'renderer/pepper/pepper_file_chooser_host.h',
'renderer/pepper/pepper_hung_plugin_filter.cc',
'renderer/pepper/pepper_hung_plugin_filter.h',
'renderer/pepper/pepper_in_process_resource_creation.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index 520031b..0320e1f 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -521,7 +521,12 @@
'content_shell_lib',
'test_support_content',
'../base/base.gyp:test_support_base',
+ '../ipc/ipc.gyp:test_support_ipc',
'../net/net.gyp:net_test_support',
+ '../ppapi/ppapi_internal.gyp:ppapi_host',
+ '../ppapi/ppapi_internal.gyp:ppapi_proxy',
+ '../ppapi/ppapi_internal.gyp:ppapi_shared',
+ '../ppapi/ppapi_internal.gyp:ppapi_unittest_shared',
'../skia/skia.gyp:skia',
'../testing/gtest.gyp:gtest',
'../ui/ui.gyp:ui',
@@ -537,6 +542,7 @@
'test/content_browser_test.h',
'test/content_browser_test.cc',
'test/content_test_launcher.cc',
+ 'renderer/pepper/pepper_file_chooser_host_browsertest.cc',
],
'conditions': [
['OS=="win"', {
diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.cc b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
index de7cf75..ec7e7ca 100644
--- a/content/renderer/pepper/content_renderer_pepper_host_factory.cc
+++ b/content/renderer/pepper/content_renderer_pepper_host_factory.cc
@@ -4,6 +4,8 @@
#include "content/renderer/pepper/content_renderer_pepper_host_factory.h"
+#include "content/renderer/pepper/pepper_instance_state_accessor.h"
+#include "content/renderer/pepper/pepper_file_chooser_host.h"
#include "ppapi/host/resource_host.h"
#include "ppapi/proxy/ppapi_messages.h"
@@ -12,8 +14,12 @@ using ppapi::host::ResourceHost;
namespace content {
ContentRendererPepperHostFactory::ContentRendererPepperHostFactory(
- RenderViewImpl* render_view)
- : render_view_(render_view) {
+ RenderViewImpl* render_view,
+ const ppapi::PpapiPermissions& permissions,
+ PepperInstanceStateAccessor* state)
+ : render_view_(render_view),
+ permissions_(permissions),
+ instance_state_(state) {
}
ContentRendererPepperHostFactory::~ContentRendererPepperHostFactory() {
@@ -24,7 +30,21 @@ scoped_ptr<ResourceHost> ContentRendererPepperHostFactory::CreateResourceHost(
const ppapi::proxy::ResourceMessageCallParams& params,
PP_Instance instance,
const IPC::Message& message) {
- // TODO(brettw) host creation goes here.
+ // Make sure the plugin is giving us a valid instance for this resource.
+ if (!instance_state_->IsValidInstance(instance))
+ return scoped_ptr<ResourceHost>();
+
+ // Resources for dev interfaces.
+ // TODO(brettw) when we support any public or private interfaces, put them in
+ // a separate switch above.
+ if (permissions_.HasPermission(ppapi::PERMISSION_DEV)) {
+ switch (message.type()) {
+ case PpapiHostMsg_FileChooser_Create::ID:
+ return scoped_ptr<ResourceHost>(new PepperFileChooserHost(
+ host, instance, params.pp_resource(), render_view_,
+ instance_state_));
+ }
+ }
return scoped_ptr<ResourceHost>();
}
diff --git a/content/renderer/pepper/content_renderer_pepper_host_factory.h b/content/renderer/pepper/content_renderer_pepper_host_factory.h
index dbb36af..ad92f5b 100644
--- a/content/renderer/pepper/content_renderer_pepper_host_factory.h
+++ b/content/renderer/pepper/content_renderer_pepper_host_factory.h
@@ -7,14 +7,20 @@
#include "base/compiler_specific.h"
#include "ppapi/host/host_factory.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
class RenderViewImpl;
namespace content {
+class PepperInstanceStateAccessor;
+
class ContentRendererPepperHostFactory : public ppapi::host::HostFactory {
public:
- explicit ContentRendererPepperHostFactory(RenderViewImpl* render_view);
+ explicit ContentRendererPepperHostFactory(
+ RenderViewImpl* render_view,
+ const ppapi::PpapiPermissions& permissions,
+ PepperInstanceStateAccessor* state);
virtual ~ContentRendererPepperHostFactory();
virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost(
@@ -24,7 +30,9 @@ class ContentRendererPepperHostFactory : public ppapi::host::HostFactory {
const IPC::Message& message) OVERRIDE;
private:
- RenderViewImpl* render_view_;
+ RenderViewImpl* render_view_; // Non-owning.
+ ppapi::PpapiPermissions permissions_;
+ PepperInstanceStateAccessor* instance_state_; // Non-owning.
DISALLOW_COPY_AND_ASSIGN(ContentRendererPepperHostFactory);
};
diff --git a/content/renderer/pepper/pepper_file_chooser_host.cc b/content/renderer/pepper/pepper_file_chooser_host.cc
new file mode 100644
index 0000000..79c825f
--- /dev/null
+++ b/content/renderer/pepper/pepper_file_chooser_host.cc
@@ -0,0 +1,176 @@
+// Copyright (c) 2012 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 "content/renderer/pepper/pepper_file_chooser_host.h"
+
+#include "base/file_path.h"
+#include "base/utf_string_conversions.h"
+#include "content/renderer/pepper/pepper_instance_state_accessor.h"
+#include "content/renderer/render_view_impl.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/dispatch_host_message.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppb_file_ref_proxy.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserCompletion.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
+#include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
+
+namespace content {
+
+class PepperFileChooserHost::CompletionHandler
+ : public WebKit::WebFileChooserCompletion {
+ public:
+ CompletionHandler(const base::WeakPtr<PepperFileChooserHost>& host)
+ : host_(host) {
+ }
+
+ virtual ~CompletionHandler() {}
+
+ virtual void didChooseFile(
+ const WebKit::WebVector<WebKit::WebString>& file_names) {
+ if (host_) {
+ std::vector<PepperFileChooserHost::ChosenFileInfo> files;
+ for (size_t i = 0; i < file_names.size(); i++) {
+ files.push_back(PepperFileChooserHost::ChosenFileInfo(
+ file_names[i].utf8(), std::string()));
+ }
+ host_->StoreChosenFiles(files);
+ }
+
+ // It is the responsibility of this method to delete the instance.
+ delete this;
+ }
+ virtual void didChooseFile(
+ const WebKit::WebVector<SelectedFileInfo>& file_names) {
+ if (host_) {
+ std::vector<PepperFileChooserHost::ChosenFileInfo> files;
+ for (size_t i = 0; i < file_names.size(); i++) {
+ files.push_back(PepperFileChooserHost::ChosenFileInfo(
+ file_names[i].path.utf8(),
+ file_names[i].displayName.utf8()));
+ }
+ host_->StoreChosenFiles(files);
+ }
+
+ // It is the responsibility of this method to delete the instance.
+ delete this;
+ }
+
+ private:
+ base::WeakPtr<PepperFileChooserHost> host_;
+
+ DISALLOW_COPY_AND_ASSIGN(CompletionHandler);
+};
+
+PepperFileChooserHost::ChosenFileInfo::ChosenFileInfo(
+ const std::string& path,
+ const std::string& display_name)
+ : path(path),
+ display_name(display_name) {
+}
+
+
+PepperFileChooserHost::PepperFileChooserHost(
+ ppapi::host::PpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource,
+ RenderViewImpl* render_view,
+ PepperInstanceStateAccessor* state)
+ : ResourceHost(host, instance, resource),
+ render_view_(render_view),
+ instance_state_(state),
+ handler_(NULL) {
+}
+
+PepperFileChooserHost::~PepperFileChooserHost() {
+}
+
+int32_t PepperFileChooserHost::OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) {
+ IPC_BEGIN_MESSAGE_MAP(PepperFileChooserHost, msg)
+ PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FileChooser_Show,
+ OnMsgShow)
+ IPC_END_MESSAGE_MAP()
+ return PP_ERROR_FAILED;
+}
+
+void PepperFileChooserHost::StoreChosenFiles(
+ const std::vector<ChosenFileInfo>& files) {
+ std::vector<ppapi::PPB_FileRef_CreateInfo> chosen_files;
+ for (size_t i = 0; i < files.size(); i++) {
+#if defined(OS_WIN)
+ FilePath file_path(UTF8ToWide(files[i].path));
+#else
+ FilePath file_path(files[i].path);
+#endif
+
+ webkit::ppapi::PPB_FileRef_Impl* ref =
+ webkit::ppapi::PPB_FileRef_Impl::CreateExternal(
+ pp_instance(), file_path, files[i].display_name);
+ ppapi::PPB_FileRef_CreateInfo create_info;
+ ppapi::proxy::PPB_FileRef_Proxy::SerializeFileRef(ref->GetReference(),
+ &create_info);
+ chosen_files.push_back(create_info);
+ }
+
+ reply_params_.set_result((chosen_files.size() > 0) ? PP_OK
+ : PP_ERROR_USERCANCEL);
+ host()->SendReply(reply_params_,
+ PpapiPluginMsg_FileChooser_ShowReply(chosen_files));
+
+ reply_params_ = ppapi::proxy::ResourceMessageReplyParams();
+ handler_ = NULL; // Handler deletes itself.
+}
+
+int32_t PepperFileChooserHost::OnMsgShow(
+ ppapi::host::HostMessageContext* context,
+ bool save_as,
+ bool open_multiple,
+ const std::string& suggested_file_name,
+ const std::vector<std::string>& accept_mime_types) {
+ if (handler_)
+ return PP_ERROR_INPROGRESS; // Already pending.
+
+ if (!host()->permissions().HasPermission(
+ ppapi::PERMISSION_BYPASS_USER_GESTURE) &&
+ !instance_state_->HasUserGesture(pp_instance())) {
+ return PP_ERROR_NO_USER_GESTURE;
+ }
+
+ WebKit::WebFileChooserParams params;
+ if (save_as) {
+ params.saveAs = true;
+ params.initialValue = WebKit::WebString::fromUTF8(
+ suggested_file_name.data(), suggested_file_name.size());
+ } else {
+ params.multiSelect = open_multiple;
+ }
+ std::vector<WebKit::WebString> mine_types(accept_mime_types.size());
+ for (size_t i = 0; i < accept_mime_types.size(); i++) {
+ mine_types[i] = WebKit::WebString::fromUTF8(
+ accept_mime_types[i].data(), accept_mime_types[i].size());
+ }
+ params.acceptTypes = mine_types;
+ params.directory = false;
+
+ handler_ = new CompletionHandler(AsWeakPtr());
+ if (!render_view_->runFileChooser(params, handler_)) {
+ delete handler_;
+ handler_ = NULL;
+ return PP_ERROR_NOACCESS;
+ }
+
+ reply_params_ = ppapi::proxy::ResourceMessageReplyParams(
+ context->params.pp_resource(),
+ context->params.sequence());
+ return PP_OK_COMPLETIONPENDING;
+}
+
+} // namespace content
diff --git a/content/renderer/pepper/pepper_file_chooser_host.h b/content/renderer/pepper/pepper_file_chooser_host.h
new file mode 100644
index 0000000..8dbc4e3
--- /dev/null
+++ b/content/renderer/pepper/pepper_file_chooser_host.h
@@ -0,0 +1,68 @@
+// Copyright (c) 2012 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 CONTENT_RENDERER_PEPPER_PEPPER_FILE_CHOOSER_HOST_H_
+#define CONTENT_RENDERER_PEPPER_PEPPER_FILE_CHOOSER_HOST_H_
+
+#include <string>
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "ppapi/host/resource_host.h"
+#include "ppapi/proxy/resource_message_params.h"
+
+class RenderViewImpl;
+
+namespace content {
+
+class PepperInstanceStateAccessor;
+
+class CONTENT_EXPORT PepperFileChooserHost
+ : public ppapi::host::ResourceHost,
+ public base::SupportsWeakPtr<PepperFileChooserHost> {
+ public:
+ // Structure to store the information about chosen files.
+ struct ChosenFileInfo {
+ ChosenFileInfo(const std::string& path, const std::string& display_name);
+ std::string path;
+ std::string display_name; // May be empty.
+ };
+
+ PepperFileChooserHost(ppapi::host::PpapiHost* host,
+ PP_Instance instance,
+ PP_Resource resource,
+ RenderViewImpl* render_view,
+ PepperInstanceStateAccessor* state);
+ virtual ~PepperFileChooserHost();
+
+ virtual int32_t OnResourceMessageReceived(
+ const IPC::Message& msg,
+ ppapi::host::HostMessageContext* context) OVERRIDE;
+
+ void StoreChosenFiles(const std::vector<ChosenFileInfo>& files);
+
+ private:
+ class CompletionHandler;
+
+ int32_t OnMsgShow(ppapi::host::HostMessageContext* context,
+ bool save_as,
+ bool open_multiple,
+ const std::string& suggested_file_name,
+ const std::vector<std::string>& accept_mime_types);
+
+ // Non-owning pointers.
+ RenderViewImpl* render_view_;
+ PepperInstanceStateAccessor* instance_state_;
+
+ ppapi::proxy::ResourceMessageReplyParams reply_params_;
+ CompletionHandler* handler_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperFileChooserHost);
+};
+
+} // namespace ppapi
+
+#endif // CONTENT_RENDERER_PEPPER_PEPPER_FILE_CHOOSER_HOST_H_
diff --git a/content/renderer/pepper/pepper_file_chooser_host_browsertest.cc b/content/renderer/pepper/pepper_file_chooser_host_browsertest.cc
new file mode 100644
index 0000000..6a482d3
--- /dev/null
+++ b/content/renderer/pepper/pepper_file_chooser_host_browsertest.cc
@@ -0,0 +1,175 @@
+// Copyright (c) 2012 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/file_path.h"
+#include "base/utf_string_conversions.h"
+#include "content/public/test/render_view_test.h"
+#include "content/common/view_messages.h"
+#include "content/public/common/file_chooser_params.h"
+#include "content/renderer/pepper/pepper_file_chooser_host.h"
+#include "content/renderer/pepper/pepper_instance_state_accessor.h"
+#include "content/renderer/render_view_impl.h"
+#include "content/test/test_content_client.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/host/host_message_context.h"
+#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "ppapi/proxy/resource_message_test_sink.h"
+#include "ppapi/shared_impl/ppapi_permissions.h"
+#include "ppapi/shared_impl/ppb_file_ref_shared.h"
+#include "ppapi/shared_impl/resource_tracker.h"
+#include "ppapi/shared_impl/test_globals.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/dialogs/selected_file_info.h"
+
+namespace content {
+
+namespace {
+
+class PepperFileChooserHostTest : public RenderViewTest {
+ public:
+ PepperFileChooserHostTest() : pp_instance_(123456) {}
+
+ virtual void SetUp() {
+ SetContentClient(&client_);
+ RenderViewTest::SetUp();
+
+ globals_.GetResourceTracker()->DidCreateInstance(pp_instance_);
+ }
+ virtual void TearDown() {
+ globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_);
+
+ RenderViewTest::TearDown();
+ SetContentClient(NULL);
+ }
+
+ PP_Instance pp_instance() const { return pp_instance_; }
+
+ private:
+ PP_Instance pp_instance_;
+
+ ppapi::TestGlobals globals_;
+ TestContentClient client_;
+};
+
+// For testing to convert our hardcoded file paths to 8-bit.
+std::string FilePathToUTF8(const FilePath::StringType& path) {
+#if defined(OS_WIN)
+ return UTF16ToUTF8(path);
+#else
+ return path;
+#endif
+}
+
+class MockInstanceState : public PepperInstanceStateAccessor {
+ public:
+ MockInstanceState() : has_user_gesture_(true) {}
+ virtual ~MockInstanceState() {}
+
+ void set_has_user_gesture(bool has) { has_user_gesture_ = has; }
+
+ // PepperInstanceStateAccessor.
+ virtual bool IsValidInstance(PP_Instance instance) OVERRIDE {
+ return true;
+ }
+ virtual bool HasUserGesture(PP_Instance instance) OVERRIDE {
+ return has_user_gesture_;
+ }
+
+ private:
+ bool has_user_gesture_;
+};
+
+} // namespace
+
+TEST_F(PepperFileChooserHostTest, Show) {
+ PP_Resource pp_resource = 123;
+
+ MockInstanceState state;
+ ppapi::proxy::ResourceMessageTestSink sink;
+ ppapi::host::PpapiHost host(&sink, NULL, ppapi::PpapiPermissions());
+ RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_);
+ PepperFileChooserHost chooser(&host, pp_instance(), pp_resource, view_impl,
+ &state);
+
+ std::vector<std::string> accept;
+ accept.push_back("text/plain");
+ PpapiHostMsg_FileChooser_Show show_msg(false, false, std::string(), accept);
+
+ ppapi::proxy::ResourceMessageCallParams call_params(pp_resource, 0);
+ ppapi::host::HostMessageContext context(call_params);
+ int32 result = chooser.OnResourceMessageReceived(show_msg, &context);
+ EXPECT_EQ(PP_OK_COMPLETIONPENDING, result);
+
+ // The render view should have sent a chooser request to the browser
+ // (caught by the render thread's test message sink).
+ const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
+ ViewHostMsg_RunFileChooser::ID);
+ ASSERT_TRUE(msg);
+ ViewHostMsg_RunFileChooser::Schema::Param call_msg_param;
+ ASSERT_TRUE(ViewHostMsg_RunFileChooser::Read(msg, &call_msg_param));
+ const FileChooserParams& chooser_params = call_msg_param.a;
+
+ // Basic validation of request.
+ EXPECT_EQ(FileChooserParams::Open, chooser_params.mode);
+ ASSERT_EQ(1u, chooser_params.accept_types.size());
+ EXPECT_EQ(accept[0], UTF16ToUTF8(chooser_params.accept_types[0]));
+
+ // Send a chooser reply to the render view. Note our reply path has to have a
+ // path separator so we include both a Unix and a Windows one.
+ ui::SelectedFileInfo selected_info;
+ selected_info.display_name = FILE_PATH_LITERAL("Hello, world");
+ selected_info.path = FilePath(FILE_PATH_LITERAL("myp\\ath/foo"));
+ std::vector<ui::SelectedFileInfo> selected_info_vector;
+ selected_info_vector.push_back(selected_info);
+ ViewMsg_RunFileChooserResponse response(view_impl->routing_id(),
+ selected_info_vector);
+ EXPECT_TRUE(view_impl->OnMessageReceived(response));
+
+ // This should have sent the Pepper reply to our test sink.
+ ppapi::proxy::ResourceMessageReplyParams reply_params;
+ IPC::Message reply_msg;
+ ASSERT_TRUE(sink.GetFirstResourceReplyMatching(
+ PpapiPluginMsg_FileChooser_ShowReply::ID, &reply_params, &reply_msg));
+
+ // Basic validation of reply.
+ EXPECT_EQ(call_params.sequence(), reply_params.sequence());
+ EXPECT_EQ(PP_OK, reply_params.result());
+ PpapiPluginMsg_FileChooser_ShowReply::Schema::Param reply_msg_param;
+ ASSERT_TRUE(PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg,
+ &reply_msg_param));
+ const std::vector<ppapi::PPB_FileRef_CreateInfo>& chooser_results =
+ reply_msg_param.a;
+ ASSERT_EQ(1u, chooser_results.size());
+ // Note path is empty because this is an external filesystem.
+ EXPECT_EQ(std::string(), chooser_results[0].path);
+ EXPECT_EQ(FilePathToUTF8(selected_info.display_name),
+ chooser_results[0].name);
+}
+
+TEST_F(PepperFileChooserHostTest, NoUserGesture) {
+ PP_Resource pp_resource = 123;
+
+ MockInstanceState state;
+ ppapi::proxy::ResourceMessageTestSink sink;
+ ppapi::host::PpapiHost host(&sink, NULL, ppapi::PpapiPermissions());
+ RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_);
+ PepperFileChooserHost chooser(&host, pp_instance(), pp_resource, view_impl,
+ &state);
+
+ // Say there's no user gesture.
+ state.set_has_user_gesture(false);
+
+ std::vector<std::string> accept;
+ accept.push_back("text/plain");
+ PpapiHostMsg_FileChooser_Show show_msg(false, false, std::string(), accept);
+
+ ppapi::proxy::ResourceMessageCallParams call_params(pp_resource, 0);
+ ppapi::host::HostMessageContext context(call_params);
+ int32 result = chooser.OnResourceMessageReceived(show_msg, &context);
+ EXPECT_EQ(PP_ERROR_NO_USER_GESTURE, result);
+}
+
+} // namespace content
diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.cc b/content/renderer/pepper/pepper_in_process_resource_creation.cc
index 3371f75..af3e0e7 100644
--- a/content/renderer/pepper/pepper_in_process_resource_creation.cc
+++ b/content/renderer/pepper/pepper_in_process_resource_creation.cc
@@ -11,10 +11,12 @@
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"
#include "ppapi/host/ppapi_host.h"
+#include "ppapi/proxy/file_chooser_resource.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "ppapi/shared_impl/resource_tracker.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
// Note that the code in the creation functions in this file should generally
// be the same as that in ppapi/proxy/resource_creation_proxy.cc. See
@@ -26,6 +28,7 @@ class PepperInProcessResourceCreation::PluginToHostRouter
: public IPC::Sender {
public:
PluginToHostRouter(RenderViewImpl* render_view,
+ PepperInstanceStateAccessor* state,
IPC::Sender* host_to_plugin_sender,
const ppapi::PpapiPermissions& perms);
virtual ~PluginToHostRouter() {}
@@ -46,10 +49,11 @@ class PepperInProcessResourceCreation::PluginToHostRouter
PepperInProcessResourceCreation::PluginToHostRouter::PluginToHostRouter(
RenderViewImpl* render_view,
+ PepperInstanceStateAccessor* state,
IPC::Sender* host_to_plugin_sender,
const ppapi::PpapiPermissions& perms)
: weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)),
- factory_(render_view),
+ factory_(render_view, perms, state),
host_(host_to_plugin_sender, &factory_, perms) {
}
@@ -136,13 +140,24 @@ PepperInProcessResourceCreation::PepperInProcessResourceCreation(
webkit::ppapi::PluginInstance* instance,
const ppapi::PpapiPermissions& perms)
: ResourceCreationImpl(instance),
+ instance_state_(instance->module()),
host_to_plugin_router_(new HostToPluginRouter),
plugin_to_host_router_(
- new PluginToHostRouter(render_view, host_to_plugin_router_.get(),
+ new PluginToHostRouter(render_view, &instance_state_,
+ host_to_plugin_router_.get(),
perms)) {
}
PepperInProcessResourceCreation::~PepperInProcessResourceCreation() {
}
+PP_Resource PepperInProcessResourceCreation::CreateFileChooser(
+ PP_Instance instance,
+ PP_FileChooserMode_Dev mode,
+ const char* accept_types) {
+ return (new ppapi::proxy::FileChooserResource(
+ plugin_to_host_router_.get(),
+ instance, mode, accept_types))->GetReference();
+}
+
} // namespace content
diff --git a/content/renderer/pepper/pepper_in_process_resource_creation.h b/content/renderer/pepper/pepper_in_process_resource_creation.h
index 0f01b81..78216b2 100644
--- a/content/renderer/pepper/pepper_in_process_resource_creation.h
+++ b/content/renderer/pepper/pepper_in_process_resource_creation.h
@@ -7,6 +7,7 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
+#include "content/renderer/pepper/pepper_instance_state_accessor_impl.h"
#include "webkit/plugins/ppapi/resource_creation_impl.h"
class RenderViewImpl;
@@ -42,7 +43,15 @@ class PepperInProcessResourceCreation
const ppapi::PpapiPermissions& perms);
virtual ~PepperInProcessResourceCreation();
+ // ResourceCreation_API implementation.
+ virtual PP_Resource CreateFileChooser(
+ PP_Instance instance,
+ PP_FileChooserMode_Dev mode,
+ const char* accept_types) OVERRIDE;
+
private:
+ PepperInstanceStateAccessorImpl instance_state_;
+
class HostToPluginRouter;
scoped_ptr<HostToPluginRouter> host_to_plugin_router_;
diff --git a/content/renderer/pepper/pepper_instance_state_accessor.h b/content/renderer/pepper/pepper_instance_state_accessor.h
new file mode 100644
index 0000000..120640c
--- /dev/null
+++ b/content/renderer/pepper/pepper_instance_state_accessor.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2012 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 CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_H_
+#define CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_H_
+
+#include "base/basictypes.h"
+#include "ppapi/c/pp_instance.h"
+
+namespace content {
+
+// This interface provides functions for querying instance state for resource
+// host implementations. It allows us to mock out some of these interactions
+// for testing, as well as limit the dependencies on the webkit layer.
+class PepperInstanceStateAccessor {
+ public:
+ virtual ~PepperInstanceStateAccessor() {}
+
+ // Returns true if the given instance is valid for the host.
+ virtual bool IsValidInstance(PP_Instance instance) = 0;
+
+ // Returns true if the given instance is considered to be currently
+ // processing a user gesture or the plugin module has the "override user
+ // gesture" flag set (in which case it can always do things normally
+ // restricted by user gestures). Returns false if the instance is invalid or
+ // if there is no current user gesture.
+ virtual bool HasUserGesture(PP_Instance instance) = 0;
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_H_
diff --git a/content/renderer/pepper/pepper_instance_state_accessor_impl.cc b/content/renderer/pepper/pepper_instance_state_accessor_impl.cc
new file mode 100644
index 0000000..376d3aa
--- /dev/null
+++ b/content/renderer/pepper/pepper_instance_state_accessor_impl.cc
@@ -0,0 +1,50 @@
+// Copyright (c) 2012 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 "content/renderer/pepper/pepper_instance_state_accessor_impl.h"
+
+#include "ppapi/shared_impl/ppapi_permissions.h"
+#include "webkit/plugins/ppapi/host_globals.h"
+#include "webkit/plugins/ppapi/plugin_module.h"
+#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
+
+using webkit::ppapi::HostGlobals;
+using webkit::ppapi::PluginInstance;
+
+namespace content {
+
+PepperInstanceStateAccessorImpl::PepperInstanceStateAccessorImpl(
+ webkit::ppapi::PluginModule* module)
+ : module_(module) {
+}
+
+PepperInstanceStateAccessorImpl::~PepperInstanceStateAccessorImpl() {
+}
+
+bool PepperInstanceStateAccessorImpl::IsValidInstance(PP_Instance instance) {
+ return !!GetAndValidateInstance(instance);
+}
+
+bool PepperInstanceStateAccessorImpl::HasUserGesture(PP_Instance pp_instance) {
+ PluginInstance* instance = GetAndValidateInstance(pp_instance);
+ if (!instance)
+ return false;
+
+ if (instance->module()->permissions().HasPermission(
+ ppapi::PERMISSION_BYPASS_USER_GESTURE))
+ return true;
+ return instance->IsProcessingUserGesture();
+}
+
+PluginInstance* PepperInstanceStateAccessorImpl::GetAndValidateInstance(
+ PP_Instance pp_instance) {
+ PluginInstance* instance = HostGlobals::Get()->GetInstance(pp_instance);
+ if (!instance)
+ return NULL;
+ if (instance->module() != module_)
+ return NULL;
+ return instance;
+}
+
+} // namespace content
diff --git a/content/renderer/pepper/pepper_instance_state_accessor_impl.h b/content/renderer/pepper/pepper_instance_state_accessor_impl.h
new file mode 100644
index 0000000..108686e
--- /dev/null
+++ b/content/renderer/pepper/pepper_instance_state_accessor_impl.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2012 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 CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_IMPL_H
+#define CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_IMPL_H
+
+#include "base/compiler_specific.h"
+#include "content/renderer/pepper/pepper_instance_state_accessor.h"
+
+namespace webkit {
+namespace ppapi {
+class PluginInstance;
+class PluginModule;
+}
+}
+
+namespace content {
+
+class PepperInstanceStateAccessorImpl : public PepperInstanceStateAccessor {
+ public:
+ PepperInstanceStateAccessorImpl(webkit::ppapi::PluginModule* module);
+ virtual ~PepperInstanceStateAccessorImpl();
+
+ // PepperInstanceStateAccessor implmentation.
+ virtual bool IsValidInstance(PP_Instance instance) OVERRIDE;
+ virtual bool HasUserGesture(PP_Instance pp_instance) OVERRIDE;
+
+ private:
+ // Retrieves the plugin instance object associated with the given PP_Instance
+ // and validates that it is one of the instances associated with our module.
+ // Returns NULL on failure.
+ //
+ // We use this to security check the PP_Instance values sent from a plugin to
+ // make sure it's not trying to spoof another instance.
+ webkit::ppapi::PluginInstance* GetAndValidateInstance(PP_Instance instance);
+
+ webkit::ppapi::PluginModule* module_;
+
+ DISALLOW_COPY_AND_ASSIGN(PepperInstanceStateAccessorImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_RENDERER_PEPPER_PEPPER_INSTANCE_STATE_ACCESSOR_IMPL_H
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.cc b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
index ec8057d..f66b4b3 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.cc
@@ -41,10 +41,12 @@
#include "content/renderer/media/pepper_platform_video_decoder_impl.h"
#include "content/renderer/p2p/p2p_transport_impl.h"
#include "content/renderer/p2p/socket_dispatcher.h"
+#include "content/renderer/pepper/content_renderer_pepper_host_factory.h"
#include "content/renderer/pepper/pepper_broker_impl.h"
#include "content/renderer/pepper/pepper_device_enumeration_event_handler.h"
#include "content/renderer/pepper/pepper_hung_plugin_filter.h"
#include "content/renderer/pepper/pepper_in_process_resource_creation.h"
+#include "content/renderer/pepper/pepper_instance_state_accessor.h"
#include "content/renderer/pepper/pepper_platform_audio_input_impl.h"
#include "content/renderer/pepper/pepper_platform_audio_output_impl.h"
#include "content/renderer/pepper/pepper_platform_context_3d_impl.h"
@@ -63,6 +65,7 @@
#include "ppapi/c/dev/pp_video_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_flash.h"
+#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/pepper_file_messages.h"
#include "ppapi/proxy/ppapi_messages.h"
@@ -75,8 +78,6 @@
#include "ppapi/thunk/ppb_tcp_server_socket_private_api.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserCompletion.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginContainer.h"
@@ -105,13 +106,19 @@ namespace {
class HostDispatcherWrapper
: public webkit::ppapi::PluginDelegate::OutOfProcessProxy {
public:
- HostDispatcherWrapper() {}
+ HostDispatcherWrapper(RenderViewImpl* rv,
+ webkit::ppapi::PluginModule* module,
+ const ppapi::PpapiPermissions& perms)
+ : module_(module),
+ instance_state_(module),
+ host_factory_(rv, perms, &instance_state_) {
+ }
virtual ~HostDispatcherWrapper() {}
bool Init(const IPC::ChannelHandle& channel_handle,
- PP_Module pp_module,
PP_GetInterface_Func local_get_interface,
const ppapi::Preferences& preferences,
+ const ppapi::PpapiPermissions& permissions,
PepperHungPluginFilter* filter) {
if (channel_handle.name.empty())
return false;
@@ -124,7 +131,11 @@ class HostDispatcherWrapper
dispatcher_delegate_.reset(new PepperProxyChannelDelegateImpl);
dispatcher_.reset(new ppapi::proxy::HostDispatcher(
- pp_module, local_get_interface, filter));
+ module_->pp_module(), local_get_interface, filter));
+
+ host_.reset(new ppapi::host::PpapiHost(dispatcher_.get(), &host_factory_,
+ permissions));
+ dispatcher_->AddFilter(host_.get());
if (!dispatcher_->InitHostWithChannel(dispatcher_delegate_.get(),
channel_handle,
@@ -151,6 +162,12 @@ class HostDispatcherWrapper
}
private:
+ webkit::ppapi::PluginModule* module_;
+ PepperInstanceStateAccessorImpl instance_state_;
+ ContentRendererPepperHostFactory host_factory_;
+
+ scoped_ptr<ppapi::host::PpapiHost> host_;
+
scoped_ptr<ppapi::proxy::HostDispatcher> dispatcher_;
scoped_ptr<ppapi::proxy::ProxyChannel::Delegate> dispatcher_delegate_;
};
@@ -325,12 +342,13 @@ PepperPluginDelegateImpl::CreatePepperPluginModule(
PepperPluginRegistry::GetInstance(),
permissions);
PepperPluginRegistry::GetInstance()->AddLiveModule(path, module);
- scoped_ptr<HostDispatcherWrapper> dispatcher(new HostDispatcherWrapper);
+ scoped_ptr<HostDispatcherWrapper> dispatcher(
+ new HostDispatcherWrapper(render_view_, module, permissions));
if (!dispatcher->Init(
channel_handle,
- module->pp_module(),
webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc(),
GetPreferences(),
+ permissions,
hung_filter.get()))
return scoped_refptr<webkit::ppapi::PluginModule>();
module->InitAsProxied(dispatcher.release());
@@ -348,6 +366,8 @@ scoped_refptr<webkit::ppapi::PluginModule>
if (module)
return module;
+ ppapi::PpapiPermissions permissions;
+
FilePath path(kBrowserPluginPath);
scoped_refptr<PepperHungPluginFilter> hung_filter(
new PepperHungPluginFilter(path,
@@ -358,15 +378,16 @@ scoped_refptr<webkit::ppapi::PluginModule>
module = new webkit::ppapi::PluginModule(kBrowserPluginName,
path,
registry,
- ppapi::PpapiPermissions());
+ permissions);
RenderThreadImpl::current()->browser_plugin_registry()->AddModule(
guest_process_id, module);
- scoped_ptr<HostDispatcherWrapper> dispatcher(new HostDispatcherWrapper);
+ scoped_ptr<HostDispatcherWrapper> dispatcher(
+ new HostDispatcherWrapper(render_view_, module, permissions));
if (!dispatcher->Init(
channel_handle,
- module->pp_module(),
webkit::ppapi::PluginModule::GetLocalGetInterfaceFunc(),
GetPreferences(),
+ permissions,
hung_filter.get()))
return scoped_refptr<webkit::ppapi::PluginModule>();
module->InitAsProxied(dispatcher.release());
@@ -786,12 +807,6 @@ PepperPluginDelegateImpl::ConnectToBroker(
return broker;
}
-bool PepperPluginDelegateImpl::RunFileChooser(
- const WebKit::WebFileChooserParams& params,
- WebKit::WebFileChooserCompletion* chooser_completion) {
- return render_view_->runFileChooser(params, chooser_completion);
-}
-
bool PepperPluginDelegateImpl::AsyncOpenFile(
const FilePath& path,
int flags,
diff --git a/content/renderer/pepper/pepper_plugin_delegate_impl.h b/content/renderer/pepper/pepper_plugin_delegate_impl.h
index d7d367b..984ae12 100644
--- a/content/renderer/pepper/pepper_plugin_delegate_impl.h
+++ b/content/renderer/pepper/pepper_plugin_delegate_impl.h
@@ -58,11 +58,9 @@ class PluginModule;
}
namespace WebKit {
-class WebFileChooserCompletion;
class WebGamepads;
class WebMouseEvent;
struct WebCompositionUnderline;
-struct WebFileChooserParams;
}
namespace content {
@@ -209,9 +207,6 @@ class PepperPluginDelegateImpl
int total,
bool final_result) OVERRIDE;
virtual void SelectedFindResultChanged(int identifier, int index) OVERRIDE;
- virtual bool RunFileChooser(
- const WebKit::WebFileChooserParams& params,
- WebKit::WebFileChooserCompletion* chooser_completion) OVERRIDE;
virtual bool AsyncOpenFile(const FilePath& path,
int flags,
const AsyncOpenFileCallback& callback) OVERRIDE;
diff --git a/ppapi/host/dispatch_host_message.h b/ppapi/host/dispatch_host_message.h
new file mode 100644
index 0000000..3e60e57
--- /dev/null
+++ b/ppapi/host/dispatch_host_message.h
@@ -0,0 +1,78 @@
+// Copyright (c) 2012 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 "ipc/ipc_message_macros.h"
+
+// This file provides infrastructure for dispatching host resource call
+// messages. Normal IPC message handlers can't take extra parameters or
+// return values. We want to take a HostMessageContext as a parameter and
+// also return the int32_t return value to the caller.
+
+#include "base/profiler/scoped_profile.h" // For TRACK_RUN_IN_IPC_HANDLER.
+#include "ppapi/c/pp_errors.h"
+
+namespace ppapi {
+namespace host {
+
+struct HostMessageContext;
+
+template <class ObjT, class Method>
+inline int32_t DispatchResourceCall(ObjT* obj, Method method,
+ HostMessageContext* context,
+ const Tuple0& arg) {
+ return (obj->*method)(context);
+}
+
+template <class ObjT, class Method, class A>
+inline int32_t DispatchResourceCall(ObjT* obj, Method method,
+ HostMessageContext* context,
+ const Tuple1<A>& arg) {
+ return (obj->*method)(context, arg.a);
+}
+
+template<class ObjT, class Method, class A, class B>
+inline int32_t DispatchResourceCall(ObjT* obj, Method method,
+ HostMessageContext* context,
+ const Tuple2<A, B>& arg) {
+ return (obj->*method)(context, arg.a, arg.b);
+}
+
+template<class ObjT, class Method, class A, class B, class C>
+inline int32_t DispatchResourceCall(ObjT* obj, Method method,
+ HostMessageContext* context,
+ const Tuple3<A, B, C>& arg) {
+ return (obj->*method)(context, arg.a, arg.b, arg.c);
+}
+
+template<class ObjT, class Method, class A, class B, class C, class D>
+inline int32_t DispatchResourceCall(ObjT* obj, Method method,
+ HostMessageContext* context,
+ const Tuple4<A, B, C, D>& arg) {
+ return (obj->*method)(context, arg.a, arg.b, arg.c, arg.d);
+}
+
+template<class ObjT, class Method, class A, class B, class C, class D, class E>
+inline int32_t DispatchResourceCall(ObjT* obj, Method method,
+ HostMessageContext* context,
+ const Tuple5<A, B, C, D, E>& arg) {
+ return (obj->*method)(context, arg.a, arg.b, arg.c, arg.d, arg.e);
+}
+
+#define PPAPI_DISPATCH_HOST_RESOURCE_CALL(msg_class, member_func) \
+ case msg_class::ID: { \
+ TRACK_RUN_IN_IPC_HANDLER(member_func); \
+ msg_class::Schema::Param p; \
+ if (msg_class::Read(&ipc_message__, &p)) { \
+ return ppapi::host::DispatchResourceCall( \
+ this, \
+ &_IpcMessageHandlerClass::member_func, \
+ context, p); \
+ } else { \
+ return PP_ERROR_FAILED; \
+ } \
+ } \
+ break;
+
+} // namespace host
+} // namespace ppapi
diff --git a/ppapi/ppapi_host.gypi b/ppapi/ppapi_host.gypi
index bc99538..c2f9ff8 100644
--- a/ppapi/ppapi_host.gypi
+++ b/ppapi/ppapi_host.gypi
@@ -19,6 +19,7 @@
'PPAPI_HOST_IMPLEMENTATION',
],
'sources': [
+ 'host/dispatch_host_message.h',
'host/host_factory.h',
'host/host_message_context.h',
'host/ppapi_host.cc',
diff --git a/ppapi/ppapi_proxy.gypi b/ppapi/ppapi_proxy.gypi
index 7a21f15..d6ed428 100644
--- a/ppapi/ppapi_proxy.gypi
+++ b/ppapi/ppapi_proxy.gypi
@@ -24,6 +24,8 @@
'proxy/dispatcher.cc',
'proxy/dispatcher.h',
'proxy/enter_proxy.h',
+ 'proxy/file_chooser_resource.cc',
+ 'proxy/file_chooser_resource.h',
'proxy/host_dispatcher.cc',
'proxy/host_dispatcher.h',
'proxy/host_var_serialization_rules.cc',
@@ -43,6 +45,8 @@
'proxy/plugin_main_nacl.cc',
'proxy/plugin_message_filter.cc',
'proxy/plugin_message_filter.h',
+ 'proxy/plugin_resource.cc',
+ 'proxy/plugin_resource.h',
'proxy/plugin_resource_tracker.cc',
'proxy/plugin_resource_tracker.h',
'proxy/plugin_var_serialization_rules.cc',
@@ -65,8 +69,6 @@
'proxy/ppb_buffer_proxy.h',
'proxy/ppb_core_proxy.cc',
'proxy/ppb_core_proxy.h',
- 'proxy/ppb_file_chooser_proxy.cc',
- 'proxy/ppb_file_chooser_proxy.h',
'proxy/ppb_file_io_proxy.cc',
'proxy/ppb_file_io_proxy.h',
'proxy/ppb_file_ref_proxy.cc',
diff --git a/ppapi/ppapi_tests.gypi b/ppapi/ppapi_tests.gypi
index 32682c1..0f52b17 100644
--- a/ppapi/ppapi_tests.gypi
+++ b/ppapi/ppapi_tests.gypi
@@ -140,6 +140,7 @@
'sources': [
'proxy/run_all_unittests.cc',
+ 'proxy/file_chooser_resource_unittest.cc',
'proxy/mock_resource.cc',
'proxy/mock_resource.h',
'proxy/plugin_dispatcher_unittest.cc',
diff --git a/ppapi/proxy/file_chooser_resource.cc b/ppapi/proxy/file_chooser_resource.cc
new file mode 100644
index 0000000..f4e21ec
--- /dev/null
+++ b/ppapi/proxy/file_chooser_resource.cc
@@ -0,0 +1,149 @@
+// Copyright (c) 2012 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/file_chooser_resource.h"
+
+#include "base/string_split.h"
+#include "ipc/ipc_message.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppb_file_ref_proxy.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+namespace proxy {
+
+FileChooserResource::FileChooserResource(IPC::Sender* sender,
+ PP_Instance instance,
+ PP_FileChooserMode_Dev mode,
+ const std::string& accept_types)
+ : PluginResource(sender, instance),
+ mode_(mode) {
+ PopulateAcceptTypes(accept_types, &accept_types_);
+}
+
+FileChooserResource::~FileChooserResource() {
+}
+
+thunk::PPB_FileChooser_API* FileChooserResource::AsPPB_FileChooser_API() {
+ return this;
+}
+
+int32_t FileChooserResource::Show(const PP_ArrayOutput& output,
+ scoped_refptr<TrackedCallback> callback) {
+ return ShowWithoutUserGesture(PP_FALSE, PP_MakeUndefined(), output, callback);
+}
+
+int32_t FileChooserResource::ShowWithoutUserGesture(
+ PP_Bool save_as,
+ PP_Var suggested_file_name,
+ const PP_ArrayOutput& output,
+ scoped_refptr<TrackedCallback> callback) {
+ int32_t result = ShowInternal(PP_FALSE, suggested_file_name, callback);
+ if (result == PP_OK_COMPLETIONPENDING)
+ output_.set_pp_array_output(output);
+ return result;
+}
+
+int32_t FileChooserResource::Show0_5(scoped_refptr<TrackedCallback> callback) {
+ return ShowInternal(PP_FALSE, PP_MakeUndefined(), callback);
+}
+
+PP_Resource FileChooserResource::GetNextChosenFile() {
+ if (file_queue_.empty())
+ return 0;
+
+ // Return the next resource in the queue. It will already have been addrefed
+ // (they're currently owned by the FileChooser) and returning it transfers
+ // ownership of that reference to the plugin.
+ PP_Resource next = file_queue_.front();
+ file_queue_.pop();
+ return next;
+}
+
+int32_t FileChooserResource::ShowWithoutUserGesture0_5(
+ PP_Bool save_as,
+ PP_Var suggested_file_name,
+ scoped_refptr<TrackedCallback> callback) {
+ return ShowInternal(save_as, suggested_file_name, callback);
+}
+
+// static
+void FileChooserResource::PopulateAcceptTypes(
+ const std::string& input,
+ std::vector<std::string>* output) {
+ if (input.empty())
+ return;
+
+ std::vector<std::string> type_list;
+ base::SplitString(input, ',', &type_list);
+ output->reserve(type_list.size());
+
+ for (size_t i = 0; i < type_list.size(); ++i) {
+ std::string type = type_list[i];
+ TrimWhitespaceASCII(type, TRIM_ALL, &type);
+
+ // If the type is a single character, it definitely cannot be valid. In the
+ // case of a file extension it would be a single ".". In the case of a MIME
+ // type it would just be a "/".
+ if (type.length() < 2)
+ continue;
+ if (type.find_first_of('/') == std::string::npos && type[0] != '.')
+ continue;
+ StringToLowerASCII(&type);
+ output->push_back(type);
+ }
+}
+
+void FileChooserResource::OnReplyReceived(int /* sequence */,
+ int32_t result,
+ const IPC::Message& msg) {
+ PpapiPluginMsg_FileChooser_ShowReply::Schema::Param param;
+ PpapiPluginMsg_FileChooser_ShowReply::Read(&msg, &param);
+ const std::vector<ppapi::PPB_FileRef_CreateInfo>& chosen_files = param.a;
+
+ if (output_.is_valid()) {
+ // Using v0.6 of the API with the output array.
+ std::vector<PP_Resource> files;
+ for (size_t i = 0; i < chosen_files.size(); i++)
+ files.push_back(PPB_FileRef_Proxy::DeserializeFileRef(chosen_files[i]));
+ output_.StoreResourceVector(files);
+ } else {
+ // 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.
+ TrackedCallback::ClearAndRun(&callback_, PP_OK);
+ // DANGER: May delete |this|!
+}
+
+int32_t FileChooserResource::ShowInternal(
+ PP_Bool save_as,
+ const PP_Var& suggested_file_name,
+ scoped_refptr<TrackedCallback> callback) {
+ if (TrackedCallback::IsPending(callback_))
+ return PP_ERROR_INPROGRESS;
+
+ if (!sent_create_to_renderer())
+ SendCreateToRenderer(PpapiHostMsg_FileChooser_Create());
+
+ callback_ = callback;
+ StringVar* sugg_str = StringVar::FromPPVar(suggested_file_name);
+
+ CallRenderer(PpapiHostMsg_FileChooser_Show(
+ PP_ToBool(save_as),
+ mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE,
+ sugg_str ? sugg_str->value() : std::string(),
+ accept_types_));
+ return PP_OK_COMPLETIONPENDING;
+}
+
+} // namespace proxy
+} // namespace ppapi
diff --git a/ppapi/proxy/file_chooser_resource.h b/ppapi/proxy/file_chooser_resource.h
new file mode 100644
index 0000000..adb20a4
--- /dev/null
+++ b/ppapi/proxy/file_chooser_resource.h
@@ -0,0 +1,89 @@
+// Copyright (c) 2012 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_FILE_CHOOSER_RESOURCE_H_
+#define PPAPI_PROXY_FILE_CHOOSER_RESOURCE_H_
+
+#include <queue>
+#include <string>
+#include <vector>
+
+#include "ppapi/proxy/plugin_resource.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+#include "ppapi/shared_impl/array_writer.h"
+#include "ppapi/shared_impl/tracked_callback.h"
+#include "ppapi/thunk/ppb_file_chooser_api.h"
+
+namespace ppapi {
+
+struct PPB_FileRef_CreateInfo;
+
+namespace proxy {
+
+class PPAPI_PROXY_EXPORT FileChooserResource
+ : public PluginResource,
+ public NON_EXPORTED_BASE(thunk::PPB_FileChooser_API) {
+ public:
+ FileChooserResource(IPC::Sender* sender,
+ PP_Instance instance,
+ PP_FileChooserMode_Dev mode,
+ const std::string& accept_types);
+ virtual ~FileChooserResource();
+
+ // Resource overrides.
+ virtual thunk::PPB_FileChooser_API* AsPPB_FileChooser_API() OVERRIDE;
+
+ // PPB_FileChooser_API.
+ virtual int32_t Show(const PP_ArrayOutput& output,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual int32_t ShowWithoutUserGesture(
+ PP_Bool save_as,
+ PP_Var suggested_file_name,
+ const PP_ArrayOutput& output,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual int32_t Show0_5(scoped_refptr<TrackedCallback> callback) OVERRIDE;
+ virtual PP_Resource GetNextChosenFile() OVERRIDE;
+ virtual int32_t ShowWithoutUserGesture0_5(
+ PP_Bool save_as,
+ PP_Var suggested_file_name,
+ scoped_refptr<TrackedCallback> callback) OVERRIDE;
+
+ // Parses the accept string into the given vector.
+ static void PopulateAcceptTypes(const std::string& input,
+ std::vector<std::string>* output);
+
+ private:
+ // PluginResource override.
+ virtual void OnReplyReceived(int sequence,
+ int32_t result,
+ const IPC::Message& msg) OVERRIDE;
+
+ void OnPluginMsgShowReply(
+ const std::vector<ppapi::PPB_FileRef_CreateInfo>& chosen_files);
+
+ int32_t ShowInternal(PP_Bool save_as,
+ const PP_Var& suggested_file_name,
+ scoped_refptr<TrackedCallback> callback);
+
+ PP_FileChooserMode_Dev mode_;
+ std::vector<std::string> accept_types_;
+
+ // When using v0.6 of the API, contains the array output info.
+ ArrayWriter output_;
+
+ // When using v0.5 of the API, contains all files returned by the current
+ // show callback that haven't yet been given to the plugin. The plugin will
+ // repeatedly call us to get the next file, and we'll vend those out of this
+ // queue, removing them when ownership has transferred to the plugin.
+ std::queue<PP_Resource> file_queue_;
+
+ scoped_refptr<TrackedCallback> callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileChooserResource);
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_FILE_CHOOSER_RESOURCE_H_
diff --git a/ppapi/proxy/file_chooser_resource_unittest.cc b/ppapi/proxy/file_chooser_resource_unittest.cc
new file mode 100644
index 0000000..10ac0b3
--- /dev/null
+++ b/ppapi/proxy/file_chooser_resource_unittest.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2012 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/message_loop.h"
+#include "ppapi/c/dev/ppb_file_chooser_dev.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/file_chooser_resource.h"
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/ppapi_proxy_test.h"
+#include "ppapi/thunk/thunk.h"
+#include "ppapi/shared_impl/scoped_pp_resource.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
+#include "ppapi/shared_impl/var.h"
+
+namespace ppapi {
+namespace proxy {
+
+namespace {
+
+typedef PluginProxyTest FileChooserResourceTest;
+
+void* GetFileRefDataBuffer(void* user_data,
+ uint32_t element_count,
+ uint32_t element_size) {
+ EXPECT_TRUE(element_size == sizeof(PP_Resource));
+ std::vector<PP_Resource>* output =
+ static_cast<std::vector<PP_Resource>*>(user_data);
+ output->resize(element_count);
+ if (element_count > 0)
+ return &(*output)[0];
+ return NULL;
+}
+
+void DoNothingCallback(void* user_data, int32_t result) {
+}
+
+// Calls PopulateAcceptTypes and verifies that the resulting array contains
+// the given values. The values may be NULL if there aren't expected to be
+// that many results.
+bool CheckParseAcceptType(const std::string& input,
+ const char* expected1,
+ const char* expected2) {
+ std::vector<std::string> output;
+ FileChooserResource::PopulateAcceptTypes(input, &output);
+
+ const size_t kCount = 2;
+ const char* expected[kCount] = { expected1, expected2 };
+
+ for (size_t i = 0; i < kCount; i++) {
+ if (!expected[i])
+ return i == output.size();
+ if (output.size() <= i)
+ return false;
+ if (output[i] != expected[i])
+ return false;
+ }
+
+ return output.size() == kCount;
+}
+
+} // namespace
+
+// Does a full test of Show() and reply functionality in the plugin side using
+// the public C interfaces.
+TEST_F(FileChooserResourceTest, Show) {
+ const PPB_FileChooser_Dev_0_6* chooser_iface =
+ thunk::GetPPB_FileChooser_Dev_0_6_Thunk();
+ ScopedPPResource res(ScopedPPResource::PassRef(),
+ chooser_iface->Create(pp_instance(), PP_FILECHOOSERMODE_OPEN,
+ PP_MakeUndefined()));
+
+ std::vector<PP_Resource> dest;
+ PP_ArrayOutput output;
+ output.GetDataBuffer = &GetFileRefDataBuffer;
+ output.user_data = &dest;
+
+ int32_t result = chooser_iface->Show(
+ res, output, PP_MakeCompletionCallback(&DoNothingCallback, NULL));
+ ASSERT_EQ(PP_OK_COMPLETIONPENDING, result);
+
+ // Should have sent a "show" message.
+ ResourceMessageCallParams params;
+ IPC::Message msg;
+ ASSERT_TRUE(sink().GetFirstResourceCallMatching(
+ PpapiHostMsg_FileChooser_Show::ID, &params, &msg));
+
+ ResourceMessageReplyParams reply_params(params.pp_resource(),
+ params.sequence());
+ reply_params.set_result(PP_OK);
+
+ // Synthesize a response with one file ref in it. Note that it must have a
+ // host resource value set or deserialization will fail. Since there isn't
+ // actually a host, this can be whatever we want.
+ std::vector<PPB_FileRef_CreateInfo> create_info_array;
+ PPB_FileRef_CreateInfo create_info;
+ create_info.resource.SetHostResource(pp_instance(), 123);
+ create_info.path = "foo/bar";
+ create_info.name = "baz";
+ create_info_array.push_back(create_info);
+ ASSERT_TRUE(plugin_dispatcher()->OnMessageReceived(
+ PpapiPluginMsg_ResourceReply(reply_params,
+ PpapiPluginMsg_FileChooser_ShowReply(create_info_array))));
+
+ // Should have populated our vector.
+ ASSERT_EQ(1u, dest.size());
+ ScopedPPResource dest_deletor(dest[0]); // Ensure it's cleaned up.
+
+ const PPB_FileRef_1_0* file_ref_iface = thunk::GetPPB_FileRef_1_0_Thunk();
+ EXPECT_EQ(PP_FILESYSTEMTYPE_EXTERNAL,
+ file_ref_iface->GetFileSystemType(dest[0]));
+
+ ScopedPPVar name_var(ScopedPPVar::PassRef(),
+ file_ref_iface->GetName(dest[0]));
+ EXPECT_VAR_IS_STRING(create_info.name, name_var.get());
+
+ // Path should be undefined since it's external filesystem.
+ ScopedPPVar path_var(ScopedPPVar::PassRef(),
+ file_ref_iface->GetPath(dest[0]));
+ EXPECT_EQ(PP_VARTYPE_UNDEFINED, path_var.get().type);
+}
+
+TEST_F(FileChooserResourceTest, PopulateAcceptTypes) {
+ EXPECT_TRUE(CheckParseAcceptType(std::string(), NULL, NULL));
+ EXPECT_TRUE(CheckParseAcceptType("/", NULL, NULL));
+ EXPECT_TRUE(CheckParseAcceptType(".", NULL, NULL));
+ EXPECT_TRUE(CheckParseAcceptType(",, , ", NULL, NULL));
+
+ EXPECT_TRUE(CheckParseAcceptType("app/txt", "app/txt", NULL));
+ EXPECT_TRUE(CheckParseAcceptType("app/txt,app/pdf", "app/txt", "app/pdf"));
+ EXPECT_TRUE(CheckParseAcceptType(" app/txt , app/pdf ",
+ "app/txt", "app/pdf"));
+
+ // No dot or slash ones should be skipped.
+ EXPECT_TRUE(CheckParseAcceptType("foo", NULL, NULL));
+ EXPECT_TRUE(CheckParseAcceptType("foo,.txt", ".txt", NULL));
+}
+
+} // namespace proxy
+} // namespace ppapi
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc
index f9d3471..21dc269 100644
--- a/ppapi/proxy/host_dispatcher.cc
+++ b/ppapi/proxy/host_dispatcher.cc
@@ -183,6 +183,11 @@ bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) {
BoolRestorer restorer(&allow_plugin_reentrancy_);
allow_plugin_reentrancy_ = false;
+ for (size_t i = 0; i < filters_.size(); i++) {
+ if (filters_[i]->OnMessageReceived(msg))
+ return true;
+ }
+
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(HostDispatcher, msg)
IPC_MESSAGE_HANDLER(PpapiHostMsg_LogWithSource, OnHostMsgLogWithSource)
diff --git a/ppapi/proxy/interface_list.cc b/ppapi/proxy/interface_list.cc
index ffed09f..72a99b3 100644
--- a/ppapi/proxy/interface_list.cc
+++ b/ppapi/proxy/interface_list.cc
@@ -80,7 +80,6 @@
#include "ppapi/proxy/ppb_broker_proxy.h"
#include "ppapi/proxy/ppb_buffer_proxy.h"
#include "ppapi/proxy/ppb_core_proxy.h"
-#include "ppapi/proxy/ppb_file_chooser_proxy.h"
#include "ppapi/proxy/ppb_file_io_proxy.h"
#include "ppapi/proxy/ppb_file_ref_proxy.h"
#include "ppapi/proxy/ppb_file_system_proxy.h"
diff --git a/ppapi/proxy/plugin_dispatcher.cc b/ppapi/proxy/plugin_dispatcher.cc
index 9cf606e..9314713 100644
--- a/ppapi/proxy/plugin_dispatcher.cc
+++ b/ppapi/proxy/plugin_dispatcher.cc
@@ -23,6 +23,8 @@
#include "ppapi/proxy/ppb_instance_proxy.h"
#include "ppapi/proxy/ppp_class_proxy.h"
#include "ppapi/proxy/resource_creation_proxy.h"
+#include "ppapi/proxy/resource_message_params.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource.h"
@@ -189,10 +191,12 @@ bool PluginDispatcher::OnMessageReceived(const IPC::Message& msg) {
TRACE_EVENT2("ppapi proxy", "PluginDispatcher::OnMessageReceived",
"Class", IPC_MESSAGE_ID_CLASS(msg.type()),
"Line", IPC_MESSAGE_ID_LINE(msg.type()));
+
if (msg.routing_id() == MSG_ROUTING_CONTROL) {
// Handle some plugin-specific control messages.
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(PluginDispatcher, msg)
+ IPC_MESSAGE_HANDLER(PpapiPluginMsg_ResourceReply, OnMsgResourceReply)
IPC_MESSAGE_HANDLER(PpapiMsg_SupportsInterface, OnMsgSupportsInterface)
IPC_MESSAGE_HANDLER(PpapiMsg_SetPreferences, OnMsgSetPreferences)
IPC_MESSAGE_UNHANDLED(handled = false);
@@ -271,6 +275,19 @@ void PluginDispatcher::ForceFreeAllInstances() {
}
}
+void PluginDispatcher::OnMsgResourceReply(
+ const ppapi::proxy::ResourceMessageReplyParams& reply_params,
+ const IPC::Message& nested_msg) {
+ Resource* resource = PpapiGlobals::Get()->GetResourceTracker()->GetResource(
+ reply_params.pp_resource());
+ if (!resource) {
+ NOTREACHED();
+ return;
+ }
+ resource->OnReplyReceived(reply_params.sequence(), reply_params.result(),
+ nested_msg);
+}
+
void PluginDispatcher::OnMsgSupportsInterface(
const std::string& interface_name,
bool* result) {
diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h
index 5dd6725..d7c118e 100644
--- a/ppapi/proxy/plugin_dispatcher.h
+++ b/ppapi/proxy/plugin_dispatcher.h
@@ -34,6 +34,8 @@ class ResourceCreationAPI;
namespace proxy {
+class ResourceMessageReplyParams;
+
// Used to keep track of per-instance data.
struct InstanceData {
InstanceData();
@@ -142,6 +144,9 @@ class PPAPI_PROXY_EXPORT PluginDispatcher
void ForceFreeAllInstances();
// IPC message handlers.
+ void OnMsgResourceReply(
+ const ppapi::proxy::ResourceMessageReplyParams& reply_params,
+ const IPC::Message& nested_msg);
void OnMsgSupportsInterface(const std::string& interface_name, bool* result);
void OnMsgSetPreferences(const Preferences& prefs);
diff --git a/ppapi/proxy/plugin_resource.cc b/ppapi/proxy/plugin_resource.cc
new file mode 100644
index 0000000..6e387bb
--- /dev/null
+++ b/ppapi/proxy/plugin_resource.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ppapi/proxy/plugin_resource.h"
+
+#include "ppapi/proxy/ppapi_messages.h"
+#include "ppapi/proxy/resource_message_params.h"
+
+namespace ppapi {
+namespace proxy {
+
+PluginResource::PluginResource(IPC::Sender* sender, PP_Instance instance)
+ : Resource(OBJECT_IS_PROXY, instance),
+ sender_(sender),
+ next_sequence_number_(0),
+ sent_create_to_renderer_(false) {
+}
+
+PluginResource::~PluginResource() {
+ if (sent_create_to_renderer_)
+ Send(new PpapiHostMsg_ResourceDestroyed(pp_resource()));
+}
+
+bool PluginResource::Send(IPC::Message* message) {
+ return sender_->Send(message);
+}
+
+void PluginResource::SendCreateToRenderer(const IPC::Message& msg) {
+ DCHECK(!sent_create_to_renderer_);
+ sent_create_to_renderer_ = true;
+ ResourceMessageCallParams params(pp_resource(),
+ next_sequence_number_++);
+ Send(new PpapiHostMsg_ResourceCreated(params, pp_instance(), msg));
+}
+
+void PluginResource::PostToRenderer(const IPC::Message& msg) {
+ ResourceMessageCallParams params(pp_resource(),
+ next_sequence_number_++);
+ Send(new PpapiHostMsg_ResourceCall(params, msg));
+}
+
+int32_t PluginResource::CallRenderer(const IPC::Message& msg) {
+ ResourceMessageCallParams params(pp_resource(),
+ next_sequence_number_++);
+ params.set_has_callback();
+ Send(new PpapiHostMsg_ResourceCall(params, msg));
+ return params.sequence();
+}
+
+} // namespace proxy
+} // namespace ppapi
diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h
new file mode 100644
index 0000000..28d1274
--- /dev/null
+++ b/ppapi/proxy/plugin_resource.h
@@ -0,0 +1,64 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PPAPI_PROXY_PLUGIN_RESOURCE_H_
+#define PPAPI_PROXY_PLUGIN_RESOURCE_H_
+
+#include "base/compiler_specific.h"
+#include "ipc/ipc_sender.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
+#include "ppapi/shared_impl/resource.h"
+
+namespace IPC {
+class Message;
+}
+
+namespace ppapi {
+namespace proxy {
+
+class PluginDispatcher;
+
+class PPAPI_PROXY_EXPORT PluginResource : public Resource,
+ public IPC::Sender {
+ public:
+ PluginResource(IPC::Sender* sender,
+ PP_Instance instance);
+ virtual ~PluginResource();
+
+ // IPC::Sender implementation.
+ virtual bool Send(IPC::Message* message) OVERRIDE;
+
+ bool sent_create_to_renderer() const { return sent_create_to_renderer_; }
+
+ protected:
+ // Sends a create message to the renderer for the current resource.
+ void SendCreateToRenderer(const IPC::Message& msg);
+
+ // Sends the given IPC message as a resource request to the host
+ // corresponding to this resource object and does not expect a reply.
+ void PostToRenderer(const IPC::Message& msg);
+
+ // Like PostToRenderer but expects a response.
+ //
+ // Returns the new request's sequence number which can be used to identify
+ // the callback. The host will reply and ppapi::Resource::OnReplyReceived
+ // will be called.
+ //
+ // Note that all integers (including 0 and -1) are valid request IDs.
+ int32_t CallRenderer(const IPC::Message& msg);
+
+ private:
+ IPC::Sender* sender_;
+
+ int32_t next_sequence_number_;
+
+ bool sent_create_to_renderer_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginResource);
+};
+
+} // namespace proxy
+} // namespace ppapi
+
+#endif // PPAPI_PROXY_PLUGIN_RESOURCE_H_
diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h
index e7881a6..b57e8eb 100644
--- a/ppapi/proxy/ppapi_messages.h
+++ b/ppapi/proxy/ppapi_messages.h
@@ -561,13 +561,6 @@ IPC_MESSAGE_ROUTED3(
IPC::PlatformFileForTransit /* handle */,
int32_t /* result */)
-// PPB_FileChooser.
-IPC_MESSAGE_ROUTED3(
- PpapiMsg_PPBFileChooser_ChooseComplete,
- ppapi::HostResource /* chooser */,
- int32_t /* result_code (will be != PP_OK on failure */,
- std::vector<ppapi::PPB_FileRef_CreateInfo> /* chosen_files */)
-
// PPB_NetworkMonitor_Private.
IPC_MESSAGE_ROUTED2(PpapiMsg_PPBNetworkMonitor_NetworkList,
uint32 /* plugin_dispatcher_id */,
@@ -1123,18 +1116,6 @@ IPC_SYNC_MESSAGE_ROUTED2_2(PpapiHostMsg_PPBBuffer_Create,
ppapi::HostResource /* result_resource */,
base::SharedMemoryHandle /* result_shm_handle */)
-// PPB_FileChooser.
-IPC_SYNC_MESSAGE_ROUTED3_1(PpapiHostMsg_PPBFileChooser_Create,
- PP_Instance /* instance */,
- int /* mode */,
- std::string /* accept_types */,
- ppapi::HostResource /* result */)
-IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBFileChooser_Show,
- ppapi::HostResource /* file_chooser */,
- PP_Bool /* save_as */,
- ppapi::proxy::SerializedVar /* suggested_file_name */,
- bool /* require_user_gesture */)
-
// PPB_NetworkMonitor_Private.
IPC_MESSAGE_CONTROL1(PpapiHostMsg_PPBNetworkMonitor_Start,
uint32 /* plugin_dispatcher_id */)
@@ -1442,3 +1423,16 @@ IPC_MESSAGE_CONTROL2(
PpapiPluginMsg_ResourceReply,
ppapi::proxy::ResourceMessageReplyParams /* reply_params */,
IPC::Message /* nested_msg */)
+
+//-----------------------------------------------------------------------------
+// Messages for resources using call/reply above.
+
+// File chooser.
+IPC_MESSAGE_CONTROL0(PpapiHostMsg_FileChooser_Create)
+IPC_MESSAGE_CONTROL4(PpapiHostMsg_FileChooser_Show,
+ bool /* save_as */,
+ bool /* open_multiple */,
+ std::string /* suggested_file_name */,
+ std::vector<std::string> /* accept_mime_types */)
+IPC_MESSAGE_CONTROL1(PpapiPluginMsg_FileChooser_ShowReply,
+ std::vector<ppapi::PPB_FileRef_CreateInfo> /* files */)
diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc
index 1e68afc..9f0422e 100644
--- a/ppapi/proxy/ppapi_proxy_test.cc
+++ b/ppapi/proxy/ppapi_proxy_test.cc
@@ -410,6 +410,5 @@ void TwoWayTest::TearDown() {
io_thread_.Stop();
}
-
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/ppapi_proxy_test.h b/ppapi/proxy/ppapi_proxy_test.h
index b4ad1b5..782b8c4 100644
--- a/ppapi/proxy/ppapi_proxy_test.h
+++ b/ppapi/proxy/ppapi_proxy_test.h
@@ -9,7 +9,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
-#include "ipc/ipc_test_sink.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/plugin_dispatcher.h"
@@ -17,6 +16,7 @@
#include "ppapi/proxy/plugin_proxy_delegate.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_tracker.h"
+#include "ppapi/proxy/resource_message_test_sink.h"
#include "ppapi/shared_impl/test_globals.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,7 +32,7 @@ class ProxyTestHarnessBase {
PP_Module pp_module() const { return pp_module_; }
PP_Instance pp_instance() const { return pp_instance_; }
- IPC::TestSink& sink() { return sink_; }
+ ResourceMessageTestSink& sink() { return sink_; }
virtual PpapiGlobals* GetGlobals() = 0;
// Returns either the plugin or host dispatcher, depending on the test.
@@ -65,7 +65,7 @@ class ProxyTestHarnessBase {
private:
// Destination for IPC messages sent by the test.
- IPC::TestSink sink_;
+ ResourceMessageTestSink sink_;
// The module and instance ID associated with the plugin dispatcher.
PP_Module pp_module_;
@@ -271,5 +271,16 @@ class TwoWayTest : public testing::Test {
base::WaitableEvent shutdown_event_;
};
+// Used during Gtests when you have a PP_Var that you want to EXPECT is equal
+// to a certain constant string value:
+//
+// EXPECT_VAR_IS_STRING("foo", my_var);
+#define EXPECT_VAR_IS_STRING(str, var) { \
+ StringVar* sv = StringVar::FromPPVar(var); \
+ EXPECT_TRUE(sv); \
+ if (sv) \
+ EXPECT_EQ(str, sv->value()); \
+}
+
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/ppb_file_chooser_proxy.cc b/ppapi/proxy/ppb_file_chooser_proxy.cc
deleted file mode 100644
index 26ab430..0000000
--- a/ppapi/proxy/ppb_file_chooser_proxy.cc
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright (c) 2012 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_file_chooser_proxy.h"
-
-#include <queue>
-
-#include "base/bind.h"
-#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/c/trusted/ppb_file_chooser_trusted.h"
-#include "ppapi/proxy/enter_proxy.h"
-#include "ppapi/proxy/host_dispatcher.h"
-#include "ppapi/proxy/plugin_dispatcher.h"
-#include "ppapi/proxy/ppapi_messages.h"
-#include "ppapi/proxy/ppb_file_ref_proxy.h"
-#include "ppapi/proxy/serialized_var.h"
-#include "ppapi/shared_impl/array_writer.h"
-#include "ppapi/shared_impl/ppapi_globals.h"
-#include "ppapi/shared_impl/resource_tracker.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/shared_impl/var.h"
-#include "ppapi/thunk/resource_creation_api.h"
-#include "ppapi/thunk/thunk.h"
-
-using ppapi::thunk::PPB_FileChooser_API;
-
-namespace ppapi {
-namespace proxy {
-
-namespace {
-InterfaceProxy* CreateFileChooserProxy(Dispatcher* dispatcher) {
- return new PPB_FileChooser_Proxy(dispatcher);
-}
-
-class FileChooser : public Resource,
- public PPB_FileChooser_API {
- public:
- FileChooser(const HostResource& resource);
- virtual ~FileChooser();
-
- // Resource overrides.
- virtual PPB_FileChooser_API* AsPPB_FileChooser_API() OVERRIDE;
-
- // PPB_FileChooser_API implementation.
- virtual int32_t Show(const PP_ArrayOutput& output,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual int32_t ShowWithoutUserGesture(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- const PP_ArrayOutput& output,
- scoped_refptr<TrackedCallback> callback);
- virtual int32_t Show0_5(scoped_refptr<TrackedCallback> callback) OVERRIDE;
- virtual PP_Resource GetNextChosenFile() OVERRIDE;
- virtual int32_t ShowWithoutUserGesture0_5(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- scoped_refptr<TrackedCallback> callback) OVERRIDE;
-
- // Handles the choose complete notification from the host.
- void ChooseComplete(
- int32_t result_code,
- const std::vector<PPB_FileRef_CreateInfo>& chosen_files);
-
- private:
- int32_t Show(bool require_user_gesture,
- PP_Bool save_as,
- PP_Var suggested_file_name,
- scoped_refptr<TrackedCallback> callback);
-
- // When using v0.6 of the API, contains the array output info.
- ArrayWriter output_;
-
- scoped_refptr<TrackedCallback> current_show_callback_;
-
- // When using v0.5 of the API, contains all files returned by the current
- // show callback that haven't yet been given to the plugin. The plugin will
- // repeatedly call us to get the next file, and we'll vend those out of this
- // queue, removing them when ownership has transferred to the plugin.
- std::queue<PP_Resource> file_queue_;
-
- DISALLOW_COPY_AND_ASSIGN(FileChooser);
-};
-
-FileChooser::FileChooser(const HostResource& resource)
- : Resource(OBJECT_IS_PROXY, resource) {
-}
-
-FileChooser::~FileChooser() {
- // Any existing files we haven't transferred ownership to the plugin need
- // to be freed.
- ResourceTracker* tracker = PpapiGlobals::Get()->GetResourceTracker();
- while (!file_queue_.empty()) {
- tracker->ReleaseResource(file_queue_.front());
- file_queue_.pop();
- }
-}
-
-PPB_FileChooser_API* FileChooser::AsPPB_FileChooser_API() {
- return this;
-}
-
-int32_t FileChooser::Show(const PP_ArrayOutput& output,
- scoped_refptr<TrackedCallback> callback) {
- int32_t result = Show(true, PP_FALSE, PP_MakeUndefined(), callback);
- if (result == PP_OK_COMPLETIONPENDING)
- output_.set_pp_array_output(output);
- return result;
-}
-
-int32_t FileChooser::ShowWithoutUserGesture(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- const PP_ArrayOutput& output,
- scoped_refptr<TrackedCallback> callback) {
- int32_t result = Show(false, save_as, suggested_file_name, callback);
- if (result == PP_OK_COMPLETIONPENDING)
- output_.set_pp_array_output(output);
- return result;
-}
-
-int32_t FileChooser::Show0_5(scoped_refptr<TrackedCallback> callback) {
- return Show(true, PP_FALSE, PP_MakeUndefined(), callback);
-}
-
-int32_t FileChooser::ShowWithoutUserGesture0_5(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- scoped_refptr<TrackedCallback> callback) {
- return Show(false, save_as, suggested_file_name, callback);
-}
-
-int32_t FileChooser::Show(bool require_user_gesture,
- PP_Bool save_as,
- PP_Var suggested_file_name,
- scoped_refptr<TrackedCallback> callback) {
- if (TrackedCallback::IsPending(current_show_callback_))
- return PP_ERROR_INPROGRESS; // Can't show more than once.
-
- current_show_callback_ = callback;
- PluginDispatcher* dispatcher = PluginDispatcher::GetForResource(this);
- dispatcher->Send(
- new PpapiHostMsg_PPBFileChooser_Show(
- API_ID_PPB_FILE_CHOOSER,
- host_resource(),
- save_as,
- SerializedVarSendInput(dispatcher, suggested_file_name),
- require_user_gesture));
- return PP_OK_COMPLETIONPENDING;
-}
-
-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 = file_queue_.front();
- file_queue_.pop();
- return next;
-}
-
-void FileChooser::ChooseComplete(
- int32_t result_code,
- const std::vector<PPB_FileRef_CreateInfo>& chosen_files) {
- if (output_.is_valid()) {
- // Using v0.6 of the API with the output array.
- std::vector<PP_Resource> files;
- for (size_t i = 0; i < chosen_files.size(); i++)
- files.push_back(PPB_FileRef_Proxy::DeserializeFileRef(chosen_files[i]));
- output_.StoreResourceVector(files);
- } else {
- // 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.
- TrackedCallback::ClearAndRun(&current_show_callback_, result_code);
- // DANGER: May delete |this|!
-}
-
-} // namespace
-
-PPB_FileChooser_Proxy::PPB_FileChooser_Proxy(Dispatcher* dispatcher)
- : InterfaceProxy(dispatcher),
- callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
-}
-
-PPB_FileChooser_Proxy::~PPB_FileChooser_Proxy() {
-}
-
-// static
-PP_Resource PPB_FileChooser_Proxy::CreateProxyResource(
- PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types) {
- Dispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
- if (!dispatcher)
- return 0;
-
- HostResource result;
- dispatcher->Send(new PpapiHostMsg_PPBFileChooser_Create(
- API_ID_PPB_FILE_CHOOSER, instance,
- mode,
- accept_types ? accept_types : "",
- &result));
-
- if (result.is_null())
- return 0;
- return (new FileChooser(result))->GetReference();
-}
-
-bool PPB_FileChooser_Proxy::OnMessageReceived(const IPC::Message& msg) {
- bool handled = true;
- IPC_BEGIN_MESSAGE_MAP(PPB_FileChooser_Proxy, msg)
- // Plugin -> host messages.
- IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileChooser_Create, OnMsgCreate)
- IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBFileChooser_Show, OnMsgShow)
-
- // Host -> plugin messages.
- IPC_MESSAGE_HANDLER(PpapiMsg_PPBFileChooser_ChooseComplete,
- OnMsgChooseComplete)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
-void PPB_FileChooser_Proxy::OnMsgCreate(
- PP_Instance instance,
- int mode,
- std::string accept_types,
- HostResource* result) {
- thunk::EnterResourceCreation enter(instance);
- if (enter.succeeded()) {
- result->SetHostResource(instance, enter.functions()->CreateFileChooser(
- instance,
- static_cast<PP_FileChooserMode_Dev>(mode),
- accept_types.c_str()));
- }
-}
-
-void PPB_FileChooser_Proxy::OnMsgShow(
- const HostResource& chooser,
- PP_Bool save_as,
- SerializedVarReceiveInput suggested_file_name,
- bool require_user_gesture) {
- scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> > output(
- new RefCountedArrayOutputAdapter<PP_Resource>);
- EnterHostFromHostResourceForceCallback<PPB_FileChooser_API> enter(
- chooser,
- callback_factory_.NewOptionalCallback(
- &PPB_FileChooser_Proxy::OnShowCallback, output, chooser));
- if (enter.succeeded()) {
- if (require_user_gesture) {
- enter.SetResult(enter.object()->Show(output->pp_array_output(),
- enter.callback()));
- } else {
- enter.SetResult(enter.object()->ShowWithoutUserGesture(
- save_as,
- suggested_file_name.Get(dispatcher()),
- output->pp_array_output(),
- enter.callback()));
- }
- }
-}
-
-void PPB_FileChooser_Proxy::OnMsgChooseComplete(
- const HostResource& chooser,
- int32_t result_code,
- const std::vector<PPB_FileRef_CreateInfo>& chosen_files) {
- EnterPluginFromHostResource<PPB_FileChooser_API> enter(chooser);
- if (enter.succeeded()) {
- static_cast<FileChooser*>(enter.object())->ChooseComplete(
- result_code, chosen_files);
- }
-}
-
-void PPB_FileChooser_Proxy::OnShowCallback(
- int32_t result,
- scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> >
- output,
- HostResource chooser) {
- EnterHostFromHostResource<PPB_FileChooser_API> enter(chooser);
-
- std::vector<PPB_FileRef_CreateInfo> files;
- if (enter.succeeded() && result == PP_OK) {
- PPB_FileRef_Proxy* file_ref_proxy = static_cast<PPB_FileRef_Proxy*>(
- dispatcher()->GetInterfaceProxy(API_ID_PPB_FILE_REF));
-
- // Convert the returned files to the serialized info.
- for (size_t i = 0; i < output->output().size(); i++) {
- PPB_FileRef_CreateInfo cur_create_info;
- file_ref_proxy->SerializeFileRef(output->output()[i], &cur_create_info);
- files.push_back(cur_create_info);
- }
- }
-
- dispatcher()->Send(new PpapiMsg_PPBFileChooser_ChooseComplete(
- API_ID_PPB_FILE_CHOOSER, chooser, result, files));
-}
-
-} // namespace proxy
-} // namespace ppapi
diff --git a/ppapi/proxy/ppb_file_chooser_proxy.h b/ppapi/proxy/ppb_file_chooser_proxy.h
deleted file mode 100644
index 1dc0921..0000000
--- a/ppapi/proxy/ppb_file_chooser_proxy.h
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef PPAPI_PROXY_PPB_FILE_CHOOSER_PROXY_H_
-#define PPAPI_PROXY_PPB_FILE_CHOOSER_PROXY_H_
-
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "ppapi/c/pp_instance.h"
-#include "ppapi/proxy/interface_proxy.h"
-#include "ppapi/proxy/proxy_array_output.h"
-#include "ppapi/proxy/proxy_completion_callback_factory.h"
-#include "ppapi/proxy/serialized_var.h"
-#include "ppapi/thunk/ppb_file_chooser_api.h"
-#include "ppapi/cpp/output_traits.h"
-#include "ppapi/utility/completion_callback_factory.h"
-
-namespace ppapi {
-
-class HostResource;
-struct PPB_FileRef_CreateInfo;
-
-namespace proxy {
-
-class PPB_FileChooser_Proxy : public InterfaceProxy {
- public:
- explicit PPB_FileChooser_Proxy(Dispatcher* dispatcher);
- virtual ~PPB_FileChooser_Proxy();
-
- static PP_Resource CreateProxyResource(
- PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types);
-
- // InterfaceProxy implementation.
- virtual bool OnMessageReceived(const IPC::Message& msg);
-
- static const ApiID kApiID = API_ID_PPB_FILE_CHOOSER;
-
- private:
- // Plugin -> host message handlers.
- void OnMsgCreate(PP_Instance instance,
- int mode,
- std::string accept_types,
- ppapi::HostResource* result);
- void OnMsgShow(const ppapi::HostResource& chooser,
- PP_Bool save_as,
- SerializedVarReceiveInput suggested_file_name,
- bool require_user_gesture);
-
- // Host -> plugin message handlers.
- void OnMsgChooseComplete(
- const ppapi::HostResource& chooser,
- int32_t result_code,
- const std::vector<PPB_FileRef_CreateInfo>& chosen_files);
-
- // Called when the show is complete in the host. This will notify the plugin
- // via IPC and OnMsgChooseComplete will be called there.
- void OnShowCallback(
- int32_t result,
- scoped_refptr<RefCountedArrayOutputAdapter<PP_Resource> > output,
- HostResource chooser);
-
- ProxyCompletionCallbackFactory<PPB_FileChooser_Proxy> callback_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(PPB_FileChooser_Proxy);
-};
-
-} // namespace proxy
-} // namespace ppapi
-
-#endif // PPAPI_PROXY_PPB_FILE_CHOOSER_PROXY_H_
diff --git a/ppapi/proxy/ppb_file_ref_proxy.cc b/ppapi/proxy/ppb_file_ref_proxy.cc
index d8ffde6..3889c77 100644
--- a/ppapi/proxy/ppb_file_ref_proxy.cc
+++ b/ppapi/proxy/ppb_file_ref_proxy.cc
@@ -217,6 +217,7 @@ bool PPB_FileRef_Proxy::OnMessageReceived(const IPC::Message& msg) {
return handled;
}
+// static
void PPB_FileRef_Proxy::SerializeFileRef(PP_Resource file_ref,
PPB_FileRef_CreateInfo* result) {
EnterResourceNoLock<PPB_FileRef_API> enter(file_ref, false);
diff --git a/ppapi/proxy/ppb_file_ref_proxy.h b/ppapi/proxy/ppb_file_ref_proxy.h
index 64febfa..e4a412e 100644
--- a/ppapi/proxy/ppb_file_ref_proxy.h
+++ b/ppapi/proxy/ppb_file_ref_proxy.h
@@ -12,6 +12,7 @@
#include "ppapi/c/pp_resource.h"
#include "ppapi/c/pp_time.h"
#include "ppapi/proxy/interface_proxy.h"
+#include "ppapi/proxy/ppapi_proxy_export.h"
#include "ppapi/proxy/proxy_completion_callback_factory.h"
#include "ppapi/utility/completion_callback_factory.h"
@@ -24,7 +25,8 @@ namespace proxy {
class SerializedVarReturnValue;
-class PPB_FileRef_Proxy : public InterfaceProxy {
+class PPAPI_PROXY_EXPORT PPB_FileRef_Proxy
+ : public NON_EXPORTED_BASE(InterfaceProxy) {
public:
explicit PPB_FileRef_Proxy(Dispatcher* dispatcher);
virtual ~PPB_FileRef_Proxy();
@@ -41,13 +43,10 @@ class PPB_FileRef_Proxy : public InterfaceProxy {
// "create info" for reconstitution in the plugin. This struct contains all
// the necessary information about the file ref.
//
- // This function is not static because it needs access to the particular
- // dispatcher and host interface.
- //
// Various PPAPI functions return file refs from various interfaces, so this
// function is public so anybody can send a file ref.
- void SerializeFileRef(PP_Resource file_ref,
- PPB_FileRef_CreateInfo* result);
+ static void SerializeFileRef(PP_Resource file_ref,
+ PPB_FileRef_CreateInfo* result);
// Creates a plugin resource from the given CreateInfo sent from the host.
// The value will be the result of calling SerializeFileRef on the host.
diff --git a/ppapi/proxy/resource_creation_proxy.cc b/ppapi/proxy/resource_creation_proxy.cc
index 7cbab75..51dd334 100644
--- a/ppapi/proxy/resource_creation_proxy.cc
+++ b/ppapi/proxy/resource_creation_proxy.cc
@@ -7,6 +7,7 @@
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_size.h"
#include "ppapi/c/trusted/ppb_image_data_trusted.h"
+#include "ppapi/proxy/file_chooser_resource.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/ppapi_messages.h"
@@ -14,7 +15,6 @@
#include "ppapi/proxy/ppb_audio_proxy.h"
#include "ppapi/proxy/ppb_buffer_proxy.h"
#include "ppapi/proxy/ppb_broker_proxy.h"
-#include "ppapi/proxy/ppb_file_chooser_proxy.h"
#include "ppapi/proxy/ppb_file_io_proxy.h"
#include "ppapi/proxy/ppb_file_ref_proxy.h"
#include "ppapi/proxy/ppb_file_system_proxy.h"
@@ -241,8 +241,8 @@ PP_Resource ResourceCreationProxy::CreateFileChooser(
PP_Instance instance,
PP_FileChooserMode_Dev mode,
const char* accept_types) {
- return PPB_FileChooser_Proxy::CreateProxyResource(instance, mode,
- accept_types);
+ return (new FileChooserResource(dispatcher(), instance, mode,
+ accept_types))->GetReference();
}
PP_Resource ResourceCreationProxy::CreateFlashDeviceID(PP_Instance instance) {
diff --git a/ppapi/shared_impl/ppb_file_ref_shared.cc b/ppapi/shared_impl/ppb_file_ref_shared.cc
index b273364..a47cdb8 100644
--- a/ppapi/shared_impl/ppb_file_ref_shared.cc
+++ b/ppapi/shared_impl/ppb_file_ref_shared.cc
@@ -17,7 +17,6 @@ PPB_FileRef_Shared::PPB_FileRef_Shared(ResourceObjectType type,
// Resource's constructor assigned a PP_Resource, so we can fill out our
// host resource now.
create_info_.resource = host_resource();
- DCHECK(!create_info_.resource.is_null());
}
}
diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h
index d2378b4..50d3ea4 100644
--- a/ppapi/thunk/interfaces_ppb_private.h
+++ b/ppapi/thunk/interfaces_ppb_private.h
@@ -23,9 +23,9 @@ PROXIED_IFACE(PPB_Instance, PPB_BROWSERFONT_TRUSTED_INTERFACE_1_0,
PPB_BrowserFont_Trusted_1_0)
PROXIED_IFACE(PPB_Instance, PPB_CHARSET_TRUSTED_INTERFACE_1_0,
PPB_CharSet_Trusted_1_0)
-PROXIED_IFACE(PPB_FileChooser, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_5,
+PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_5,
PPB_FileChooserTrusted_0_5)
-PROXIED_IFACE(PPB_FileChooser, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_6,
+PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_6,
PPB_FileChooserTrusted_0_6)
PROXIED_IFACE(PPB_FileRef, PPB_FILEREFPRIVATE_INTERFACE_0_1,
PPB_FileRefPrivate_0_1)
diff --git a/ppapi/thunk/interfaces_ppb_public_dev.h b/ppapi/thunk/interfaces_ppb_public_dev.h
index a204d22..418326b 100644
--- a/ppapi/thunk/interfaces_ppb_public_dev.h
+++ b/ppapi/thunk/interfaces_ppb_public_dev.h
@@ -10,7 +10,6 @@
PROXIED_API(PPB_AudioInput)
PROXIED_API(PPB_Buffer)
UNPROXIED_API(PPB_DirectoryReader)
-PROXIED_API(PPB_FileChooser)
PROXIED_API(PPB_Graphics3D)
UNPROXIED_API(PPB_LayerCompositor)
UNPROXIED_API(PPB_Scrollbar)
@@ -38,9 +37,9 @@ PROXIED_IFACE(NoAPIName, PPB_DEVICEREF_DEV_INTERFACE_0_1, PPB_DeviceRef_Dev_0_1)
UNPROXIED_IFACE(PPB_DirectoryReader, PPB_DIRECTORYREADER_DEV_INTERFACE_0_5,
PPB_DirectoryReader_Dev_0_5)
UNPROXIED_IFACE(PPB_Find, PPB_FIND_DEV_INTERFACE_0_3, PPB_Find_Dev_0_3)
-PROXIED_IFACE(PPB_FileChooser, PPB_FILECHOOSER_DEV_INTERFACE_0_5,
+PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_DEV_INTERFACE_0_5,
PPB_FileChooser_Dev_0_5)
-PROXIED_IFACE(PPB_FileChooser, PPB_FILECHOOSER_DEV_INTERFACE_0_6,
+PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_DEV_INTERFACE_0_6,
PPB_FileChooser_Dev_0_6)
PROXIED_IFACE(NoAPIName, PPB_GRAPHICS2D_DEV_INTERFACE_0_1,
PPB_Graphics2D_Dev_0_1)
diff --git a/webkit/glue/webkit_glue.gypi b/webkit/glue/webkit_glue.gypi
index e471305..9edf509 100644
--- a/webkit/glue/webkit_glue.gypi
+++ b/webkit/glue/webkit_glue.gypi
@@ -263,8 +263,6 @@
'../plugins/ppapi/ppb_buffer_impl.h',
'../plugins/ppapi/ppb_directory_reader_impl.cc',
'../plugins/ppapi/ppb_directory_reader_impl.h',
- '../plugins/ppapi/ppb_file_chooser_impl.cc',
- '../plugins/ppapi/ppb_file_chooser_impl.h',
'../plugins/ppapi/ppb_file_io_impl.cc',
'../plugins/ppapi/ppb_file_io_impl.h',
'../plugins/ppapi/ppb_file_ref_impl.cc',
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.cc b/webkit/plugins/ppapi/mock_plugin_delegate.cc
index 08f4f2a..69279f7 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.cc
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.cc
@@ -130,12 +130,6 @@ void MockPluginDelegate::NumberOfFindResultsChanged(int identifier,
void MockPluginDelegate::SelectedFindResultChanged(int identifier, int index) {
}
-bool MockPluginDelegate::RunFileChooser(
- const WebKit::WebFileChooserParams& params,
- WebKit::WebFileChooserCompletion* chooser_completion) {
- return false;
-}
-
bool MockPluginDelegate::AsyncOpenFile(const FilePath& path,
int flags,
const AsyncOpenFileCallback& callback) {
diff --git a/webkit/plugins/ppapi/mock_plugin_delegate.h b/webkit/plugins/ppapi/mock_plugin_delegate.h
index 2c7d6e2..9d74c2b 100644
--- a/webkit/plugins/ppapi/mock_plugin_delegate.h
+++ b/webkit/plugins/ppapi/mock_plugin_delegate.h
@@ -61,9 +61,6 @@ class MockPluginDelegate : public PluginDelegate {
int total,
bool final_result);
virtual void SelectedFindResultChanged(int identifier, int index);
- virtual bool RunFileChooser(
- const WebKit::WebFileChooserParams& params,
- WebKit::WebFileChooserCompletion* chooser_completion);
virtual bool AsyncOpenFile(const FilePath& path,
int flags,
const AsyncOpenFileCallback& callback);
diff --git a/webkit/plugins/ppapi/plugin_delegate.h b/webkit/plugins/ppapi/plugin_delegate.h
index 7ba136e..9c3e38c 100644
--- a/webkit/plugins/ppapi/plugin_delegate.h
+++ b/webkit/plugins/ppapi/plugin_delegate.h
@@ -73,12 +73,10 @@ class PlatformCanvas;
}
namespace WebKit {
-class WebFileChooserCompletion;
class WebGamepads;
class WebPlugin;
struct WebCompositionUnderline;
struct WebCursorInfo;
-struct WebFileChooserParams;
}
namespace webkit_glue {
@@ -417,11 +415,6 @@ class PluginDelegate {
// Notifies that the index of the currently selected item has been updated.
virtual void SelectedFindResultChanged(int identifier, int index) = 0;
- // Runs a file chooser.
- virtual bool RunFileChooser(
- const WebKit::WebFileChooserParams& params,
- WebKit::WebFileChooserCompletion* chooser_completion) = 0;
-
// Sends an async IPC to open a local file.
typedef base::Callback<void (base::PlatformFileError, base::PassPlatformFile)>
AsyncOpenFileCallback;
diff --git a/webkit/plugins/ppapi/ppb_file_chooser_impl.cc b/webkit/plugins/ppapi/ppb_file_chooser_impl.cc
deleted file mode 100644
index 40ef147..0000000
--- a/webkit/plugins/ppapi/ppb_file_chooser_impl.cc
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "webkit/plugins/ppapi/ppb_file_chooser_impl.h"
-
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/string_split.h"
-#include "base/string_util.h"
-#include "base/sys_string_conversions.h"
-#include "ppapi/c/pp_completion_callback.h"
-#include "ppapi/c/pp_errors.h"
-#include "ppapi/shared_impl/tracked_callback.h"
-#include "ppapi/shared_impl/var.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserCompletion.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileChooserParams.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebVector.h"
-#include "webkit/glue/webkit_glue.h"
-#include "webkit/plugins/ppapi/common.h"
-#include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
-#include "webkit/plugins/ppapi/plugin_delegate.h"
-#include "webkit/plugins/ppapi/plugin_module.h"
-#include "webkit/plugins/ppapi/ppapi_plugin_instance.h"
-#include "webkit/plugins/ppapi/resource_helper.h"
-
-using ppapi::StringVar;
-using ppapi::thunk::PPB_FileChooser_API;
-using ppapi::TrackedCallback;
-using WebKit::WebCString;
-using WebKit::WebFileChooserCompletion;
-using WebKit::WebFileChooserParams;
-using WebKit::WebString;
-using WebKit::WebVector;
-
-namespace webkit {
-namespace ppapi {
-
-namespace {
-
-class FileChooserCompletionImpl : public WebFileChooserCompletion {
- public:
- FileChooserCompletionImpl(PPB_FileChooser_Impl* file_chooser)
- : file_chooser_(file_chooser) {
- DCHECK(file_chooser_);
- }
-
- virtual ~FileChooserCompletionImpl() {}
-
- virtual void didChooseFile(const WebVector<WebString>& file_names) {
- std::vector<PPB_FileChooser_Impl::ChosenFileInfo> files;
- for (size_t i = 0; i < file_names.size(); i++) {
- files.push_back(
- PPB_FileChooser_Impl::ChosenFileInfo(file_names[i].utf8(),
- std::string()));
- }
-
- file_chooser_->StoreChosenFiles(files);
-
- // It is the responsibility of this method to delete the instance.
- delete this;
- }
- virtual void didChooseFile(const WebVector<SelectedFileInfo>& file_names) {
- std::vector<PPB_FileChooser_Impl::ChosenFileInfo> files;
- for (size_t i = 0; i < file_names.size(); i++) {
- files.push_back(
- PPB_FileChooser_Impl::ChosenFileInfo(
- file_names[i].path.utf8(),
- file_names[i].displayName.utf8()));
- }
-
- file_chooser_->StoreChosenFiles(files);
-
- // It is the responsibility of this method to delete the instance.
- delete this;
- }
-
- private:
- scoped_refptr<PPB_FileChooser_Impl> file_chooser_;
-};
-
-} // namespace
-
-PPB_FileChooser_Impl::ChosenFileInfo::ChosenFileInfo(
- const std::string& path,
- const std::string& display_name)
- : path(path),
- display_name(display_name) {
-}
-
-PPB_FileChooser_Impl::PPB_FileChooser_Impl(
- PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types)
- : Resource(::ppapi::OBJECT_IS_IMPL, instance),
- mode_(mode),
- next_chosen_file_index_(0) {
- if (accept_types)
- accept_types_ = std::string(accept_types);
-}
-
-PPB_FileChooser_Impl::~PPB_FileChooser_Impl() {
-}
-
-// static
-PP_Resource PPB_FileChooser_Impl::Create(
- PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types) {
- if (mode != PP_FILECHOOSERMODE_OPEN &&
- mode != PP_FILECHOOSERMODE_OPENMULTIPLE)
- return 0;
- return (new PPB_FileChooser_Impl(instance, mode,
- accept_types))->GetReference();
-}
-
-PPB_FileChooser_Impl* PPB_FileChooser_Impl::AsPPB_FileChooser_Impl() {
- return this;
-}
-
-PPB_FileChooser_API* PPB_FileChooser_Impl::AsPPB_FileChooser_API() {
- return this;
-}
-
-void PPB_FileChooser_Impl::StoreChosenFiles(
- const std::vector<ChosenFileInfo>& files) {
- next_chosen_file_index_ = 0;
-
- // It is possible that |callback_| has been run: before the user takes action
- // on the file chooser, the page navigates away and causes the plugin module
- // (whose instance requested to show the file chooser) to be destroyed. In
- // that case, |callback_| has been aborted when we get here.
- if (!TrackedCallback::IsPending(callback_)) {
- // To be cautious, reset our internal state.
- output_.Reset();
- chosen_files_.clear();
- return;
- }
-
- std::vector< scoped_refptr<Resource> > chosen_files;
- for (std::vector<ChosenFileInfo>::const_iterator it = files.begin();
- it != files.end(); ++it) {
-#if defined(OS_WIN)
- FilePath file_path(base::SysUTF8ToWide(it->path));
-#else
- FilePath file_path(it->path);
-#endif
-
- chosen_files.push_back(scoped_refptr<Resource>(
- PPB_FileRef_Impl::CreateExternal(pp_instance(),
- file_path,
- it->display_name)));
- }
-
- int32_t result_code = (chosen_files.size() > 0) ? PP_OK : PP_ERROR_USERCANCEL;
- if (output_.is_valid())
- output_.StoreResourceVector(chosen_files);
- else // v0.5 API.
- chosen_files_.swap(chosen_files);
- RunCallback(result_code);
-}
-
-int32_t PPB_FileChooser_Impl::ValidateCallback(
- scoped_refptr<TrackedCallback> callback) {
- if (TrackedCallback::IsPending(callback_))
- return PP_ERROR_INPROGRESS;
-
- return PP_OK;
-}
-
-void PPB_FileChooser_Impl::RegisterCallback(
- scoped_refptr<TrackedCallback> callback) {
- DCHECK(!TrackedCallback::IsPending(callback_));
-
- PluginModule* plugin_module = ResourceHelper::GetPluginModule(this);
- if (!plugin_module)
- return;
-
- callback_ = callback;
-}
-
-void PPB_FileChooser_Impl::RunCallback(int32_t result) {
- TrackedCallback::ClearAndRun(&callback_, result);
-}
-
-int32_t PPB_FileChooser_Impl::Show(const PP_ArrayOutput& output,
- scoped_refptr<TrackedCallback> callback) {
- int32_t result = Show0_5(callback);
- if (result == PP_OK_COMPLETIONPENDING)
- output_.set_pp_array_output(output);
- return result;
-}
-
-int32_t PPB_FileChooser_Impl::ShowWithoutUserGesture(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- const PP_ArrayOutput& output,
- scoped_refptr<TrackedCallback> callback) {
- int32_t result = ShowWithoutUserGesture0_5(save_as, suggested_file_name,
- callback);
- if (result == PP_OK_COMPLETIONPENDING)
- output_.set_pp_array_output(output);
- return result;
-}
-
-int32_t PPB_FileChooser_Impl::Show0_5(scoped_refptr<TrackedCallback> callback) {
- PluginInstance* plugin_instance = ResourceHelper::GetPluginInstance(this);
- if (!plugin_instance)
- return PP_ERROR_FAILED;
- if (!plugin_instance->IsProcessingUserGesture())
- return PP_ERROR_NO_USER_GESTURE;
- return ShowWithoutUserGesture0_5(PP_FALSE, PP_MakeUndefined(), callback);
-}
-
-int32_t PPB_FileChooser_Impl::ShowWithoutUserGesture0_5(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- scoped_refptr<TrackedCallback> callback) {
- int32_t rv = ValidateCallback(callback);
- if (rv != PP_OK)
- return rv;
-
- DCHECK((mode_ == PP_FILECHOOSERMODE_OPEN) ||
- (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE));
-
- WebFileChooserParams params;
- if (save_as) {
- params.saveAs = true;
- StringVar* str = StringVar::FromPPVar(suggested_file_name);
- if (str)
- params.initialValue = WebString::fromUTF8(str->value().c_str());
- } else {
- params.multiSelect = (mode_ == PP_FILECHOOSERMODE_OPENMULTIPLE);
- }
- params.acceptTypes = ParseAcceptValue(accept_types_);
- params.directory = false;
-
- PluginDelegate* plugin_delegate = ResourceHelper::GetPluginDelegate(this);
- if (!plugin_delegate)
- return PP_ERROR_FAILED;
-
- if (!plugin_delegate->RunFileChooser(params,
- new FileChooserCompletionImpl(this)))
- return PP_ERROR_FAILED;
-
- RegisterCallback(callback);
- return PP_OK_COMPLETIONPENDING;
-}
-
-PP_Resource PPB_FileChooser_Impl::GetNextChosenFile() {
- if (next_chosen_file_index_ >= chosen_files_.size())
- return 0;
-
- return chosen_files_[next_chosen_file_index_++]->GetReference();
-}
-
-std::vector<WebString> PPB_FileChooser_Impl::ParseAcceptValue(
- const std::string& accept_types) {
- if (accept_types.empty())
- return std::vector<WebString>();
- std::vector<std::string> type_list;
- base::SplitString(accept_types, ',', &type_list);
- std::vector<WebString> normalized_type_list;
- normalized_type_list.reserve(type_list.size());
- for (size_t i = 0; i < type_list.size(); ++i) {
- std::string type = type_list[i];
- TrimWhitespaceASCII(type, TRIM_ALL, &type);
-
- // If the type is a single character, it definitely cannot be valid. In the
- // case of a file extension it would be a single ".". In the case of a MIME
- // type it would just be a "/".
- if (type.length() < 2)
- continue;
- if (type.find_first_of('/') == std::string::npos && type[0] != '.')
- continue;
- StringToLowerASCII(&type);
- normalized_type_list.push_back(WebString::fromUTF8(type.data(),
- type.size()));
- }
- return normalized_type_list;
-}
-
-} // namespace ppapi
-} // namespace webkit
diff --git a/webkit/plugins/ppapi/ppb_file_chooser_impl.h b/webkit/plugins/ppapi/ppb_file_chooser_impl.h
deleted file mode 100644
index 59de2ac..0000000
--- a/webkit/plugins/ppapi/ppb_file_chooser_impl.h
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef WEBKIT_PLUGINS_PPAPI_PPB_FILE_CHOOSER_IMPL_H_
-#define WEBKIT_PLUGINS_PPAPI_PPB_FILE_CHOOSER_IMPL_H_
-
-#include <string>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/memory/ref_counted.h"
-#include "ppapi/c/dev/ppb_file_chooser_dev.h"
-#include "ppapi/shared_impl/array_writer.h"
-#include "ppapi/shared_impl/resource.h"
-#include "ppapi/thunk/ppb_file_chooser_api.h"
-#include "webkit/plugins/webkit_plugins_export.h"
-
-namespace ppapi {
-class TrackedCallback;
-}
-
-namespace WebKit {
-class WebString;
-}
-
-namespace webkit {
-namespace ppapi {
-
-class PPB_FileRef_Impl;
-
-class PPB_FileChooser_Impl : public ::ppapi::Resource,
- public ::ppapi::thunk::PPB_FileChooser_API {
- public:
- // Structure to store the information of chosen files.
- struct ChosenFileInfo {
- ChosenFileInfo(const std::string& path, const std::string& display_name);
- std::string path;
- // |display_name| may be empty.
- std::string display_name;
- };
-
- PPB_FileChooser_Impl(PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types);
- virtual ~PPB_FileChooser_Impl();
-
- static PP_Resource Create(PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types);
-
- // Resource overrides.
- virtual PPB_FileChooser_Impl* AsPPB_FileChooser_Impl();
-
- // Resource overrides.
- virtual ::ppapi::thunk::PPB_FileChooser_API* AsPPB_FileChooser_API() OVERRIDE;
-
- // Stores the list of selected files.
- void StoreChosenFiles(const std::vector<ChosenFileInfo>& files);
-
- // Check that |callback| is valid (only non-blocking operation is supported)
- // and that no callback is already pending. Returns |PP_OK| if okay, else
- // |PP_ERROR_...| to be returned to the plugin.
- int32_t ValidateCallback(scoped_refptr< ::ppapi::TrackedCallback> callback);
-
- // Sets up |callback| as the pending callback. This should only be called once
- // it is certain that |PP_OK_COMPLETIONPENDING| will be returned.
- void RegisterCallback(scoped_refptr< ::ppapi::TrackedCallback> callback);
-
- void RunCallback(int32_t result);
-
- // PPB_FileChooser_API implementation.
- virtual int32_t Show(
- const PP_ArrayOutput& output,
- scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE;
- virtual int32_t ShowWithoutUserGesture(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- const PP_ArrayOutput& output,
- scoped_refptr< ::ppapi::TrackedCallback> callback);
- virtual int32_t Show0_5(
- scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE;
- virtual PP_Resource GetNextChosenFile() OVERRIDE;
- virtual int32_t ShowWithoutUserGesture0_5(
- PP_Bool save_as,
- PP_Var suggested_file_name,
- scoped_refptr< ::ppapi::TrackedCallback> callback) OVERRIDE;
-
- // Splits a comma-separated MIME type/extension list |accept_types|, trims the
- // resultant split types, makes them lowercase, and returns them.
- // Though this should be private, this is public for testing.
- WEBKIT_PLUGINS_EXPORT static std::vector<WebKit::WebString> ParseAcceptValue(
- const std::string& accept_types);
-
- private:
- PP_FileChooserMode_Dev mode_;
- std::string accept_types_;
- scoped_refptr< ::ppapi::TrackedCallback> callback_;
-
- // When using the v0.6 of the API, this will contain the output for the
- // resources when the show command is complete. When using 0.5, this
- // object will be is_null() and the chosen_files_ will be used instead.
- ::ppapi::ArrayWriter output_;
-
- // Used to store and iterate over the results when using 0.5 of the API.
- // These are valid when we get a file result and output_ is not null.
- std::vector< scoped_refptr<Resource> > chosen_files_;
- size_t next_chosen_file_index_;
-};
-
-} // namespace ppapi
-} // namespace webkit
-
-#endif // WEBKIT_PLUGINS_PPAPI_PPB_FILE_CHOOSER_IMPL_H_
diff --git a/webkit/plugins/ppapi/ppb_file_chooser_impl_unittest.cc b/webkit/plugins/ppapi/ppb_file_chooser_impl_unittest.cc
deleted file mode 100644
index 129566f..0000000
--- a/webkit/plugins/ppapi/ppb_file_chooser_impl_unittest.cc
+++ /dev/null
@@ -1,39 +0,0 @@
-// 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 "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
-#include "webkit/plugins/ppapi/ppb_file_chooser_impl.h"
-
-using WebKit::WebString;
-
-namespace webkit {
-namespace ppapi {
-
-TEST(PPB_FileChooser_ImplTest, ParseAcceptValue) {
- std::vector<WebString> parsed;
-
- parsed = PPB_FileChooser_Impl::ParseAcceptValue("");
- EXPECT_EQ(0U, parsed.size());
-
- parsed = PPB_FileChooser_Impl::ParseAcceptValue(" ");
- EXPECT_EQ(0U, parsed.size());
-
- parsed = PPB_FileChooser_Impl::ParseAcceptValue("a");
- EXPECT_EQ(0U, parsed.size());
-
- parsed = PPB_FileChooser_Impl::ParseAcceptValue(",, ");
- EXPECT_EQ(0U, parsed.size());
-
- parsed = PPB_FileChooser_Impl::ParseAcceptValue(
- "IMAGE/*,,!!,,text/plain, audio /(*) ");
- EXPECT_EQ(3U, parsed.size());
- EXPECT_EQ("image/*", parsed[0]);
- EXPECT_EQ("text/plain", parsed[1]);
- // We don't need to reject invalid MIME tokens strictly.
- EXPECT_EQ("audio /(*)", parsed[2]);
-}
-
-} // namespace ppapi
-} // namespace webkit
diff --git a/webkit/plugins/ppapi/ppb_file_ref_impl.h b/webkit/plugins/ppapi/ppb_file_ref_impl.h
index 9b33758..d7bb8c5 100644
--- a/webkit/plugins/ppapi/ppb_file_ref_impl.h
+++ b/webkit/plugins/ppapi/ppb_file_ref_impl.h
@@ -12,6 +12,7 @@
#include "ppapi/c/ppb_file_ref.h"
#include "ppapi/shared_impl/ppb_file_ref_shared.h"
#include "ppapi/shared_impl/var.h"
+#include "webkit/glue/webkit_glue_export.h"
namespace webkit {
namespace ppapi {
@@ -20,7 +21,8 @@ using ::ppapi::StringVar;
class PPB_FileSystem_Impl;
-class PPB_FileRef_Impl : public ::ppapi::PPB_FileRef_Shared {
+class WEBKIT_GLUE_EXPORT PPB_FileRef_Impl
+ : public ::ppapi::PPB_FileRef_Shared {
public:
PPB_FileRef_Impl(const ::ppapi::PPB_FileRef_CreateInfo& info,
PPB_FileSystem_Impl* file_system);
diff --git a/webkit/plugins/ppapi/resource_creation_impl.cc b/webkit/plugins/ppapi/resource_creation_impl.cc
index 8636056..3d4fd0a 100644
--- a/webkit/plugins/ppapi/resource_creation_impl.cc
+++ b/webkit/plugins/ppapi/resource_creation_impl.cc
@@ -16,7 +16,6 @@
#include "webkit/plugins/ppapi/ppb_broker_impl.h"
#include "webkit/plugins/ppapi/ppb_buffer_impl.h"
#include "webkit/plugins/ppapi/ppb_directory_reader_impl.h"
-#include "webkit/plugins/ppapi/ppb_file_chooser_impl.h"
#include "webkit/plugins/ppapi/ppb_file_io_impl.h"
#include "webkit/plugins/ppapi/ppb_file_ref_impl.h"
#include "webkit/plugins/ppapi/ppb_file_system_impl.h"
@@ -115,13 +114,6 @@ PP_Resource ResourceCreationImpl::CreateDirectoryReader(
return PPB_DirectoryReader_Impl::Create(directory_ref);
}
-PP_Resource ResourceCreationImpl::CreateFileChooser(
- PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types) {
- return PPB_FileChooser_Impl::Create(instance, mode, accept_types);
-}
-
PP_Resource ResourceCreationImpl::CreateFileIO(PP_Instance instance) {
return (new PPB_FileIO_Impl(instance))->GetReference();
}
diff --git a/webkit/plugins/ppapi/resource_creation_impl.h b/webkit/plugins/ppapi/resource_creation_impl.h
index 9c5a97c..42796ed 100644
--- a/webkit/plugins/ppapi/resource_creation_impl.h
+++ b/webkit/plugins/ppapi/resource_creation_impl.h
@@ -43,10 +43,6 @@ class WEBKIT_PLUGINS_EXPORT ResourceCreationImpl
virtual PP_Resource CreateBuffer(PP_Instance instance,
uint32_t size) OVERRIDE;
virtual PP_Resource CreateDirectoryReader(PP_Resource directory_ref) OVERRIDE;
- virtual PP_Resource CreateFileChooser(
- PP_Instance instance,
- PP_FileChooserMode_Dev mode,
- const char* accept_types) OVERRIDE;
virtual PP_Resource CreateFileIO(PP_Instance instance) OVERRIDE;
virtual PP_Resource CreateFileRef(PP_Resource file_system,
const char* path) OVERRIDE;
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index 76299c6f..2ac3fae 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -389,7 +389,6 @@
'../../plugins/ppapi/mock_resource.h',
'../../plugins/ppapi/ppapi_unittest.cc',
'../../plugins/ppapi/ppapi_unittest.h',
- '../../plugins/ppapi/ppb_file_chooser_impl_unittest.cc',
'../../plugins/ppapi/quota_file_io_unittest.cc',
'../../plugins/ppapi/time_conversion_unittest.cc',
'../../plugins/ppapi/url_request_info_unittest.cc',