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 ChildIdToMediaFSMap::iterator child_it = media_fs_map_.find(rph); |
kinuko
2012/06/11 12:21:06
Can we simply call insert() here and check the sec
Lei Zhang
2012/06/11 19:59:07
Done.
| |
35 it != media_fs_map_.end(); | 44 if (child_it == media_fs_map_.end()) { |
45 // Never seen a GetMediaFileSystems call from this RPH. Initialize its | |
46 // file system mappings. | |
47 RegisterForRPHGoneNotifications(rph); | |
48 child_it = media_fs_map_.insert(child_it, | |
49 std::make_pair(rph, MediaPathToFSIDMap())); | |
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)); | |
kinuko
2012/06/11 12:21:06
nit:
child_it->second[pictures_path] = fsid;
might
Lei Zhang
2012/06/11 19:59:07
Yes, but "foo[bar] = qux" is less efficient. My C+
kinuko
2012/06/12 04:40:11
Ok, in chromium review I was once told I should us
| |
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 |