blob: f20f1346cfb2f7b2c700ee452680be147dd0fb27 [file] [log] [blame]
[email protected]c77144722013-01-19 04:16:361// 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#ifndef PPAPI_PROXY_FILE_IO_RESOURCE_H_
6#define PPAPI_PROXY_FILE_IO_RESOURCE_H_
7
avie029c4132015-12-23 06:45:228#include <stdint.h>
9
dchengced92242016-04-07 00:00:1210#include <memory>
[email protected]c77144722013-01-19 04:16:3611#include <string>
12
[email protected]141bcc52014-01-27 21:36:0013#include "base/files/file.h"
avie029c4132015-12-23 06:45:2214#include "base/macros.h"
[email protected]d35d3f42013-10-02 19:52:2015#include "base/memory/ref_counted.h"
[email protected]8f96cef2013-04-01 16:51:1316#include "ppapi/c/private/pp_file_handle.h"
[email protected]c77144722013-01-19 04:16:3617#include "ppapi/proxy/connection.h"
18#include "ppapi/proxy/plugin_resource.h"
19#include "ppapi/proxy/ppapi_proxy_export.h"
20#include "ppapi/shared_impl/file_io_state_manager.h"
[email protected]c6420f082013-09-18 22:42:4121#include "ppapi/shared_impl/resource.h"
[email protected]4837a982013-11-25 18:11:1322#include "ppapi/shared_impl/scoped_pp_resource.h"
[email protected]c77144722013-01-19 04:16:3623#include "ppapi/thunk/ppb_file_io_api.h"
24
25namespace ppapi {
26
27class TrackedCallback;
28
29namespace proxy {
30
31class PPAPI_PROXY_EXPORT FileIOResource
32 : public PluginResource,
33 public thunk::PPB_FileIO_API {
34 public:
35 FileIOResource(Connection connection, PP_Instance instance);
nicke4784432015-04-23 14:01:4836 ~FileIOResource() override;
[email protected]c77144722013-01-19 04:16:3637
38 // Resource overrides.
nicke4784432015-04-23 14:01:4839 thunk::PPB_FileIO_API* AsPPB_FileIO_API() override;
[email protected]c77144722013-01-19 04:16:3640
41 // PPB_FileIO_API implementation.
nicke4784432015-04-23 14:01:4842 int32_t Open(PP_Resource file_ref,
43 int32_t open_flags,
44 scoped_refptr<TrackedCallback> callback) override;
45 int32_t Query(PP_FileInfo* info,
46 scoped_refptr<TrackedCallback> callback) override;
47 int32_t Touch(PP_Time last_access_time,
48 PP_Time last_modified_time,
49 scoped_refptr<TrackedCallback> callback) override;
50 int32_t Read(int64_t offset,
51 char* buffer,
52 int32_t bytes_to_read,
53 scoped_refptr<TrackedCallback> callback) override;
54 int32_t ReadToArray(int64_t offset,
55 int32_t max_read_length,
56 PP_ArrayOutput* array_output,
57 scoped_refptr<TrackedCallback> callback) override;
58 int32_t Write(int64_t offset,
59 const char* buffer,
60 int32_t bytes_to_write,
61 scoped_refptr<TrackedCallback> callback) override;
62 int32_t SetLength(int64_t length,
63 scoped_refptr<TrackedCallback> callback) override;
64 int64_t GetMaxWrittenOffset() const override;
65 int64_t GetAppendModeWriteAmount() const override;
66 void SetMaxWrittenOffset(int64_t max_written_offset) override;
67 void SetAppendModeWriteAmount(int64_t append_mode_write_amount) override;
68 int32_t Flush(scoped_refptr<TrackedCallback> callback) override;
69 void Close() override;
70 int32_t RequestOSFileHandle(PP_FileHandle* handle,
mostynb699af3c2014-10-06 18:03:3471 scoped_refptr<TrackedCallback> callback) override;
[email protected]c77144722013-01-19 04:16:3672
[email protected]35b05b12014-06-03 00:01:0373 // FileHolder is used to guarantee that file operations will have a valid FD
74 // to operate on, even if they're in a different thread.
[email protected]d35d3f42013-10-02 19:52:2075 // If instead we just passed the raw FD, the FD could be closed before the
76 // file operation has a chance to run. It could interact with an invalid FD,
77 // or worse, the FD value could be reused if another file is opened quickly
78 // (POSIX is required to provide the lowest available value when opening a
79 // file). This could result in strange problems such as writing data to the
80 // wrong file.
81 //
82 // Operations that run on a background thread should hold one of these to
83 // ensure they have a valid file descriptor. The file handle is only closed
[email protected]35b05b12014-06-03 00:01:0384 // when the last reference to the FileHolder is removed, so we are guaranteed
85 // to operate on the correct file descriptor. It *is* still possible that the
86 // FileIOResource will be destroyed and "Abort" callbacks just before the
87 // operation does its task (e.g., Reading). In that case, we might for example
88 // Read from a file even though the FileIO has been destroyed and the plugin's
89 // callback got a PP_ERROR_ABORTED result. In the case of a write, we could
90 // write some data to the file despite the plugin receiving a
91 // PP_ERROR_ABORTED instead of a successful result.
92 class FileHolder : public base::RefCountedThreadSafe<FileHolder> {
[email protected]d35d3f42013-10-02 19:52:2093 public:
[email protected]35b05b12014-06-03 00:01:0394 explicit FileHolder(PP_FileHandle file_handle);
95 base::File* file() {
96 return &file_;
[email protected]d35d3f42013-10-02 19:52:2097 }
98 static bool IsValid(
[email protected]35b05b12014-06-03 00:01:0399 const scoped_refptr<FileIOResource::FileHolder>& handle);
[email protected]d35d3f42013-10-02 19:52:20100 private:
[email protected]35b05b12014-06-03 00:01:03101 friend class base::RefCountedThreadSafe<FileHolder>;
102 ~FileHolder();
103 base::File file_;
[email protected]d35d3f42013-10-02 19:52:20104 };
[email protected]35b05b12014-06-03 00:01:03105
106 scoped_refptr<FileHolder> file_holder() {
107 return file_holder_;
[email protected]f54329e2014-01-29 00:49:51108 }
[email protected]d35d3f42013-10-02 19:52:20109
[email protected]f54329e2014-01-29 00:49:51110 private:
[email protected]914a4ba92013-08-10 13:38:48111 // Class to perform file query operations across multiple threads.
112 class QueryOp : public base::RefCountedThreadSafe<QueryOp> {
113 public:
[email protected]35b05b12014-06-03 00:01:03114 explicit QueryOp(scoped_refptr<FileHolder> file_holder);
[email protected]914a4ba92013-08-10 13:38:48115
116 // Queries the file. Called on the file thread (non-blocking) or the plugin
117 // thread (blocking). This should not be called when we hold the proxy lock.
118 int32_t DoWork();
119
[email protected]141bcc52014-01-27 21:36:00120 const base::File::Info& file_info() const { return file_info_; }
[email protected]914a4ba92013-08-10 13:38:48121
122 private:
123 friend class base::RefCountedThreadSafe<QueryOp>;
124 ~QueryOp();
125
[email protected]35b05b12014-06-03 00:01:03126 scoped_refptr<FileHolder> file_holder_;
[email protected]141bcc52014-01-27 21:36:00127 base::File::Info file_info_;
[email protected]914a4ba92013-08-10 13:38:48128 };
129
130 // Class to perform file read operations across multiple threads.
131 class ReadOp : public base::RefCountedThreadSafe<ReadOp> {
132 public:
[email protected]35b05b12014-06-03 00:01:03133 ReadOp(scoped_refptr<FileHolder> file_holder,
[email protected]d35d3f42013-10-02 19:52:20134 int64_t offset,
135 int32_t bytes_to_read);
[email protected]914a4ba92013-08-10 13:38:48136
137 // Reads the file. Called on the file thread (non-blocking) or the plugin
138 // thread (blocking). This should not be called when we hold the proxy lock.
139 int32_t DoWork();
140
141 char* buffer() const { return buffer_.get(); }
142
143 private:
144 friend class base::RefCountedThreadSafe<ReadOp>;
145 ~ReadOp();
146
[email protected]35b05b12014-06-03 00:01:03147 scoped_refptr<FileHolder> file_holder_;
[email protected]914a4ba92013-08-10 13:38:48148 int64_t offset_;
149 int32_t bytes_to_read_;
dchengced92242016-04-07 00:00:12150 std::unique_ptr<char[]> buffer_;
[email protected]914a4ba92013-08-10 13:38:48151 };
152
[email protected]7a90b852013-12-28 17:54:27153 // Class to perform file write operations across multiple threads.
154 class WriteOp : public base::RefCountedThreadSafe<WriteOp> {
155 public:
[email protected]35b05b12014-06-03 00:01:03156 WriteOp(scoped_refptr<FileHolder> file_holder,
[email protected]7a90b852013-12-28 17:54:27157 int64_t offset,
dchengced92242016-04-07 00:00:12158 std::unique_ptr<char[]> buffer,
[email protected]7a90b852013-12-28 17:54:27159 int32_t bytes_to_write,
160 bool append);
161
162 // Writes the file. Called on the file thread (non-blocking) or the plugin
163 // thread (blocking). This should not be called when we hold the proxy lock.
164 int32_t DoWork();
165
166 private:
167 friend class base::RefCountedThreadSafe<WriteOp>;
168 ~WriteOp();
169
[email protected]35b05b12014-06-03 00:01:03170 scoped_refptr<FileHolder> file_holder_;
[email protected]7a90b852013-12-28 17:54:27171 int64_t offset_;
dchengced92242016-04-07 00:00:12172 std::unique_ptr<char[]> buffer_;
[email protected]7a90b852013-12-28 17:54:27173 int32_t bytes_to_write_;
174 bool append_;
175 };
176
177 void OnRequestWriteQuotaComplete(int64_t offset,
dchengced92242016-04-07 00:00:12178 std::unique_ptr<char[]> buffer,
[email protected]7a90b852013-12-28 17:54:27179 int32_t bytes_to_write,
180 scoped_refptr<TrackedCallback> callback,
181 int64_t granted);
182 void OnRequestSetLengthQuotaComplete(int64_t length,
183 scoped_refptr<TrackedCallback> callback,
184 int64_t granted);
185
[email protected]c77144722013-01-19 04:16:36186 int32_t ReadValidated(int64_t offset,
187 int32_t bytes_to_read,
188 const PP_ArrayOutput& array_output,
189 scoped_refptr<TrackedCallback> callback);
[email protected]7a90b852013-12-28 17:54:27190 int32_t WriteValidated(int64_t offset,
191 const char* buffer,
192 int32_t bytes_to_write,
193 scoped_refptr<TrackedCallback> callback);
194 void SetLengthValidated(int64_t length,
195 scoped_refptr<TrackedCallback> callback);
[email protected]c77144722013-01-19 04:16:36196
[email protected]914a4ba92013-08-10 13:38:48197 // Completion tasks for file operations that are done in the plugin.
198 int32_t OnQueryComplete(scoped_refptr<QueryOp> query_op,
199 PP_FileInfo* info,
200 int32_t result);
201 int32_t OnReadComplete(scoped_refptr<ReadOp> read_op,
202 PP_ArrayOutput array_output,
203 int32_t result);
[email protected]6c644b7e2014-05-22 06:25:18204 int32_t OnWriteComplete(int32_t result);
[email protected]914a4ba92013-08-10 13:38:48205
[email protected]d45f29b2013-08-09 04:18:06206 // Reply message handlers for operations that are done in the host.
[email protected]c77144722013-01-19 04:16:36207 void OnPluginMsgGeneralComplete(scoped_refptr<TrackedCallback> callback,
208 const ResourceMessageReplyParams& params);
209 void OnPluginMsgOpenFileComplete(scoped_refptr<TrackedCallback> callback,
[email protected]7a90b852013-12-28 17:54:27210 const ResourceMessageReplyParams& params,
211 PP_Resource quota_file_system,
212 int64_t max_written_offset);
[email protected]8f96cef2013-04-01 16:51:13213 void OnPluginMsgRequestOSFileHandleComplete(
214 scoped_refptr<TrackedCallback> callback,
215 PP_FileHandle* output_handle,
216 const ResourceMessageReplyParams& params);
[email protected]c77144722013-01-19 04:16:36217
[email protected]35b05b12014-06-03 00:01:03218 scoped_refptr<FileHolder> file_holder_;
[email protected]d45f29b2013-08-09 04:18:06219 PP_FileSystemType file_system_type_;
[email protected]3dbfbe512013-12-27 22:53:00220 scoped_refptr<Resource> file_system_resource_;
[email protected]c77144722013-01-19 04:16:36221 FileIOStateManager state_manager_;
222
[email protected]c6420f082013-09-18 22:42:41223 scoped_refptr<Resource> file_ref_;
224
[email protected]7a90b852013-12-28 17:54:27225 int32_t open_flags_;
226 int64_t max_written_offset_;
[email protected]304875d2014-01-22 10:31:12227 int64_t append_mode_write_amount_;
[email protected]7a90b852013-12-28 17:54:27228 bool check_quota_;
229 bool called_close_;
230
[email protected]c77144722013-01-19 04:16:36231 DISALLOW_COPY_AND_ASSIGN(FileIOResource);
232};
233
234} // namespace proxy
235} // namespace ppapi
236
237#endif // PPAPI_PROXY_FILE_IO_RESOURCE_H_