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

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: Rebase 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/threading/sequenced_worker_pool.h"
18 #include "base/utf_string_conversions.h"
19 #include "chrome/browser/media_gallery/win/mtp_device_object_entry.h"
20 #include "chrome/browser/media_gallery/win/mtp_device_object_enumerator.h"
21 #include "chrome/browser/media_gallery/win/mtp_device_operations_util.h"
22 #include "chrome/browser/media_gallery/win/recursive_mtp_device_object_enumerato r.h"
23 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi n.h"
24 #include "chrome/browser/system_monitor/removable_storage_notifications.h"
25 #include "content/public/browser/browser_thread.h"
26
27 namespace chrome {
28
29 namespace {
30
31 // Gets the details of the MTP partition storage specified by the
32 // |storage_path|. On success, returns true and fills in |pnp_device_id| and
33 // |storage_object_id|. On failure, returns false and |pnp_device_id| and
34 // |storage_object_id| are not set.
35 bool GetStorageInfoFromStoragePath(const string16& storage_path,
36 string16* pnp_device_id,
37 string16* storage_object_id) {
38 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
Peter Kasting 2012/12/20 21:24:20 Based on discussion with rsleevi, I suggest two DC
kmadhusu 2012/12/21 01:45:23 Done. Removed the DCHECK.
39 DCHECK(!storage_path.empty());
40 DCHECK(pnp_device_id);
41 DCHECK(storage_object_id);
42 string16 storage_device_id;
43 RemoveChars(storage_path, L"\\\\", &storage_device_id);
44 DCHECK(!storage_device_id.empty());
45 RemovableStorageNotifications* notifications =
46 RemovableStorageNotifications::GetInstance();
47 DCHECK(notifications);
48 return notifications->GetMTPStorageInfoFromDeviceId(
49 UTF16ToUTF8(storage_device_id), pnp_device_id, storage_object_id);
50 }
51
52 } // namespace
53
54 void CreateMTPDeviceDelegate(const string16& device_location,
55 base::SequencedTaskRunner* media_task_runner,
56 const CreateMTPDeviceDelegateCallback& callback) {
57 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
Peter Kasting 2012/12/20 21:24:20 The second change is here. Rather than check that
kmadhusu 2012/12/21 01:45:23 Done.
58 callback.Run(new MTPDeviceDelegateImplWin(device_location,
59 media_task_runner));
60 }
61
62 // MTPDeviceDelegateImplWin ---------------------------------------------------
63
64 MTPDeviceDelegateImplWin::MTPDeviceDelegateImplWin(
65 const string16& fs_root_path,
66 base::SequencedTaskRunner* media_task_runner)
67 : registered_device_path_(fs_root_path),
68 media_task_runner_(media_task_runner),
69 cancel_pending_tasks_(false) {
70 DCHECK(media_task_runner_.get());
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 base::SequencedTaskRunner* MTPDeviceDelegateImplWin::GetMediaTaskRunner() {
146 return media_task_runner_.get();
147 }
148
149 void MTPDeviceDelegateImplWin::CancelPendingTasksAndDeleteDelegate() {
150 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
151 // Caution: This function is called on the UI thread. Access only the thread
152 // safe member variables in this function.
Peter Kasting 2012/12/19 20:17:58 Nit: Given your DCHECK above, this is probably not
kmadhusu 2012/12/20 20:37:29 Removed.
153 {
154 base::AutoLock locked(cancel_tasks_lock_);
155 cancel_pending_tasks_ = true;
156 }
157 media_task_runner_->DeleteSoon(FROM_HERE, this);
158 }
159
160 bool MTPDeviceDelegateImplWin::LazyInit() {
161 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
162 {
163 // Device delegate will be destructed soon.
Peter Kasting 2012/12/19 20:17:58 Nit: Perhaps this should instead be: Both OpenDev
kmadhusu 2012/12/20 20:37:29 Done.
164 base::AutoLock locked(cancel_tasks_lock_);
165 if (cancel_pending_tasks_)
166 return false;
167 }
168 if (device_.get())
169 return true; // Already successfully initialized.
170 DCHECK(!pnp_device_id_.empty());
171 return MTPDeviceOperationsUtil::OpenDevice(pnp_device_id_, &device_);
172 }
173
174 string16 MTPDeviceDelegateImplWin::GetFileObjectIdFromPath(
175 const string16& file_path) {
176 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
177 DCHECK(!file_path.empty());
178 if (registered_device_path_ == file_path)
179 return storage_object_id_;
180
181 string16 actual_file_path(file_path);
182 ReplaceFirstSubstringAfterOffset(&actual_file_path, 0,
183 registered_device_path_, string16());
184 DCHECK(!actual_file_path.empty());
185 typedef std::vector<string16> PathComponents;
186 PathComponents path_components;
187 base::SplitString(actual_file_path, L'\\', &path_components);
188 DCHECK(!path_components.empty());
189 string16 parent_id(storage_object_id_);
190 string16 file_object_id;
191 for (PathComponents::const_iterator path_iter = path_components.begin() + 1;
192 path_iter != path_components.end(); ++path_iter) {
193 file_object_id = MTPDeviceOperationsUtil::GetObjectIdFromName(device_,
194 parent_id,
195 *path_iter);
196 if (file_object_id.empty())
197 break;
198 parent_id = file_object_id;
199 }
200 return file_object_id;
201 }
202
203 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698