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

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

Powered by Google App Engine
This is Rietveld 408576698