Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: chrome/browser/media_gallery/media_file_system_registry.cc

Issue 10871049: Connect MediaFileSystemRegistry with MediaGalleriesPreferences (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix win - use after free Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // MediaFileSystemRegistry implementation. 5 // MediaFileSystemRegistry implementation.
6 6
7 #include "chrome/browser/media_gallery/media_file_system_registry.h" 7 #include "chrome/browser/media_gallery/media_file_system_registry.h"
8 8
9 #include <set> 9 #include <set>
10 #include <vector>
10 11
12 #include "base/callback.h"
11 #include "base/file_path.h" 13 #include "base/file_path.h"
12 #include "base/path_service.h" 14 #include "base/path_service.h"
15 #include "base/stl_util.h"
13 #include "base/system_monitor/system_monitor.h" 16 #include "base/system_monitor/system_monitor.h"
14 #include "base/utf_string_conversions.h" 17 #include "base/utf_string_conversions.h"
18 #include "chrome/browser/media_gallery/media_galleries_preferences.h"
19 #include "chrome/browser/media_gallery/media_galleries_preferences_factory.h"
20 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/system_monitor/media_storage_util.h" 21 #include "chrome/browser/system_monitor/media_storage_util.h"
16 #include "chrome/common/chrome_paths.h" 22 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/extensions/extension_constants.h" 23 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/common/extensions/extension.h" 24 #include "chrome/common/extensions/extension.h"
19 #include "content/public/browser/browser_thread.h" 25 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/notification_observer.h"
27 #include "content/public/browser/notification_registrar.h"
20 #include "content/public/browser/notification_source.h" 28 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/notification_types.h" 29 #include "content/public/browser/notification_types.h"
22 #include "content/public/browser/render_process_host.h" 30 #include "content/public/browser/render_process_host.h"
31 #include "content/public/browser/render_view_host.h"
32 #include "content/public/browser/web_contents.h"
23 #include "webkit/fileapi/file_system_types.h" 33 #include "webkit/fileapi/file_system_types.h"
24 #include "webkit/fileapi/isolated_context.h" 34 #include "webkit/fileapi/isolated_context.h"
25 #include "webkit/fileapi/media/media_file_system_config.h" 35 #include "webkit/fileapi/media/media_file_system_config.h"
26 36
27 #if defined(SUPPORT_MEDIA_FILESYSTEM) 37 #if defined(SUPPORT_MEDIA_FILESYSTEM)
28 #include "webkit/fileapi/media/media_device_map_service.h" 38 #include "webkit/fileapi/media/media_device_map_service.h"
29
30 using fileapi::MediaDeviceMapService;
31 #endif 39 #endif
32 40
33 namespace chrome { 41 namespace chrome {
34 42
35 static base::LazyInstance<MediaFileSystemRegistry>::Leaky 43 static base::LazyInstance<MediaFileSystemRegistry>::Leaky
36 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER; 44 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER;
37 45
38 using base::SystemMonitor; 46 using base::SystemMonitor;
39 using content::BrowserThread; 47 using content::BrowserThread;
48 using content::NavigationController;
40 using content::RenderProcessHost; 49 using content::RenderProcessHost;
50 using content::WebContents;
41 using fileapi::IsolatedContext; 51 using fileapi::IsolatedContext;
42 52
43 namespace { 53 namespace {
44 54
45 bool IsGalleryPermittedForExtension(const extensions::Extension& extension, 55 struct InvalidatedGalleriesInfo {
46 const FilePath::StringType& location) { 56 std::set<ExtensionGalleriesHost*> extension_hosts;
47 if (extension.HasAPIPermission( 57 std::set<MediaGalleryPrefId> pref_ids;
48 extensions::APIPermission::kMediaGalleriesAllGalleries)) { 58 };
49 return true; 59
50 } 60 std::string RegisterFileSystem(std::string device_id, const FilePath& path) {
51 // TODO(vandebo) Check with prefs for permission to this gallery. 61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
52 return false; 62
63 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
64 if (MediaStorageUtil::IsMassStorageDevice(device_id)) {
65 // Sanity checks for |path|.
66 CHECK(path.IsAbsolute());
67 CHECK(!path.ReferencesParent());
68 std::string fs_name(extension_misc::kMediaFileSystemPathPart);
69 const std::string fsid = isolated_context->RegisterFileSystemForPath(
70 fileapi::kFileSystemTypeNativeMedia, path, &fs_name);
71 CHECK(!fsid.empty());
72 return fsid;
73 }
74
75 // TODO(kmadhusu) handle MTP devices.
76 NOTREACHED();
77 return std::string();
53 } 78 }
54 79
55 } // namespace 80 } // namespace
56 81
82 // Refcounted only so it can easily be put in map. All instances are owned
83 // by |MediaFileSystemRegistry::extension_hosts_map_|.
84 class ExtensionGalleriesHost
85 : public base::RefCounted<ExtensionGalleriesHost>,
86 public content::NotificationObserver {
87 public:
88 // |no_references_callback| is called when the last RenderViewHost reference
89 // goes away. RenderViewHost references are added through ReferenceFromRVH().
90 explicit ExtensionGalleriesHost(const base::Closure& no_references_callback)
91 : no_references_callback_(no_references_callback) {
92 }
93
94 // For each gallery in the list of permitted |galleries|, looks up or creates
95 // a file system id and returns the information needed for the renderer to
96 // create those file system objects.
97 std::vector<MediaFileSystemRegistry::MediaFSInfo> GetMediaFileSystems(
98 const MediaGalleryPrefIdSet& galleries,
99 const MediaGalleriesPrefInfoMap& galleries_info) {
100 std::vector<MediaFileSystemRegistry::MediaFSInfo> result;
101 for (std::set<MediaGalleryPrefId>::const_iterator id = galleries.begin();
102 id != galleries.end();
103 ++id) {
104 PrefIdFsInfoMap::const_iterator existing_info = pref_id_map_.find(*id);
105 if (existing_info != pref_id_map_.end()) {
106 result.push_back(existing_info->second);
107 continue;
108 }
109 const MediaGalleryPrefInfo& gallery_info =
110 galleries_info.find(*id)->second;
111 const std::string& device_id = gallery_info.device_id;
112 // TODO(kmadhusu) handle MTP devices.
113 DCHECK(MediaStorageUtil::IsMassStorageDevice(device_id));
114 FilePath path = MediaStorageUtil::FindDevicePathById(device_id);
115 // TODO(vandebo) we also need to check that these galleries are attached.
116 // For now, just skip over entries that we couldn't find.
117 if (path.empty())
118 continue;
119 CHECK(!path.empty());
120 path = path.Append(gallery_info.path);
121
122 MediaFileSystemRegistry::MediaFSInfo new_entry;
123 new_entry.name = gallery_info.display_name;
124 new_entry.path = path;
125 new_entry.fsid = RegisterFileSystem(device_id, path);
126 result.push_back(new_entry);
127 pref_id_map_[*id] = new_entry;
128 }
129
130 // TODO(vandebo) We need a way of getting notification when permission for
131 // galleries are revoked (http://crbug.com/145855). For now, invalidate
132 // any fsid we have that we didn't get this time around.
133 if (galleries.size() != pref_id_map_.size()) {
134 MediaGalleryPrefIdSet old_galleries;
135 for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin();
136 it != pref_id_map_.end();
137 ++it) {
138 old_galleries.insert(it->first);
139 }
140 MediaGalleryPrefIdSet invalid_galleries;
141 std::set_difference(old_galleries.begin(), old_galleries.end(),
142 galleries.begin(), galleries.end(),
143 std::inserter(invalid_galleries,
144 invalid_galleries.begin()));
145 for (MediaGalleryPrefIdSet::const_iterator it = invalid_galleries.begin();
146 it != invalid_galleries.end();
147 ++it) {
148 RevokeGalleryByPrefId(*it);
149 }
150 }
151
152 return result;
153 }
154
155 // TODO(kmadhusu): Clean up this code. http://crbug.com/140340.
156 // Revoke the file system for |id| if this extension has created one for |id|.
157 void RevokeGalleryByPrefId(MediaGalleryPrefId id) {
158 PrefIdFsInfoMap::iterator gallery = pref_id_map_.find(id);
159 if (gallery == pref_id_map_.end())
160 return;
161
162 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
163 isolated_context->RevokeFileSystem(gallery->second.fsid);
164
165 pref_id_map_.erase(gallery);
166 }
167
168 // Indicate that the passed |rvh| will reference the file system ids created
169 // by this class. It is safe to call this multiple times with the same RVH.
170 void ReferenceFromRVH(const content::RenderViewHost* rvh) {
171 WebContents* contents = WebContents::FromRenderViewHost(rvh);
172 if (registrar_.IsRegistered(this,
173 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
174 content::Source<WebContents>(contents))) {
175 return;
176 }
177 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
178 content::Source<WebContents>(contents));
179 registrar_.Add(
180 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
181 content::Source<NavigationController>(&contents->GetController()));
182
183 RenderProcessHost* rph = contents->GetRenderProcessHost();
184 rph_refs_[rph].insert(contents);
185 if (rph_refs_[rph].size() == 1) {
186 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
187 content::Source<RenderProcessHost>(rph));
188 }
189 }
190
191 // NotificationObserver implementation.
192 virtual void Observe(int type,
193 const content::NotificationSource& source,
194 const content::NotificationDetails& details) OVERRIDE {
195 switch (type) {
196 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
197 OnRendererProcessClosed(
198 content::Source<RenderProcessHost>(source).ptr());
199 break;
200 }
201 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
202 OnWebContentsDestroyedOrNavigated(
203 content::Source<WebContents>(source).ptr());
204 break;
205 }
206 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
207 NavigationController* controller =
208 content::Source<NavigationController>(source).ptr();
209 WebContents* contents = controller->GetWebContents();
210 OnWebContentsDestroyedOrNavigated(contents);
211 break;
212 }
213 default: {
214 NOTREACHED();
215 break;
216 }
217 }
218 }
219
220 private:
221 typedef std::map<MediaGalleryPrefId, MediaFileSystemRegistry::MediaFSInfo>
222 PrefIdFsInfoMap;
223 typedef std::map<const RenderProcessHost*, std::set<const WebContents*> >
224 RenderProcessHostRefCount;
225
226 // Private destructor and friend declaration for ref counted implementation.
227 friend class base::RefCounted<ExtensionGalleriesHost>;
228
229 virtual ~ExtensionGalleriesHost() {
230 DCHECK(rph_refs_.empty());
231 DCHECK(pref_id_map_.empty());
232 }
233
234 void OnRendererProcessClosed(const RenderProcessHost* rph) {
235 RenderProcessHostRefCount::const_iterator rph_info = rph_refs_.find(rph);
236 DCHECK(rph_info != rph_refs_.end());
237 // We're going to remove everything from the set, so we make a copy
238 // before operating on it.
239 std::set<const WebContents*> closed_web_contents = rph_info->second;
240 DCHECK(!closed_web_contents.empty());
241
242 for (std::set<const WebContents*>::const_iterator it =
243 closed_web_contents.begin();
244 it != closed_web_contents.end();
245 ++it) {
246 OnWebContentsDestroyedOrNavigated(*it);
247 }
248 }
249
250 void OnWebContentsDestroyedOrNavigated(const WebContents* contents) {
251 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
252 content::Source<WebContents>(contents));
253 registrar_.Remove(
254 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
255 content::Source<NavigationController>(&contents->GetController()));
256
257 RenderProcessHost* rph = contents->GetRenderProcessHost();
258 RenderProcessHostRefCount::iterator process_refs = rph_refs_.find(rph);
259 DCHECK(process_refs != rph_refs_.end());
260 process_refs->second.erase(contents);
261 if (process_refs->second.empty()) {
262 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
263 content::Source<RenderProcessHost>(rph));
264 rph_refs_.erase(process_refs);
265 }
266
267 if (rph_refs_.empty()) {
268 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
269 for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin();
270 it != pref_id_map_.end();
271 ++it) {
272 isolated_context->RevokeFileSystem(it->second.fsid);
273 }
274 pref_id_map_.clear();
275 no_references_callback_.Run();
276 }
277 }
278
279 // A callback to call when the last RVH reference goes away.
280 base::Closure no_references_callback_;
281
282 // A map from the gallery preferences id to the file system information.
283 PrefIdFsInfoMap pref_id_map_;
284
285 // The set of render processes and web contents that may have references to
286 // the file system ids this instance manages.
287 RenderProcessHostRefCount rph_refs_;
288
289 // A registrar for listening notifications.
290 content::NotificationRegistrar registrar_;
291
292 DISALLOW_COPY_AND_ASSIGN(ExtensionGalleriesHost);
293 };
57 294
58 /****************** 295 /******************
59 * Public methods 296 * Public methods
60 ******************/ 297 ******************/
61 298
62 // static 299 // static
63 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() { 300 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() {
64 return g_media_file_system_registry.Pointer(); 301 return g_media_file_system_registry.Pointer();
65 } 302 }
66 303
304 // TODO(vandebo) We need to make this async so that we check that the
305 // galleries are attached (requires the file thread).
67 std::vector<MediaFileSystemRegistry::MediaFSInfo> 306 std::vector<MediaFileSystemRegistry::MediaFSInfo>
68 MediaFileSystemRegistry::GetMediaFileSystemsForExtension( 307 MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
69 const content::RenderProcessHost* rph, 308 const content::RenderViewHost* rvh,
70 const extensions::Extension& extension) { 309 const extensions::Extension* extension) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 310 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72 311
73 std::vector<MediaFSInfo> results; 312 Profile* profile =
74 std::pair<ChildIdToMediaFSMap::iterator, bool> ret = 313 Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext());
75 media_fs_map_.insert(std::make_pair(rph, MediaPathToFSIDMap())); 314 MediaGalleriesPreferences* preferences =
76 ChildIdToMediaFSMap::iterator& child_it = ret.first; 315 MediaGalleriesPreferencesFactory::GetForProfile(profile);
77 if (ret.second) { 316 MediaGalleryPrefIdSet galleries =
78 // Never seen a GetMediaFileSystems call from this RPH. Initialize its 317 preferences->GalleriesForExtension(*extension);
79 // file system mappings. 318 ExtensionGalleriesHost* extension_host =
80 RegisterForRPHGoneNotifications(rph); 319 extension_hosts_map_[profile][extension->id()].get();
81 FilePath pictures_path; 320
82 // TODO(vandebo) file system galleries need a unique id as well. 321 // If the extension has no galleries and it didn't have any last time, just
83 if (PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path) && 322 // return the empty list. The second check is needed because of
84 IsGalleryPermittedForExtension(extension, pictures_path.value())) { 323 // http://crbug.com/145855.
85 std::string fsid = RegisterPathAsFileSystem(pictures_path); 324 if (galleries.empty() && !extension_host)
86 child_it->second.insert(std::make_pair(pictures_path, fsid)); 325 return std::vector<MediaFileSystemRegistry::MediaFSInfo>();
87 } 326
327 if (!extension_host) {
328 extension_host = new ExtensionGalleriesHost(
329 base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty,
330 base::Unretained(this), profile, extension->id()));
331 extension_hosts_map_[profile][extension->id()] = extension_host;
88 } 332 }
333 extension_host->ReferenceFromRVH(rvh);
89 334
90 // TODO(thestig) Handle overlap between devices and media directories. 335 return extension_host->GetMediaFileSystems(galleries,
91 SystemMonitor* monitor = SystemMonitor::Get(); 336 preferences->known_galleries());
92 const std::vector<SystemMonitor::RemovableStorageInfo> media_devices =
93 monitor->GetAttachedRemovableStorage();
94 for (size_t i = 0; i < media_devices.size(); ++i) {
95 MediaStorageUtil::Type type;
96 MediaStorageUtil::CrackDeviceId(media_devices[i].device_id, &type, NULL);
97 // TODO(vandebo) Handle MTP devices.
98 if (type != MediaStorageUtil::MTP_OR_PTP &&
99 IsGalleryPermittedForExtension(extension, media_devices[i].location)) {
100 device_id_map_.insert(std::make_pair(media_devices[i].device_id,
101 media_devices[i]));
102 FilePath path(media_devices[i].location);
103 const std::string fsid = RegisterPathAsFileSystem(path);
104 child_it->second.insert(std::make_pair(path, fsid));
105 }
106 }
107
108 MediaPathToFSIDMap& child_map = child_it->second;
109 for (MediaPathToFSIDMap::const_iterator it = child_map.begin();
110 it != child_map.end();
111 ++it) {
112 MediaFSInfo entry;
113 // TODO(vandebo) use a better name, fsid for now.
114 entry.name = it->second;
115 entry.fsid = it->second;
116 entry.path = it->first;
117 results.push_back(entry);
118 }
119 return results;
120 } 337 }
121 338
339 // TODO(vandebo) We also need to listen for the attach event and add newly
340 // attached media devices to MediaGalleriesPreferences.
122 void MediaFileSystemRegistry::OnRemovableStorageDetached( 341 void MediaFileSystemRegistry::OnRemovableStorageDetached(
123 const std::string& id) { 342 const std::string& id) {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125 344
126 DeviceIdToInfoMap::iterator it = device_id_map_.find(id); 345 // Since revoking a gallery in the ExtensionGalleriesHost may cause it
127 if (it == device_id_map_.end()) 346 // to be removed from the map and therefore invalidate any iterator pointing
128 return; 347 // to it, this code first copies all the invalid gallery ids and the
348 // extension hosts in which they may appear (per profile) and revoked it in
349 // a second step.
350 std::vector<InvalidatedGalleriesInfo> invalid_galleries_info;
129 351
130 FilePath path(it->second.location); 352 for (ExtensionGalleriesHostMap::iterator profile_it =
131 RevokeMediaFileSystem(path); 353 extension_hosts_map_.begin();
132 device_id_map_.erase(it); 354 profile_it != extension_hosts_map_.end();
133 } 355 ++profile_it) {
356 MediaGalleriesPreferences* preferences =
357 MediaGalleriesPreferencesFactory::GetForProfile(profile_it->first);
358 InvalidatedGalleriesInfo invalid_galleries_in_profile;
359 invalid_galleries_in_profile.pref_ids =
360 preferences->LookUpGalleriesByDeviceId(id);
134 361
135 void MediaFileSystemRegistry::Observe( 362 for (ExtensionHostMap::const_iterator extension_host_it =
136 int type, 363 profile_it->second.begin();
137 const content::NotificationSource& source, 364 extension_host_it != profile_it->second.end();
138 const content::NotificationDetails& details) { 365 ++extension_host_it) {
139 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED || 366 invalid_galleries_in_profile.extension_hosts.insert(
140 type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); 367 extension_host_it->second.get());
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 368 }
142 const RenderProcessHost* rph = 369
143 content::Source<content::RenderProcessHost>(source).ptr(); 370 invalid_galleries_info.push_back(invalid_galleries_in_profile);
144 ChildIdToMediaFSMap::iterator child_it = media_fs_map_.find(rph); 371 }
145 CHECK(child_it != media_fs_map_.end()); 372
146 // No need to revoke the isolated file systems. The RPH will do that. 373 for (size_t i = 0; i < invalid_galleries_info.size(); i++) {
147 media_fs_map_.erase(child_it); 374 for (std::set<ExtensionGalleriesHost*>::const_iterator extension_host_it =
148 UnregisterForRPHGoneNotifications(rph); 375 invalid_galleries_info[i].extension_hosts.begin();
376 extension_host_it != invalid_galleries_info[i].extension_hosts.end();
377 ++extension_host_it) {
378 for (std::set<MediaGalleryPrefId>::const_iterator pref_id_it =
379 invalid_galleries_info[i].pref_ids.begin();
380 pref_id_it != invalid_galleries_info[i].pref_ids.end();
381 ++pref_id_it) {
382 (*extension_host_it)->RevokeGalleryByPrefId(*pref_id_it);
383 }
384 }
385 }
149 } 386 }
150 387
151 /****************** 388 /******************
152 * Private methods 389 * Private methods
153 ******************/ 390 ******************/
154 391
155 MediaFileSystemRegistry::MediaFileSystemRegistry() { 392 MediaFileSystemRegistry::MediaFileSystemRegistry() {
156 // SystemMonitor may be NULL in unit tests. 393 // SystemMonitor may be NULL in unit tests.
157 SystemMonitor* system_monitor = SystemMonitor::Get(); 394 SystemMonitor* system_monitor = SystemMonitor::Get();
158 if (system_monitor) 395 if (system_monitor)
159 system_monitor->AddDevicesChangedObserver(this); 396 system_monitor->AddDevicesChangedObserver(this);
397 // TODO(vandebo) We should add all the currently attached media devices
398 // to MediaGalleriesPreferences here.
160 } 399 }
161 400
162 MediaFileSystemRegistry::~MediaFileSystemRegistry() { 401 MediaFileSystemRegistry::~MediaFileSystemRegistry() {
163 // SystemMonitor may be NULL in unit tests. 402 // SystemMonitor may be NULL in unit tests.
164 SystemMonitor* system_monitor = SystemMonitor::Get(); 403 SystemMonitor* system_monitor = SystemMonitor::Get();
165 if (system_monitor) 404 if (system_monitor)
166 system_monitor->RemoveDevicesChangedObserver(this); 405 system_monitor->RemoveDevicesChangedObserver(this);
167 } 406 }
168 407
169 void MediaFileSystemRegistry::RegisterForRPHGoneNotifications( 408 void MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty(
170 const content::RenderProcessHost* rph) { 409 Profile* profile, const std::string& extension_id) {
171 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
172 content::Source<RenderProcessHost>(rph));
173 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
174 content::Source<RenderProcessHost>(rph));
175 }
176
177 void MediaFileSystemRegistry::UnregisterForRPHGoneNotifications(
178 const content::RenderProcessHost* rph) {
179 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
180 content::Source<RenderProcessHost>(rph));
181 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
182 content::Source<RenderProcessHost>(rph));
183 }
184
185 std::string MediaFileSystemRegistry::RegisterPathAsFileSystem(
186 const FilePath& path) {
187 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 410 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
188 411
189 // Sanity checks for |path|. 412 ExtensionGalleriesHostMap::iterator extension_hosts =
190 CHECK(path.IsAbsolute()); 413 extension_hosts_map_.find(profile);
191 CHECK(!path.ReferencesParent()); 414 DCHECK(extension_hosts != extension_hosts_map_.end());
192 415 ExtensionHostMap::size_type erase_count =
193 // The directory name is not exposed to the js layer and we simply use 416 extension_hosts->second.erase(extension_id);
194 // a fixed name (as we only register a single directory per file system). 417 DCHECK_EQ(1U, erase_count);
195 std::string register_name(extension_misc::kMediaFileSystemPathPart); 418 if (extension_hosts->second.empty())
196 const std::string fsid = 419 extension_hosts_map_.erase(extension_hosts);
197 IsolatedContext::GetInstance()->RegisterFileSystemForPath(
198 fileapi::kFileSystemTypeNativeMedia, path, &register_name);
199 CHECK(!fsid.empty());
200 return fsid;
201 }
202
203 void MediaFileSystemRegistry::RevokeMediaFileSystem(const FilePath& path) {
204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
205
206 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
207 isolated_context->RevokeFileSystemByPath(path);
208
209 for (ChildIdToMediaFSMap::iterator child_it = media_fs_map_.begin();
210 child_it != media_fs_map_.end();
211 ++child_it) {
212 MediaPathToFSIDMap& child_map = child_it->second;
213 MediaPathToFSIDMap::iterator media_path_it = child_map.find(path);
214 if (media_path_it == child_map.end())
215 continue;
216
217 child_map.erase(media_path_it);
218 }
219 } 420 }
220 421
221 } // namespace chrome 422 } // namespace chrome
OLDNEW
« no previous file with comments | « chrome/browser/media_gallery/media_file_system_registry.h ('k') | chrome/browser/system_monitor/media_storage_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698