xref: /aosp_15_r20/external/cronet/base/files/file_proxy.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2014 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/files/file_proxy.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <memory>
8*6777b538SAndroid Build Coastguard Worker #include <optional>
9*6777b538SAndroid Build Coastguard Worker #include <utility>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/containers/heap_array.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/task/task_runner.h"
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker namespace {
21*6777b538SAndroid Build Coastguard Worker 
FileDeleter(base::File file)22*6777b538SAndroid Build Coastguard Worker void FileDeleter(base::File file) {
23*6777b538SAndroid Build Coastguard Worker }
24*6777b538SAndroid Build Coastguard Worker 
25*6777b538SAndroid Build Coastguard Worker }  // namespace
26*6777b538SAndroid Build Coastguard Worker 
27*6777b538SAndroid Build Coastguard Worker namespace base {
28*6777b538SAndroid Build Coastguard Worker 
29*6777b538SAndroid Build Coastguard Worker class FileHelper {
30*6777b538SAndroid Build Coastguard Worker  public:
FileHelper(base::WeakPtr<FileProxy> proxy,File file)31*6777b538SAndroid Build Coastguard Worker   FileHelper(base::WeakPtr<FileProxy> proxy, File file)
32*6777b538SAndroid Build Coastguard Worker       : file_(std::move(file)),
33*6777b538SAndroid Build Coastguard Worker         task_runner_(proxy->task_runner()),
34*6777b538SAndroid Build Coastguard Worker         proxy_(proxy) {}
35*6777b538SAndroid Build Coastguard Worker   FileHelper(const FileHelper&) = delete;
36*6777b538SAndroid Build Coastguard Worker   FileHelper& operator=(const FileHelper&) = delete;
37*6777b538SAndroid Build Coastguard Worker 
PassFile()38*6777b538SAndroid Build Coastguard Worker   void PassFile() {
39*6777b538SAndroid Build Coastguard Worker     if (proxy_)
40*6777b538SAndroid Build Coastguard Worker       proxy_->SetFile(std::move(file_));
41*6777b538SAndroid Build Coastguard Worker     else if (file_.IsValid())
42*6777b538SAndroid Build Coastguard Worker       task_runner_->PostTask(FROM_HERE,
43*6777b538SAndroid Build Coastguard Worker                              BindOnce(&FileDeleter, std::move(file_)));
44*6777b538SAndroid Build Coastguard Worker   }
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker  protected:
47*6777b538SAndroid Build Coastguard Worker   File file_;
48*6777b538SAndroid Build Coastguard Worker   File::Error error_ = File::FILE_ERROR_FAILED;
49*6777b538SAndroid Build Coastguard Worker 
50*6777b538SAndroid Build Coastguard Worker  private:
51*6777b538SAndroid Build Coastguard Worker   scoped_refptr<TaskRunner> task_runner_;
52*6777b538SAndroid Build Coastguard Worker   WeakPtr<FileProxy> proxy_;
53*6777b538SAndroid Build Coastguard Worker };
54*6777b538SAndroid Build Coastguard Worker 
55*6777b538SAndroid Build Coastguard Worker namespace {
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker class GenericFileHelper : public FileHelper {
58*6777b538SAndroid Build Coastguard Worker  public:
GenericFileHelper(base::WeakPtr<FileProxy> proxy,File file)59*6777b538SAndroid Build Coastguard Worker   GenericFileHelper(base::WeakPtr<FileProxy> proxy, File file)
60*6777b538SAndroid Build Coastguard Worker       : FileHelper(std::move(proxy), std::move(file)) {}
61*6777b538SAndroid Build Coastguard Worker   GenericFileHelper(const GenericFileHelper&) = delete;
62*6777b538SAndroid Build Coastguard Worker   GenericFileHelper& operator=(const GenericFileHelper&) = delete;
63*6777b538SAndroid Build Coastguard Worker 
Close()64*6777b538SAndroid Build Coastguard Worker   void Close() {
65*6777b538SAndroid Build Coastguard Worker     file_.Close();
66*6777b538SAndroid Build Coastguard Worker     error_ = File::FILE_OK;
67*6777b538SAndroid Build Coastguard Worker   }
68*6777b538SAndroid Build Coastguard Worker 
SetTimes(Time last_access_time,Time last_modified_time)69*6777b538SAndroid Build Coastguard Worker   void SetTimes(Time last_access_time, Time last_modified_time) {
70*6777b538SAndroid Build Coastguard Worker     bool rv = file_.SetTimes(last_access_time, last_modified_time);
71*6777b538SAndroid Build Coastguard Worker     error_ = rv ? File::FILE_OK : File::FILE_ERROR_FAILED;
72*6777b538SAndroid Build Coastguard Worker   }
73*6777b538SAndroid Build Coastguard Worker 
SetLength(int64_t length)74*6777b538SAndroid Build Coastguard Worker   void SetLength(int64_t length) {
75*6777b538SAndroid Build Coastguard Worker     if (file_.SetLength(length))
76*6777b538SAndroid Build Coastguard Worker       error_ = File::FILE_OK;
77*6777b538SAndroid Build Coastguard Worker   }
78*6777b538SAndroid Build Coastguard Worker 
Flush()79*6777b538SAndroid Build Coastguard Worker   void Flush() {
80*6777b538SAndroid Build Coastguard Worker     if (file_.Flush())
81*6777b538SAndroid Build Coastguard Worker       error_ = File::FILE_OK;
82*6777b538SAndroid Build Coastguard Worker   }
83*6777b538SAndroid Build Coastguard Worker 
Reply(FileProxy::StatusCallback callback)84*6777b538SAndroid Build Coastguard Worker   void Reply(FileProxy::StatusCallback callback) {
85*6777b538SAndroid Build Coastguard Worker     PassFile();
86*6777b538SAndroid Build Coastguard Worker     if (!callback.is_null())
87*6777b538SAndroid Build Coastguard Worker       std::move(callback).Run(error_);
88*6777b538SAndroid Build Coastguard Worker   }
89*6777b538SAndroid Build Coastguard Worker };
90*6777b538SAndroid Build Coastguard Worker 
91*6777b538SAndroid Build Coastguard Worker class CreateOrOpenHelper : public FileHelper {
92*6777b538SAndroid Build Coastguard Worker  public:
CreateOrOpenHelper(base::WeakPtr<FileProxy> proxy,File file)93*6777b538SAndroid Build Coastguard Worker   CreateOrOpenHelper(base::WeakPtr<FileProxy> proxy, File file)
94*6777b538SAndroid Build Coastguard Worker       : FileHelper(std::move(proxy), std::move(file)) {}
95*6777b538SAndroid Build Coastguard Worker   CreateOrOpenHelper(const CreateOrOpenHelper&) = delete;
96*6777b538SAndroid Build Coastguard Worker   CreateOrOpenHelper& operator=(const CreateOrOpenHelper&) = delete;
97*6777b538SAndroid Build Coastguard Worker 
RunWork(const FilePath & file_path,uint32_t file_flags)98*6777b538SAndroid Build Coastguard Worker   void RunWork(const FilePath& file_path, uint32_t file_flags) {
99*6777b538SAndroid Build Coastguard Worker     file_.Initialize(file_path, file_flags);
100*6777b538SAndroid Build Coastguard Worker     error_ = file_.IsValid() ? File::FILE_OK : file_.error_details();
101*6777b538SAndroid Build Coastguard Worker   }
102*6777b538SAndroid Build Coastguard Worker 
Reply(FileProxy::StatusCallback callback)103*6777b538SAndroid Build Coastguard Worker   void Reply(FileProxy::StatusCallback callback) {
104*6777b538SAndroid Build Coastguard Worker     DCHECK(!callback.is_null());
105*6777b538SAndroid Build Coastguard Worker     PassFile();
106*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(error_);
107*6777b538SAndroid Build Coastguard Worker   }
108*6777b538SAndroid Build Coastguard Worker };
109*6777b538SAndroid Build Coastguard Worker 
110*6777b538SAndroid Build Coastguard Worker class CreateTemporaryHelper : public FileHelper {
111*6777b538SAndroid Build Coastguard Worker  public:
CreateTemporaryHelper(base::WeakPtr<FileProxy> proxy,File file)112*6777b538SAndroid Build Coastguard Worker   CreateTemporaryHelper(base::WeakPtr<FileProxy> proxy, File file)
113*6777b538SAndroid Build Coastguard Worker       : FileHelper(std::move(proxy), std::move(file)) {}
114*6777b538SAndroid Build Coastguard Worker   CreateTemporaryHelper(const CreateTemporaryHelper&) = delete;
115*6777b538SAndroid Build Coastguard Worker   CreateTemporaryHelper& operator=(const CreateTemporaryHelper&) = delete;
116*6777b538SAndroid Build Coastguard Worker 
RunWork(uint32_t additional_file_flags)117*6777b538SAndroid Build Coastguard Worker   void RunWork(uint32_t additional_file_flags) {
118*6777b538SAndroid Build Coastguard Worker     // TODO(darin): file_util should have a variant of CreateTemporaryFile
119*6777b538SAndroid Build Coastguard Worker     // that returns a FilePath and a File.
120*6777b538SAndroid Build Coastguard Worker     if (!CreateTemporaryFile(&file_path_)) {
121*6777b538SAndroid Build Coastguard Worker       // TODO(davidben): base::CreateTemporaryFile should preserve the error
122*6777b538SAndroid Build Coastguard Worker       // code.
123*6777b538SAndroid Build Coastguard Worker       error_ = File::FILE_ERROR_FAILED;
124*6777b538SAndroid Build Coastguard Worker       return;
125*6777b538SAndroid Build Coastguard Worker     }
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker     uint32_t file_flags = File::FLAG_WRITE | File::FLAG_WIN_TEMPORARY |
128*6777b538SAndroid Build Coastguard Worker                           File::FLAG_CREATE_ALWAYS | additional_file_flags;
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker     file_.Initialize(file_path_, file_flags);
131*6777b538SAndroid Build Coastguard Worker     if (file_.IsValid()) {
132*6777b538SAndroid Build Coastguard Worker       error_ = File::FILE_OK;
133*6777b538SAndroid Build Coastguard Worker     } else {
134*6777b538SAndroid Build Coastguard Worker       error_ = file_.error_details();
135*6777b538SAndroid Build Coastguard Worker       DeleteFile(file_path_);
136*6777b538SAndroid Build Coastguard Worker       file_path_.clear();
137*6777b538SAndroid Build Coastguard Worker     }
138*6777b538SAndroid Build Coastguard Worker   }
139*6777b538SAndroid Build Coastguard Worker 
Reply(FileProxy::CreateTemporaryCallback callback)140*6777b538SAndroid Build Coastguard Worker   void Reply(FileProxy::CreateTemporaryCallback callback) {
141*6777b538SAndroid Build Coastguard Worker     DCHECK(!callback.is_null());
142*6777b538SAndroid Build Coastguard Worker     PassFile();
143*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(error_, file_path_);
144*6777b538SAndroid Build Coastguard Worker   }
145*6777b538SAndroid Build Coastguard Worker 
146*6777b538SAndroid Build Coastguard Worker  private:
147*6777b538SAndroid Build Coastguard Worker   FilePath file_path_;
148*6777b538SAndroid Build Coastguard Worker };
149*6777b538SAndroid Build Coastguard Worker 
150*6777b538SAndroid Build Coastguard Worker class GetInfoHelper : public FileHelper {
151*6777b538SAndroid Build Coastguard Worker  public:
GetInfoHelper(base::WeakPtr<FileProxy> proxy,File file)152*6777b538SAndroid Build Coastguard Worker   GetInfoHelper(base::WeakPtr<FileProxy> proxy, File file)
153*6777b538SAndroid Build Coastguard Worker       : FileHelper(std::move(proxy), std::move(file)) {}
154*6777b538SAndroid Build Coastguard Worker   GetInfoHelper(const GetInfoHelper&) = delete;
155*6777b538SAndroid Build Coastguard Worker   GetInfoHelper& operator=(const GetInfoHelper&) = delete;
156*6777b538SAndroid Build Coastguard Worker 
RunWork()157*6777b538SAndroid Build Coastguard Worker   void RunWork() {
158*6777b538SAndroid Build Coastguard Worker     if (file_.GetInfo(&file_info_))
159*6777b538SAndroid Build Coastguard Worker       error_  = File::FILE_OK;
160*6777b538SAndroid Build Coastguard Worker   }
161*6777b538SAndroid Build Coastguard Worker 
Reply(FileProxy::GetFileInfoCallback callback)162*6777b538SAndroid Build Coastguard Worker   void Reply(FileProxy::GetFileInfoCallback callback) {
163*6777b538SAndroid Build Coastguard Worker     PassFile();
164*6777b538SAndroid Build Coastguard Worker     DCHECK(!callback.is_null());
165*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(error_, file_info_);
166*6777b538SAndroid Build Coastguard Worker   }
167*6777b538SAndroid Build Coastguard Worker 
168*6777b538SAndroid Build Coastguard Worker  private:
169*6777b538SAndroid Build Coastguard Worker   File::Info file_info_;
170*6777b538SAndroid Build Coastguard Worker };
171*6777b538SAndroid Build Coastguard Worker 
172*6777b538SAndroid Build Coastguard Worker class ReadHelper : public FileHelper {
173*6777b538SAndroid Build Coastguard Worker  public:
ReadHelper(base::WeakPtr<FileProxy> proxy,File file,int bytes_to_read)174*6777b538SAndroid Build Coastguard Worker   ReadHelper(base::WeakPtr<FileProxy> proxy, File file, int bytes_to_read)
175*6777b538SAndroid Build Coastguard Worker       : FileHelper(std::move(proxy), std::move(file)),
176*6777b538SAndroid Build Coastguard Worker         // SAFETY - References to `buffer_` are provided as a span only after
177*6777b538SAndroid Build Coastguard Worker         // successfully reading some bytes.
178*6777b538SAndroid Build Coastguard Worker         buffer_(base::HeapArray<uint8_t>::Uninit(
179*6777b538SAndroid Build Coastguard Worker             static_cast<size_t>(bytes_to_read))) {}
180*6777b538SAndroid Build Coastguard Worker 
181*6777b538SAndroid Build Coastguard Worker   ReadHelper(const ReadHelper&) = delete;
182*6777b538SAndroid Build Coastguard Worker   ReadHelper& operator=(const ReadHelper&) = delete;
183*6777b538SAndroid Build Coastguard Worker 
RunWork(int64_t offset)184*6777b538SAndroid Build Coastguard Worker   void RunWork(int64_t offset) {
185*6777b538SAndroid Build Coastguard Worker     std::optional<size_t> result = file_.Read(offset, buffer_);
186*6777b538SAndroid Build Coastguard Worker     if (!result.has_value()) {
187*6777b538SAndroid Build Coastguard Worker       bytes_read_ = -1;
188*6777b538SAndroid Build Coastguard Worker       error_ = File::FILE_ERROR_FAILED;
189*6777b538SAndroid Build Coastguard Worker       return;
190*6777b538SAndroid Build Coastguard Worker     }
191*6777b538SAndroid Build Coastguard Worker     bytes_read_ = checked_cast<int>(result.value());
192*6777b538SAndroid Build Coastguard Worker     error_ = File::FILE_OK;
193*6777b538SAndroid Build Coastguard Worker   }
194*6777b538SAndroid Build Coastguard Worker 
Reply(FileProxy::ReadCallback callback)195*6777b538SAndroid Build Coastguard Worker   void Reply(FileProxy::ReadCallback callback) {
196*6777b538SAndroid Build Coastguard Worker     PassFile();
197*6777b538SAndroid Build Coastguard Worker     DCHECK(!callback.is_null());
198*6777b538SAndroid Build Coastguard Worker     base::span<uint8_t> read_span;
199*6777b538SAndroid Build Coastguard Worker     if (error_ == File::FILE_OK) {
200*6777b538SAndroid Build Coastguard Worker       read_span = buffer_.first(checked_cast<size_t>(bytes_read_));
201*6777b538SAndroid Build Coastguard Worker     }
202*6777b538SAndroid Build Coastguard Worker     std::move(callback).Run(error_, base::as_chars(read_span));
203*6777b538SAndroid Build Coastguard Worker   }
204*6777b538SAndroid Build Coastguard Worker 
205*6777b538SAndroid Build Coastguard Worker  private:
206*6777b538SAndroid Build Coastguard Worker   base::HeapArray<uint8_t> buffer_;
207*6777b538SAndroid Build Coastguard Worker   int bytes_read_ = 0;
208*6777b538SAndroid Build Coastguard Worker };
209*6777b538SAndroid Build Coastguard Worker 
210*6777b538SAndroid Build Coastguard Worker class WriteHelper : public FileHelper {
211*6777b538SAndroid Build Coastguard Worker  public:
WriteHelper(base::WeakPtr<FileProxy> proxy,File file,base::span<const uint8_t> data)212*6777b538SAndroid Build Coastguard Worker   WriteHelper(base::WeakPtr<FileProxy> proxy,
213*6777b538SAndroid Build Coastguard Worker               File file,
214*6777b538SAndroid Build Coastguard Worker               base::span<const uint8_t> data)
215*6777b538SAndroid Build Coastguard Worker       : FileHelper(std::move(proxy), std::move(file)),
216*6777b538SAndroid Build Coastguard Worker         buffer_(base::HeapArray<uint8_t>::CopiedFrom(data)) {}
217*6777b538SAndroid Build Coastguard Worker 
218*6777b538SAndroid Build Coastguard Worker   WriteHelper(const WriteHelper&) = delete;
219*6777b538SAndroid Build Coastguard Worker   WriteHelper& operator=(const WriteHelper&) = delete;
220*6777b538SAndroid Build Coastguard Worker 
RunWork(int64_t offset)221*6777b538SAndroid Build Coastguard Worker   void RunWork(int64_t offset) {
222*6777b538SAndroid Build Coastguard Worker     std::optional<size_t> result = file_.Write(offset, buffer_);
223*6777b538SAndroid Build Coastguard Worker     if (!result.has_value()) {
224*6777b538SAndroid Build Coastguard Worker       bytes_written_ = -1;
225*6777b538SAndroid Build Coastguard Worker       error_ = File::FILE_ERROR_FAILED;
226*6777b538SAndroid Build Coastguard Worker       return;
227*6777b538SAndroid Build Coastguard Worker     }
228*6777b538SAndroid Build Coastguard Worker     bytes_written_ = checked_cast<int>(result.value());
229*6777b538SAndroid Build Coastguard Worker     error_ = File::FILE_OK;
230*6777b538SAndroid Build Coastguard Worker   }
231*6777b538SAndroid Build Coastguard Worker 
Reply(FileProxy::WriteCallback callback)232*6777b538SAndroid Build Coastguard Worker   void Reply(FileProxy::WriteCallback callback) {
233*6777b538SAndroid Build Coastguard Worker     PassFile();
234*6777b538SAndroid Build Coastguard Worker     if (!callback.is_null())
235*6777b538SAndroid Build Coastguard Worker       std::move(callback).Run(error_, bytes_written_);
236*6777b538SAndroid Build Coastguard Worker   }
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker  private:
239*6777b538SAndroid Build Coastguard Worker   base::HeapArray<uint8_t> buffer_;
240*6777b538SAndroid Build Coastguard Worker   int bytes_written_ = 0;
241*6777b538SAndroid Build Coastguard Worker };
242*6777b538SAndroid Build Coastguard Worker 
243*6777b538SAndroid Build Coastguard Worker }  // namespace
244*6777b538SAndroid Build Coastguard Worker 
FileProxy(TaskRunner * task_runner)245*6777b538SAndroid Build Coastguard Worker FileProxy::FileProxy(TaskRunner* task_runner) : task_runner_(task_runner) {}
246*6777b538SAndroid Build Coastguard Worker 
~FileProxy()247*6777b538SAndroid Build Coastguard Worker FileProxy::~FileProxy() {
248*6777b538SAndroid Build Coastguard Worker   if (file_.IsValid())
249*6777b538SAndroid Build Coastguard Worker     task_runner_->PostTask(FROM_HERE, BindOnce(&FileDeleter, std::move(file_)));
250*6777b538SAndroid Build Coastguard Worker }
251*6777b538SAndroid Build Coastguard Worker 
CreateOrOpen(const FilePath & file_path,uint32_t file_flags,StatusCallback callback)252*6777b538SAndroid Build Coastguard Worker bool FileProxy::CreateOrOpen(const FilePath& file_path,
253*6777b538SAndroid Build Coastguard Worker                              uint32_t file_flags,
254*6777b538SAndroid Build Coastguard Worker                              StatusCallback callback) {
255*6777b538SAndroid Build Coastguard Worker   DCHECK(!file_.IsValid());
256*6777b538SAndroid Build Coastguard Worker   CreateOrOpenHelper* helper =
257*6777b538SAndroid Build Coastguard Worker       new CreateOrOpenHelper(weak_ptr_factory_.GetWeakPtr(), File());
258*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
259*6777b538SAndroid Build Coastguard Worker       FROM_HERE,
260*6777b538SAndroid Build Coastguard Worker       BindOnce(&CreateOrOpenHelper::RunWork, Unretained(helper), file_path,
261*6777b538SAndroid Build Coastguard Worker                file_flags),
262*6777b538SAndroid Build Coastguard Worker       BindOnce(&CreateOrOpenHelper::Reply, Owned(helper), std::move(callback)));
263*6777b538SAndroid Build Coastguard Worker }
264*6777b538SAndroid Build Coastguard Worker 
CreateTemporary(uint32_t additional_file_flags,CreateTemporaryCallback callback)265*6777b538SAndroid Build Coastguard Worker bool FileProxy::CreateTemporary(uint32_t additional_file_flags,
266*6777b538SAndroid Build Coastguard Worker                                 CreateTemporaryCallback callback) {
267*6777b538SAndroid Build Coastguard Worker   DCHECK(!file_.IsValid());
268*6777b538SAndroid Build Coastguard Worker   CreateTemporaryHelper* helper =
269*6777b538SAndroid Build Coastguard Worker       new CreateTemporaryHelper(weak_ptr_factory_.GetWeakPtr(), File());
270*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
271*6777b538SAndroid Build Coastguard Worker       FROM_HERE,
272*6777b538SAndroid Build Coastguard Worker       BindOnce(&CreateTemporaryHelper::RunWork, Unretained(helper),
273*6777b538SAndroid Build Coastguard Worker                additional_file_flags),
274*6777b538SAndroid Build Coastguard Worker       BindOnce(&CreateTemporaryHelper::Reply, Owned(helper),
275*6777b538SAndroid Build Coastguard Worker                std::move(callback)));
276*6777b538SAndroid Build Coastguard Worker }
277*6777b538SAndroid Build Coastguard Worker 
IsValid() const278*6777b538SAndroid Build Coastguard Worker bool FileProxy::IsValid() const {
279*6777b538SAndroid Build Coastguard Worker   return file_.IsValid();
280*6777b538SAndroid Build Coastguard Worker }
281*6777b538SAndroid Build Coastguard Worker 
SetFile(File file)282*6777b538SAndroid Build Coastguard Worker void FileProxy::SetFile(File file) {
283*6777b538SAndroid Build Coastguard Worker   DCHECK(!file_.IsValid());
284*6777b538SAndroid Build Coastguard Worker   file_ = std::move(file);
285*6777b538SAndroid Build Coastguard Worker }
286*6777b538SAndroid Build Coastguard Worker 
TakeFile()287*6777b538SAndroid Build Coastguard Worker File FileProxy::TakeFile() {
288*6777b538SAndroid Build Coastguard Worker   return std::move(file_);
289*6777b538SAndroid Build Coastguard Worker }
290*6777b538SAndroid Build Coastguard Worker 
DuplicateFile()291*6777b538SAndroid Build Coastguard Worker File FileProxy::DuplicateFile() {
292*6777b538SAndroid Build Coastguard Worker   return file_.Duplicate();
293*6777b538SAndroid Build Coastguard Worker }
294*6777b538SAndroid Build Coastguard Worker 
GetPlatformFile() const295*6777b538SAndroid Build Coastguard Worker PlatformFile FileProxy::GetPlatformFile() const {
296*6777b538SAndroid Build Coastguard Worker   return file_.GetPlatformFile();
297*6777b538SAndroid Build Coastguard Worker }
298*6777b538SAndroid Build Coastguard Worker 
Close(StatusCallback callback)299*6777b538SAndroid Build Coastguard Worker bool FileProxy::Close(StatusCallback callback) {
300*6777b538SAndroid Build Coastguard Worker   DCHECK(file_.IsValid());
301*6777b538SAndroid Build Coastguard Worker   GenericFileHelper* helper =
302*6777b538SAndroid Build Coastguard Worker       new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
303*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
304*6777b538SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&GenericFileHelper::Close, Unretained(helper)),
305*6777b538SAndroid Build Coastguard Worker       BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
306*6777b538SAndroid Build Coastguard Worker }
307*6777b538SAndroid Build Coastguard Worker 
GetInfo(GetFileInfoCallback callback)308*6777b538SAndroid Build Coastguard Worker bool FileProxy::GetInfo(GetFileInfoCallback callback) {
309*6777b538SAndroid Build Coastguard Worker   DCHECK(file_.IsValid());
310*6777b538SAndroid Build Coastguard Worker   GetInfoHelper* helper =
311*6777b538SAndroid Build Coastguard Worker       new GetInfoHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
312*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
313*6777b538SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&GetInfoHelper::RunWork, Unretained(helper)),
314*6777b538SAndroid Build Coastguard Worker       BindOnce(&GetInfoHelper::Reply, Owned(helper), std::move(callback)));
315*6777b538SAndroid Build Coastguard Worker }
316*6777b538SAndroid Build Coastguard Worker 
Read(int64_t offset,int bytes_to_read,ReadCallback callback)317*6777b538SAndroid Build Coastguard Worker bool FileProxy::Read(int64_t offset, int bytes_to_read, ReadCallback callback) {
318*6777b538SAndroid Build Coastguard Worker   DCHECK(file_.IsValid());
319*6777b538SAndroid Build Coastguard Worker   if (bytes_to_read < 0)
320*6777b538SAndroid Build Coastguard Worker     return false;
321*6777b538SAndroid Build Coastguard Worker 
322*6777b538SAndroid Build Coastguard Worker   ReadHelper* helper = new ReadHelper(weak_ptr_factory_.GetWeakPtr(),
323*6777b538SAndroid Build Coastguard Worker                                       std::move(file_), bytes_to_read);
324*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
325*6777b538SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&ReadHelper::RunWork, Unretained(helper), offset),
326*6777b538SAndroid Build Coastguard Worker       BindOnce(&ReadHelper::Reply, Owned(helper), std::move(callback)));
327*6777b538SAndroid Build Coastguard Worker }
328*6777b538SAndroid Build Coastguard Worker 
Write(int64_t offset,base::span<const uint8_t> data,WriteCallback callback)329*6777b538SAndroid Build Coastguard Worker bool FileProxy::Write(int64_t offset,
330*6777b538SAndroid Build Coastguard Worker                       base::span<const uint8_t> data,
331*6777b538SAndroid Build Coastguard Worker                       WriteCallback callback) {
332*6777b538SAndroid Build Coastguard Worker   DCHECK(file_.IsValid());
333*6777b538SAndroid Build Coastguard Worker   if (data.empty()) {
334*6777b538SAndroid Build Coastguard Worker     return false;
335*6777b538SAndroid Build Coastguard Worker   }
336*6777b538SAndroid Build Coastguard Worker   WriteHelper* helper =
337*6777b538SAndroid Build Coastguard Worker       new WriteHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_), data);
338*6777b538SAndroid Build Coastguard Worker 
339*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
340*6777b538SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&WriteHelper::RunWork, Unretained(helper), offset),
341*6777b538SAndroid Build Coastguard Worker       BindOnce(&WriteHelper::Reply, Owned(helper), std::move(callback)));
342*6777b538SAndroid Build Coastguard Worker }
343*6777b538SAndroid Build Coastguard Worker 
SetTimes(Time last_access_time,Time last_modified_time,StatusCallback callback)344*6777b538SAndroid Build Coastguard Worker bool FileProxy::SetTimes(Time last_access_time,
345*6777b538SAndroid Build Coastguard Worker                          Time last_modified_time,
346*6777b538SAndroid Build Coastguard Worker                          StatusCallback callback) {
347*6777b538SAndroid Build Coastguard Worker   DCHECK(file_.IsValid());
348*6777b538SAndroid Build Coastguard Worker   GenericFileHelper* helper =
349*6777b538SAndroid Build Coastguard Worker       new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
350*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
351*6777b538SAndroid Build Coastguard Worker       FROM_HERE,
352*6777b538SAndroid Build Coastguard Worker       BindOnce(&GenericFileHelper::SetTimes, Unretained(helper),
353*6777b538SAndroid Build Coastguard Worker                last_access_time, last_modified_time),
354*6777b538SAndroid Build Coastguard Worker       BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
355*6777b538SAndroid Build Coastguard Worker }
356*6777b538SAndroid Build Coastguard Worker 
SetLength(int64_t length,StatusCallback callback)357*6777b538SAndroid Build Coastguard Worker bool FileProxy::SetLength(int64_t length, StatusCallback callback) {
358*6777b538SAndroid Build Coastguard Worker   DCHECK(file_.IsValid());
359*6777b538SAndroid Build Coastguard Worker   GenericFileHelper* helper =
360*6777b538SAndroid Build Coastguard Worker       new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
361*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
362*6777b538SAndroid Build Coastguard Worker       FROM_HERE,
363*6777b538SAndroid Build Coastguard Worker       BindOnce(&GenericFileHelper::SetLength, Unretained(helper), length),
364*6777b538SAndroid Build Coastguard Worker       BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
365*6777b538SAndroid Build Coastguard Worker }
366*6777b538SAndroid Build Coastguard Worker 
Flush(StatusCallback callback)367*6777b538SAndroid Build Coastguard Worker bool FileProxy::Flush(StatusCallback callback) {
368*6777b538SAndroid Build Coastguard Worker   DCHECK(file_.IsValid());
369*6777b538SAndroid Build Coastguard Worker   GenericFileHelper* helper =
370*6777b538SAndroid Build Coastguard Worker       new GenericFileHelper(weak_ptr_factory_.GetWeakPtr(), std::move(file_));
371*6777b538SAndroid Build Coastguard Worker   return task_runner_->PostTaskAndReply(
372*6777b538SAndroid Build Coastguard Worker       FROM_HERE, BindOnce(&GenericFileHelper::Flush, Unretained(helper)),
373*6777b538SAndroid Build Coastguard Worker       BindOnce(&GenericFileHelper::Reply, Owned(helper), std::move(callback)));
374*6777b538SAndroid Build Coastguard Worker }
375*6777b538SAndroid Build Coastguard Worker 
376*6777b538SAndroid Build Coastguard Worker }  // namespace base
377