15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 59ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/dev/ppb_file_chooser_dev.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h" 8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ppapi/c/ppb_file_ref.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/file_chooser_resource.h" 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/proxy/locking_resource_releaser.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ppapi/proxy/plugin_message_filter.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_proxy_test.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/scoped_pp_var.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/var.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/thunk/thunk.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ppapi { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace proxy { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef PluginProxyTest FileChooserResourceTest; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* GetFileRefDataBuffer(void* user_data, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_count, 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32_t element_size) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(element_size == sizeof(PP_Resource)); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_Resource>* output = 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<std::vector<PP_Resource>*>(user_data); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->resize(element_count); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element_count > 0) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &(*output)[0]; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DoNothingCallback(void* user_data, int32_t result) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Calls PopulateAcceptTypes and verifies that the resulting array contains 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the given values. The values may be NULL if there aren't expected to be 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that many results. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CheckParseAcceptType(const std::string& input, 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* expected1, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* expected2) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> output; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileChooserResource::PopulateAcceptTypes(input, &output); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const size_t kCount = 2; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* expected[kCount] = { expected1, expected2 }; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < kCount; i++) { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!expected[i]) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return i == output.size(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output.size() <= i) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (output[i] != expected[i]) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return output.size() == kCount; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Does a full test of Show() and reply functionality in the plugin side using 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the public C interfaces. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileChooserResourceTest, Show) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_FileChooser_Dev_0_6* chooser_iface = 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thunk::GetPPB_FileChooser_Dev_0_6_Thunk(); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LockingResourceReleaser res( 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chooser_iface->Create(pp_instance(), PP_FILECHOOSERMODE_OPEN, 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_MakeUndefined())); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<PP_Resource> dest; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PP_ArrayOutput output; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.GetDataBuffer = &GetFileRefDataBuffer; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.user_data = &dest; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32_t result = chooser_iface->Show( 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) res.get(), output, PP_MakeCompletionCallback(&DoNothingCallback, NULL)); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(PP_OK_COMPLETIONPENDING, result); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should have sent a "show" message. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceMessageCallParams params; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC::Message msg; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(sink().GetFirstResourceCallMatching( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PpapiHostMsg_FileChooser_Show::ID, ¶ms, &msg)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResourceMessageReplyParams reply_params(params.pp_resource(), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.sequence()); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_params.set_result(PP_OK); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Synthesize a response with one file ref in it. Note that it must have a 96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // pending_host_resource_id set. Since there isn't actually a host, this can 97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // be whatever we want. 98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) std::vector<FileRefCreateInfo> create_info_array; 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) FileRefCreateInfo create_info; 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) create_info.file_system_type = PP_FILESYSTEMTYPE_EXTERNAL; 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) create_info.display_name = "bar"; 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) create_info.browser_pending_host_resource_id = 12; 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) create_info.renderer_pending_host_resource_id = 15; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_info_array.push_back(create_info); 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) PluginMessageFilter::DispatchResourceReplyForTest( 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) reply_params, PpapiPluginMsg_FileChooser_ShowReply(create_info_array)); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should have populated our vector. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1u, dest.size()); 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LockingResourceReleaser dest_deletor(dest[0]); // Ensure it's cleaned up. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PPB_FileRef_1_0* file_ref_iface = thunk::GetPPB_FileRef_1_0_Thunk(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_ref_iface->GetFileSystemType(dest[0])); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Var name_var(file_ref_iface->GetName(dest[0])); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyAutoLock lock; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedPPVar release_name_var(ScopedPPVar::PassRef(), name_var); 120d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) EXPECT_VAR_IS_STRING("bar", name_var); 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Var path_var(file_ref_iface->GetPath(dest[0])); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ProxyAutoLock lock; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ScopedPPVar release_path_var(ScopedPPVar::PassRef(), path_var); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(PP_VARTYPE_UNDEFINED, path_var.type); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(FileChooserResourceTest, PopulateAcceptTypes) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType(std::string(), NULL, NULL)); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType("/", NULL, NULL)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType(".", NULL, NULL)); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType(",, , ", NULL, NULL)); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType("app/txt", "app/txt", NULL)); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType("app/txt,app/pdf", "app/txt", "app/pdf")); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType(" app/txt , app/pdf ", 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "app/txt", "app/pdf")); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No dot or slash ones should be skipped. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType("foo", NULL, NULL)); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(CheckParseAcceptType("foo,.txt", ".txt", NULL)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace proxy 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ppapi 148