Upstream version 11.40.277.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/files/file_path.h"
9 #include "base/files/file_util.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   return base::AppendToFile(snapshot_file_path, data.c_str(), data.size())
31              ? base::checked_cast<uint32>(data.size())
32              : 0;
33 }
34
35 }  // namespace
36
37 MTPReadFileWorker::MTPReadFileWorker(const std::string& device_handle)
38     : device_handle_(device_handle),
39       weak_ptr_factory_(this) {
40   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
41   DCHECK(!device_handle_.empty());
42 }
43
44 MTPReadFileWorker::~MTPReadFileWorker() {
45 }
46
47 void MTPReadFileWorker::WriteDataIntoSnapshotFile(
48     const SnapshotRequestInfo& request_info,
49     const base::File::Info& snapshot_file_info) {
50   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
51   ReadDataChunkFromDeviceFile(
52       make_scoped_ptr(new SnapshotFileDetails(request_info,
53                                               snapshot_file_info)));
54 }
55
56 void MTPReadFileWorker::ReadDataChunkFromDeviceFile(
57     scoped_ptr<SnapshotFileDetails> snapshot_file_details) {
58   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
59   DCHECK(snapshot_file_details.get());
60
61   // To avoid calling |snapshot_file_details| methods and passing ownership of
62   // |snapshot_file_details| in the same_line.
63   SnapshotFileDetails* snapshot_file_details_ptr = snapshot_file_details.get();
64
65   device::MediaTransferProtocolManager* mtp_device_manager =
66       StorageMonitor::GetInstance()->media_transfer_protocol_manager();
67   mtp_device_manager->ReadFileChunk(
68       device_handle_,
69       snapshot_file_details_ptr->file_id(),
70       snapshot_file_details_ptr->bytes_written(),
71       snapshot_file_details_ptr->BytesToRead(),
72       base::Bind(&MTPReadFileWorker::OnDidReadDataChunkFromDeviceFile,
73                  weak_ptr_factory_.GetWeakPtr(),
74                  base::Passed(&snapshot_file_details)));
75 }
76
77 void MTPReadFileWorker::OnDidReadDataChunkFromDeviceFile(
78     scoped_ptr<SnapshotFileDetails> snapshot_file_details,
79     const std::string& data,
80     bool error) {
81   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
82   DCHECK(snapshot_file_details.get());
83   snapshot_file_details->set_error_occurred(
84       error || (data.size() != snapshot_file_details->BytesToRead()));
85   if (snapshot_file_details->error_occurred()) {
86     OnDidWriteIntoSnapshotFile(snapshot_file_details.Pass());
87     return;
88   }
89
90   // To avoid calling |snapshot_file_details| methods and passing ownership of
91   // |snapshot_file_details| in the same_line.
92   SnapshotFileDetails* snapshot_file_details_ptr = snapshot_file_details.get();
93   content::BrowserThread::PostTaskAndReplyWithResult(
94       content::BrowserThread::FILE,
95       FROM_HERE,
96       base::Bind(&WriteDataChunkIntoSnapshotFileOnFileThread,
97                  snapshot_file_details_ptr->snapshot_file_path(),
98                  data),
99       base::Bind(&MTPReadFileWorker::OnDidWriteDataChunkIntoSnapshotFile,
100                  weak_ptr_factory_.GetWeakPtr(),
101                  base::Passed(&snapshot_file_details)));
102 }
103
104 void MTPReadFileWorker::OnDidWriteDataChunkIntoSnapshotFile(
105     scoped_ptr<SnapshotFileDetails> snapshot_file_details,
106     uint32 bytes_written) {
107   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
108   DCHECK(snapshot_file_details.get());
109   if (snapshot_file_details->AddBytesWritten(bytes_written)) {
110     if (!snapshot_file_details->IsSnapshotFileWriteComplete()) {
111       ReadDataChunkFromDeviceFile(snapshot_file_details.Pass());
112       return;
113     }
114   } else {
115     snapshot_file_details->set_error_occurred(true);
116   }
117   OnDidWriteIntoSnapshotFile(snapshot_file_details.Pass());
118 }
119
120 void MTPReadFileWorker::OnDidWriteIntoSnapshotFile(
121     scoped_ptr<SnapshotFileDetails> snapshot_file_details) {
122   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
123   DCHECK(snapshot_file_details.get());
124
125   if (snapshot_file_details->error_occurred()) {
126     content::BrowserThread::PostTask(
127         content::BrowserThread::IO,
128         FROM_HERE,
129         base::Bind(snapshot_file_details->error_callback(),
130                    base::File::FILE_ERROR_FAILED));
131     return;
132   }
133   content::BrowserThread::PostTask(
134       content::BrowserThread::IO,
135       FROM_HERE,
136       base::Bind(snapshot_file_details->success_callback(),
137                  snapshot_file_details->file_info(),
138                  snapshot_file_details->snapshot_file_path()));
139 }