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

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: Self review 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 10
11 #include "base/callback.h"
11 #include "base/file_path.h" 12 #include "base/file_path.h"
12 #include "base/path_service.h" 13 #include "base/path_service.h"
13 #include "base/system_monitor/system_monitor.h" 14 #include "base/system_monitor/system_monitor.h"
14 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/media_gallery/media_galleries_preferences.h"
17 #include "chrome/browser/media_gallery/media_galleries_preferences_factory.h"
15 #include "chrome/browser/media_gallery/media_storage_util.h" 18 #include "chrome/browser/media_gallery/media_storage_util.h"
19 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/chrome_paths.h" 20 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/extensions/extension_constants.h" 21 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/common/extensions/extension.h" 22 #include "chrome/common/extensions/extension.h"
19 #include "content/public/browser/browser_thread.h" 23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/notification_observer.h"
25 #include "content/public/browser/notification_registrar.h"
20 #include "content/public/browser/notification_source.h" 26 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/notification_types.h" 27 #include "content/public/browser/notification_types.h"
22 #include "content/public/browser/render_process_host.h" 28 #include "content/public/browser/render_process_host.h"
29 #include "content/public/browser/render_view_host.h"
30 #include "content/public/browser/web_contents.h"
23 #include "webkit/fileapi/file_system_types.h" 31 #include "webkit/fileapi/file_system_types.h"
24 #include "webkit/fileapi/isolated_context.h" 32 #include "webkit/fileapi/isolated_context.h"
25 #include "webkit/fileapi/media/media_file_system_config.h" 33 #include "webkit/fileapi/media/media_file_system_config.h"
26 34
27 #if defined(SUPPORT_MEDIA_FILESYSTEM) 35 #if defined(SUPPORT_MEDIA_FILESYSTEM)
28 #include "webkit/fileapi/media/media_device_map_service.h" 36 #include "webkit/fileapi/media/media_device_map_service.h"
29
30 using fileapi::MediaDeviceMapService;
31 #endif 37 #endif
32 38
33 namespace chrome { 39 namespace chrome {
34 40
35 static base::LazyInstance<MediaFileSystemRegistry>::Leaky 41 static base::LazyInstance<MediaFileSystemRegistry>::Leaky
36 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER; 42 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER;
37 43
38 using base::SystemMonitor; 44 using base::SystemMonitor;
39 using content::BrowserThread; 45 using content::BrowserThread;
46 using content::NavigationController;
40 using content::RenderProcessHost; 47 using content::RenderProcessHost;
48 using content::WebContents;
41 using fileapi::IsolatedContext; 49 using fileapi::IsolatedContext;
42 50
43 namespace { 51 namespace {
44 52
45 bool IsGalleryPermittedForExtension(const extensions::Extension& extension, 53 struct InvalidatedGallery {
Lei Zhang 2012/09/04 23:38:51 Move this to inside MediaFileSystemRegistry::OnRem
vandebo (ex-Chrome) 2012/09/05 00:58:12 I did try that originally, but the compiler compla
46 const FilePath::StringType& location) { 54 ExtensionGalleriesHost* extension_host;
47 if (extension.HasAPIPermission( 55 MediaGalleryPrefId pref_id;
48 extensions::APIPermission::kMediaGalleriesAllGalleries)) { 56 };
49 return true; 57
50 } 58 typedef std::list<InvalidatedGallery> InvalidatedGalleries;
Lei Zhang 2012/09/04 23:38:51 nit: #include <list>
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
51 // TODO(vandebo) Check with prefs for permission to this gallery. 59
52 return false; 60 std::string RegisterFileSystem(std::string device_id, const FilePath& path) {
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
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 galelry in the list of permitted |galleries|, looks up or creates
Lei Zhang 2012/09/04 23:38:51 nit: typo
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
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 // TODO(vandebo) we also need to check that these galleries are attached.
105 PrefIdFsInfoMap::const_iterator existing_info = pref_id_map_.find(*id);
106 if (existing_info != pref_id_map_.end()) {
107 result.push_back(existing_info->second);
108 continue;
109 }
110 const MediaGalleryPrefInfo& gallery_info =
111 galleries_info.find(*id)->second;
112 const std::string& device_id = gallery_info.device_id;
113 // TODO(kmadhusu) handle MTP devices.
114 DCHECK(MediaStorageUtil::IsMassStorageDevice(device_id));
115 FilePath path = MediaStorageUtil::FindDevicePathById(device_id);
116 CHECK(!path.empty());
117 path = path.Append(gallery_info.path);
118
119 MediaFileSystemRegistry::MediaFSInfo new_entry;
120 new_entry.name = gallery_info.display_name;
121 new_entry.path = path;
122 new_entry.fsid = RegisterFileSystem(device_id, path);
123 result.push_back(new_entry);
124 pref_id_map_[*id] = new_entry;
125 }
126
127 // TODO(vandebo) We need a way of getting notification when permission for
128 // galleries are revoked (http://crbug.com/145855). For now, invalidate
129 // any fsid we have that we didn't get this time around.
130 if (galleries.size() != pref_id_map_.size()) {
131 MediaGalleryPrefIdSet old_galleries;
132 for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin();
133 it != pref_id_map_.end();
134 ++it) {
135 old_galleries.insert(it->first);
136 }
137 MediaGalleryPrefIdSet invalid_galleries;
138 std::set_difference(old_galleries.begin(), old_galleries.end(),
139 galleries.begin(), galleries.end(),
140 std::inserter(invalid_galleries,
141 invalid_galleries.begin()));
142 for (MediaGalleryPrefIdSet::const_iterator it = invalid_galleries.begin();
143 it != invalid_galleries.end();
144 ++it) {
145 RevokeGalleryByPrefId(*it);
146 }
147 }
148
149 return result;
150 }
151
152 // Revoke the file system for |id| if this extension has created one for |id|.
153 void RevokeGalleryByPrefId(MediaGalleryPrefId id) {
154 PrefIdFsInfoMap::iterator gallery = pref_id_map_.find(id);
155 if (gallery == pref_id_map_.end())
Lei Zhang 2012/09/04 23:38:51 Can this ever happen?
vandebo (ex-Chrome) 2012/09/05 00:58:12 Yes. If an extension doesn't have access to a rem
156 return;
157
158 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
159 isolated_context->RevokeFileSystem(gallery->second.fsid);
160
161 pref_id_map_.erase(gallery);
162 }
163
164 // Indicate that the passed render process will reference the file system
Lei Zhang 2012/09/04 23:38:51 render process -> rvh
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
165 // ids created by this class. It is safe to call this multiple times with
166 // the same RVH.
167 void ReferenceFromRVH(const content::RenderViewHost* rvh) {
168 WebContents* contents = WebContents::FromRenderViewHost(rvh);
169 if (registrar_.IsRegistered(this,
170 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
171 content::Source<WebContents>(contents))) {
172 return;
173 }
174 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
175 content::Source<WebContents>(contents));
176 registrar_.Add(
177 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
178 content::Source<NavigationController>(&contents->GetController()));
179
180 RenderProcessHost* rph = contents->GetRenderProcessHost();
181 rph_refs_[rph].insert(contents);
182 if (rph_refs_[rph].size() == 1) {
183 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
184 content::Source<RenderProcessHost>(rph));
185 }
186 }
187
188 // NotificationObserver implementation.
189 virtual void Observe(int type,
190 const content::NotificationSource& source,
191 const content::NotificationDetails& details) OVERRIDE {
192 switch (type) {
193 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
194 OnRendererProcessClosed(
195 content::Source<RenderProcessHost>(source).ptr());
196 break;
197 }
198 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
199 OnWebContentsDestroyedOrNavigated(
200 content::Source<WebContents>(source).ptr());
201 break;
202 }
203 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
204 NavigationController* controller =
205 content::Source<NavigationController>(source).ptr();
206 WebContents* contents = controller->GetWebContents();
207 OnWebContentsDestroyedOrNavigated(contents);
208 break;
209 }
210 default: {
211 NOTREACHED();
212 break;
213 }
214 }
215 }
216
217 private:
218 typedef std::map<MediaGalleryPrefId, MediaFileSystemRegistry::MediaFSInfo>
219 PrefIdFsInfoMap;
220 typedef std::map<const RenderProcessHost*, std::set<const WebContents*> >
221 RenderProcessHostRefCount;
222
223 // Private destructor and friend declaration for ref counted implementation.
224 friend class base::RefCounted<ExtensionGalleriesHost>;
Lei Zhang 2012/09/04 23:38:51 nit: blan line after this
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
225 virtual ~ExtensionGalleriesHost() {
226 DCHECK(rph_refs_.empty());
227 DCHECK(pref_id_map_.empty());
228 }
229
230 void OnRendererProcessClosed(const RenderProcessHost* rph) {
231 RenderProcessHostRefCount::const_iterator rph_info = rph_refs_.find(rph);
232 DCHECK(rph_info != rph_refs_.end());
233 // We're going to remove everything from the set, so we make a copy
234 // before operating on it.
235 std::set<const WebContents*> dead_rvhs = rph_info->second;
Lei Zhang 2012/09/04 23:38:51 |dead_rvhs| is weirdly named, since it's a set of
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
236 DCHECK(!dead_rvhs.empty());
237
238 for (std::set<const WebContents*>::const_iterator it = dead_rvhs.begin();
239 it != dead_rvhs.end();
240 ++it) {
241 OnWebContentsDestroyedOrNavigated(*it);
242 }
243 DCHECK(rph_refs_.find(rph) == rph_refs_.end());
Lei Zhang 2012/09/04 23:38:51 You can use ContainsKey() here.
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
244 }
245
246 void OnWebContentsDestroyedOrNavigated(const WebContents* contents) {
247 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
248 content::Source<WebContents>(contents));
249 registrar_.Remove(
250 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
251 content::Source<NavigationController>(&contents->GetController()));
252
253 RenderProcessHost* rph = contents->GetRenderProcessHost();
254 rph_refs_[rph].erase(contents);
255 if (rph_refs_[rph].empty()) {
256 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
257 content::Source<RenderProcessHost>(rph));
258 rph_refs_.erase(rph);
259 }
260
261 if (rph_refs_.empty()) {
262 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
263 for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin();
264 it != pref_id_map_.end();
265 ++it) {
266 isolated_context->RevokeFileSystem(it->second.fsid);
267 }
268 pref_id_map_.clear();
269 no_references_callback_.Run();
270 }
271 }
272
273 // A callback to call when the last RVH reference goes away.
274 base::Closure no_references_callback_;
275
276 // A map from the gallery preferences id to the file system information.
277 PrefIdFsInfoMap pref_id_map_;
278
279 // The set of render processes and web contents that may have references to
280 // the file system ids this instance manages.
281 RenderProcessHostRefCount rph_refs_;
282
283 // A registrar for listening notifications.
284 content::NotificationRegistrar registrar_;
285
286 DISALLOW_COPY_AND_ASSIGN(ExtensionGalleriesHost);
287 };
57 288
58 /****************** 289 /******************
59 * Public methods 290 * Public methods
60 ******************/ 291 ******************/
61 292
62 // static 293 // static
63 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() { 294 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() {
64 return g_media_file_system_registry.Pointer(); 295 return g_media_file_system_registry.Pointer();
65 } 296 }
66 297
298 // TODO(vandebo) We need to make this async so that we check that the
299 // galleries are attached (requires the file thread).
67 std::vector<MediaFileSystemRegistry::MediaFSInfo> 300 std::vector<MediaFileSystemRegistry::MediaFSInfo>
68 MediaFileSystemRegistry::GetMediaFileSystemsForExtension( 301 MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
69 const content::RenderProcessHost* rph, 302 const content::RenderViewHost* rvh,
70 const extensions::Extension& extension) { 303 const extensions::Extension* extension) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 304 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72 305
73 std::vector<MediaFSInfo> results; 306 Profile* profile =
74 std::pair<ChildIdToMediaFSMap::iterator, bool> ret = 307 Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext());
75 media_fs_map_.insert(std::make_pair(rph, MediaPathToFSIDMap())); 308 MediaGalleriesPreferences* preferences =
76 ChildIdToMediaFSMap::iterator& child_it = ret.first; 309 MediaGalleriesPreferencesFactory::GetForProfile(profile);
77 if (ret.second) { 310 MediaGalleryPrefIdSet galleries =
78 // Never seen a GetMediaFileSystems call from this RPH. Initialize its 311 preferences->GalleriesForExtension(*extension);
79 // file system mappings. 312 ExtensionGalleriesHost* extension_host =
80 RegisterForRPHGoneNotifications(rph); 313 extension_hosts_map_[profile][extension->id()].get();
81 FilePath pictures_path; 314
82 // TODO(vandebo) file system galleries need a unique id as well. 315 if (galleries.empty() && !extension_host)
Lei Zhang 2012/09/04 23:38:51 Can you comment what this case means? "Never had a
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
83 if (PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path) && 316 return std::vector<MediaFileSystemRegistry::MediaFSInfo>();
84 IsGalleryPermittedForExtension(extension, pictures_path.value())) { 317
85 std::string fsid = RegisterPathAsFileSystem(pictures_path); 318 if (!extension_host) {
Lei Zhang 2012/09/04 23:38:51 ditto, please comment. "Has access to galleries, b
vandebo (ex-Chrome) 2012/09/05 00:58:12 I'm not sure this chunk of code needs a comment...
86 child_it->second.insert(std::make_pair(pictures_path, fsid)); 319 extension_hosts_map_[profile][extension->id()] =
87 } 320 new ExtensionGalleriesHost(
321 base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty,
322 base::Unretained(this), profile, extension->id()));
323 extension_host = extension_hosts_map_[profile][extension->id()].get();
88 } 324 }
325 extension_host->ReferenceFromRVH(rvh);
89 326
90 // TODO(thestig) Handle overlap between devices and media directories. 327 return extension_host->GetMediaFileSystems(galleries,
91 SystemMonitor* monitor = SystemMonitor::Get(); 328 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 } 329 }
121 330
331 // TODO(vandebo) We also need to listen for the attach event and add newly
332 // attached media devices to MediaGalleriesPreferences.
122 void MediaFileSystemRegistry::OnRemovableStorageDetached( 333 void MediaFileSystemRegistry::OnRemovableStorageDetached(
123 const std::string& id) { 334 const std::string& id) {
124 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
125 336
126 DeviceIdToInfoMap::iterator it = device_id_map_.find(id); 337 // Since revoking a gallery in the ExtensionGalleriesHost may cause it
127 if (it == device_id_map_.end()) 338 // to be removed from the map and therefore invalidate any iterator pointing
128 return; 339 // to it, we first make a list of all the ExtensionGalleriesHost*, pref_id
340 // pairs to invalidate and then invalidate them in a second step.
341 InvalidatedGalleries invalidated_galleries;
129 342
130 FilePath path(it->second.location); 343 for (ExtensionGalleriesHostMap::iterator extension_hosts_map_it =
131 RevokeMediaFileSystem(path); 344 extension_hosts_map_.begin();
132 device_id_map_.erase(it); 345 extension_hosts_map_it != extension_hosts_map_.end();
133 } 346 ++extension_hosts_map_it) {
347 MediaGalleriesPreferences* preferences =
348 MediaGalleriesPreferencesFactory::GetForProfile(
349 extension_hosts_map_it->first);
350 MediaGalleryPrefIdSet detached_galleries =
351 preferences->LookUpGalleriesByDeviceId(id);
352 for (ExtensionHostMap::const_iterator extension_host_it =
Lei Zhang 2012/09/04 23:38:51 Do you think it'll be cleaner to put the second an
vandebo (ex-Chrome) 2012/09/05 00:58:12 I realized that this code was inefficient in that
353 extension_hosts_map_it->second.begin();
354 extension_host_it != extension_hosts_map_it->second.end();
355 ++extension_host_it) {
356 for (MediaGalleryPrefIdSet::const_iterator pref_id =
357 detached_galleries.begin();
358 pref_id != detached_galleries.end();
359 ++pref_id) {
360 InvalidatedGallery gallery;
361 gallery.extension_host = extension_host_it->second.get();
362 gallery.pref_id = *pref_id;
363 invalidated_galleries.push_back(gallery);
364 }
365 }
366 }
134 367
135 void MediaFileSystemRegistry::Observe( 368 // TODO(kmadhusu, vandebo): Clean up this code. http://crbug.com/140340.
136 int type, 369 DCHECK(MediaStorageUtil::IsMassStorageDevice(id));
137 const content::NotificationSource& source, 370 for (InvalidatedGalleries::const_iterator it = invalidated_galleries.begin();
138 const content::NotificationDetails& details) { 371 it != invalidated_galleries.end();
139 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED || 372 ++it) {
140 type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); 373 it->extension_host->RevokeGalleryByPrefId(it->pref_id);
141 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 374 }
142 const RenderProcessHost* rph =
143 content::Source<content::RenderProcessHost>(source).ptr();
144 ChildIdToMediaFSMap::iterator child_it = media_fs_map_.find(rph);
145 CHECK(child_it != media_fs_map_.end());
146 // No need to revoke the isolated file systems. The RPH will do that.
147 media_fs_map_.erase(child_it);
148 UnregisterForRPHGoneNotifications(rph);
149 } 375 }
150 376
151 /****************** 377 /******************
152 * Private methods 378 * Private methods
153 ******************/ 379 ******************/
154 380
155 MediaFileSystemRegistry::MediaFileSystemRegistry() { 381 MediaFileSystemRegistry::MediaFileSystemRegistry() {
156 // SystemMonitor may be NULL in unit tests. 382 // SystemMonitor may be NULL in unit tests.
157 SystemMonitor* system_monitor = SystemMonitor::Get(); 383 SystemMonitor* system_monitor = SystemMonitor::Get();
158 if (system_monitor) 384 if (system_monitor)
159 system_monitor->AddDevicesChangedObserver(this); 385 system_monitor->AddDevicesChangedObserver(this);
386 // TODO(vandebo) We should add all the currently attached media devices
387 // to MediaGalleriesPreferences here.
160 } 388 }
161 389
162 MediaFileSystemRegistry::~MediaFileSystemRegistry() { 390 MediaFileSystemRegistry::~MediaFileSystemRegistry() {
163 // SystemMonitor may be NULL in unit tests. 391 // SystemMonitor may be NULL in unit tests.
164 SystemMonitor* system_monitor = SystemMonitor::Get(); 392 SystemMonitor* system_monitor = SystemMonitor::Get();
165 if (system_monitor) 393 if (system_monitor)
166 system_monitor->RemoveDevicesChangedObserver(this); 394 system_monitor->RemoveDevicesChangedObserver(this);
167 } 395 }
168 396
169 void MediaFileSystemRegistry::RegisterForRPHGoneNotifications( 397 void MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty(
170 const content::RenderProcessHost* rph) { 398 Profile* profile, const std::string& extension_id) {
Lei Zhang 2012/09/04 23:38:51 Also DCHECK this is on the UI thread since we acce
vandebo (ex-Chrome) 2012/09/05 00:58:12 Done.
171 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 399 ExtensionGalleriesHostMap::iterator extension_hosts =
172 content::Source<RenderProcessHost>(rph)); 400 extension_hosts_map_.find(profile);
173 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 401 DCHECK(extension_hosts != extension_hosts_map_.end());
174 content::Source<RenderProcessHost>(rph)); 402 ExtensionHostMap::size_type erase_count =
175 } 403 extension_hosts->second.erase(extension_id);
176 404 DCHECK_EQ(1U, erase_count);
177 void MediaFileSystemRegistry::UnregisterForRPHGoneNotifications( 405 if (extension_hosts->second.empty())
178 const content::RenderProcessHost* rph) { 406 extension_hosts_map_.erase(profile);
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));
188
189 // Sanity checks for |path|.
190 CHECK(path.IsAbsolute());
191 CHECK(!path.ReferencesParent());
192
193 // The directory name is not exposed to the js layer and we simply use
194 // a fixed name (as we only register a single directory per file system).
195 std::string register_name(extension_misc::kMediaFileSystemPathPart);
196 const std::string fsid =
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 } 407 }
220 408
221 } // namespace chrome 409 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698