Elim cr-checkbox
[chromium-blink-merge.git] / ppapi / proxy / file_io_resource.h
blobf32879a43a778497c25f9affe4b48cdbf5d8ca62
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.
5 #ifndef PPAPI_PROXY_FILE_IO_RESOURCE_H_
6 #define PPAPI_PROXY_FILE_IO_RESOURCE_H_
8 #include <string>
10 #include "base/files/file.h"
11 #include "base/memory/ref_counted.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "ppapi/c/private/pp_file_handle.h"
14 #include "ppapi/proxy/connection.h"
15 #include "ppapi/proxy/plugin_resource.h"
16 #include "ppapi/proxy/ppapi_proxy_export.h"
17 #include "ppapi/shared_impl/file_io_state_manager.h"
18 #include "ppapi/shared_impl/resource.h"
19 #include "ppapi/shared_impl/scoped_pp_resource.h"
20 #include "ppapi/thunk/ppb_file_io_api.h"
22 namespace ppapi {
24 class TrackedCallback;
26 namespace proxy {
28 class PPAPI_PROXY_EXPORT FileIOResource
29 : public PluginResource,
30 public thunk::PPB_FileIO_API {
31 public:
32 FileIOResource(Connection connection, PP_Instance instance);
33 ~FileIOResource() override;
35 // Resource overrides.
36 thunk::PPB_FileIO_API* AsPPB_FileIO_API() override;
38 // PPB_FileIO_API implementation.
39 int32_t Open(PP_Resource file_ref,
40 int32_t open_flags,
41 scoped_refptr<TrackedCallback> callback) override;
42 int32_t Query(PP_FileInfo* info,
43 scoped_refptr<TrackedCallback> callback) override;
44 int32_t Touch(PP_Time last_access_time,
45 PP_Time last_modified_time,
46 scoped_refptr<TrackedCallback> callback) override;
47 int32_t Read(int64_t offset,
48 char* buffer,
49 int32_t bytes_to_read,
50 scoped_refptr<TrackedCallback> callback) override;
51 int32_t ReadToArray(int64_t offset,
52 int32_t max_read_length,
53 PP_ArrayOutput* array_output,
54 scoped_refptr<TrackedCallback> callback) override;
55 int32_t Write(int64_t offset,
56 const char* buffer,
57 int32_t bytes_to_write,
58 scoped_refptr<TrackedCallback> callback) override;
59 int32_t SetLength(int64_t length,
60 scoped_refptr<TrackedCallback> callback) override;
61 int64_t GetMaxWrittenOffset() const override;
62 int64_t GetAppendModeWriteAmount() const override;
63 void SetMaxWrittenOffset(int64_t max_written_offset) override;
64 void SetAppendModeWriteAmount(int64_t append_mode_write_amount) override;
65 int32_t Flush(scoped_refptr<TrackedCallback> callback) override;
66 void Close() override;
67 int32_t RequestOSFileHandle(PP_FileHandle* handle,
68 scoped_refptr<TrackedCallback> callback) override;
70 // FileHolder is used to guarantee that file operations will have a valid FD
71 // to operate on, even if they're in a different thread.
72 // If instead we just passed the raw FD, the FD could be closed before the
73 // file operation has a chance to run. It could interact with an invalid FD,
74 // or worse, the FD value could be reused if another file is opened quickly
75 // (POSIX is required to provide the lowest available value when opening a
76 // file). This could result in strange problems such as writing data to the
77 // wrong file.
79 // Operations that run on a background thread should hold one of these to
80 // ensure they have a valid file descriptor. The file handle is only closed
81 // when the last reference to the FileHolder is removed, so we are guaranteed
82 // to operate on the correct file descriptor. It *is* still possible that the
83 // FileIOResource will be destroyed and "Abort" callbacks just before the
84 // operation does its task (e.g., Reading). In that case, we might for example
85 // Read from a file even though the FileIO has been destroyed and the plugin's
86 // callback got a PP_ERROR_ABORTED result. In the case of a write, we could
87 // write some data to the file despite the plugin receiving a
88 // PP_ERROR_ABORTED instead of a successful result.
89 class FileHolder : public base::RefCountedThreadSafe<FileHolder> {
90 public:
91 explicit FileHolder(PP_FileHandle file_handle);
92 base::File* file() {
93 return &file_;
95 static bool IsValid(
96 const scoped_refptr<FileIOResource::FileHolder>& handle);
97 private:
98 friend class base::RefCountedThreadSafe<FileHolder>;
99 ~FileHolder();
100 base::File file_;
103 scoped_refptr<FileHolder> file_holder() {
104 return file_holder_;
107 private:
108 // Class to perform file query operations across multiple threads.
109 class QueryOp : public base::RefCountedThreadSafe<QueryOp> {
110 public:
111 explicit QueryOp(scoped_refptr<FileHolder> file_holder);
113 // Queries the file. Called on the file thread (non-blocking) or the plugin
114 // thread (blocking). This should not be called when we hold the proxy lock.
115 int32_t DoWork();
117 const base::File::Info& file_info() const { return file_info_; }
119 private:
120 friend class base::RefCountedThreadSafe<QueryOp>;
121 ~QueryOp();
123 scoped_refptr<FileHolder> file_holder_;
124 base::File::Info file_info_;
127 // Class to perform file read operations across multiple threads.
128 class ReadOp : public base::RefCountedThreadSafe<ReadOp> {
129 public:
130 ReadOp(scoped_refptr<FileHolder> file_holder,
131 int64_t offset,
132 int32_t bytes_to_read);
134 // Reads the file. Called on the file thread (non-blocking) or the plugin
135 // thread (blocking). This should not be called when we hold the proxy lock.
136 int32_t DoWork();
138 char* buffer() const { return buffer_.get(); }
140 private:
141 friend class base::RefCountedThreadSafe<ReadOp>;
142 ~ReadOp();
144 scoped_refptr<FileHolder> file_holder_;
145 int64_t offset_;
146 int32_t bytes_to_read_;
147 scoped_ptr<char[]> buffer_;
150 // Class to perform file write operations across multiple threads.
151 class WriteOp : public base::RefCountedThreadSafe<WriteOp> {
152 public:
153 WriteOp(scoped_refptr<FileHolder> file_holder,
154 int64_t offset,
155 scoped_ptr<char[]> buffer,
156 int32_t bytes_to_write,
157 bool append);
159 // Writes the file. Called on the file thread (non-blocking) or the plugin
160 // thread (blocking). This should not be called when we hold the proxy lock.
161 int32_t DoWork();
163 private:
164 friend class base::RefCountedThreadSafe<WriteOp>;
165 ~WriteOp();
167 scoped_refptr<FileHolder> file_holder_;
168 int64_t offset_;
169 scoped_ptr<char[]> buffer_;
170 int32_t bytes_to_write_;
171 bool append_;
174 void OnRequestWriteQuotaComplete(int64_t offset,
175 scoped_ptr<char[]> buffer,
176 int32_t bytes_to_write,
177 scoped_refptr<TrackedCallback> callback,
178 int64_t granted);
179 void OnRequestSetLengthQuotaComplete(int64_t length,
180 scoped_refptr<TrackedCallback> callback,
181 int64_t granted);
183 int32_t ReadValidated(int64_t offset,
184 int32_t bytes_to_read,
185 const PP_ArrayOutput& array_output,
186 scoped_refptr<TrackedCallback> callback);
187 int32_t WriteValidated(int64_t offset,
188 const char* buffer,
189 int32_t bytes_to_write,
190 scoped_refptr<TrackedCallback> callback);
191 void SetLengthValidated(int64_t length,
192 scoped_refptr<TrackedCallback> callback);
194 // Completion tasks for file operations that are done in the plugin.
195 int32_t OnQueryComplete(scoped_refptr<QueryOp> query_op,
196 PP_FileInfo* info,
197 int32_t result);
198 int32_t OnReadComplete(scoped_refptr<ReadOp> read_op,
199 PP_ArrayOutput array_output,
200 int32_t result);
201 int32_t OnWriteComplete(int32_t result);
203 // Reply message handlers for operations that are done in the host.
204 void OnPluginMsgGeneralComplete(scoped_refptr<TrackedCallback> callback,
205 const ResourceMessageReplyParams& params);
206 void OnPluginMsgOpenFileComplete(scoped_refptr<TrackedCallback> callback,
207 const ResourceMessageReplyParams& params,
208 PP_Resource quota_file_system,
209 int64_t max_written_offset);
210 void OnPluginMsgRequestOSFileHandleComplete(
211 scoped_refptr<TrackedCallback> callback,
212 PP_FileHandle* output_handle,
213 const ResourceMessageReplyParams& params);
215 scoped_refptr<FileHolder> file_holder_;
216 PP_FileSystemType file_system_type_;
217 scoped_refptr<Resource> file_system_resource_;
218 FileIOStateManager state_manager_;
220 scoped_refptr<Resource> file_ref_;
222 int32_t open_flags_;
223 int64_t max_written_offset_;
224 int64_t append_mode_write_amount_;
225 bool check_quota_;
226 bool called_close_;
228 DISALLOW_COPY_AND_ASSIGN(FileIOResource);
231 } // namespace proxy
232 } // namespace ppapi
234 #endif // PPAPI_PROXY_FILE_IO_RESOURCE_H_