mtp_device_map_service.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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 "webkit/browser/fileapi/external_mount_points.h" 14 15namespace { 16 17base::LazyInstance<MTPDeviceMapService> g_mtp_device_map_service = 18 LAZY_INSTANCE_INITIALIZER; 19 20} // namespace 21 22// static 23MTPDeviceMapService* MTPDeviceMapService::GetInstance() { 24 return g_mtp_device_map_service.Pointer(); 25} 26 27void MTPDeviceMapService::RegisterMTPFileSystem( 28 const base::FilePath::StringType& device_location, 29 const std::string& fsid) { 30 DCHECK(content::BrowserThread::CurrentlyOn(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 46void MTPDeviceMapService::RevokeMTPFileSystem(const std::string& fsid) { 47 DCHECK(content::BrowserThread::CurrentlyOn(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 64void MTPDeviceMapService::AddAsyncDelegate( 65 const base::FilePath::StringType& device_location, 66 MTPDeviceAsyncDelegate* delegate) { 67 DCHECK(content::BrowserThread::CurrentlyOn(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 75void MTPDeviceMapService::RemoveAsyncDelegate( 76 const base::FilePath::StringType& device_location) { 77 DCHECK(content::BrowserThread::CurrentlyOn(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 84MTPDeviceAsyncDelegate* MTPDeviceMapService::GetMTPDeviceAsyncDelegate( 85 const std::string& filesystem_id) { 86 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); 87 base::FilePath device_path; 88 if (!fileapi::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 100MTPDeviceMapService::MTPDeviceMapService() { 101} 102 103MTPDeviceMapService::~MTPDeviceMapService() { 104 DCHECK(mtp_device_usage_map_.empty()); 105} 106