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