blob: 38ac6836b0c07bca0d222d46e0759ee90c40c98d [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
8#include <string>
9
[email protected]d35d3f42013-10-02 19:52:2010#include "base/memory/ref_counted.h"
[email protected]c6420f082013-09-18 22:42:4111#include "base/memory/scoped_ptr.h"
[email protected]8f96cef2013-04-01 16:51:1312#include "ppapi/c/private/pp_file_handle.h"
[email protected]c77144722013-01-19 04:16:3613#include "ppapi/proxy/connection.h"
14#include "ppapi/proxy/plugin_resource.h"
15#include "ppapi/proxy/ppapi_proxy_export.h"
16#include "ppapi/shared_impl/file_io_state_manager.h"
[email protected]c6420f082013-09-18 22:42:4117#include "ppapi/shared_impl/resource.h"
[email protected]4837a982013-11-25 18:11:1318#include "ppapi/shared_impl/scoped_pp_resource.h"
[email protected]c77144722013-01-19 04:16:3619#include "ppapi/thunk/ppb_file_io_api.h"
20
21namespace ppapi {
22
23class TrackedCallback;
24
25namespace proxy {
26
27class PPAPI_PROXY_EXPORT FileIOResource
28 : public PluginResource,
29 public thunk::PPB_FileIO_API {
30 public:
31 FileIOResource(Connection connection, PP_Instance instance);
32 virtual ~FileIOResource();
33
34 // Resource overrides.
35 virtual thunk::PPB_FileIO_API* AsPPB_FileIO_API() OVERRIDE;
36
37 // PPB_FileIO_API implementation.
38 virtual int32_t Open(PP_Resource file_ref,
39 int32_t open_flags,
40 scoped_refptr<TrackedCallback> callback) OVERRIDE;
41 virtual int32_t Query(PP_FileInfo* info,
42 scoped_refptr<TrackedCallback> callback) OVERRIDE;
43 virtual int32_t Touch(PP_Time last_access_time,
44 PP_Time last_modified_time,
45 scoped_refptr<TrackedCallback> callback) OVERRIDE;
46 virtual int32_t Read(int64_t offset,
47 char* buffer,
48 int32_t bytes_to_read,
49 scoped_refptr<TrackedCallback> callback) OVERRIDE;
50 virtual int32_t ReadToArray(int64_t offset,
51 int32_t max_read_length,
52 PP_ArrayOutput* array_output,
53 scoped_refptr<TrackedCallback> callback) OVERRIDE;
54 virtual int32_t Write(int64_t offset,
55 const char* buffer,
56 int32_t bytes_to_write,
57 scoped_refptr<TrackedCallback> callback) OVERRIDE;
58 virtual int32_t SetLength(int64_t length,
59 scoped_refptr<TrackedCallback> callback) OVERRIDE;
[email protected]7a90b852013-12-28 17:54:2760 virtual int64_t GetMaxWrittenOffset() const OVERRIDE;
[email protected]304875d2014-01-22 10:31:1261 virtual int64_t GetAppendModeWriteAmount() const OVERRIDE;
[email protected]7a90b852013-12-28 17:54:2762 virtual void SetMaxWrittenOffset(int64_t max_written_offset) OVERRIDE;
[email protected]304875d2014-01-22 10:31:1263 virtual void SetAppendModeWriteAmount(
64 int64_t append_mode_write_amount) OVERRIDE;
[email protected]c77144722013-01-19 04:16:3665 virtual int32_t Flush(scoped_refptr<TrackedCallback> callback) OVERRIDE;
66 virtual void Close() OVERRIDE;
[email protected]8f96cef2013-04-01 16:51:1367 virtual int32_t RequestOSFileHandle(
68 PP_FileHandle* handle,
69 scoped_refptr<TrackedCallback> callback) OVERRIDE;
[email protected]c77144722013-01-19 04:16:3670
71 private:
[email protected]d35d3f42013-10-02 19:52:2072 // FileHandleHolder is used to guarantee that file operations will have a
73 // valid FD to operate on, even if they're in a different thread.
74 // If instead we just passed the raw FD, the FD could be closed before the
75 // file operation has a chance to run. It could interact with an invalid FD,
76 // or worse, the FD value could be reused if another file is opened quickly
77 // (POSIX is required to provide the lowest available value when opening a
78 // file). This could result in strange problems such as writing data to the
79 // wrong file.
80 //
81 // Operations that run on a background thread should hold one of these to
82 // ensure they have a valid file descriptor. The file handle is only closed
83 // when the last reference to the FileHandleHolder is removed, so we are
84 // guaranteed to operate on the correct file descriptor. It *is* still
85 // possible that the FileIOResource will be destroyed and "Abort" callbacks
86 // just before the operation does its task (e.g., Reading). In that case, we
87 // might for example Read from a file even though the FileIO has been
88 // destroyed and the plugin's callback got a PP_ERROR_ABORTED result. In the
89 // case of a write, we could write some data to the file despite the plugin
90 // receiving a PP_ERROR_ABORTED instead of a successful result.
91 class FileHandleHolder : public base::RefCountedThreadSafe<FileHandleHolder> {
92 public:
93 explicit FileHandleHolder(PP_FileHandle file_handle_);
94 PP_FileHandle raw_handle() {
95 return raw_handle_;
96 }
97 static bool IsValid(
98 const scoped_refptr<FileIOResource::FileHandleHolder>& handle);
99 private:
100 friend class base::RefCountedThreadSafe<FileHandleHolder>;
101 ~FileHandleHolder();
102 PP_FileHandle raw_handle_;
103 };
104
[email protected]914a4ba92013-08-10 13:38:48105 // Class to perform file query operations across multiple threads.
106 class QueryOp : public base::RefCountedThreadSafe<QueryOp> {
107 public:
[email protected]d35d3f42013-10-02 19:52:20108 explicit QueryOp(scoped_refptr<FileHandleHolder> file_handle);
[email protected]914a4ba92013-08-10 13:38:48109
110 // Queries the file. Called on the file thread (non-blocking) or the plugin
111 // thread (blocking). This should not be called when we hold the proxy lock.
112 int32_t DoWork();
113
114 const base::PlatformFileInfo& file_info() const { return file_info_; }
115
116 private:
117 friend class base::RefCountedThreadSafe<QueryOp>;
118 ~QueryOp();
119
[email protected]d35d3f42013-10-02 19:52:20120 scoped_refptr<FileHandleHolder> file_handle_;
[email protected]914a4ba92013-08-10 13:38:48121 base::PlatformFileInfo file_info_;
122 };
123
124 // Class to perform file read operations across multiple threads.
125 class ReadOp : public base::RefCountedThreadSafe<ReadOp> {
126 public:
[email protected]d35d3f42013-10-02 19:52:20127 ReadOp(scoped_refptr<FileHandleHolder> file_handle,
128 int64_t offset,
129 int32_t bytes_to_read);
[email protected]914a4ba92013-08-10 13:38:48130
131 // Reads the file. Called on the file thread (non-blocking) or the plugin
132 // thread (blocking). This should not be called when we hold the proxy lock.
133 int32_t DoWork();
134
135 char* buffer() const { return buffer_.get(); }
136
137 private:
138 friend class base::RefCountedThreadSafe<ReadOp>;
139 ~ReadOp();
140
[email protected]d35d3f42013-10-02 19:52:20141 scoped_refptr<FileHandleHolder> file_handle_;
[email protected]914a4ba92013-08-10 13:38:48142 int64_t offset_;
143 int32_t bytes_to_read_;
144 scoped_ptr<char[]> buffer_;
145 };
146
[email protected]7a90b852013-12-28 17:54:27147 // Class to perform file write operations across multiple threads.
148 class WriteOp : public base::RefCountedThreadSafe<WriteOp> {
149 public:
150 WriteOp(scoped_refptr<FileHandleHolder> file_handle,
151 int64_t offset,
152 const char* buffer,
153 int32_t bytes_to_write,
154 bool append);
155
156 // Writes the file. Called on the file thread (non-blocking) or the plugin
157 // thread (blocking). This should not be called when we hold the proxy lock.
158 int32_t DoWork();
159
160 private:
161 friend class base::RefCountedThreadSafe<WriteOp>;
162 ~WriteOp();
163
164 scoped_refptr<FileHandleHolder> file_handle_;
165 int64_t offset_;
166 const char* buffer_;
167 int32_t bytes_to_write_;
168 bool append_;
169 };
170
171 void OnRequestWriteQuotaComplete(int64_t offset,
172 const char* buffer,
173 int32_t bytes_to_write,
174 scoped_refptr<TrackedCallback> callback,
175 int64_t granted);
176 void OnRequestSetLengthQuotaComplete(int64_t length,
177 scoped_refptr<TrackedCallback> callback,
178 int64_t granted);
179
[email protected]c77144722013-01-19 04:16:36180 int32_t ReadValidated(int64_t offset,
181 int32_t bytes_to_read,
182 const PP_ArrayOutput& array_output,
183 scoped_refptr<TrackedCallback> callback);
[email protected]7a90b852013-12-28 17:54:27184 int32_t WriteValidated(int64_t offset,
185 const char* buffer,
186 int32_t bytes_to_write,
187 scoped_refptr<TrackedCallback> callback);
188 void SetLengthValidated(int64_t length,
189 scoped_refptr<TrackedCallback> callback);
[email protected]c77144722013-01-19 04:16:36190
[email protected]914a4ba92013-08-10 13:38:48191 // Completion tasks for file operations that are done in the plugin.
192 int32_t OnQueryComplete(scoped_refptr<QueryOp> query_op,
193 PP_FileInfo* info,
194 int32_t result);
195 int32_t OnReadComplete(scoped_refptr<ReadOp> read_op,
196 PP_ArrayOutput array_output,
197 int32_t result);
[email protected]7a90b852013-12-28 17:54:27198 int32_t OnWriteComplete(scoped_refptr<WriteOp> write_op,
199 int32_t result);
[email protected]914a4ba92013-08-10 13:38:48200
[email protected]d45f29b2013-08-09 04:18:06201 // Reply message handlers for operations that are done in the host.
[email protected]c77144722013-01-19 04:16:36202 void OnPluginMsgGeneralComplete(scoped_refptr<TrackedCallback> callback,
203 const ResourceMessageReplyParams& params);
204 void OnPluginMsgOpenFileComplete(scoped_refptr<TrackedCallback> callback,
[email protected]7a90b852013-12-28 17:54:27205 const ResourceMessageReplyParams& params,
206 PP_Resource quota_file_system,
207 int64_t max_written_offset);
[email protected]8f96cef2013-04-01 16:51:13208 void OnPluginMsgRequestOSFileHandleComplete(
209 scoped_refptr<TrackedCallback> callback,
210 PP_FileHandle* output_handle,
211 const ResourceMessageReplyParams& params);
[email protected]c77144722013-01-19 04:16:36212
[email protected]d35d3f42013-10-02 19:52:20213 scoped_refptr<FileHandleHolder> file_handle_;
[email protected]d45f29b2013-08-09 04:18:06214 PP_FileSystemType file_system_type_;
[email protected]3dbfbe512013-12-27 22:53:00215 scoped_refptr<Resource> file_system_resource_;
[email protected]c77144722013-01-19 04:16:36216 FileIOStateManager state_manager_;
217
[email protected]c6420f082013-09-18 22:42:41218 scoped_refptr<Resource> file_ref_;
219
[email protected]7a90b852013-12-28 17:54:27220 int32_t open_flags_;
221 int64_t max_written_offset_;
[email protected]304875d2014-01-22 10:31:12222 int64_t append_mode_write_amount_;
[email protected]7a90b852013-12-28 17:54:27223 bool check_quota_;
224 bool called_close_;
225
[email protected]c77144722013-01-19 04:16:36226 DISALLOW_COPY_AND_ASSIGN(FileIOResource);
227};
228
229} // namespace proxy
230} // namespace ppapi
231
232#endif // PPAPI_PROXY_FILE_IO_RESOURCE_H_