Home | History | Annotate | Download | only in proxy
      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 "ppapi/proxy/flash_file_resource.h"
      6 
      7 #include "base/files/file_path.h"
      8 #include "ipc/ipc_message.h"
      9 #include "ppapi/c/pp_errors.h"
     10 #include "ppapi/proxy/ppapi_messages.h"
     11 #include "ppapi/shared_impl/file_type_conversion.h"
     12 #include "ppapi/shared_impl/scoped_pp_var.h"
     13 #include "ppapi/shared_impl/time_conversion.h"
     14 #include "ppapi/shared_impl/var.h"
     15 #include "ppapi/thunk/enter.h"
     16 
     17 namespace ppapi {
     18 namespace proxy {
     19 
     20 namespace {
     21 
     22 // Returns the path that a PPB_FileRef resource references as long as it is an
     23 // PP_FILESYSTEMTYPE_EXTERNAL path. Returns an empty string on error.
     24 std::string GetPathFromFileRef(PP_Resource file_ref) {
     25   thunk::EnterResourceNoLock<thunk::PPB_FileRef_API> enter(file_ref, true);
     26   if (enter.failed())
     27     return std::string();
     28   if (enter.object()->GetFileSystemType() != PP_FILESYSTEMTYPE_EXTERNAL)
     29     return std::string();
     30   ScopedPPVar var(ScopedPPVar::PassRef(), enter.object()->GetAbsolutePath());
     31   StringVar* string_var = StringVar::FromPPVar(var.get());
     32   if (!string_var)
     33     return std::string();
     34   return string_var->value();
     35 }
     36 
     37 }  // namespace
     38 
     39 FlashFileResource::FlashFileResource(Connection connection,
     40                                      PP_Instance instance)
     41     : PluginResource(connection, instance) {
     42   SendCreate(BROWSER, PpapiHostMsg_FlashFile_Create());
     43 }
     44 
     45 FlashFileResource::~FlashFileResource() {
     46 }
     47 
     48 thunk::PPB_Flash_File_API* FlashFileResource::AsPPB_Flash_File_API() {
     49   return this;
     50 }
     51 
     52 int32_t FlashFileResource::OpenFile(PP_Instance /*instance*/,
     53                                     const char* path,
     54                                     int32_t mode,
     55                                     PP_FileHandle* file) {
     56   return OpenFileHelper(path, PepperFilePath::DOMAIN_MODULE_LOCAL, mode, file);
     57 }
     58 
     59 int32_t FlashFileResource::RenameFile(PP_Instance /*instance*/,
     60                                       const char* path_from,
     61                                       const char* path_to) {
     62   PepperFilePath pepper_from(PepperFilePath::DOMAIN_MODULE_LOCAL,
     63                              base::FilePath::FromUTF8Unsafe(path_from));
     64   PepperFilePath pepper_to(PepperFilePath::DOMAIN_MODULE_LOCAL,
     65                            base::FilePath::FromUTF8Unsafe(path_to));
     66 
     67   int32_t error = SyncCall<IPC::Message>(
     68       BROWSER, PpapiHostMsg_FlashFile_RenameFile(pepper_from, pepper_to));
     69 
     70   return error;
     71 }
     72 
     73 int32_t FlashFileResource::DeleteFileOrDir(PP_Instance /*instance*/,
     74                                            const char* path,
     75                                            PP_Bool recursive) {
     76   PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL,
     77                              base::FilePath::FromUTF8Unsafe(path));
     78 
     79   int32_t error = SyncCall<IPC::Message>(
     80       BROWSER, PpapiHostMsg_FlashFile_DeleteFileOrDir(pepper_path,
     81                                                       PP_ToBool(recursive)));
     82 
     83   return error;
     84 }
     85 
     86 int32_t FlashFileResource::CreateDir(PP_Instance /*instance*/,
     87                                      const char* path) {
     88   PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL,
     89                              base::FilePath::FromUTF8Unsafe(path));
     90 
     91   int32_t error = SyncCall<IPC::Message>(BROWSER,
     92       PpapiHostMsg_FlashFile_CreateDir(pepper_path));
     93 
     94   return error;
     95 }
     96 
     97 int32_t FlashFileResource::QueryFile(PP_Instance /*instance*/,
     98                                      const char* path,
     99                                      PP_FileInfo* info) {
    100   return QueryFileHelper(path, PepperFilePath::DOMAIN_MODULE_LOCAL, info);
    101 }
    102 
    103 int32_t FlashFileResource::GetDirContents(PP_Instance /*instance*/,
    104                                           const char* path,
    105                                           PP_DirContents_Dev** contents) {
    106   ppapi::DirContents entries;
    107   PepperFilePath pepper_path(PepperFilePath::DOMAIN_MODULE_LOCAL,
    108                              base::FilePath::FromUTF8Unsafe(path));
    109 
    110   int32_t error = SyncCall<PpapiPluginMsg_FlashFile_GetDirContentsReply>(
    111       BROWSER, PpapiHostMsg_FlashFile_GetDirContents(pepper_path), &entries);
    112 
    113   if (error == PP_OK) {
    114     // Copy the serialized dir entries to the output struct.
    115     *contents = new PP_DirContents_Dev;
    116     (*contents)->count = static_cast<int32_t>(entries.size());
    117     (*contents)->entries = new PP_DirEntry_Dev[entries.size()];
    118     for (size_t i = 0; i < entries.size(); i++) {
    119       const ppapi::DirEntry& source = entries[i];
    120       PP_DirEntry_Dev* dest = &(*contents)->entries[i];
    121       std::string name = source.name.AsUTF8Unsafe();
    122       char* name_copy = new char[name.size() + 1];
    123       memcpy(name_copy, name.c_str(), name.size() + 1);
    124       dest->name = name_copy;
    125       dest->is_dir = PP_FromBool(source.is_dir);
    126     }
    127   }
    128 
    129   return error;
    130 }
    131 
    132 void FlashFileResource::FreeDirContents(PP_Instance /*instance*/,
    133                                         PP_DirContents_Dev* contents) {
    134   for (int32_t i = 0; i < contents->count; ++i)
    135     delete[] contents->entries[i].name;
    136   delete[] contents->entries;
    137   delete contents;
    138 }
    139 
    140 int32_t FlashFileResource::CreateTemporaryFile(PP_Instance /*instance*/,
    141                                                PP_FileHandle* file) {
    142   if (!file)
    143     return PP_ERROR_BADARGUMENT;
    144 
    145   IPC::Message unused;
    146   ResourceMessageReplyParams reply_params;
    147   int32_t error = GenericSyncCall(BROWSER,
    148       PpapiHostMsg_FlashFile_CreateTemporaryFile(), &unused, &reply_params);
    149   if (error != PP_OK)
    150     return error;
    151 
    152   IPC::PlatformFileForTransit transit_file;
    153   if (!reply_params.TakeFileHandleAtIndex(0, &transit_file))
    154     return PP_ERROR_FAILED;
    155 
    156   *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
    157   return PP_OK;
    158 }
    159 
    160 int32_t FlashFileResource::OpenFileRef(PP_Instance /*instance*/,
    161                                        PP_Resource file_ref,
    162                                        int32_t mode,
    163                                        PP_FileHandle* file) {
    164   return OpenFileHelper(GetPathFromFileRef(file_ref),
    165                         PepperFilePath::DOMAIN_ABSOLUTE, mode, file);
    166 }
    167 
    168 int32_t FlashFileResource::QueryFileRef(PP_Instance /*instance*/,
    169                                         PP_Resource file_ref,
    170                                         PP_FileInfo* info) {
    171   return QueryFileHelper(GetPathFromFileRef(file_ref),
    172                          PepperFilePath::DOMAIN_ABSOLUTE, info);
    173 }
    174 
    175 int32_t FlashFileResource::OpenFileHelper(const std::string& path,
    176                                           PepperFilePath::Domain domain_type,
    177                                           int32_t mode,
    178                                           PP_FileHandle* file) {
    179   if (path.empty() ||
    180       !ppapi::PepperFileOpenFlagsToPlatformFileFlags(mode, NULL) ||
    181       !file)
    182     return PP_ERROR_BADARGUMENT;
    183 
    184   PepperFilePath pepper_path(domain_type, base::FilePath::FromUTF8Unsafe(path));
    185 
    186   IPC::Message unused;
    187   ResourceMessageReplyParams reply_params;
    188   int32_t error = GenericSyncCall(BROWSER,
    189       PpapiHostMsg_FlashFile_OpenFile(pepper_path, mode), &unused,
    190       &reply_params);
    191   if (error != PP_OK)
    192     return error;
    193 
    194   IPC::PlatformFileForTransit transit_file;
    195   if (!reply_params.TakeFileHandleAtIndex(0, &transit_file))
    196     return PP_ERROR_FAILED;
    197 
    198   *file = IPC::PlatformFileForTransitToPlatformFile(transit_file);
    199   return PP_OK;
    200 }
    201 
    202 int32_t FlashFileResource::QueryFileHelper(const std::string& path,
    203                                            PepperFilePath::Domain domain_type,
    204                                            PP_FileInfo* info) {
    205   if (path.empty() || !info)
    206     return PP_ERROR_BADARGUMENT;
    207 
    208   base::PlatformFileInfo file_info;
    209   PepperFilePath pepper_path(domain_type, base::FilePath::FromUTF8Unsafe(path));
    210 
    211   int32_t error = SyncCall<PpapiPluginMsg_FlashFile_QueryFileReply>(BROWSER,
    212       PpapiHostMsg_FlashFile_QueryFile(pepper_path), &file_info);
    213 
    214   if (error == PP_OK) {
    215     info->size = file_info.size;
    216     info->creation_time = TimeToPPTime(file_info.creation_time);
    217     info->last_access_time = TimeToPPTime(file_info.last_accessed);
    218     info->last_modified_time = TimeToPPTime(file_info.last_modified);
    219     info->system_type = PP_FILESYSTEMTYPE_EXTERNAL;
    220     if (file_info.is_directory)
    221       info->type = PP_FILETYPE_DIRECTORY;
    222     else
    223       info->type = PP_FILETYPE_REGULAR;
    224   }
    225 
    226   return error;
    227 }
    228 
    229 }  // namespace proxy
    230 }  // namespace ppapi
    231