Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / media_galleries / fileapi / mtp_device_map_service.cc
blob6941878f69c33e8a1711cfa7292fb9c98103a952
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.
5 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h"
7 #include <string>
8 #include <utility>
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"
15 namespace {
17 base::LazyInstance<MTPDeviceMapService> g_mtp_device_map_service =
18 LAZY_INSTANCE_INITIALIZER;
20 } // namespace
22 // static
23 MTPDeviceMapService* MTPDeviceMapService::GetInstance() {
24 return g_mtp_device_map_service.Pointer();
27 void MTPDeviceMapService::RegisterMTPFileSystem(
28 const base::FilePath::StringType& device_location,
29 const std::string& filesystem_id,
30 const bool read_only) {
31 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
32 DCHECK(!device_location.empty());
33 DCHECK(!filesystem_id.empty());
35 const AsyncDelegateKey key = GetAsyncDelegateKey(device_location, read_only);
36 if (!ContainsKey(mtp_device_usage_map_, key)) {
37 // Note that this initializes the delegate asynchronously, but since
38 // the delegate will only be used from the IO thread, it is guaranteed
39 // to be created before use of it expects it to be there.
40 CreateMTPDeviceAsyncDelegate(
41 device_location, read_only,
42 base::Bind(&MTPDeviceMapService::AddAsyncDelegate,
43 base::Unretained(this), device_location, read_only));
44 mtp_device_usage_map_[key] = 0;
47 mtp_device_usage_map_[key]++;
48 mtp_device_map_[filesystem_id] = make_pair(device_location, read_only);
51 void MTPDeviceMapService::RevokeMTPFileSystem(
52 const std::string& filesystem_id) {
53 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
54 DCHECK(!filesystem_id.empty());
56 MTPDeviceFileSystemMap::iterator it = mtp_device_map_.find(filesystem_id);
57 if (it != mtp_device_map_.end()) {
58 const base::FilePath::StringType device_location = it->second.first;
59 const bool read_only = it->second.second;
61 mtp_device_map_.erase(it);
63 const AsyncDelegateKey key =
64 GetAsyncDelegateKey(device_location, read_only);
65 MTPDeviceUsageMap::iterator delegate_it = mtp_device_usage_map_.find(key);
66 DCHECK(delegate_it != mtp_device_usage_map_.end());
68 mtp_device_usage_map_[key]--;
69 if (mtp_device_usage_map_[key] == 0) {
70 mtp_device_usage_map_.erase(delegate_it);
71 RemoveAsyncDelegate(device_location, read_only);
76 void MTPDeviceMapService::AddAsyncDelegate(
77 const base::FilePath::StringType& device_location,
78 const bool read_only,
79 MTPDeviceAsyncDelegate* delegate) {
80 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
81 DCHECK(delegate);
82 DCHECK(!device_location.empty());
84 const AsyncDelegateKey key = GetAsyncDelegateKey(device_location, read_only);
85 if (ContainsKey(async_delegate_map_, key))
86 return;
87 async_delegate_map_[key] = delegate;
90 void MTPDeviceMapService::RemoveAsyncDelegate(
91 const base::FilePath::StringType& device_location,
92 const bool read_only) {
93 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
94 DCHECK(!device_location.empty());
96 const AsyncDelegateKey key = GetAsyncDelegateKey(device_location, read_only);
97 AsyncDelegateMap::iterator it = async_delegate_map_.find(key);
98 DCHECK(it != async_delegate_map_.end());
99 it->second->CancelPendingTasksAndDeleteDelegate();
100 async_delegate_map_.erase(it);
103 // static
104 MTPDeviceMapService::AsyncDelegateKey MTPDeviceMapService::GetAsyncDelegateKey(
105 const base::FilePath::StringType& device_location,
106 const bool read_only) {
107 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
109 base::FilePath::StringType key;
110 key.append(read_only ? FILE_PATH_LITERAL("ReadOnly")
111 : FILE_PATH_LITERAL("ReadWrite"));
112 key.append(FILE_PATH_LITERAL("|"));
113 key.append(device_location);
114 return key;
117 MTPDeviceAsyncDelegate* MTPDeviceMapService::GetMTPDeviceAsyncDelegate(
118 const std::string& filesystem_id) {
119 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
120 DCHECK(!filesystem_id.empty());
122 // File system may be already revoked on ExternalMountPoints side, we check
123 // here that the file system is still valid.
124 base::FilePath device_path;
125 if (!storage::ExternalMountPoints::GetSystemInstance()->GetRegisteredPath(
126 filesystem_id, &device_path)) {
127 return NULL;
130 const base::FilePath::StringType& device_location = device_path.value();
132 MTPDeviceFileSystemMap::const_iterator mtp_device_map_it =
133 mtp_device_map_.find(filesystem_id);
134 if (mtp_device_map_it == mtp_device_map_.end())
135 return NULL;
137 DCHECK_EQ(device_path.value(), mtp_device_map_it->second.first);
138 const bool read_only = mtp_device_map_it->second.second;
139 const AsyncDelegateKey key = GetAsyncDelegateKey(device_location, read_only);
141 AsyncDelegateMap::const_iterator async_delegate_map_it =
142 async_delegate_map_.find(key);
143 return (async_delegate_map_it != async_delegate_map_.end())
144 ? async_delegate_map_it->second
145 : NULL;
148 MTPDeviceMapService::MTPDeviceMapService() {
151 MTPDeviceMapService::~MTPDeviceMapService() {
152 DCHECK(mtp_device_usage_map_.empty());