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

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: Removed DCHECK, added lock in PortableDeviceWatcherWin and fixed tests. Created 8 years 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/sequenced_task_runner.h"
15 #include "base/string_split.h"
16 #include "base/string_util.h"
17 #include "base/utf_string_conversions.h"
18 #include "chrome/browser/media_gallery/win/mtp_device_object_entry.h"
19 #include "chrome/browser/media_gallery/win/mtp_device_object_enumerator.h"
20 #include "chrome/browser/media_gallery/win/mtp_device_operations_util.h"
21 #include "chrome/browser/media_gallery/win/recursive_mtp_device_object_enumerato r.h"
22 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi n.h"
23 #include "chrome/browser/system_monitor/removable_storage_notifications.h"
24 #include "content/public/browser/browser_thread.h"
25
26 namespace chrome {
27
28 namespace {
29
30 // Gets the details of the MTP partition storage specified by the
31 // |storage_path|. On success, returns true and fills in |pnp_device_id| and
32 // |storage_object_id|. On failure, returns false and |pnp_device_id| and
33 // |storage_object_id| are not set.
34 bool GetStorageInfoFromStoragePath(const string16& storage_path,
35 string16* pnp_device_id,
36 string16* storage_object_id) {
37 DCHECK(!storage_path.empty());
38 DCHECK(pnp_device_id);
39 DCHECK(storage_object_id);
40 string16 storage_device_id;
41 RemoveChars(storage_path, L"\\\\", &storage_device_id);
42 DCHECK(!storage_device_id.empty());
43 RemovableStorageNotifications* notifications =
44 RemovableStorageNotifications::GetInstance();
45 DCHECK(notifications);
46 return notifications->GetMTPStorageInfoFromDeviceId(
47 UTF16ToUTF8(storage_device_id), pnp_device_id, storage_object_id);
48 }
49
50 } // namespace
51
52 void CreateMTPDeviceDelegate(const string16& device_location,
53 base::SequencedTaskRunner* media_task_runner,
54 const CreateMTPDeviceDelegateCallback& callback) {
55 DCHECK(media_task_runner->RunsTasksOnCurrentThread());
56 callback.Run(new MTPDeviceDelegateImplWin(device_location,
57 media_task_runner));
58 }
59
60 // MTPDeviceDelegateImplWin ---------------------------------------------------
61
62 MTPDeviceDelegateImplWin::MTPDeviceDelegateImplWin(
63 const string16& fs_root_path,
64 base::SequencedTaskRunner* media_task_runner)
65 : registered_device_path_(fs_root_path),
66 media_task_runner_(media_task_runner),
67 cancel_pending_tasks_(false) {
68 DCHECK(media_task_runner_.get());
Peter Kasting 2012/12/21 18:13:30 Nit: This DCHECK should probably move to CreateMTP
kmadhusu 2013/01/02 19:48:31 Added a DCHECK in CreateMTPDeviceDelegate.
69 // TODO(kmadhusu): After fixing crbug.com/154835, post a task on the UI thread
70 // to get storage information from the specified storage path.
71 bool success = GetStorageInfoFromStoragePath(
72 registered_device_path_, &pnp_device_id_, &storage_object_id_);
73 DCHECK(success);
74 }
75
76 MTPDeviceDelegateImplWin::~MTPDeviceDelegateImplWin() {
77 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
78 }
79
80 base::PlatformFileError MTPDeviceDelegateImplWin::GetFileInfo(
81 const FilePath& file_path,
82 base::PlatformFileInfo* file_info) {
83 if (!LazyInit())
84 return base::PLATFORM_FILE_ERROR_FAILED;
85 string16 object_id = GetFileObjectIdFromPath(file_path.value());
86 if (object_id.empty())
87 return base::PLATFORM_FILE_ERROR_FAILED;
88 return MTPDeviceOperationsUtil::GetFileEntryInfo(device_.get(), object_id,
89 file_info);
90 }
91
92 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator>
93 MTPDeviceDelegateImplWin::CreateFileEnumerator(const FilePath& root,
94 bool recursive) {
95 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator>
96 file_enumerator(new fileapi::FileSystemFileUtil::EmptyFileEnumerator());
97 if (root.value().empty() || !LazyInit())
98 return file_enumerator.Pass();
99
100 string16 object_id = GetFileObjectIdFromPath(root.value());
101 if (object_id.empty())
102 return file_enumerator.Pass();
103
104 MTPDeviceObjectEntries entries;
105 if (!MTPDeviceOperationsUtil::GetDirectoryEntries(device_.get(), object_id,
106 &entries) ||
107 entries.empty())
108 return file_enumerator.Pass();
109
110 if (recursive) {
111 file_enumerator.reset(
112 new RecursiveMTPDeviceObjectEnumerator(device_.get(), entries));
113 } else {
114 file_enumerator.reset(new MTPDeviceObjectEnumerator(entries));
115 }
116 return file_enumerator.Pass();
117 }
118
119 base::PlatformFileError MTPDeviceDelegateImplWin::CreateSnapshotFile(
120 const FilePath& device_file_path,
121 const FilePath& local_path,
122 base::PlatformFileInfo* file_info) {
123 if (!LazyInit())
124 return base::PLATFORM_FILE_ERROR_FAILED;
125 string16 file_object_id = GetFileObjectIdFromPath(device_file_path.value());
126 if (file_object_id.empty())
127 return base::PLATFORM_FILE_ERROR_FAILED;
128 if (!MTPDeviceOperationsUtil::WriteFileObjectData(device_.get(),
129 file_object_id,
130 local_path))
131 return base::PLATFORM_FILE_ERROR_FAILED;
132 base::PlatformFileError error = GetFileInfo(device_file_path, file_info);
133
134 // LocalFileStreamReader is used to read the contents of the snapshot file.
135 // Snapshot file modification time does not match the last modified time
136 // of the original media file. Therefore, set the last modified time to null
137 // in order to avoid the verification in LocalFileStreamReader.
138 //
139 // Users will use HTML5 FileSystem Entry getMetadata() interface to get actual
140 // last modified time of the media file.
141 file_info->last_modified = base::Time();
142 return error;
143 }
144
145 void MTPDeviceDelegateImplWin::CancelPendingTasksAndDeleteDelegate() {
146 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
147 {
148 base::AutoLock locked(cancel_tasks_lock_);
149 cancel_pending_tasks_ = true;
150 }
151 media_task_runner_->DeleteSoon(FROM_HERE, this);
152 }
153
154 bool MTPDeviceDelegateImplWin::LazyInit() {
155 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
156 {
157 // Both OpenDevice() (which we call below) and any operations our callers do
158 // may take some time. Abort them immediately if we're in the process of
159 // shutting down.
160 base::AutoLock locked(cancel_tasks_lock_);
161 if (cancel_pending_tasks_)
162 return false;
163 }
164 if (device_.get())
165 return true; // Already successfully initialized.
166 DCHECK(!pnp_device_id_.empty());
167 return MTPDeviceOperationsUtil::OpenDevice(pnp_device_id_, &device_);
168 }
169
170 string16 MTPDeviceDelegateImplWin::GetFileObjectIdFromPath(
171 const string16& file_path) {
172 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
173 DCHECK(!file_path.empty());
174 if (registered_device_path_ == file_path)
175 return storage_object_id_;
176
177 string16 actual_file_path(file_path);
178 ReplaceFirstSubstringAfterOffset(&actual_file_path, 0,
179 registered_device_path_, string16());
180 DCHECK(!actual_file_path.empty());
181 typedef std::vector<string16> PathComponents;
182 PathComponents path_components;
183 base::SplitString(actual_file_path, L'\\', &path_components);
184 DCHECK(!path_components.empty());
185 string16 parent_id(storage_object_id_);
186 string16 file_object_id;
187 for (PathComponents::const_iterator path_iter = path_components.begin() + 1;
188 path_iter != path_components.end(); ++path_iter) {
189 file_object_id = MTPDeviceOperationsUtil::GetObjectIdFromName(device_,
190 parent_id,
191 *path_iter);
192 if (file_object_id.empty())
193 break;
194 parent_id = file_object_id;
195 }
196 return file_object_id;
197 }
198
199 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698