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_galleries/fileapi/mtp_device_map_service.h" 6 7 #include <string> 8 #include <utility> 9 10 #include "base/stl_util.h" 11 #include "chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h" 12 #include "content/public/browser/browser_thread.h" 13 #include "storage/browser/fileapi/external_mount_points.h" 14 15 namespace { 16 17 base::LazyInstance<MTPDeviceMapService> g_mtp_device_map_service = 18 LAZY_INSTANCE_INITIALIZER; 19 20 } // namespace 21 22 // static 23 MTPDeviceMapService* MTPDeviceMapService::GetInstance() { 24 return g_mtp_device_map_service.Pointer(); 25 } 26 27 void MTPDeviceMapService::RegisterMTPFileSystem( 28 const base::FilePath::StringType& device_location, 29 const std::string& fsid) { 30 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 31 32 if (!ContainsKey(mtp_device_usage_map_, device_location)) { 33 // Note that this initializes the delegate asynchronously, but since 34 // the delegate will only be used from the IO thread, it is guaranteed 35 // to be created before use of it expects it to be there. 36 CreateMTPDeviceAsyncDelegate(device_location, 37 base::Bind(&MTPDeviceMapService::AddAsyncDelegate, 38 base::Unretained(this), device_location)); 39 mtp_device_usage_map_[device_location] = 0; 40 } 41 42 mtp_device_usage_map_[device_location]++; 43 mtp_device_map_[fsid] = device_location; 44 } 45 46 void MTPDeviceMapService::RevokeMTPFileSystem(const std::string& fsid) { 47 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 48 49 MTPDeviceFileSystemMap::iterator it = mtp_device_map_.find(fsid); 50 if (it != mtp_device_map_.end()) { 51 base::FilePath::StringType device_location = it->second; 52 mtp_device_map_.erase(it); 53 MTPDeviceUsageMap::iterator delegate_it = 54 mtp_device_usage_map_.find(device_location); 55 DCHECK(delegate_it != mtp_device_usage_map_.end()); 56 mtp_device_usage_map_[device_location]--; 57 if (mtp_device_usage_map_[device_location] == 0) { 58 mtp_device_usage_map_.erase(delegate_it); 59 RemoveAsyncDelegate(device_location); 60 } 61 } 62 } 63 64 void MTPDeviceMapService::AddAsyncDelegate( 65 const base::FilePath::StringType& device_location, 66 MTPDeviceAsyncDelegate* delegate) { 67 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 68 DCHECK(delegate); 69 DCHECK(!device_location.empty()); 70 if (ContainsKey(async_delegate_map_, device_location)) 71 return; 72 async_delegate_map_[device_location] = delegate; 73 } 74 75 void MTPDeviceMapService::RemoveAsyncDelegate( 76 const base::FilePath::StringType& device_location) { 77 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 78 AsyncDelegateMap::iterator it = async_delegate_map_.find(device_location); 79 DCHECK(it != async_delegate_map_.end()); 80 it->second->CancelPendingTasksAndDeleteDelegate(); 81 async_delegate_map_.erase(it); 82 } 83 84 MTPDeviceAsyncDelegate* MTPDeviceMapService::GetMTPDeviceAsyncDelegate( 85 const std::string& filesystem_id) { 86 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 87 base::FilePath device_path; 88 if (!storage::ExternalMountPoints::GetSystemInstance()->GetRegisteredPath( 89 filesystem_id, &device_path)) { 90 return NULL; 91 } 92 93 const base::FilePath::StringType& device_location = device_path.value(); 94 DCHECK(!device_location.empty()); 95 AsyncDelegateMap::const_iterator it = 96 async_delegate_map_.find(device_location); 97 return (it != async_delegate_map_.end()) ? it->second : NULL; 98 } 99 100 MTPDeviceMapService::MTPDeviceMapService() { 101 } 102 103 MTPDeviceMapService::~MTPDeviceMapService() { 104 DCHECK(mtp_device_usage_map_.empty()); 105 } 106