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

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

Issue 11027051: MediaFileSystemRegistry unit tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix compile Created 8 years, 1 month 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 #include <vector>
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 const FilePath& fs_path, 119 const FilePath& fs_path,
120 const std::string& filesystem_id) 120 const std::string& filesystem_id)
121 : name(fs_name), 121 : name(fs_name),
122 path(fs_path), 122 path(fs_path),
123 fsid(filesystem_id) { 123 fsid(filesystem_id) {
124 } 124 }
125 125
126 MediaFileSystemInfo::MediaFileSystemInfo() {} 126 MediaFileSystemInfo::MediaFileSystemInfo() {}
127 127
128 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM) 128 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM)
129 // Class to manage MTPDeviceDelegateImpl object for the attached MTP device.
130 // Refcounted to reuse the same MTP device delegate entry across extensions.
131 // This class supports WeakPtr (extends SupportsWeakPtr) to expose itself as
132 // a weak pointer to MediaFileSystemRegistry.
133 class ScopedMTPDeviceMapEntry
134 : public base::RefCounted<ScopedMTPDeviceMapEntry>,
135 public base::SupportsWeakPtr<ScopedMTPDeviceMapEntry> {
136 public:
137 // |no_references_callback| is called when the last ScopedMTPDeviceMapEntry
138 // reference goes away.
139 ScopedMTPDeviceMapEntry(const FilePath::StringType& device_location,
140 const base::Closure& no_references_callback)
141 : device_location_(device_location),
142 no_references_callback_(no_references_callback) {
143 BrowserThread::PostTask(
144 BrowserThread::IO, FROM_HERE,
145 Bind(&MTPDeviceMapService::AddDelegate,
146 base::Unretained(MTPDeviceMapService::GetInstance()),
147 device_location_,
148 make_scoped_refptr(new MTPDeviceDelegateImpl(device_location))));
149 }
150 129
151 private: 130 ScopedMTPDeviceMapEntry::ScopedMTPDeviceMapEntry(
152 // Friend declaration for ref counted implementation. 131 const FilePath::StringType& device_location,
153 friend class base::RefCounted<ScopedMTPDeviceMapEntry>; 132 const base::Closure& no_references_callback)
133 : device_location_(device_location),
134 delegate_(new MTPDeviceDelegateImpl(device_location)),
135 no_references_callback_(no_references_callback) {
136 DCHECK(delegate_);
Lei Zhang 2012/11/09 09:14:53 No need to check for OOM conditions
vandebo (ex-Chrome) 2012/11/13 06:50:18 Done.
137 BrowserThread::PostTask(
138 BrowserThread::IO, FROM_HERE,
139 Bind(&MTPDeviceMapService::AddDelegate,
140 base::Unretained(MTPDeviceMapService::GetInstance()),
141 device_location_, make_scoped_refptr(delegate_)));
142 }
154 143
155 // Private because this class is ref-counted. 144 ScopedMTPDeviceMapEntry::~ScopedMTPDeviceMapEntry() {
156 ~ScopedMTPDeviceMapEntry() { 145 BrowserThread::PostTask(
157 BrowserThread::PostTask( 146 BrowserThread::IO, FROM_HERE,
158 BrowserThread::IO, FROM_HERE, 147 Bind(&MTPDeviceMapService::RemoveDelegate,
159 Bind(&MTPDeviceMapService::RemoveDelegate, 148 base::Unretained(MTPDeviceMapService::GetInstance()),
160 base::Unretained(MTPDeviceMapService::GetInstance()), 149 device_location_));
161 device_location_)); 150 no_references_callback_.Run();
162 no_references_callback_.Run(); 151 }
163 }
164 152
165 // Store the MTP or PTP device location. 153 #endif // defined(SUPPORT_MTP_DEVICE_FILESYSTEM)
166 const FilePath::StringType device_location_;
167
168 // A callback to call when the last reference of this object goes away.
169 base::Closure no_references_callback_;
170
171 DISALLOW_COPY_AND_ASSIGN(ScopedMTPDeviceMapEntry);
172 };
173 #endif
174 154
175 // The main owner of this class is 155 // The main owner of this class is
176 // |MediaFileSystemRegistry::extension_hosts_map_|, but a callback may 156 // |MediaFileSystemRegistry::extension_hosts_map_|, but a callback may
177 // temporarily hold a reference. 157 // temporarily hold a reference.
178 class ExtensionGalleriesHost 158 class ExtensionGalleriesHost
179 : public base::RefCountedThreadSafe<ExtensionGalleriesHost>, 159 : public base::RefCountedThreadSafe<ExtensionGalleriesHost>,
180 public content::NotificationObserver { 160 public content::NotificationObserver {
181 public: 161 public:
182 // |no_references_callback| is called when the last RenderViewHost reference 162 // |no_references_callback| is called when the last RenderViewHost reference
183 // goes away. RenderViewHost references are added through ReferenceFromRVH(). 163 // goes away. RenderViewHost references are added through ReferenceFromRVH().
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 218
239 file_system_context_->RevokeFileSystem(gallery->second.fsid); 219 file_system_context_->RevokeFileSystem(gallery->second.fsid);
240 pref_id_map_.erase(gallery); 220 pref_id_map_.erase(gallery);
241 221
242 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM) 222 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM)
243 MediaDeviceEntryReferencesMap::iterator mtp_device_host = 223 MediaDeviceEntryReferencesMap::iterator mtp_device_host =
244 media_device_map_references_.find(id); 224 media_device_map_references_.find(id);
245 if (mtp_device_host != media_device_map_references_.end()) 225 if (mtp_device_host != media_device_map_references_.end())
246 media_device_map_references_.erase(mtp_device_host); 226 media_device_map_references_.erase(mtp_device_host);
247 #endif 227 #endif
228
229 if (pref_id_map_.empty()) {
230 rph_refs_.clear();
231 CleanUp();
232 }
248 } 233 }
249 234
250 // Indicate that the passed |rvh| will reference the file system ids created 235 // Indicate that the passed |rvh| will reference the file system ids created
251 // by this class. It is safe to call this multiple times with the same RVH. 236 // by this class. It is safe to call this multiple times with the same RVH.
252 void ReferenceFromRVH(const content::RenderViewHost* rvh) { 237 void ReferenceFromRVH(const content::RenderViewHost* rvh) {
253 WebContents* contents = WebContents::FromRenderViewHost(rvh); 238 WebContents* contents = WebContents::FromRenderViewHost(rvh);
254 if (registrar_.IsRegistered(this, 239 if (registrar_.IsRegistered(this,
255 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 240 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
256 content::Source<WebContents>(contents))) { 241 content::Source<WebContents>(contents))) {
257 return; 242 return;
258 } 243 }
259 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 244 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
260 content::Source<WebContents>(contents)); 245 content::Source<WebContents>(contents));
261 registrar_.Add( 246 registrar_.Add(
262 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 247 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
263 content::Source<NavigationController>(&contents->GetController())); 248 content::Source<NavigationController>(&contents->GetController()));
264 249
265 RenderProcessHost* rph = contents->GetRenderProcessHost(); 250 RenderProcessHost* rph = contents->GetRenderProcessHost();
266 rph_refs_[rph].insert(contents); 251 rph_refs_[rph].insert(contents);
267 if (rph_refs_[rph].size() == 1) { 252 if (rph_refs_[rph].size() == 1) {
268 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 253 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
269 content::Source<RenderProcessHost>(rph)); 254 content::Source<RenderProcessHost>(rph));
270 } 255 }
271 } 256 }
272 257
273 private: 258 private:
274 typedef std::map<MediaGalleryPrefId, MediaFileSystemInfo> 259 typedef std::map<MediaGalleryPrefId, MediaFileSystemInfo>
275 PrefIdFsInfoMap; 260 PrefIdFsInfoMap;
276 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM) 261 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM)
277 typedef std::map<MediaGalleryPrefId, 262 typedef std::map<MediaGalleryPrefId,
278 scoped_refptr<ScopedMTPDeviceMapEntry> > 263 scoped_refptr<ScopedMTPDeviceMapEntry> >
(...skipping 12 matching lines...) Expand all
291 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM) 276 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM)
292 DCHECK(media_device_map_references_.empty()); 277 DCHECK(media_device_map_references_.empty());
293 #endif 278 #endif
294 } 279 }
295 280
296 // NotificationObserver implementation. 281 // NotificationObserver implementation.
297 virtual void Observe(int type, 282 virtual void Observe(int type,
298 const content::NotificationSource& source, 283 const content::NotificationSource& source,
299 const content::NotificationDetails& details) OVERRIDE { 284 const content::NotificationDetails& details) OVERRIDE {
300 switch (type) { 285 switch (type) {
301 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { 286 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
302 OnRendererProcessClosed( 287 OnRendererProcessTerminated(
303 content::Source<RenderProcessHost>(source).ptr()); 288 content::Source<RenderProcessHost>(source).ptr());
304 break; 289 break;
305 } 290 }
306 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: { 291 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
307 OnWebContentsDestroyedOrNavigated( 292 OnWebContentsDestroyedOrNavigated(
308 content::Source<WebContents>(source).ptr()); 293 content::Source<WebContents>(source).ptr());
309 break; 294 break;
310 } 295 }
311 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { 296 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
312 NavigationController* controller = 297 NavigationController* controller =
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 MakeJSONFileSystemName(gallery_info.display_name, 359 MakeJSONFileSystemName(gallery_info.display_name,
375 pref_id, 360 pref_id,
376 GetTransientIdForRemovableDeviceId(device_id)), 361 GetTransientIdForRemovableDeviceId(device_id)),
377 path, 362 path,
378 fsid); 363 fsid);
379 result.push_back(new_entry); 364 result.push_back(new_entry);
380 new_galleries.insert(pref_id); 365 new_galleries.insert(pref_id);
381 pref_id_map_[pref_id] = new_entry; 366 pref_id_map_[pref_id] = new_entry;
382 } 367 }
383 368
384 RevokeOldGalleries(new_galleries); 369 if (result.size() == 0) {
370 rph_refs_.clear();
371 CleanUp();
372 } else {
373 RevokeOldGalleries(new_galleries);
374 }
385 375
386 callback.Run(result); 376 callback.Run(result);
387 } 377 }
388 378
389 void OnRendererProcessClosed(const RenderProcessHost* rph) { 379 void OnRendererProcessTerminated(const RenderProcessHost* rph) {
390 RenderProcessHostRefCount::const_iterator rph_info = rph_refs_.find(rph); 380 RenderProcessHostRefCount::const_iterator rph_info = rph_refs_.find(rph);
391 DCHECK(rph_info != rph_refs_.end()); 381 DCHECK(rph_info != rph_refs_.end());
392 // We're going to remove everything from the set, so we make a copy 382 // We're going to remove everything from the set, so we make a copy
393 // before operating on it. 383 // before operating on it.
394 std::set<const WebContents*> closed_web_contents = rph_info->second; 384 std::set<const WebContents*> closed_web_contents = rph_info->second;
395 DCHECK(!closed_web_contents.empty()); 385 DCHECK(!closed_web_contents.empty());
396 386
397 for (std::set<const WebContents*>::const_iterator it = 387 for (std::set<const WebContents*>::const_iterator it =
398 closed_web_contents.begin(); 388 closed_web_contents.begin();
399 it != closed_web_contents.end(); 389 it != closed_web_contents.end();
400 ++it) { 390 ++it) {
401 OnWebContentsDestroyedOrNavigated(*it); 391 OnWebContentsDestroyedOrNavigated(*it);
402 } 392 }
403 } 393 }
404 394
405 void OnWebContentsDestroyedOrNavigated(const WebContents* contents) { 395 void OnWebContentsDestroyedOrNavigated(const WebContents* contents) {
406 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 396 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
407 content::Source<WebContents>(contents)); 397 content::Source<WebContents>(contents));
408 registrar_.Remove( 398 registrar_.Remove(
409 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, 399 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
410 content::Source<NavigationController>(&contents->GetController())); 400 content::Source<NavigationController>(&contents->GetController()));
411 401
412 RenderProcessHost* rph = contents->GetRenderProcessHost(); 402 RenderProcessHost* rph = contents->GetRenderProcessHost();
413 RenderProcessHostRefCount::iterator process_refs = rph_refs_.find(rph); 403 RenderProcessHostRefCount::iterator process_refs = rph_refs_.find(rph);
414 DCHECK(process_refs != rph_refs_.end()); 404 DCHECK(process_refs != rph_refs_.end());
415 process_refs->second.erase(contents); 405 process_refs->second.erase(contents);
416 if (process_refs->second.empty()) { 406 if (process_refs->second.empty()) {
417 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 407 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
418 content::Source<RenderProcessHost>(rph)); 408 content::Source<RenderProcessHost>(rph));
419 rph_refs_.erase(process_refs); 409 rph_refs_.erase(process_refs);
420 } 410 }
421 411
422 if (rph_refs_.empty()) { 412 if (rph_refs_.empty())
423 for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin(); 413 CleanUp();
424 it != pref_id_map_.end(); 414 }
425 ++it) { 415
426 file_system_context_->RevokeFileSystem(it->second.fsid); 416 void CleanUp() {
427 } 417 DCHECK(rph_refs_.empty());
428 pref_id_map_.clear(); 418 for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin();
419 it != pref_id_map_.end();
420 ++it) {
421 file_system_context_->RevokeFileSystem(it->second.fsid);
422 }
423 pref_id_map_.clear();
429 424
430 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM) 425 #if defined(SUPPORT_MTP_DEVICE_FILESYSTEM)
431 media_device_map_references_.clear(); 426 media_device_map_references_.clear();
432 #endif 427 #endif
433 428
434 no_references_callback_.Run(); 429 registrar_.RemoveAll();
435 } 430
431 no_references_callback_.Run();
436 } 432 }
437 433
438 // MediaFileSystemRegistry owns |this| and |file_system_context_|, so it's 434 // MediaFileSystemRegistry owns |this| and |file_system_context_|, so it's
439 // safe to store a raw pointer. 435 // safe to store a raw pointer.
440 MediaFileSystemContext* file_system_context_; 436 MediaFileSystemContext* file_system_context_;
441 437
442 // A callback to call when the last RVH reference goes away. 438 // A callback to call when the last RVH reference goes away.
443 base::Closure no_references_callback_; 439 base::Closure no_references_callback_;
444 440
445 // A map from the gallery preferences id to the file system information. 441 // A map from the gallery preferences id to the file system information.
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 538
543 for (ExtensionGalleriesHostMap::iterator profile_it = 539 for (ExtensionGalleriesHostMap::iterator profile_it =
544 extension_hosts_map_.begin(); 540 extension_hosts_map_.begin();
545 profile_it != extension_hosts_map_.end(); 541 profile_it != extension_hosts_map_.end();
546 ++profile_it) { 542 ++profile_it) {
547 MediaGalleriesPreferences* preferences = GetPreferences(profile_it->first); 543 MediaGalleriesPreferences* preferences = GetPreferences(profile_it->first);
548 preferences->AddGallery(id, name, FilePath(), false /*not user added*/); 544 preferences->AddGallery(id, name, FilePath(), false /*not user added*/);
549 } 545 }
550 } 546 }
551 547
548 size_t MediaFileSystemRegistry::GetExtensionHostCountForTests() {
549 return extension_hosts_map_.size();
550 }
551
552 void MediaFileSystemRegistry::OnRemovableStorageDetached( 552 void MediaFileSystemRegistry::OnRemovableStorageDetached(
553 const std::string& id) { 553 const std::string& id) {
554 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 554 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
555 555
556 // Since revoking a gallery in the ExtensionGalleriesHost may cause it 556 // Since revoking a gallery in the ExtensionGalleriesHost may cause it
557 // to be removed from the map and therefore invalidate any iterator pointing 557 // to be removed from the map and therefore invalidate any iterator pointing
558 // to it, this code first copies all the invalid gallery ids and the 558 // to it, this code first copies all the invalid gallery ids and the
559 // extension hosts in which they may appear (per profile) and revoked it in 559 // extension hosts in which they may appear (per profile) and revoked it in
560 // a second step. 560 // a second step.
561 std::vector<InvalidatedGalleriesInfo> invalid_galleries_info; 561 std::vector<InvalidatedGalleriesInfo> invalid_galleries_info;
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 751
752 PrefChangeRegistrarMap::iterator pref_it = 752 PrefChangeRegistrarMap::iterator pref_it =
753 pref_change_registrar_map_.find(profile); 753 pref_change_registrar_map_.find(profile);
754 DCHECK(pref_it != pref_change_registrar_map_.end()); 754 DCHECK(pref_it != pref_change_registrar_map_.end());
755 delete pref_it->second; 755 delete pref_it->second;
756 pref_change_registrar_map_.erase(pref_it); 756 pref_change_registrar_map_.erase(pref_it);
757 } 757 }
758 } 758 }
759 759
760 } // namespace chrome 760 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698