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

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 // Gets the details of the MTP storage specified by the |storage_path|. On
34 // success, returns true and fills in |pnp_device_id| and |storage_object_id|.
35 // On failure, returns false and |pnp_device_id| and |storage_object_id| are
36 // not set.
37 bool GetStorageInfoFromStoragePath(const string16& storage_path,
38 string16* pnp_device_id,
39 string16* storage_object_id) {
40 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
41 DCHECK(!storage_path.empty());
42 DCHECK(pnp_device_id);
43 DCHECK(storage_object_id);
44 string16 storage_device_id;
45 RemoveChars(storage_path, L"\\\\", &storage_device_id);
46 DCHECK(!storage_device_id.empty());
47 RemovableDeviceNotificationsWindowWin* notifications =
48 RemovableDeviceNotificationsWindowWin::GetInstance();
49 return notifications->GetMTPStorageInfoFromDeviceId(
50 UTF16ToUTF8(storage_device_id), pnp_device_id, storage_object_id);
51 }
52
53 } // namespace
54
55
56 // MTPDeviceDelegateImplWin ---------------------------------------------------
57
58 MTPDeviceDelegateImplWin::MTPDeviceDelegateImplWin(const string16& fs_root_path)
59 : registered_device_path_(fs_root_path) {
60 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
61 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool();
62 media_task_runner_ = pool->GetSequencedTaskRunner(
63 pool->GetNamedSequenceToken("media-task-runner"));
64
65 bool success = GetStorageInfoFromStoragePath(
66 registered_device_path_, &pnp_device_id_, &storage_object_id_);
67 DCHECK(success);
68 registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
69 content::NotificationService::AllSources());
70 }
71
72 MTPDeviceDelegateImplWin::~MTPDeviceDelegateImplWin() {
73 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
74 }
75
76 base::PlatformFileError MTPDeviceDelegateImplWin::GetFileInfo(
77 const FilePath& file_path,
78 base::PlatformFileInfo* file_info) {
79 if (app_terminating_flag_.IsSet() || !LazyInit())
80 return base::PLATFORM_FILE_ERROR_FAILED;
81 string16 object_id = GetFileObjectIdFromPath(file_path.value());
82 if (object_id.empty())
83 return base::PLATFORM_FILE_ERROR_FAILED;
84 return MTPDeviceOperationsUtil::GetFileEntryInfo(device_.get(), object_id,
85 file_info);
86 }
87
88 fileapi::FileSystemFileUtil::AbstractFileEnumerator*
89 MTPDeviceDelegateImplWin::CreateFileEnumerator(const FilePath& root,
90 bool recursive) {
91 if (app_terminating_flag_.IsSet() || root.value().empty() || !LazyInit())
92 return new fileapi::FileSystemFileUtil::EmptyFileEnumerator();
93 string16 object_id = GetFileObjectIdFromPath(root.value());
94 if (object_id.empty())
95 return new fileapi::FileSystemFileUtil::EmptyFileEnumerator();
96
97 MTPDeviceObjectEntries entries;
98 bool success = MTPDeviceOperationsUtil::GetDirectoryEntries(device_.get(),
99 object_id,
100 &entries);
101 if (!success || entries.empty())
102 return new fileapi::FileSystemFileUtil::EmptyFileEnumerator();
103
104 if (recursive)
105 return new RecursiveMTPDeviceObjectEnumerator(device_.get(), entries);
106 return new MTPDeviceObjectEnumerator(entries);
107 }
108
109 base::PlatformFileError MTPDeviceDelegateImplWin::CreateSnapshotFile(
110 const FilePath& device_file_path,
111 const FilePath& local_path,
112 base::PlatformFileInfo* file_info) {
113 if (app_terminating_flag_.IsSet() || !LazyInit())
114 return base::PLATFORM_FILE_ERROR_FAILED;
115 string16 file_object_id = GetFileObjectIdFromPath(device_file_path.value());
116 if (file_object_id.empty())
117 return base::PLATFORM_FILE_ERROR_FAILED;
118 std::string file_data;
119 bool success = MTPDeviceOperationsUtil::GetFileObjectData(device_.get(),
120 file_object_id,
121 &file_data);
122 if (!success || file_data.empty())
123 return base::PLATFORM_FILE_ERROR_FAILED;
124 int size = static_cast<int>(file_data.length());
125 if (file_util::WriteFile(local_path, file_data.c_str(), size) != size)
126 return base::PLATFORM_FILE_ERROR_FAILED;
127 base::PlatformFileError error = GetFileInfo(device_file_path, file_info);
128
129 // Modify the last modified time to null. This prevents the time stamp
130 // verification in LocalFileStreamReader.
131 file_info->last_modified = base::Time();
132 return error;
133 }
134
135 base::SequencedTaskRunner* MTPDeviceDelegateImplWin::media_task_runner() {
136 return media_task_runner_.get();
137 }
138
139 void MTPDeviceDelegateImplWin::DeleteOnCorrectThread() const {
140 if (content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
141 delete this;
142 return;
143 }
144 content::BrowserThread::DeleteSoon(content::BrowserThread::UI, FROM_HERE,
145 this);
146 }
147
148 void MTPDeviceDelegateImplWin::Observe(
149 int type,
150 const content::NotificationSource& source,
151 const content::NotificationDetails& details) {
152 DCHECK_EQ(chrome::NOTIFICATION_APP_TERMINATING, type);
153 app_terminating_flag_.Set();
154 }
155
156 bool MTPDeviceDelegateImplWin::LazyInit() {
157 DCHECK(media_task_runner_);
158 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
159 if (device_.get())
160 return true; // Already successfully initialized.
161 DCHECK(!pnp_device_id_.empty());
162 return MTPDeviceOperationsUtil::OpenDevice(pnp_device_id_, &device_);
163 }
164
165 string16 MTPDeviceDelegateImplWin::GetFileObjectIdFromPath(
166 const string16& file_path) {
167 DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
168 DCHECK(!file_path.empty());
169 if (registered_device_path_ == file_path)
170 return storage_object_id_;
171
172 string16 actual_file_path(file_path);
173 ReplaceFirstSubstringAfterOffset(&actual_file_path, 0,
174 registered_device_path_, L"");
Peter Kasting 2012/11/01 21:38:37 Nit: L"" -> std::string()
kmadhusu 2012/11/02 03:27:16 Changed L"" -> string16(). Did you mean string16()
175 DCHECK(!actual_file_path.empty());
176 typedef std::vector<string16> PathComponents;
177 PathComponents path_components;
178 base::SplitString(actual_file_path, L'\\', &path_components);
179 DCHECK_GE(path_components.size(), static_cast<size_t>(1));
Peter Kasting 2012/11/01 21:38:37 Nit: How about just DCHECK(!path_components.empty(
kmadhusu 2012/11/02 03:27:16 I would like to keep this as it is. For e.g., if
Peter Kasting 2012/11/02 04:08:11 Your existing check is "path_components.size() >=
kmadhusu 2012/11/29 23:58:14 Thanks for the explanation. You are right. DCHECK(
180 string16 parent_id(storage_object_id_);
181 string16 file_object_id;
182 for (PathComponents::const_iterator path_iter = path_components.begin() + 1;
183 path_iter != path_components.end(); ++path_iter) {
184 file_object_id = MTPDeviceOperationsUtil::GetObjectIdFromName(device_,
185 parent_id,
186 *path_iter);
187 parent_id = file_object_id;
188 }
189 return file_object_id;
190 }
191
192 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698