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"
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/isolated_context.h"
17 base::LazyInstance
<MTPDeviceMapService
> g_mtp_device_map_service
=
18 LAZY_INSTANCE_INITIALIZER
;
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
& fsid
) {
30 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
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;
42 mtp_device_usage_map_
[device_location
]++;
43 mtp_device_map_
[fsid
] = device_location
;
46 void MTPDeviceMapService::RevokeMTPFileSystem(const std::string
& fsid
) {
47 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
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
);
64 void MTPDeviceMapService::AddAsyncDelegate(
65 const base::FilePath::StringType
& device_location
,
66 MTPDeviceAsyncDelegate
* delegate
) {
67 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
69 DCHECK(!device_location
.empty());
70 if (ContainsKey(async_delegate_map_
, device_location
))
72 async_delegate_map_
[device_location
] = delegate
;
75 void 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
);
84 MTPDeviceAsyncDelegate
* MTPDeviceMapService::GetMTPDeviceAsyncDelegate(
85 const std::string
& filesystem_id
) {
86 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO
));
87 base::FilePath device_path
;
88 if (!fileapi::IsolatedContext::GetInstance()->GetRegisteredPath(
89 filesystem_id
, &device_path
)) {
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
;
100 MTPDeviceMapService::MTPDeviceMapService() {
103 MTPDeviceMapService::~MTPDeviceMapService() {
104 DCHECK(mtp_device_usage_map_
.empty());