1 // Copyright 2014 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 #include "chrome/browser/chromeos/file_system_provider/operations/write_file.h"
6 
7 #include <utility>
8 
9 #include "base/containers/span.h"
10 #include "base/trace_event/trace_event.h"
11 #include "base/values.h"
12 #include "chrome/common/extensions/api/file_system_provider.h"
13 #include "chrome/common/extensions/api/file_system_provider_internal.h"
14 
15 namespace chromeos {
16 namespace file_system_provider {
17 namespace operations {
18 
WriteFile(extensions::EventRouter * event_router,const ProvidedFileSystemInfo & file_system_info,int file_handle,scoped_refptr<net::IOBuffer> buffer,int64_t offset,int length,storage::AsyncFileUtil::StatusCallback callback)19 WriteFile::WriteFile(extensions::EventRouter* event_router,
20                      const ProvidedFileSystemInfo& file_system_info,
21                      int file_handle,
22                      scoped_refptr<net::IOBuffer> buffer,
23                      int64_t offset,
24                      int length,
25                      storage::AsyncFileUtil::StatusCallback callback)
26     : Operation(event_router, file_system_info),
27       file_handle_(file_handle),
28       buffer_(buffer),
29       offset_(offset),
30       length_(length),
31       callback_(std::move(callback)) {}
32 
~WriteFile()33 WriteFile::~WriteFile() {
34 }
35 
Execute(int request_id)36 bool WriteFile::Execute(int request_id) {
37   TRACE_EVENT0("file_system_provider", "WriteFile::Execute");
38   using extensions::api::file_system_provider::WriteFileRequestedOptions;
39 
40   if (!file_system_info_.writable())
41     return false;
42 
43   WriteFileRequestedOptions options;
44   options.file_system_id = file_system_info_.file_system_id();
45   options.request_id = request_id;
46   options.open_request_id = file_handle_;
47   options.offset = offset_;
48   // Length is not passed directly since it can be accessed via data.byteLength.
49 
50   // Set the data directly on base::Value() to avoid an extra string copy.
51   DCHECK(buffer_.get());
52 
53   base::Value options_as_value =
54       base::Value::FromUniquePtrValue(options.ToValue());
55   options_as_value.SetKey(
56       "data",
57       base::Value(base::as_bytes(base::make_span(buffer_->data(), length_))));
58 
59   base::Value event_args(base::Value::Type::LIST);
60   event_args.Append(std::move(options_as_value));
61 
62   return SendEvent(
63       request_id,
64       extensions::events::FILE_SYSTEM_PROVIDER_ON_WRITE_FILE_REQUESTED,
65       extensions::api::file_system_provider::OnWriteFileRequested::kEventName,
66       base::ListValue::From(
67           base::Value::ToUniquePtrValue(std::move(event_args))));
68 }
69 
OnSuccess(int,std::unique_ptr<RequestValue>,bool)70 void WriteFile::OnSuccess(int /* request_id */,
71                           std::unique_ptr<RequestValue> /* result */,
72                           bool /* has_more */) {
73   TRACE_EVENT0("file_system_provider", "WriteFile::OnSuccess");
74   DCHECK(callback_);
75   std::move(callback_).Run(base::File::FILE_OK);
76 }
77 
OnError(int,std::unique_ptr<RequestValue>,base::File::Error error)78 void WriteFile::OnError(int /* request_id */,
79                         std::unique_ptr<RequestValue> /* result */,
80                         base::File::Error error) {
81   TRACE_EVENT0("file_system_provider", "WriteFile::OnError");
82   DCHECK(callback_);
83   std::move(callback_).Run(error);
84 }
85 
86 }  // namespace operations
87 }  // namespace file_system_provider
88 }  // namespace chromeos
89