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
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, ¶ms, &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