1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "base/message_loop/message_loop.h" 6 #include "ppapi/c/dev/ppb_file_chooser_dev.h" 7 #include "ppapi/c/pp_errors.h" 8 #include "ppapi/c/ppb_file_ref.h" 9 #include "ppapi/proxy/file_chooser_resource.h" 10 #include "ppapi/proxy/locking_resource_releaser.h" 11 #include "ppapi/proxy/plugin_message_filter.h" 12 #include "ppapi/proxy/ppapi_messages.h" 13 #include "ppapi/proxy/ppapi_proxy_test.h" 14 #include "ppapi/shared_impl/proxy_lock.h" 15 #include "ppapi/shared_impl/scoped_pp_var.h" 16 #include "ppapi/shared_impl/var.h" 17 #include "ppapi/thunk/thunk.h" 18 19 namespace ppapi { 20 namespace proxy { 21 22 namespace { 23 24 typedef PluginProxyTest FileChooserResourceTest; 25 26 void* GetFileRefDataBuffer(void* user_data, 27 uint32_t element_count, 28 uint32_t element_size) { 29 EXPECT_TRUE(element_size == sizeof(PP_Resource)); 30 std::vector<PP_Resource>* output = 31 static_cast<std::vector<PP_Resource>*>(user_data); 32 output->resize(element_count); 33 if (element_count > 0) 34 return &(*output)[0]; 35 return NULL; 36 } 37 38 void DoNothingCallback(void* user_data, int32_t result) { 39 } 40 41 // Calls PopulateAcceptTypes and verifies that the resulting array contains 42 // the given values. The values may be NULL if there aren't expected to be 43 // that many results. 44 bool CheckParseAcceptType(const std::string& input, 45 const char* expected1, 46 const char* expected2) { 47 std::vector<std::string> output; 48 FileChooserResource::PopulateAcceptTypes(input, &output); 49 50 const size_t kCount = 2; 51 const char* expected[kCount] = { expected1, expected2 }; 52 53 for (size_t i = 0; i < kCount; i++) { 54 if (!expected[i]) 55 return i == output.size(); 56 if (output.size() <= i) 57 return false; 58 if (output[i] != expected[i]) 59 return false; 60 } 61 62 return output.size() == kCount; 63 } 64 65 } // namespace 66 67 // Does a full test of Show() and reply functionality in the plugin side using 68 // the public C interfaces. 69 TEST_F(FileChooserResourceTest, Show) { 70 const PPB_FileChooser_Dev_0_6* chooser_iface = 71 thunk::GetPPB_FileChooser_Dev_0_6_Thunk(); 72 LockingResourceReleaser res( 73 chooser_iface->Create(pp_instance(), PP_FILECHOOSERMODE_OPEN, 74 PP_MakeUndefined())); 75 76 std::vector<PP_Resource> dest; 77 PP_ArrayOutput output; 78 output.GetDataBuffer = &GetFileRefDataBuffer; 79 output.user_data = &dest; 80 81 int32_t result = chooser_iface->Show( 82 res.get(), output, PP_MakeCompletionCallback(&DoNothingCallback, NULL)); 83 ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 84 85 // Should have sent a "show" message. 86 ResourceMessageCallParams params; 87 IPC::Message msg; 88 ASSERT_TRUE(sink().GetFirstResourceCallMatching( 89 PpapiHostMsg_FileChooser_Show::ID, ¶ms, &msg)); 90 91 ResourceMessageReplyParams reply_params(params.pp_resource(), 92 params.sequence()); 93 reply_params.set_result(PP_OK); 94 95 // Synthesize a response with one file ref in it. Note that it must have a 96 // pending_host_resource_id set. Since there isn't actually a host, this can 97 // be whatever we want. 98 std::vector<FileRefCreateInfo> create_info_array; 99 FileRefCreateInfo create_info; 100 create_info.file_system_type = PP_FILESYSTEMTYPE_EXTERNAL; 101 create_info.display_name = "bar"; 102 create_info.browser_pending_host_resource_id = 12; 103 create_info.renderer_pending_host_resource_id = 15; 104 create_info_array.push_back(create_info); 105 PluginMessageFilter::DispatchResourceReplyForTest( 106 reply_params, PpapiPluginMsg_FileChooser_ShowReply(create_info_array)); 107 108 // Should have populated our vector. 109 ASSERT_EQ(1u, dest.size()); 110 LockingResourceReleaser dest_deletor(dest[0]); // Ensure it's cleaned up. 111 112 const PPB_FileRef_1_0* file_ref_iface = thunk::GetPPB_FileRef_1_0_Thunk(); 113 EXPECT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, 114 file_ref_iface->GetFileSystemType(dest[0])); 115 116 PP_Var name_var(file_ref_iface->GetName(dest[0])); 117 { 118 ProxyAutoLock lock; 119 ScopedPPVar release_name_var(ScopedPPVar::PassRef(), name_var); 120 EXPECT_VAR_IS_STRING("bar", name_var); 121 } 122 PP_Var path_var(file_ref_iface->GetPath(dest[0])); 123 { 124 ProxyAutoLock lock; 125 ScopedPPVar release_path_var(ScopedPPVar::PassRef(), path_var); 126 EXPECT_EQ(PP_VARTYPE_UNDEFINED, path_var.type); 127 } 128 } 129 130 TEST_F(FileChooserResourceTest, PopulateAcceptTypes) { 131 EXPECT_TRUE(CheckParseAcceptType(std::string(), NULL, NULL)); 132 EXPECT_TRUE(CheckParseAcceptType("/", NULL, NULL)); 133 EXPECT_TRUE(CheckParseAcceptType(".", NULL, NULL)); 134 EXPECT_TRUE(CheckParseAcceptType(",, , ", NULL, NULL)); 135 136 EXPECT_TRUE(CheckParseAcceptType("app/txt", "app/txt", NULL)); 137 EXPECT_TRUE(CheckParseAcceptType("app/txt,app/pdf", "app/txt", "app/pdf")); 138 EXPECT_TRUE(CheckParseAcceptType(" app/txt , app/pdf ", 139 "app/txt", "app/pdf")); 140 141 // No dot or slash ones should be skipped. 142 EXPECT_TRUE(CheckParseAcceptType("foo", NULL, NULL)); 143 EXPECT_TRUE(CheckParseAcceptType("foo,.txt", ".txt", NULL)); 144 } 145 146 } // namespace proxy 147 } // namespace ppapi 148