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

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: Modified LazyInit() to handle GetDeviceStorageInfo failure 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/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/mtp_get_storage_info_worker.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 void CreateMTPDeviceDelegate(const string16& device_location,
32 base::SequencedTaskRunner* media_task_runner,
33 const CreateMTPDeviceDelegateCallback& callback) {
34 DCHECK(media_task_runner && media_task_runner->RunsTasksOnCurrentThread());
35 callback.Run(new MTPDeviceDelegateImplWin(device_location,
36 media_task_runner));
37 }
38
39 // MTPDeviceDelegateImplWin ---------------------------------------------------
40
41 bool MTPDeviceDelegateImplWin::IsCancelTasksFlagSet() {
42 base::AutoLock locked(cancel_tasks_lock_);
43 return cancel_pending_tasks_;
44 }
45
46 MTPDeviceDelegateImplWin::MTPDeviceDelegateImplWin(
47 const string16& fs_root_path,
48 base::SequencedTaskRunner* media_task_runner)
49 : registered_device_path_(fs_root_path),
50 media_task_runner_(media_task_runner),
51 cancel_pending_tasks_(false),
52 task_completed_event_(false, false) {
53 DCHECK(media_task_runner_.get());
54 }
55
56 MTPDeviceDelegateImplWin::~MTPDeviceDelegateImplWin() {
57 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
58 }
59
60 base::PlatformFileError MTPDeviceDelegateImplWin::GetFileInfo(
61 const FilePath& file_path,
62 base::PlatformFileInfo* file_info) {
63 if (!LazyInit())
64 return base::PLATFORM_FILE_ERROR_FAILED;
65 string16 object_id = GetFileObjectIdFromPath(file_path.value());
66 if (object_id.empty())
67 return base::PLATFORM_FILE_ERROR_FAILED;
68 return MTPDeviceOperationsUtil::GetFileEntryInfo(device_.get(), object_id,
69 file_info);
70 }
71
72 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator>
73 MTPDeviceDelegateImplWin::CreateFileEnumerator(const FilePath& root,
74 bool recursive) {
75 scoped_ptr<fileapi::FileSystemFileUtil::AbstractFileEnumerator>
76 file_enumerator(new fileapi::FileSystemFileUtil::EmptyFileEnumerator());
77 if (root.value().empty() || !LazyInit())
78 return file_enumerator.Pass();
79
80 string16 object_id = GetFileObjectIdFromPath(root.value());
81 if (object_id.empty())
82 return file_enumerator.Pass();
83
84 MTPDeviceObjectEntries entries;
85 if (!MTPDeviceOperationsUtil::GetDirectoryEntries(device_.get(), object_id,
86 &entries) ||
87 entries.empty())
88 return file_enumerator.Pass();
89
90 if (recursive) {
91 file_enumerator.reset(
92 new RecursiveMTPDeviceObjectEnumerator(device_.get(), entries));
93 } else {
94 file_enumerator.reset(new MTPDeviceObjectEnumerator(entries));
95 }
96 return file_enumerator.Pass();
97 }
98
99 base::PlatformFileError MTPDeviceDelegateImplWin::CreateSnapshotFile(
100 const FilePath& device_file_path,
101 const FilePath& local_path,
102 base::PlatformFileInfo* file_info) {
103 if (!LazyInit())
104 return base::PLATFORM_FILE_ERROR_FAILED;
105 string16 file_object_id = GetFileObjectIdFromPath(device_file_path.value());
106 if (file_object_id.empty())
107 return base::PLATFORM_FILE_ERROR_FAILED;
108 if (!MTPDeviceOperationsUtil::WriteFileObjectData(device_.get(),
109 file_object_id,
110 local_path))
111 return base::PLATFORM_FILE_ERROR_FAILED;
112 base::PlatformFileError error = GetFileInfo(device_file_path, file_info);
113
114 // LocalFileStreamReader is used to read the contents of the snapshot file.
115 // Snapshot file modification time does not match the last modified time
116 // of the original media file. Therefore, set the last modified time to null
117 // in order to avoid the verification in LocalFileStreamReader.
118 //
119 // Users will use HTML5 FileSystem Entry getMetadata() interface to get actual
120 // last modified time of the media file.
121 file_info->last_modified = base::Time();
122 return error;
123 }
124
125 void MTPDeviceDelegateImplWin::CancelPendingTasksAndDeleteDelegate() {
126 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
127 {
128 base::AutoLock locked(cancel_tasks_lock_);
129 cancel_pending_tasks_ = true;
130 }
131 task_completed_event_.Signal();
132 media_task_runner_->DeleteSoon(FROM_HERE, this);
133 }
134
135 bool MTPDeviceDelegateImplWin::LazyInit() {
136 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
137 // Both OpenDevice() (which we call below) and any operations our callers do
138 // may take some time. Abort them immediately if we're in the process of
139 // shutting down.
140 if (IsCancelTasksFlagSet())
141 return false;
142
143 if (device_.get())
144 return true; // Already successfully initialized.
145
146 scoped_refptr<MTPGetStorageInfoWorker> worker(
147 new MTPGetStorageInfoWorker(registered_device_path_,
148 media_task_runner_,
149 this,
150 &task_completed_event_));
151 worker->Run();
152 if (!worker->GetDeviceStorageInfo(&pnp_device_id_, &storage_object_id_))
153 return false;
154 DCHECK(!pnp_device_id_.empty());
155 return MTPDeviceOperationsUtil::OpenDevice(pnp_device_id_, &device_);
156 }
157
158 string16 MTPDeviceDelegateImplWin::GetFileObjectIdFromPath(
159 const string16& file_path) {
160 DCHECK(media_task_runner_->RunsTasksOnCurrentThread());
161 DCHECK(!file_path.empty());
162 if (registered_device_path_ == file_path)
163 return storage_object_id_;
164
165 string16 actual_file_path(file_path);
166 ReplaceFirstSubstringAfterOffset(&actual_file_path, 0,
167 registered_device_path_, string16());
168 DCHECK(!actual_file_path.empty());
169 typedef std::vector<string16> PathComponents;
170 PathComponents path_components;
171 base::SplitString(actual_file_path, L'\\', &path_components);
172 DCHECK(!path_components.empty());
173 string16 parent_id(storage_object_id_);
174 string16 file_object_id;
175 for (PathComponents::const_iterator path_iter = path_components.begin() + 1;
176 path_iter != path_components.end(); ++path_iter) {
177 file_object_id = MTPDeviceOperationsUtil::GetObjectIdFromName(device_,
178 parent_id,
179 *path_iter);
180 if (file_object_id.empty())
181 break;
182 parent_id = file_object_id;
183 }
184 return file_object_id;
185 }
186
187 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698