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