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

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: Addressed review comments Created 8 years, 1 month 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
11 #include <vector>
12
13 #include "base/file_path.h"
14 #include "base/file_util.h"
15 #include "base/sequenced_task_runner.h"
16 #include "base/string_split.h"
17 #include "base/string_util.h"
18 #include "base/threading/sequenced_worker_pool.h"
19 #include "base/utf_string_conversions.h"
20 #include "chrome/browser/media_gallery/win/mtp_device_object_entry.h"
21 #include "chrome/browser/media_gallery/win/mtp_device_object_enumerator.h"
22 #include "chrome/browser/media_gallery/win/mtp_device_operations_util.h"
23 #include "chrome/browser/media_gallery/win/recursive_mtp_device_object_enumerato r.h"
24 #include "chrome/browser/system_monitor/removable_device_notifications_window_wi n.h"
25 #include "chrome/common/chrome_notification_types.h"
26 #include "content/public/browser/browser_thread.h"
27 #include "content/public/browser/notification_service.h"
28
29 namespace chrome {
30
31 namespace {
32
33 // Returns the object id of the file object specified by the |file_path|.
34 // E.g.: If the |file_path| is "\\MTP:StorageSerial:SID-{10001,,1922}:125\DCIM"
35 // and |registered_device_path| is "\\MTP:StorageSerial:SID-{100,,1922}:125",
36 // this function returns the object id of "DCIM" folder.
37 string16 GetFileObjectIdFromPath(IPortableDevice* device,
Lei Zhang 2012/11/01 02:34:57 In this case, GetFileObjectIdFromPath() would have
kmadhusu 2012/11/01 17:59:00 Done.
38 const string16& registered_device_path,
39 const string16& file_path,
40 const string16& root_storage_object_id) {
41 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
42 DCHECK(device);
43 DCHECK(!registered_device_path.empty());
44 DCHECK(!file_path.empty());
45 DCHECK(!root_storage_object_id.empty());
46 if (registered_device_path == file_path)
47 return root_storage_object_id;
48
49 string16 actual_file_path(file_path);
50 ReplaceFirstSubstringAfterOffset(&actual_file_path, 0,
51 registered_device_path, L"");
52 DCHECK(!actual_file_path.empty());
53 typedef std::vector<string16> PathComponents;
54 PathComponents path_components;
55 base::SplitString(actual_file_path, L'\\', &path_components);
56 DCHECK(path_components.size() >= 1);
Lei Zhang 2012/11/01 02:34:57 DCHECK_GE
kmadhusu 2012/11/01 17:59:00 Done.
57 string16 parent_id(root_storage_object_id);
58 string16 file_object_id;
59 for (PathComponents::const_iterator path_iter = path_components.begin() + 1;
60 path_iter != path_components.end(); ++path_iter) {
61 file_object_id = MTPDeviceOperationsUtil::GetObjectIdFromName(device,
62 parent_id,
63 *path_iter);
64 parent_id = file_object_id;
65 }
66 return file_object_id;
67 }
68
69 // Gets the details of the MTP storage specified by the |storage_path|. On
70 // success, returns true and fills in |pnp_device_id| and |storage_object_id|.
71 // On failure, returns false and |pnp_device_id| and |storage_object_id| are
72 // not set.
73 bool GetStorageInfoFromStoragePath(const string16& storage_path,
74 string16* pnp_device_id,
75 string16* storage_object_id) {
76 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
77 DCHECK(!storage_path.empty());
78 DCHECK(pnp_device_id);
79 DCHECK(storage_object_id);
80 string16 storage_unique_id;
81 RemoveChars(storage_path, L"\\\\", &storage_unique_id);
82 DCHECK(!storage_unique_id.empty());
83 RemovableDeviceNotificationsWindowWin* notifications =
84 RemovableDeviceNotificationsWindowWin::GetInstance();
85 return notifications->GetMTPStorageInfoFromUniqueId(
86 UTF16ToUTF8(storage_unique_id), pnp_device_id, storage_object_id);
87 }
88
89 } // namespace
90
91
92 // MTPDeviceDelegateImplWin ---------------------------------------------------
93
94 MTPDeviceDelegateImplWin::MTPDeviceDelegateImplWin(const string16& fs_root_path)
95 : registered_device_path_(fs_root_path),
96 app_terminating_(false) {
97 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
98 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
99 media_task_runner_ = pool->GetSequencedTaskRunner(
100 pool->GetNamedSequenceToken("media-task-runner"));
101
102 if (!GetStorageInfoFromStoragePath(registered_device_path_,
Lei Zhang 2012/11/01 02:34:57 Unless the compiler objects, I'd prefer this as:
kmadhusu 2012/11/01 17:59:00 Done.
103 &pnp_device_id_, &storage_object_id_)) {
104 NOTREACHED();
105 }
106 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
107 content::NotificationService::AllSources());
108 }
109
110 MTPDeviceDelegateImplWin::~MTPDeviceDelegateImplWin() {
111 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
112 }
113
114 base::PlatformFileError MTPDeviceDelegateImplWin::GetFileInfo(
115 const FilePath& file_path,
116 base::PlatformFileInfo* file_info) {
117 if (app_terminating_ || !LazyInit())
118 return base::PLATFORM_FILE_ERROR_FAILED;
119 string16 object_id = GetFileObjectIdFromPath(device_.get(),
120 registered_device_path_,
121 file_path.value(),
122 storage_object_id_);
123 if (object_id.empty())
124 return base::PLATFORM_FILE_ERROR_FAILED;
125 return MTPDeviceOperationsUtil::GetFileEntryInfo(device_.get(), object_id,
126 file_info);
127 }
128
129 fileapi::FileSystemFileUtil::AbstractFileEnumerator*
130 MTPDeviceDelegateImplWin::CreateFileEnumerator(const FilePath& root,
131 bool recursive) {
132 if (app_terminating_ || root.value().empty() || !LazyInit())
133 return new fileapi::FileSystemFileUtil::EmptyFileEnumerator();
134 string16 object_id = GetFileObjectIdFromPath(device_.get(),
135 registered_device_path_,
136 root.value(),
137 storage_object_id_);
138 if (object_id.empty())
139 return new fileapi::FileSystemFileUtil::EmptyFileEnumerator();
140
141 MTPDeviceObjectEntries entries;
142 bool success = MTPDeviceOperationsUtil::GetDirectoryEntries(device_.get(),
143 object_id,
144 &entries);
145 if (!success || entries.empty())
146 return new fileapi::FileSystemFileUtil::EmptyFileEnumerator();
147
148 if (recursive)
149 return new RecursiveMTPDeviceObjectEnumerator(device_.get(), entries);
150 return new MTPDeviceObjectEnumerator(entries);
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 (app_terminating_ || !LazyInit())
158 return base::PLATFORM_FILE_ERROR_FAILED;
159 string16 file_object_id = GetFileObjectIdFromPath(device_.get(),
160 registered_device_path_,
161 device_file_path.value(),
162 storage_object_id_);
163 if (file_object_id.empty())
164 return base::PLATFORM_FILE_ERROR_FAILED;
165 std::string file_data;
166 bool success = MTPDeviceOperationsUtil::GetFileObjectData(device_.get(),
167 file_object_id,
168 &file_data);
169 if (!success || file_data.empty())
170 return base::PLATFORM_FILE_ERROR_FAILED;
171 int size = static_cast<int>(file_data.length());
172 if (file_util::WriteFile(local_path, file_data.c_str(), size) != size)
173 return base::PLATFORM_FILE_ERROR_FAILED;
174 base::PlatformFileError error = GetFileInfo(device_file_path, file_info);
175
176 // Modify the last modified time to null. This prevents the time stamp
177 // verfication in LocalFileStreamReader.
Lei Zhang 2012/11/01 02:34:57 typo
kmadhusu 2012/11/01 17:59:00 Done.
178 file_info->last_modified = base::Time();
179 return error;
180 }
181
182 base::SequencedTaskRunner* MTPDeviceDelegateImplWin::media_task_runner() {
183 return media_task_runner_.get();
184 }
185
186 void MTPDeviceDelegateImplWin::DeleteOnCorrectThread() const {
187 if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
188 delete this;
189 return;
190 }
191 content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
192 this);
193 }
194
195 void MTPDeviceDelegateImplWin::Observe(
196 int type,
197 const content::NotificationSource& source,
198 const content::NotificationDetails& details) {
199 DCHECK_EQ(chrome::NOTIFICATION_APP_TERMINATING, type);
200 app_terminating_ = true;
201 }
202
203 bool MTPDeviceDelegateImplWin::LazyInit() {
204 DCHECK(media_task_runner_);
205 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
206 if (device_.get())
207 return true; // Already successfully initialized.
208 DCHECK(!pnp_device_id_.empty());
209 return MTPDeviceOperationsUtil::OpenDevice(pnp_device_id_, &device_);
210 }
211
212 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698