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

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

Powered by Google App Engine
This is Rietveld 408576698