Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ppapi / proxy / file_ref_resource.cc
blob098ef5f336abfccdee12abc903e012e789942b89
1 // Copyright 2013 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.
5 #include "ppapi/proxy/file_ref_resource.h"
7 #include "ppapi/c/pp_directory_entry.h"
8 #include "ppapi/c/pp_instance.h"
9 #include "ppapi/c/pp_resource.h"
10 #include "ppapi/proxy/ppapi_messages.h"
11 #include "ppapi/shared_impl/array_writer.h"
12 #include "ppapi/shared_impl/file_ref_util.h"
13 #include "ppapi/shared_impl/resource.h"
14 #include "ppapi/shared_impl/resource_tracker.h"
15 #include "ppapi/shared_impl/var.h"
16 #include "ppapi/thunk/enter.h"
17 #include "ppapi/thunk/ppb_file_system_api.h"
19 namespace ppapi {
20 namespace proxy {
22 FileRefResource::FileRefResource(
23 Connection connection,
24 PP_Instance instance,
25 const FileRefCreateInfo& create_info)
26 : PluginResource(connection, instance),
27 create_info_(create_info),
28 file_system_resource_(create_info.file_system_plugin_resource) {
29 if (uses_internal_paths()) {
30 // If path ends with a slash, then normalize it away unless path is
31 // the root path.
32 int path_size = create_info_.internal_path.size();
33 if (path_size > 1 && create_info_.internal_path.at(path_size - 1) == '/')
34 create_info_.internal_path.erase(path_size - 1, 1);
36 path_var_ = new StringVar(create_info_.internal_path);
37 create_info_.display_name = GetNameForInternalFilePath(
38 create_info_.internal_path);
39 } else {
40 DCHECK(!create_info_.display_name.empty());
42 name_var_ = new StringVar(create_info_.display_name);
44 if (create_info_.browser_pending_host_resource_id != 0 &&
45 create_info_.renderer_pending_host_resource_id != 0) {
46 AttachToPendingHost(BROWSER, create_info_.browser_pending_host_resource_id);
47 AttachToPendingHost(RENDERER,
48 create_info_.renderer_pending_host_resource_id);
49 } else {
50 CHECK_EQ(0, create_info_.browser_pending_host_resource_id);
51 CHECK_EQ(0, create_info_.renderer_pending_host_resource_id);
52 CHECK(uses_internal_paths());
53 SendCreate(BROWSER, PpapiHostMsg_FileRef_CreateForFileAPI(
54 create_info.file_system_plugin_resource,
55 create_info.internal_path));
56 SendCreate(RENDERER, PpapiHostMsg_FileRef_CreateForFileAPI(
57 create_info.file_system_plugin_resource,
58 create_info.internal_path));
62 FileRefResource::~FileRefResource() {
65 // static
66 PP_Resource FileRefResource::CreateFileRef(
67 Connection connection,
68 PP_Instance instance,
69 const FileRefCreateInfo& create_info) {
70 // If we have a valid file_system resource, ensure that its type matches that
71 // of the fs_type parameter.
72 if (create_info.file_system_plugin_resource != 0) {
73 thunk::EnterResourceNoLock<thunk::PPB_FileSystem_API> enter(
74 create_info.file_system_plugin_resource, true);
75 if (enter.failed())
76 return 0;
77 if (enter.object()->GetType() != create_info.file_system_type) {
78 NOTREACHED() << "file system type mismatch with resource";
79 return 0;
83 if (create_info.file_system_type == PP_FILESYSTEMTYPE_LOCALPERSISTENT ||
84 create_info.file_system_type == PP_FILESYSTEMTYPE_LOCALTEMPORARY) {
85 if (!IsValidInternalPath(create_info.internal_path))
86 return 0;
88 return (new FileRefResource(connection,
89 instance,
90 create_info))->GetReference();
93 thunk::PPB_FileRef_API* FileRefResource::AsPPB_FileRef_API() {
94 return this;
97 PP_FileSystemType FileRefResource::GetFileSystemType() const {
98 return create_info_.file_system_type;
101 PP_Var FileRefResource::GetName() const {
102 return name_var_->GetPPVar();
105 PP_Var FileRefResource::GetPath() const {
106 if (!uses_internal_paths())
107 return PP_MakeUndefined();
108 return path_var_->GetPPVar();
111 PP_Resource FileRefResource::GetParent() {
112 if (!uses_internal_paths())
113 return 0;
115 size_t pos = create_info_.internal_path.rfind('/');
116 CHECK(pos != std::string::npos);
117 if (pos == 0)
118 pos++;
119 std::string parent_path = create_info_.internal_path.substr(0, pos);
121 ppapi::FileRefCreateInfo parent_info;
122 parent_info.file_system_type = create_info_.file_system_type;
123 parent_info.internal_path = parent_path;
124 parent_info.display_name = GetNameForInternalFilePath(parent_path);
125 parent_info.file_system_plugin_resource =
126 create_info_.file_system_plugin_resource;
128 return (new FileRefResource(connection(),
129 pp_instance(),
130 parent_info))->GetReference();
133 int32_t FileRefResource::MakeDirectory(
134 int32_t make_directory_flags,
135 scoped_refptr<TrackedCallback> callback) {
136 Call<PpapiPluginMsg_FileRef_MakeDirectoryReply>(
137 BROWSER,
138 PpapiHostMsg_FileRef_MakeDirectory(make_directory_flags),
139 base::Bind(&FileRefResource::RunTrackedCallback, this, callback));
140 return PP_OK_COMPLETIONPENDING;
143 int32_t FileRefResource::Touch(PP_Time last_access_time,
144 PP_Time last_modified_time,
145 scoped_refptr<TrackedCallback> callback) {
146 Call<PpapiPluginMsg_FileRef_TouchReply>(
147 BROWSER,
148 PpapiHostMsg_FileRef_Touch(last_access_time,
149 last_modified_time),
150 base::Bind(&FileRefResource::RunTrackedCallback, this, callback));
151 return PP_OK_COMPLETIONPENDING;
154 int32_t FileRefResource::Delete(scoped_refptr<TrackedCallback> callback) {
155 Call<PpapiPluginMsg_FileRef_DeleteReply>(
156 BROWSER,
157 PpapiHostMsg_FileRef_Delete(),
158 base::Bind(&FileRefResource::RunTrackedCallback, this, callback));
159 return PP_OK_COMPLETIONPENDING;
162 int32_t FileRefResource::Rename(PP_Resource new_file_ref,
163 scoped_refptr<TrackedCallback> callback) {
164 Call<PpapiPluginMsg_FileRef_RenameReply>(
165 BROWSER,
166 PpapiHostMsg_FileRef_Rename(new_file_ref),
167 base::Bind(&FileRefResource::RunTrackedCallback, this, callback));
168 return PP_OK_COMPLETIONPENDING;
171 int32_t FileRefResource::Query(PP_FileInfo* info,
172 scoped_refptr<TrackedCallback> callback) {
173 if (info == NULL)
174 return PP_ERROR_BADARGUMENT;
176 Call<PpapiPluginMsg_FileRef_QueryReply>(
177 BROWSER,
178 PpapiHostMsg_FileRef_Query(),
179 base::Bind(&FileRefResource::OnQueryReply, this, info, callback));
180 return PP_OK_COMPLETIONPENDING;
183 int32_t FileRefResource::ReadDirectoryEntries(
184 const PP_ArrayOutput& output,
185 scoped_refptr<TrackedCallback> callback) {
186 Call<PpapiPluginMsg_FileRef_ReadDirectoryEntriesReply>(
187 BROWSER,
188 PpapiHostMsg_FileRef_ReadDirectoryEntries(),
189 base::Bind(&FileRefResource::OnDirectoryEntriesReply,
190 this, output, callback));
191 return PP_OK_COMPLETIONPENDING;
194 const FileRefCreateInfo& FileRefResource::GetCreateInfo() const {
195 return create_info_;
198 PP_Var FileRefResource::GetAbsolutePath() {
199 if (!absolute_path_var_.get()) {
200 std::string absolute_path;
201 int32_t result = SyncCall<PpapiPluginMsg_FileRef_GetAbsolutePathReply>(
202 BROWSER, PpapiHostMsg_FileRef_GetAbsolutePath(), &absolute_path);
203 if (result != PP_OK)
204 return PP_MakeUndefined();
205 absolute_path_var_ = new StringVar(absolute_path);
207 return absolute_path_var_->GetPPVar();
210 void FileRefResource::RunTrackedCallback(
211 scoped_refptr<TrackedCallback> callback,
212 const ResourceMessageReplyParams& params) {
213 if (TrackedCallback::IsPending(callback))
214 callback->Run(params.result());
217 void FileRefResource::OnQueryReply(
218 PP_FileInfo* out_info,
219 scoped_refptr<TrackedCallback> callback,
220 const ResourceMessageReplyParams& params,
221 const PP_FileInfo& info) {
222 if (!TrackedCallback::IsPending(callback))
223 return;
225 if (params.result() == PP_OK)
226 *out_info = info;
227 callback->Run(params.result());
230 void FileRefResource::OnDirectoryEntriesReply(
231 const PP_ArrayOutput& output,
232 scoped_refptr<TrackedCallback> callback,
233 const ResourceMessageReplyParams& params,
234 const std::vector<ppapi::FileRefCreateInfo>& infos,
235 const std::vector<PP_FileType>& file_types) {
236 if (!TrackedCallback::IsPending(callback))
237 return;
239 if (params.result() == PP_OK) {
240 ArrayWriter writer(output);
241 if (!writer.is_valid()) {
242 callback->Run(PP_ERROR_BADARGUMENT);
243 return;
246 std::vector<PP_DirectoryEntry> entries;
247 for (size_t i = 0; i < infos.size(); ++i) {
248 PP_DirectoryEntry entry;
249 entry.file_ref = FileRefResource::CreateFileRef(connection(),
250 pp_instance(),
251 infos[i]);
252 entry.file_type = file_types[i];
253 entries.push_back(entry);
256 writer.StoreVector(entries);
258 callback->Run(params.result());
261 bool FileRefResource::uses_internal_paths() const {
262 return (create_info_.file_system_type != PP_FILESYSTEMTYPE_EXTERNAL) ||
263 !create_info_.internal_path.empty();
266 } // namespace proxy
267 } // namespace ppapi