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