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