1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <string> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <utility> 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/stl_util.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/media_galleries/fileapi/mtp_device_async_delegate.h" 121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/external_mount_points.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::LazyInstance<MTPDeviceMapService> g_mtp_device_map_service = 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LAZY_INSTANCE_INITIALIZER; 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MTPDeviceMapService* MTPDeviceMapService::GetInstance() { 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return g_mtp_device_map_service.Pointer(); 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MTPDeviceMapService::RegisterMTPFileSystem( 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const base::FilePath::StringType& device_location, 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) const std::string& fsid) { 30e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!ContainsKey(mtp_device_usage_map_, device_location)) { 331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Note that this initializes the delegate asynchronously, but since 341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // the delegate will only be used from the IO thread, it is guaranteed 351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // to be created before use of it expects it to be there. 361e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) CreateMTPDeviceAsyncDelegate(device_location, 371e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Bind(&MTPDeviceMapService::AddAsyncDelegate, 381e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::Unretained(this), device_location)); 391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mtp_device_usage_map_[device_location] = 0; 401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mtp_device_usage_map_[device_location]++; 431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mtp_device_map_[fsid] = device_location; 441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MTPDeviceMapService::RevokeMTPFileSystem(const std::string& fsid) { 47e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 481e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 491e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MTPDeviceFileSystemMap::iterator it = mtp_device_map_.find(fsid); 501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (it != mtp_device_map_.end()) { 511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) base::FilePath::StringType device_location = it->second; 521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mtp_device_map_.erase(it); 531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MTPDeviceUsageMap::iterator delegate_it = 541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mtp_device_usage_map_.find(device_location); 551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(delegate_it != mtp_device_usage_map_.end()); 561e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mtp_device_usage_map_[device_location]--; 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (mtp_device_usage_map_[device_location] == 0) { 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) mtp_device_usage_map_.erase(delegate_it); 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) RemoveAsyncDelegate(device_location); 601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MTPDeviceMapService::AddAsyncDelegate( 65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath::StringType& device_location, 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MTPDeviceAsyncDelegate* delegate) { 67e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(delegate); 69c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!device_location.empty()); 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (ContainsKey(async_delegate_map_, device_location)) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_delegate_map_[device_location] = delegate; 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MTPDeviceMapService::RemoveAsyncDelegate( 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath::StringType& device_location) { 77e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AsyncDelegateMap::iterator it = async_delegate_map_.find(device_location); 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(it != async_delegate_map_.end()); 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it->second->CancelPendingTasksAndDeleteDelegate(); 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_delegate_map_.erase(it); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MTPDeviceAsyncDelegate* MTPDeviceMapService::GetMTPDeviceAsyncDelegate( 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& filesystem_id) { 86e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK_CURRENTLY_ON(content::BrowserThread::IO); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath device_path; 8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) if (!storage::ExternalMountPoints::GetSystemInstance()->GetRegisteredPath( 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) filesystem_id, &device_path)) { 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath::StringType& device_location = device_path.value(); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(!device_location.empty()); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) AsyncDelegateMap::const_iterator it = 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) async_delegate_map_.find(device_location); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return (it != async_delegate_map_.end()) ? it->second : NULL; 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MTPDeviceMapService::MTPDeviceMapService() { 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 103d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)MTPDeviceMapService::~MTPDeviceMapService() { 1041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(mtp_device_usage_map_.empty()); 105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} 106