Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(222)

Side by Side Diff: chrome/browser/media_gallery/win/mtp_device_delegate_impl_win.cc

Issue 11297002: [Media Gallery] Added code to support mtp device media file system on Windows. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed class comments and removed file comments Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 // MTPDeviceDelegateImplWin implementation.
6
7 #include "chrome/browser/media_gallery/win/mtp_device_delegate_impl_win.h"
8
9 #include <portabledevice.h>
10 #include <vector>
11
12 #include "base/file_path.h"
13 #include "base/file_util.h"
14 #include "base/memory/ref_counted.h"
15 #include "base/sequenced_task_runner.h"
16 #include "base/sequenced_task_runner_helpers.h"
17 #include "base/string_split.h"
18 #include "base/string_util.h"
19 #include "base/threading/thread_restrictions.h"
20 #include "base/utf_string_conversions.h"
21 #include "chrome/browser/media_gallery/win/mtp_device_object_entry.h"
22 #include "chrome/browser/media_gallery/win/mtp_device_object_enumerator.h"
23 #include "chrome/browser/media_gallery/win/mtp_device_operations_util.h"
24 #include "chrome/browser/media_gallery/win/recursive_mtp_device_object_enumerato r.h"
25 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi n.h"
26 #include "chrome/browser/system_monitor/removable_storage_notifications.h"
27 #include "content/public/browser/browser_thread.h"
28
29 namespace chrome {
30
31 namespace {
32
33 // Gets the details of the MTP partition storage specified by the
34 // |storage_path| on the UI thread. If the storage details are valid, creates a
35 // MTP device delegate on the blocking pool thread.
Ryan Sleevi 2013/01/09 20:22:25 nit: s/blocking pool thread/media task runner/
kmadhusu 2013/01/10 04:59:19 Done.
36 void GetStorageInfoAndMaybeCreateDelegate(
37 const string16& storage_path,
38 const scoped_refptr<base::SequencedTaskRunner>& media_task_runner,
39 const CreateMTPDeviceDelegateCallback& callback) {
40 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
41 DCHECK(!storage_path.empty());
42 DCHECK(media_task_runner.get());
43 string16 storage_device_id;
44 RemoveChars(storage_path, L"\\\\", &storage_device_id);
45 DCHECK(!storage_device_id.empty());
46 RemovableStorageNotifications* notifications =
47 RemovableStorageNotifications::GetInstance();
48 DCHECK(notifications);
49 string16 pnp_device_id;
50 string16 storage_object_id;
51 if ((!notifications->GetMTPStorageInfoFromDeviceId(
52 UTF16ToUTF8(storage_device_id), &pnp_device_id,
53 &storage_object_id)) ||
54 pnp_device_id.empty() ||
55 storage_object_id.empty())
56 return;
57 media_task_runner->PostTask(FROM_HERE,
58 base::Bind(&OnGotStorageInfoCreateDelegate,
59 storage_path,
60 media_task_runner,
61 callback,
62 pnp_device_id,
63 storage_object_id));
64 }
65
66 } // namespace
67
68 // Used by GetStorageInfoAndMaybeCreateDelegate() to create the MTP device
69 // delegate on the blocking pool thread.
Ryan Sleevi 2013/01/09 20:22:25 nit: s/blocking pool thread/media task runner/
kmadhusu 2013/01/10 04:59:19 Done.
70 void OnGotStorageInfoCreateDelegate(
71 const string16& device_location,
72 base::SequencedTaskRunner* media_task_runner,
73 const CreateMTPDeviceDelegateCallback& callback,
74 const string16& pnp_device_id,
75 const string16& storage_object_id) {
76 DCHECK(media_task_runner && media_task_runner->RunsTasksOnCurrentThread());
Ryan Sleevi 2013/01/09 20:22:25 nit: Split this into two DCHECKs, based on the res
kmadhusu 2013/01/10 04:59:19 Done.
77 callback.Run(new MTPDeviceDelegateImplWin(device_location,
78 pnp_device_id,
79 storage_object_id,
80 media_task_runner));
81 }
82
83 void CreateMTPDeviceDelegate(const string16& device_location,
84 base::SequencedTaskRunner* media_task_runner,
85 const CreateMTPDeviceDelegateCallback& callback) {
86 DCHECK(media_task_runner && media_task_runner->RunsTasksOnCurrentThread());
87 content::BrowserThread::PostTask(
88 content::BrowserThread::UI, FROM_HERE,
89 base::Bind(&GetStorageInfoAndMaybeCreateDelegate,
90 device_location,
91 make_scoped_refptr(media_task_runner),
92 callback));
93 }
94
95 // MTPDeviceDelegateImplWin ---------------------------------------------------
96
97 MTPDeviceDelegateImplWin::MTPDeviceDelegateImplWin(
98 const string16& fs_root_path,
99 const string16& pnp_device_id,
100 const string16& storage_object_id,
101 base::SequencedTaskRunner* media_task_runner)
102 : registered_device_path_(fs_root_path),
103 pnp_device_id_(pnp_device_id),
104 storage_object_id_(storage_object_id),
105 media_task_runner_(media_task_runner),
106 cancel_pending_tasks_(false) {
107 DCHECK(!pnp_device_id_.empty());
108 DCHECK(!storage_object_id_.empty());
109 DCHECK(media_task_runner_.get());
110 }
111
112 MTPDeviceDelegateImplWin::~MTPDeviceDelegateImplWin() {
113 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
114 }
115
116 base::PlatformFileError MTPDeviceDelegateImplWin::GetFileInfo(
117 const FilePath& file_path,
118 base::PlatformFileInfo* file_info) {
119 if (!LazyInit())
120 return base::PLATFORM_FILE_ERROR_FAILED;
121 string16 object_id = GetFileObjectIdFromPath(file_path.value());
122 if (object_id.empty())
123 return base::PLATFORM_FILE_ERROR_FAILED;
124 return GetFileEntryInfo(device_.get(), object_id, file_info);
125 }
126
127 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator>
128 MTPDeviceDelegateImplWin::CreateFileEnumerator(const FilePath& root,
129 bool recursive) {
130 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator>
131 file_enumerator(new fileapi::FileSystemFileUtil::EmptyFileEnumerator());
132 if (root.value().empty() || !LazyInit())
133 return file_enumerator.Pass();
134
135 string16 object_id = GetFileObjectIdFromPath(root.value());
136 if (object_id.empty())
137 return file_enumerator.Pass();
138
139 MTPDeviceObjectEntries entries;
140 if (!GetDirectoryEntries(device_.get(), object_id, &entries) ||
141 entries.empty())
142 return file_enumerator.Pass();
143
144 if (recursive) {
145 file_enumerator.reset(
146 new RecursiveMTPDeviceObjectEnumerator(device_.get(), entries));
147 } else {
148 file_enumerator.reset(new MTPDeviceObjectEnumerator(entries));
149 }
150 return file_enumerator.Pass();
151 }
152
153 base::PlatformFileError MTPDeviceDelegateImplWin::CreateSnapshotFile(
154 const FilePath& device_file_path,
155 const FilePath& local_path,
156 base::PlatformFileInfo* file_info) {
157 if (!LazyInit())
158 return base::PLATFORM_FILE_ERROR_FAILED;
159 string16 file_object_id = GetFileObjectIdFromPath(device_file_path.value());
160 if (file_object_id.empty())
161 return base::PLATFORM_FILE_ERROR_FAILED;
162 if (!WriteFileObjectData(device_.get(), file_object_id, local_path))
163 return base::PLATFORM_FILE_ERROR_FAILED;
164 base::PlatformFileError error = GetFileInfo(device_file_path, file_info);
165
166 // LocalFileStreamReader is used to read the contents of the snapshot file.
167 // Snapshot file modification time does not match the last modified time
168 // of the original media file. Therefore, set the last modified time to null
169 // in order to avoid the verification in LocalFileStreamReader.
170 //
171 // Users will use HTML5 FileSystem Entry getMetadata() interface to get actual
Ryan Sleevi 2013/01/09 20:22:25 nit: s/get actual/get the actual/
kmadhusu 2013/01/10 04:59:19 Done.
172 // last modified time of the media file.
173 file_info->last_modified = base::Time();
174 return error;
175 }
176
177 void MTPDeviceDelegateImplWin::CancelPendingTasksAndDeleteDelegate() {
178 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
179 {
180 base::AutoLock locked(cancel_tasks_lock_);
181 cancel_pending_tasks_ = true;
182 }
183 media_task_runner_->DeleteSoon(FROM_HERE, this);
184 }
185
186 bool MTPDeviceDelegateImplWin::LazyInit() {
187 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
188 // Both OpenDevice() (which we call below) and any operations our callers do
189 // may take some time. Abort them immediately if we're in the process of
190 // shutting down.
191 {
192 base::AutoLock locked(cancel_tasks_lock_);
193 if (cancel_pending_tasks_)
194 return false;
195 }
196 if (device_.get())
197 return true; // Already successfully initialized.
198 return OpenDevice(pnp_device_id_, &device_);
199 }
200
201 string16 MTPDeviceDelegateImplWin::GetFileObjectIdFromPath(
202 const string16& file_path) {
203 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
204 DCHECK(!file_path.empty());
205 if (registered_device_path_ == file_path)
206 return storage_object_id_;
207
208 string16 actual_file_path(file_path);
209 ReplaceFirstSubstringAfterOffset(&actual_file_path, 0,
210 registered_device_path_, string16());
211 DCHECK(!actual_file_path.empty());
212 typedef std::vector<string16> PathComponents;
213 PathComponents path_components;
214 base::SplitString(actual_file_path, L'\\', &path_components);
215 DCHECK(!path_components.empty());
216 string16 parent_id(storage_object_id_);
217 string16 file_object_id;
218 for (PathComponents::const_iterator path_iter = path_components.begin() + 1;
219 path_iter != path_components.end(); ++path_iter) {
220 file_object_id = GetObjectIdFromName(device_, parent_id, *path_iter);
221 if (file_object_id.empty())
222 break;
223 parent_id = file_object_id;
224 }
225 return file_object_id;
226 }
227
228 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698