OLD | NEW |
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/path_service.h" | 11 #include "base/path_service.h" |
12 #include "base/sys_string_conversions.h" | |
13 #include "chrome/common/chrome_paths.h" | 12 #include "chrome/common/chrome_paths.h" |
14 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "content/public/browser/notification_source.h" |
| 15 #include "content/public/browser/notification_types.h" |
| 16 #include "content/public/browser/render_process_host.h" |
15 #include "webkit/fileapi/isolated_context.h" | 17 #include "webkit/fileapi/isolated_context.h" |
16 | 18 |
17 namespace chrome { | 19 namespace chrome { |
18 | 20 |
19 static base::LazyInstance<MediaFileSystemRegistry>::Leaky | 21 static base::LazyInstance<MediaFileSystemRegistry>::Leaky |
20 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER; | 22 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER; |
21 | 23 |
22 using content::BrowserThread; | 24 using content::BrowserThread; |
| 25 using content::RenderProcessHost; |
23 using fileapi::IsolatedContext; | 26 using fileapi::IsolatedContext; |
24 | 27 |
| 28 /****************** |
| 29 * Public methods |
| 30 ******************/ |
| 31 |
25 // static | 32 // static |
26 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() { | 33 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() { |
27 return g_media_file_system_registry.Pointer(); | 34 return g_media_file_system_registry.Pointer(); |
28 } | 35 } |
29 | 36 |
30 std::vector<MediaFileSystemRegistry::MediaFSIDAndPath> | 37 std::vector<MediaFileSystemRegistry::MediaFSIDAndPath> |
31 MediaFileSystemRegistry::GetMediaFileSystems() const { | 38 MediaFileSystemRegistry::GetMediaFileSystems( |
| 39 const content::RenderProcessHost* rph) { |
32 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 41 |
33 std::vector<MediaFSIDAndPath> results; | 42 std::vector<MediaFSIDAndPath> results; |
34 for (MediaPathToFSIDMap::const_iterator it = media_fs_map_.begin(); | 43 std::pair<ChildIdToMediaFSMap::iterator, bool> ret = |
35 it != media_fs_map_.end(); | 44 media_fs_map_.insert(std::make_pair(rph, MediaPathToFSIDMap())); |
| 45 ChildIdToMediaFSMap::iterator& child_it = ret.first; |
| 46 if (ret.second) { |
| 47 // Never seen a GetMediaFileSystems call from this RPH. Initialize its |
| 48 // file system mappings. |
| 49 RegisterForRPHGoneNotifications(rph); |
| 50 FilePath pictures_path; |
| 51 if (PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path)) { |
| 52 std::string fsid = RegisterPathAsFileSystem(pictures_path); |
| 53 child_it->second.insert(std::make_pair(pictures_path, fsid)); |
| 54 } |
| 55 } |
| 56 |
| 57 MediaPathToFSIDMap& child_map = child_it->second; |
| 58 for (MediaPathToFSIDMap::const_iterator it = child_map.begin(); |
| 59 it != child_map.end(); |
36 ++it) { | 60 ++it) { |
37 const FilePath path = it->first; | 61 const FilePath path = it->first; |
38 const std::string fsid = it->second; | 62 const std::string fsid = it->second; |
39 results.push_back(std::make_pair(fsid, path)); | 63 results.push_back(std::make_pair(fsid, path)); |
40 } | 64 } |
41 return results; | 65 return results; |
42 } | 66 } |
43 | 67 |
| 68 void MediaFileSystemRegistry::Observe( |
| 69 int type, |
| 70 const content::NotificationSource& source, |
| 71 const content::NotificationDetails& details) { |
| 72 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED || |
| 73 type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); |
| 74 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 75 const RenderProcessHost* rph = |
| 76 content::Source<content::RenderProcessHost>(source).ptr(); |
| 77 ChildIdToMediaFSMap::iterator child_it = media_fs_map_.find(rph); |
| 78 CHECK(child_it != media_fs_map_.end()); |
| 79 // No need to revoke the isolated file systems. The RPH will do that. |
| 80 media_fs_map_.erase(child_it); |
| 81 UnregisterForRPHGoneNotifications(rph); |
| 82 } |
| 83 |
| 84 /****************** |
| 85 * Private methods |
| 86 ******************/ |
| 87 |
44 MediaFileSystemRegistry::MediaFileSystemRegistry() { | 88 MediaFileSystemRegistry::MediaFileSystemRegistry() { |
45 FilePath pictures_path; | |
46 if (PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path)) { | |
47 RegisterPathAsFileSystem(pictures_path); | |
48 } | |
49 } | 89 } |
50 | 90 |
51 MediaFileSystemRegistry::~MediaFileSystemRegistry() { | 91 MediaFileSystemRegistry::~MediaFileSystemRegistry() { |
52 } | 92 } |
53 | 93 |
54 void MediaFileSystemRegistry::RegisterPathAsFileSystem(const FilePath& path) { | 94 void MediaFileSystemRegistry::RegisterForRPHGoneNotifications( |
| 95 const content::RenderProcessHost* rph) { |
| 96 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 97 content::Source<RenderProcessHost>(rph)); |
| 98 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 99 content::Source<RenderProcessHost>(rph)); |
| 100 } |
| 101 |
| 102 void MediaFileSystemRegistry::UnregisterForRPHGoneNotifications( |
| 103 const content::RenderProcessHost* rph) { |
| 104 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 105 content::Source<RenderProcessHost>(rph)); |
| 106 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 107 content::Source<RenderProcessHost>(rph)); |
| 108 } |
| 109 |
| 110 std::string MediaFileSystemRegistry::RegisterPathAsFileSystem( |
| 111 const FilePath& path) { |
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 112 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
56 | 113 |
57 // Sanity checks for |path|. | 114 // Sanity checks for |path|. |
58 CHECK(path.IsAbsolute()); | 115 CHECK(path.IsAbsolute()); |
59 CHECK(!path.ReferencesParent()); | 116 CHECK(!path.ReferencesParent()); |
60 // Make sure |path| does not refer to '/' on Unix. | 117 // Make sure |path| does not refer to '/' on Unix. |
61 // TODO(thestig) Check how BaseName() works for say, 'C:\' on Windows. | 118 // TODO(thestig) Check how BaseName() works for say, 'C:\' on Windows. |
62 CHECK(!path.BaseName().IsAbsolute()); | 119 CHECK(!path.BaseName().IsAbsolute()); |
63 CHECK(!path.BaseName().empty()); | 120 CHECK(!path.BaseName().empty()); |
64 | 121 |
65 std::set<FilePath> fileset; | 122 std::set<FilePath> fileset; |
66 fileset.insert(path); | 123 fileset.insert(path); |
67 const std::string fsid = | 124 const std::string fsid = |
68 IsolatedContext::GetInstance()->RegisterIsolatedFileSystem(fileset); | 125 IsolatedContext::GetInstance()->RegisterIsolatedFileSystem(fileset); |
69 CHECK(!fsid.empty()); | 126 CHECK(!fsid.empty()); |
70 media_fs_map_.insert(std::make_pair(path, fsid)); | 127 return fsid; |
71 } | 128 } |
72 | 129 |
73 } // namespace chrome | 130 } // namespace chrome |
OLD | NEW |