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

Side by Side Diff: chrome/browser/media_transfer_protocol/media_transfer_protocol_manager.cc

Issue 11744030: Try 2 [Media Gallery] Move chrome/browser/media_transfer_protocol code to src/device. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fixed gyp dependencies. 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 #include "chrome/browser/media_transfer_protocol/media_transfer_protocol_manager .h"
6
7 #include <map>
8 #include <queue>
9 #include <set>
10 #include <utility>
11
12 #include "base/bind.h"
13 #include "base/command_line.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/observer_list.h"
16 #include "base/stl_util.h"
17 #include "chrome/browser/media_transfer_protocol/media_transfer_protocol_daemon_ client.h"
18 #include "chrome/browser/media_transfer_protocol/mtp_file_entry.pb.h"
19 #include "chrome/browser/media_transfer_protocol/mtp_storage_info.pb.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "content/public/browser/browser_thread.h"
22
23 #if defined(OS_CHROMEOS)
24 #include "chromeos/dbus/dbus_thread_manager.h"
25 #else
26 #include "dbus/bus.h"
27 #endif
28
29 using content::BrowserThread;
30
31 namespace chrome {
32
33 namespace {
34
35 MediaTransferProtocolManager* g_media_transfer_protocol_manager = NULL;
36
37 // The MediaTransferProtocolManager implementation.
38 class MediaTransferProtocolManagerImpl : public MediaTransferProtocolManager {
39 public:
40 MediaTransferProtocolManagerImpl() : weak_ptr_factory_(this) {
41 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kTestType))
42 return;
43
44 dbus::Bus* bus = NULL;
45 #if defined(OS_CHROMEOS)
46 chromeos::DBusThreadManager* dbus_thread_manager =
47 chromeos::DBusThreadManager::Get();
48 bus = dbus_thread_manager->GetSystemBus();
49 if (!bus)
50 return;
51 #else
52 dbus::Bus::Options options;
53 options.bus_type = dbus::Bus::SYSTEM;
54 options.connection_type = dbus::Bus::PRIVATE;
55 options.dbus_thread_message_loop_proxy =
56 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE);
57 session_bus_ = new dbus::Bus(options);
58 bus = session_bus_.get();
59 #endif
60
61 DCHECK(bus);
62 mtp_client_.reset(
63 MediaTransferProtocolDaemonClient::Create(bus, false /* not stub */));
64
65 // Set up signals and start initializing |storage_info_map_|.
66 mtp_client_->SetUpConnections(
67 base::Bind(&MediaTransferProtocolManagerImpl::OnStorageChanged,
68 weak_ptr_factory_.GetWeakPtr()));
69 mtp_client_->EnumerateStorages(
70 base::Bind(&MediaTransferProtocolManagerImpl::OnEnumerateStorages,
71 weak_ptr_factory_.GetWeakPtr()),
72 base::Bind(&base::DoNothing));
73 }
74
75 virtual ~MediaTransferProtocolManagerImpl() {
76 }
77
78 // MediaTransferProtocolManager override.
79 virtual void AddObserver(Observer* observer) OVERRIDE {
80 observers_.AddObserver(observer);
81 }
82
83 // MediaTransferProtocolManager override.
84 virtual void RemoveObserver(Observer* observer) OVERRIDE {
85 observers_.RemoveObserver(observer);
86 }
87
88 // MediaTransferProtocolManager override.
89 const std::vector<std::string> GetStorages() const OVERRIDE {
90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
91 std::vector<std::string> storages;
92 for (StorageInfoMap::const_iterator it = storage_info_map_.begin();
93 it != storage_info_map_.end();
94 ++it) {
95 storages.push_back(it->first);
96 }
97 return storages;
98 }
99
100 // MediaTransferProtocolManager override.
101 virtual const MtpStorageInfo* GetStorageInfo(
102 const std::string& storage_name) const OVERRIDE {
103 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
104 StorageInfoMap::const_iterator it = storage_info_map_.find(storage_name);
105 if (it == storage_info_map_.end())
106 return NULL;
107 return &it->second;
108 }
109
110 // MediaTransferProtocolManager override.
111 virtual void OpenStorage(const std::string& storage_name,
112 const std::string& mode,
113 const OpenStorageCallback& callback) OVERRIDE {
114 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
115 if (!ContainsKey(storage_info_map_, storage_name)) {
116 callback.Run("", true);
117 return;
118 }
119 open_storage_callbacks_.push(callback);
120 mtp_client_->OpenStorage(
121 storage_name,
122 mode,
123 base::Bind(&MediaTransferProtocolManagerImpl::OnOpenStorage,
124 weak_ptr_factory_.GetWeakPtr()),
125 base::Bind(&MediaTransferProtocolManagerImpl::OnOpenStorageError,
126 weak_ptr_factory_.GetWeakPtr()));
127 }
128
129 // MediaTransferProtocolManager override.
130 virtual void CloseStorage(const std::string& storage_handle,
131 const CloseStorageCallback& callback) OVERRIDE {
132 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
133 if (!ContainsKey(handles_, storage_handle)) {
134 callback.Run(true);
135 return;
136 }
137 close_storage_callbacks_.push(std::make_pair(callback, storage_handle));
138 mtp_client_->CloseStorage(
139 storage_handle,
140 base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorage,
141 weak_ptr_factory_.GetWeakPtr()),
142 base::Bind(&MediaTransferProtocolManagerImpl::OnCloseStorageError,
143 weak_ptr_factory_.GetWeakPtr()));
144 }
145
146 // MediaTransferProtocolManager override.
147 virtual void ReadDirectoryByPath(
148 const std::string& storage_handle,
149 const std::string& path,
150 const ReadDirectoryCallback& callback) OVERRIDE {
151 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
152 if (!ContainsKey(handles_, storage_handle)) {
153 callback.Run(std::vector<MtpFileEntry>(), true);
154 return;
155 }
156 read_directory_callbacks_.push(callback);
157 mtp_client_->ReadDirectoryByPath(
158 storage_handle,
159 path,
160 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectory,
161 weak_ptr_factory_.GetWeakPtr()),
162 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError,
163 weak_ptr_factory_.GetWeakPtr()));
164 }
165
166 // MediaTransferProtocolManager override.
167 virtual void ReadDirectoryById(
168 const std::string& storage_handle,
169 uint32 file_id,
170 const ReadDirectoryCallback& callback) OVERRIDE {
171 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
172 if (!ContainsKey(handles_, storage_handle)) {
173 callback.Run(std::vector<MtpFileEntry>(), true);
174 return;
175 }
176 read_directory_callbacks_.push(callback);
177 mtp_client_->ReadDirectoryById(
178 storage_handle,
179 file_id,
180 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectory,
181 weak_ptr_factory_.GetWeakPtr()),
182 base::Bind(&MediaTransferProtocolManagerImpl::OnReadDirectoryError,
183 weak_ptr_factory_.GetWeakPtr()));
184 }
185
186 // MediaTransferProtocolManager override.
187 virtual void ReadFileChunkByPath(const std::string& storage_handle,
188 const std::string& path,
189 uint32 offset,
190 uint32 count,
191 const ReadFileCallback& callback) OVERRIDE {
192 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
193 if (!ContainsKey(handles_, storage_handle)) {
194 callback.Run(std::string(), true);
195 return;
196 }
197 read_file_callbacks_.push(callback);
198 mtp_client_->ReadFileChunkByPath(
199 storage_handle, path, offset, count,
200 base::Bind(&MediaTransferProtocolManagerImpl::OnReadFile,
201 weak_ptr_factory_.GetWeakPtr()),
202 base::Bind(&MediaTransferProtocolManagerImpl::OnReadFileError,
203 weak_ptr_factory_.GetWeakPtr()));
204 }
205
206 // MediaTransferProtocolManager override.
207 virtual void ReadFileChunkById(const std::string& storage_handle,
208 uint32 file_id,
209 uint32 offset,
210 uint32 count,
211 const ReadFileCallback& callback) OVERRIDE {
212 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
213 if (!ContainsKey(handles_, storage_handle)) {
214 callback.Run(std::string(), true);
215 return;
216 }
217 read_file_callbacks_.push(callback);
218 mtp_client_->ReadFileChunkById(
219 storage_handle, file_id, offset, count,
220 base::Bind(&MediaTransferProtocolManagerImpl::OnReadFile,
221 weak_ptr_factory_.GetWeakPtr()),
222 base::Bind(&MediaTransferProtocolManagerImpl::OnReadFileError,
223 weak_ptr_factory_.GetWeakPtr()));
224 }
225
226 virtual void GetFileInfoByPath(const std::string& storage_handle,
227 const std::string& path,
228 const GetFileInfoCallback& callback) OVERRIDE {
229 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
230 if (!ContainsKey(handles_, storage_handle)) {
231 callback.Run(MtpFileEntry(), true);
232 return;
233 }
234 get_file_info_callbacks_.push(callback);
235 mtp_client_->GetFileInfoByPath(
236 storage_handle,
237 path,
238 base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfo,
239 weak_ptr_factory_.GetWeakPtr()),
240 base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfoError,
241 weak_ptr_factory_.GetWeakPtr()));
242 }
243
244 virtual void GetFileInfoById(const std::string& storage_handle,
245 uint32 file_id,
246 const GetFileInfoCallback& callback) OVERRIDE {
247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
248 if (!ContainsKey(handles_, storage_handle)) {
249 callback.Run(MtpFileEntry(), true);
250 return;
251 }
252 get_file_info_callbacks_.push(callback);
253 mtp_client_->GetFileInfoById(
254 storage_handle,
255 file_id,
256 base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfo,
257 weak_ptr_factory_.GetWeakPtr()),
258 base::Bind(&MediaTransferProtocolManagerImpl::OnGetFileInfoError,
259 weak_ptr_factory_.GetWeakPtr()));
260 }
261
262 private:
263 // Map of storage names to storage info.
264 typedef std::map<std::string, MtpStorageInfo> StorageInfoMap;
265 // Callback queues - DBus communication is in-order, thus callbacks are
266 // received in the same order as the requests.
267 typedef std::queue<OpenStorageCallback> OpenStorageCallbackQueue;
268 // (callback, handle)
269 typedef std::queue<std::pair<CloseStorageCallback, std::string>
270 > CloseStorageCallbackQueue;
271 typedef std::queue<ReadDirectoryCallback> ReadDirectoryCallbackQueue;
272 typedef std::queue<ReadFileCallback> ReadFileCallbackQueue;
273 typedef std::queue<GetFileInfoCallback> GetFileInfoCallbackQueue;
274
275 void OnStorageChanged(bool is_attach, const std::string& storage_name) {
276 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
277 if (is_attach) {
278 mtp_client_->GetStorageInfo(
279 storage_name,
280 base::Bind(&MediaTransferProtocolManagerImpl::OnGetStorageInfo,
281 weak_ptr_factory_.GetWeakPtr()),
282 base::Bind(&base::DoNothing));
283 return;
284 }
285
286 // Detach case.
287 StorageInfoMap::iterator it = storage_info_map_.find(storage_name);
288 if (it == storage_info_map_.end()) {
289 // This might happen during initialization when |storage_info_map_| has
290 // not been fully populated yet?
291 return;
292 }
293 storage_info_map_.erase(it);
294 FOR_EACH_OBSERVER(Observer,
295 observers_,
296 StorageChanged(false /* detach */, storage_name));
297 }
298
299 void OnEnumerateStorages(const std::vector<std::string>& storage_names) {
300 for (size_t i = 0; i < storage_names.size(); ++i) {
301 mtp_client_->GetStorageInfo(
302 storage_names[i],
303 base::Bind(&MediaTransferProtocolManagerImpl::OnGetStorageInfo,
304 weak_ptr_factory_.GetWeakPtr()),
305 base::Bind(&base::DoNothing));
306 }
307 }
308
309 void OnGetStorageInfo(const MtpStorageInfo& storage_info) {
310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
311 const std::string& storage_name = storage_info.storage_name();
312 if (ContainsKey(storage_info_map_, storage_name)) {
313 // This should not happen, since MediaTransferProtocolManagerImpl should
314 // only call EnumerateStorages() once, which populates |storage_info_map_|
315 // with the already-attached devices.
316 // After that, all incoming signals are either for new storage
317 // attachments, which should not be in |storage_info_map_|, or for
318 // storage detachements, which do not add to |storage_info_map_|.
319 NOTREACHED();
320 return;
321 }
322
323 // New storage. Add it and let the observers know.
324 storage_info_map_.insert(std::make_pair(storage_name, storage_info));
325 FOR_EACH_OBSERVER(Observer,
326 observers_,
327 StorageChanged(true /* is attach */, storage_name));
328 }
329
330 void OnOpenStorage(const std::string& handle) {
331 if (!ContainsKey(handles_, handle)) {
332 handles_.insert(handle);
333 open_storage_callbacks_.front().Run(handle, false);
334 } else {
335 NOTREACHED();
336 open_storage_callbacks_.front().Run("", true);
337 }
338 open_storage_callbacks_.pop();
339 }
340
341 void OnOpenStorageError() {
342 open_storage_callbacks_.front().Run("", true);
343 open_storage_callbacks_.pop();
344 }
345
346 void OnCloseStorage() {
347 const std::string& handle = close_storage_callbacks_.front().second;
348 if (ContainsKey(handles_, handle)) {
349 handles_.erase(handle);
350 close_storage_callbacks_.front().first.Run(false);
351 } else {
352 NOTREACHED();
353 close_storage_callbacks_.front().first.Run(true);
354 }
355 close_storage_callbacks_.pop();
356 }
357
358 void OnCloseStorageError() {
359 close_storage_callbacks_.front().first.Run(true);
360 close_storage_callbacks_.pop();
361 }
362
363 void OnReadDirectory(const std::vector<MtpFileEntry>& file_entries) {
364 read_directory_callbacks_.front().Run(file_entries, false);
365 read_directory_callbacks_.pop();
366 }
367
368 void OnReadDirectoryError() {
369 read_directory_callbacks_.front().Run(std::vector<MtpFileEntry>(), true);
370 read_directory_callbacks_.pop();
371 }
372
373 void OnReadFile(const std::string& data) {
374 read_file_callbacks_.front().Run(data, false);
375 read_file_callbacks_.pop();
376 }
377
378 void OnReadFileError() {
379 read_file_callbacks_.front().Run(std::string(), true);
380 read_file_callbacks_.pop();
381 }
382
383 void OnGetFileInfo(const MtpFileEntry& entry) {
384 get_file_info_callbacks_.front().Run(entry, false);
385 get_file_info_callbacks_.pop();
386 }
387
388 void OnGetFileInfoError() {
389 get_file_info_callbacks_.front().Run(MtpFileEntry(), true);
390 get_file_info_callbacks_.pop();
391 }
392
393 // Mtpd DBus client.
394 scoped_ptr<chrome::MediaTransferProtocolDaemonClient> mtp_client_;
395
396 #if !defined(OS_CHROMEOS)
397 // And a D-Bus session for talking to mtpd.
398 scoped_refptr<dbus::Bus> session_bus_;
399 #endif
400
401 // Device attachment / detachment observers.
402 ObserverList<Observer> observers_;
403
404 base::WeakPtrFactory<MediaTransferProtocolManagerImpl> weak_ptr_factory_;
405
406 // Everything below is only accessed on the UI thread.
407
408 // Map to keep track of attached storages by name.
409 StorageInfoMap storage_info_map_;
410
411 // Set of open storage handles.
412 std::set<std::string> handles_;
413
414 // Queued callbacks.
415 OpenStorageCallbackQueue open_storage_callbacks_;
416 CloseStorageCallbackQueue close_storage_callbacks_;
417 ReadDirectoryCallbackQueue read_directory_callbacks_;
418 ReadFileCallbackQueue read_file_callbacks_;
419 GetFileInfoCallbackQueue get_file_info_callbacks_;
420
421 DISALLOW_COPY_AND_ASSIGN(MediaTransferProtocolManagerImpl);
422 };
423
424 } // namespace
425
426 // static
427 void MediaTransferProtocolManager::Initialize() {
428 if (g_media_transfer_protocol_manager) {
429 LOG(WARNING) << "MediaTransferProtocolManager was already initialized";
430 return;
431 }
432 g_media_transfer_protocol_manager = new MediaTransferProtocolManagerImpl();
433 VLOG(1) << "MediaTransferProtocolManager initialized";
434 }
435
436 // static
437 void MediaTransferProtocolManager::Shutdown() {
438 if (!g_media_transfer_protocol_manager) {
439 LOG(WARNING) << "MediaTransferProtocolManager::Shutdown() called with "
440 << "NULL manager";
441 return;
442 }
443 delete g_media_transfer_protocol_manager;
444 g_media_transfer_protocol_manager = NULL;
445 VLOG(1) << "MediaTransferProtocolManager Shutdown completed";
446 }
447
448 // static
449 MediaTransferProtocolManager* MediaTransferProtocolManager::GetInstance() {
450 return g_media_transfer_protocol_manager;
451 }
452
453 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698