Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media_galleries / linux / mtp_read_file_worker.cc
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.
4
5 #include "chrome/browser/media_galleries/linux/mtp_read_file_worker.h"
6
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "chrome/browser/media_galleries/linux/snapshot_file_details.h"
12 #include "components/storage_monitor/storage_monitor.h"
13 #include "content/public/browser/browser_thread.h"
14 #include "device/media_transfer_protocol/media_transfer_protocol_manager.h"
15 #include "third_party/cros_system_api/dbus/service_constants.h"
16
17 using content::BrowserThread;
18 using storage_monitor::StorageMonitor;
19
20 namespace {
21
22 // Appends |data| to the snapshot file specified by the |snapshot_file_path| on
23 // the file thread.
24 // Returns the number of bytes written to the snapshot file. In case of failure,
25 // returns zero.
26 uint32 WriteDataChunkIntoSnapshotFileOnFileThread(
27     const base::FilePath& snapshot_file_path,
28     const std::string& data) {
29   DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
30   int bytes_written =
31       base::AppendToFile(snapshot_file_path, data.data(),
32                          base::checked_cast<int>(data.size()));
33   return (static_cast<int>(data.size()) == bytes_written) ?
34       base::checked_cast<uint32>(bytes_written) : 0;
35 }
36
37 }  // namespace
38
39 MTPReadFileWorker::MTPReadFileWorker(const std::string& device_handle)
40     : device_handle_(device_handle),
41       weak_ptr_factory_(this) {
42   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
43   DCHECK(!device_handle_.empty());
44 }
45
46 MTPReadFileWorker::~MTPReadFileWorker() {
47 }
48
49 void MTPReadFileWorker::WriteDataIntoSnapshotFile(
50     const SnapshotRequestInfo& request_info,
51     const base::File::Info& snapshot_file_info) {
52   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
53   ReadDataChunkFromDeviceFile(
54       make_scoped_ptr(new SnapshotFileDetails(request_info,
55                                               snapshot_file_info)));
56 }
57
58 void MTPReadFileWorker::ReadDataChunkFromDeviceFile(
59     scoped_ptr<SnapshotFileDetails> snapshot_file_details) {
60   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
61   DCHECK(snapshot_file_details.get());
62
63   // To avoid calling |snapshot_file_details| methods and passing ownership of
64   // |snapshot_file_details| in the same_line.
65   SnapshotFileDetails* snapshot_file_details_ptr = snapshot_file_details.get();
66
67   device::MediaTransferProtocolManager* mtp_device_manager =
68       StorageMonitor::GetInstance()->media_transfer_protocol_manager();
69   mtp_device_manager->ReadFileChunk(
70       device_handle_,
71       snapshot_file_details_ptr->file_id(),
72       snapshot_file_details_ptr->bytes_written(),
73       snapshot_file_details_ptr->BytesToRead(),
74       base::Bind(&MTPReadFileWorker::OnDidReadDataChunkFromDeviceFile,
75                  weak_ptr_factory_.GetWeakPtr(),
76                  base::Passed(&snapshot_file_details)));
77 }
78
79 void MTPReadFileWorker::OnDidReadDataChunkFromDeviceFile(
80     scoped_ptr<SnapshotFileDetails> snapshot_file_details,
81     const std::string& data,
82     bool error) {
83   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
84   DCHECK(snapshot_file_details.get());
85   snapshot_file_details->set_error_occurred(
86       error || (data.size() != snapshot_file_details->BytesToRead()));
87   if (snapshot_file_details->error_occurred()) {
88     OnDidWriteIntoSnapshotFile(snapshot_file_details.Pass());
89     return;
90   }
91
92   // To avoid calling |snapshot_file_details| methods and passing ownership of
93   // |snapshot_file_details| in the same_line.
94   SnapshotFileDetails* snapshot_file_details_ptr = snapshot_file_details.get();
95   content::BrowserThread::PostTaskAndReplyWithResult(
96       content::BrowserThread::FILE,
97       FROM_HERE,
98       base::Bind(&WriteDataChunkIntoSnapshotFileOnFileThread,
99                  snapshot_file_details_ptr->snapshot_file_path(),
100                  data),
101       base::Bind(&MTPReadFileWorker::OnDidWriteDataChunkIntoSnapshotFile,
102                  weak_ptr_factory_.GetWeakPtr(),
103                  base::Passed(&snapshot_file_details)));
104 }
105
106 void MTPReadFileWorker::OnDidWriteDataChunkIntoSnapshotFile(
107     scoped_ptr<SnapshotFileDetails> snapshot_file_details,
108     uint32 bytes_written) {
109   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
110   DCHECK(snapshot_file_details.get());
111   if (snapshot_file_details->AddBytesWritten(bytes_written)) {
112     if (!snapshot_file_details->IsSnapshotFileWriteComplete()) {
113       ReadDataChunkFromDeviceFile(snapshot_file_details.Pass());
114       return;
115     }
116   } else {
117     snapshot_file_details->set_error_occurred(true);
118   }
119   OnDidWriteIntoSnapshotFile(snapshot_file_details.Pass());
120 }
121
122 void MTPReadFileWorker::OnDidWriteIntoSnapshotFile(
123     scoped_ptr<SnapshotFileDetails> snapshot_file_details) {
124   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
125   DCHECK(snapshot_file_details.get());
126
127   if (snapshot_file_details->error_occurred()) {
128     content::BrowserThread::PostTask(
129         content::BrowserThread::IO,
130         FROM_HERE,
131         base::Bind(snapshot_file_details->error_callback(),
132                    base::File::FILE_ERROR_FAILED));
133     return;
134   }
135   content::BrowserThread::PostTask(
136       content::BrowserThread::IO,
137       FROM_HERE,
138       base::Bind(snapshot_file_details->success_callback(),
139                  snapshot_file_details->file_info(),
140                  snapshot_file_details->snapshot_file_path()));
141 }