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)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/common/view_messages.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/file_chooser_params.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/test/render_view_test.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/pepper/mock_renderer_ppapi_host.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/pepper/pepper_file_chooser_host.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/render_view_impl.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/test/test_content_client.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/host/host_message_context.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/host/ppapi_host.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/resource_message_params.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/proxy/resource_message_test_sink.h"
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ppapi/shared_impl/file_ref_create_info.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/ppapi_permissions.h"
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ppapi/shared_impl/proxy_lock.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/resource_tracker.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/shared_impl/test_globals.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/shell_dialogs/selected_file_info.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PepperFileChooserHostTest : public RenderViewTest {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  PepperFileChooserHostTest() : pp_instance_(123456) {}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SetContentClient(&client_);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewTest::SetUp();
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ppapi::ProxyLock::DisableLockingOnThreadForTest();
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    globals_.GetResourceTracker()->DidCreateInstance(pp_instance_);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RenderViewTest::TearDown();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Instance pp_instance() const { return pp_instance_; }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Instance pp_instance_;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppapi::TestGlobals globals_;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestContentClient client_;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For testing to convert our hardcoded file paths to 8-bit.
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FilePathToUTF8(const base::FilePath::StringType& path) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::UTF16ToUTF8(path);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return path;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben MurdochTEST_F(PepperFileChooserHostTest, Show) {
70c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  PP_Resource pp_resource = 123;
71c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
72c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  MockRendererPpapiHost host(view_, pp_instance());
73c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  PepperFileChooserHost chooser(&host, pp_instance(), pp_resource);
74c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
75c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // Say there's a user gesture.
76c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  host.set_has_user_gesture(true);
77c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
78c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  std::vector<std::string> accept;
79c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  accept.push_back("text/plain");
80c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  PpapiHostMsg_FileChooser_Show show_msg(false, false, std::string(), accept);
81c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
82c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ppapi::proxy::ResourceMessageCallParams call_params(pp_resource, 0);
83c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ppapi::host::HostMessageContext context(call_params);
84c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  int32 result = chooser.OnResourceMessageReceived(show_msg, &context);
85c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXPECT_EQ(PP_OK_COMPLETIONPENDING, result);
86c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
87c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // The render view should have sent a chooser request to the browser
88c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // (caught by the render thread's test message sink).
89c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  const IPC::Message* msg = render_thread_->sink().GetUniqueMessageMatching(
90c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      ViewHostMsg_RunFileChooser::ID);
91c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ASSERT_TRUE(msg);
92c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ViewHostMsg_RunFileChooser::Schema::Param call_msg_param;
93c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ASSERT_TRUE(ViewHostMsg_RunFileChooser::Read(msg, &call_msg_param));
94c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  const FileChooserParams& chooser_params = call_msg_param.a;
95c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
96c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // Basic validation of request.
97c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXPECT_EQ(FileChooserParams::Open, chooser_params.mode);
98c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ASSERT_EQ(1u, chooser_params.accept_types.size());
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EXPECT_EQ(accept[0], base::UTF16ToUTF8(chooser_params.accept_types[0]));
100c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
101c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // Send a chooser reply to the render view. Note our reply path has to have a
102c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // path separator so we include both a Unix and a Windows one.
103c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ui::SelectedFileInfo selected_info;
104c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  selected_info.display_name = FILE_PATH_LITERAL("Hello, world");
105c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  selected_info.local_path = base::FilePath(FILE_PATH_LITERAL("myp\\ath/foo"));
106c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  std::vector<ui::SelectedFileInfo> selected_info_vector;
107c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  selected_info_vector.push_back(selected_info);
108c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  RenderViewImpl* view_impl = static_cast<RenderViewImpl*>(view_);
109c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ViewMsg_RunFileChooserResponse response(view_impl->routing_id(),
110c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                          selected_info_vector);
111c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXPECT_TRUE(view_impl->OnMessageReceived(response));
112c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
113c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // This should have sent the Pepper reply to our test sink.
114c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ppapi::proxy::ResourceMessageReplyParams reply_params;
115c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  IPC::Message reply_msg;
116c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ASSERT_TRUE(host.sink().GetFirstResourceReplyMatching(
117c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      PpapiPluginMsg_FileChooser_ShowReply::ID, &reply_params, &reply_msg));
118c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
119c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  // Basic validation of reply.
120c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXPECT_EQ(call_params.sequence(), reply_params.sequence());
121c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXPECT_EQ(PP_OK, reply_params.result());
122c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  PpapiPluginMsg_FileChooser_ShowReply::Schema::Param reply_msg_param;
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ASSERT_TRUE(
124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg, &reply_msg_param));
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  const std::vector<ppapi::FileRefCreateInfo>& chooser_results =
126c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      reply_msg_param.a;
127c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  ASSERT_EQ(1u, chooser_results.size());
128c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXPECT_EQ(FilePathToUTF8(selected_info.display_name),
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)            chooser_results[0].display_name);
130c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch}
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(PepperFileChooserHostTest, NoUserGesture) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource pp_resource = 123;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MockRendererPpapiHost host(view_, pp_instance());
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PepperFileChooserHost chooser(&host, pp_instance(), pp_resource);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Say there's no user gesture.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host.set_has_user_gesture(false);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> accept;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  accept.push_back("text/plain");
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PpapiHostMsg_FileChooser_Show show_msg(false, false, std::string(), accept);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppapi::proxy::ResourceMessageCallParams call_params(pp_resource, 0);
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ppapi::host::HostMessageContext context(call_params);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32 result = chooser.OnResourceMessageReceived(show_msg, &context);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(PP_ERROR_NO_USER_GESTURE, result);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace content
152