1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// found in the LICENSE file. 4a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 5a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include <string> 6a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 7a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/c/ppb_file_io.h" 8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/cpp/file_io.h" 9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/cpp/file_ref.h" 10a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/cpp/file_system.h" 11a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/cpp/instance.h" 12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/cpp/module.h" 13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/cpp/var.h" 14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/cpp/var_dictionary.h" 15a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ppapi/tests/test_utils.h" 16a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 17a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch/// The Instance class. Receives the file through HandleMessage(), and returns 18a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch/// data to the plugin with PostMessage(). 19a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass FilePassingInstance : public pp::Instance { 20a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public: 21a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch /// The constructor creates the plugin-side instance. 22a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch /// @param[in] instance the handle to the browser-side plugin instance. 23a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch explicit FilePassingInstance(PP_Instance instance); 24a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual ~FilePassingInstance(); 25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]); 27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 28a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch private: 29a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch /// Handler for messages coming in from the browser via postMessage(). 30a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch /// @param[in] var_message The message posted by the browser. 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual void HandleMessage(const pp::Var& var_message); 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 33a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch /// Takes a fileEntry-dictionary message received from JavaScript and converts 34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch /// it into a pp::FileRef. On failure, returns a null FileRef. 35a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::FileRef ParseMessage(const pp::Var& var_message, std::string* test_type); 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch void TestRead(pp::FileRef file_ref); 38a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch void TestWrite(pp::FileRef file_ref); 39a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 40a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 41a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochFilePassingInstance::FilePassingInstance(PP_Instance instance) 42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch : pp::Instance(instance) {} 43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 44a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochFilePassingInstance::~FilePassingInstance() {} 45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 46a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochbool FilePassingInstance::Init(uint32_t argc, 47a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const char* argn[], 48a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const char* argv[]) { 49a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("ready"); 50a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return true; 51a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 52a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 53a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochpp::FileRef FilePassingInstance::ParseMessage(const pp::Var& var_message, 54a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string* test_type) { 55a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!var_message.is_dictionary()) { 56a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Message was not a dictionary."); 57a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return pp::FileRef(); 58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::VarDictionary var_dictionary_message(var_message); 60a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::Var var_filesystem = var_dictionary_message.Get("filesystem"); 61a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::Var var_fullpath = var_dictionary_message.Get("fullPath"); 62a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::Var var_testtype = var_dictionary_message.Get("testType"); 63a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 64a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!var_filesystem.is_resource()) { 65a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Filesystem was missing or not a resource."); 66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return pp::FileRef(); 67a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 68a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::Resource resource_filesystem = var_filesystem.AsResource(); 69a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!var_fullpath.is_string()) { 70a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("FullPath was missing or not a string."); 71a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return pp::FileRef(); 72a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 73a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string fullpath = var_fullpath.AsString(); 74a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!var_testtype.is_string()) { 75a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("TestType was missing or not a string."); 76a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return pp::FileRef(); 77a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string name_of_test = var_testtype.AsString(); 79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 80a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!pp::FileSystem::IsFileSystem(resource_filesystem)) { 81a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Filesystem was not a file system."); 82a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return pp::FileRef(); 83a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 84a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 85a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch *test_type = name_of_test; 86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::FileSystem filesystem(resource_filesystem); 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Note: The filesystem is already open (there is no need to call Open again). 88a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 89a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return pp::FileRef(filesystem, fullpath.c_str()); 90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid FilePassingInstance::HandleMessage(const pp::Var& var_message) { 93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // Extract the filesystem and fullPath from the message. 94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch std::string test_type; 95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::FileRef file_ref = ParseMessage(var_message, &test_type); 96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (file_ref.is_null()) 97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (test_type == "read_test") { 100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch TestRead(file_ref); 101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else if (test_type == "write_test") { 102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch TestWrite(file_ref); 103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } else { 104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Unknown test type"); 105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid FilePassingInstance::TestRead(pp::FileRef file_ref) { 109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::FileIO file_io(pp::InstanceHandle(this)); 110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch { 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch TestCompletionCallback callback(pp_instance(), PP_REQUIRED); 113a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback.WaitForResult( 114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch file_io.Open(file_ref, PP_FILEOPENFLAG_READ, callback.GetCallback())); 115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (callback.result() != PP_OK) { 116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Could not open file"); 117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch { 121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch TestCompletionCallbackWithOutput<std::vector<char> > callback(pp_instance(), 122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PP_REQUIRED); 123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback.WaitForResult( 124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch file_io.Read(0, 1024, callback.GetCallback())); 125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (callback.result() < 0) { 126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Could not read file"); 127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 129a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 130a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (callback.output().size() != 306) { 131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Read the wrong number of bytes"); 132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("read_success"); 136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid FilePassingInstance::TestWrite(pp::FileRef file_ref) { 139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch pp::FileIO file_io(pp::InstanceHandle(this)); 140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch TestCompletionCallback callback(pp_instance(), PP_REQUIRED); 141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch callback.WaitForResult( 142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch file_io.Open(file_ref, PP_FILEOPENFLAG_WRITE, callback.GetCallback())); 143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (callback.result() != PP_ERROR_NOACCESS) { 144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("Opening for write should have failed"); 145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return; 146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PostMessage("write_success"); 148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochclass FilePassingModule : public pp::Module { 151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch public: 152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FilePassingModule() : pp::Module() {} 153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual ~FilePassingModule() {} 154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch virtual pp::Instance* CreateInstance(PP_Instance instance) { 156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return new FilePassingInstance(instance); 157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch } 158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}; 159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochnamespace pp { 161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 162a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochModule* CreateModule() { 163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return new FilePassingModule(); 164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} 165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch} // namespace pp 167