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

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: 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 <set> 9 #include <set>
10 10
11 #include "base/file_path.h" 11 #include "base/file_path.h"
12 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/system_monitor/system_monitor.h" 13 #include "base/system_monitor/system_monitor.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "chrome/browser/media_gallery/media_storage_util.h" 15 #include "chrome/browser/media_gallery/media_storage_util.h"
16 #include "chrome/common/chrome_paths.h" 16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/common/extensions/extension_constants.h" 17 #include "chrome/common/extensions/extension_constants.h"
18 #include "chrome/common/extensions/extension.h" 18 #include "chrome/common/extensions/extension.h"
19 #include "content/public/browser/browser_thread.h" 19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/notification_source.h" 20 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/notification_types.h" 21 #include "content/public/browser/notification_types.h"
22 #include "content/public/browser/render_process_host.h" 22 #include "content/public/browser/render_process_host.h"
23 #include "webkit/fileapi/file_system_types.h" 23 #include "webkit/fileapi/file_system_types.h"
24 #include "webkit/fileapi/isolated_context.h" 24 #include "webkit/fileapi/isolated_context.h"
25 #include "webkit/fileapi/media/media_file_system_config.h" 25 #include "webkit/fileapi/media/media_file_system_config.h"
26 26
27 #if defined(SUPPORT_MEDIA_FILESYSTEM) 27 #if defined(SUPPORT_MEDIA_FILESYSTEM)
28 #include "webkit/fileapi/media/media_device_map_service.h" 28 #include "webkit/fileapi/media/media_device_map_service.h"
29
30 using fileapi::MediaDeviceMapService;
31 #endif 29 #endif
32 30
33 namespace chrome { 31 namespace chrome {
34 32
35 static base::LazyInstance<MediaFileSystemRegistry>::Leaky 33 static base::LazyInstance<MediaFileSystemRegistry>::Leaky
36 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER; 34 g_media_file_system_registry = LAZY_INSTANCE_INITIALIZER;
37 35
38 using base::SystemMonitor; 36 using base::SystemMonitor;
39 using content::BrowserThread; 37 using content::BrowserThread;
40 using content::RenderProcessHost; 38 using content::RenderProcessHost;
41 using fileapi::IsolatedContext; 39 using fileapi::IsolatedContext;
42 40
43 namespace { 41 namespace {
44 42
45 bool IsGalleryPermittedForExtension(const extensions::Extension& extension, 43 FilePath DeviceIdToPath(std::string device_id) {
46 const FilePath::StringType& location) { 44 // TODO(vandebo) This needs to be cleaned up. We need a device manager
47 if (extension.HasAPIPermission( 45 // type class that will handle this kind of thing. Right now
48 extensions::APIPermission::kMediaGalleriesAllGalleries)) { 46 // MediaFileSystemRegistry::GetDeviceIdFromPath just turns the path into
49 return true; 47 // a string, so for now we can just go the other way.
50 } 48 return FilePath(device_id);
51 // TODO(vandebo) Check with prefs for permission to this gallery.
52 return false;
53 } 49 }
54 50
51 std::string MediaFileSystemRegistry::RegisterPathAsFileSystem(
52 const SystemMonitor::MediaDeviceType& device_type,
53 std::string device_id,
54 const FilePath& relative_path) {
55 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
56
57
58 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
59 if (device_type == SystemMonitor::TYPE_PATH) {
60 FilePath path = DeviceIdToPath(device_id).Append(relative_path);
61 // Sanity checks for |path|.
62 CHECK(path.IsAbsolute());
63 CHECK(!path.ReferencesParent());
64 const std::string fsid = isolated_context->RegisterFileSystemForPath(
65 fileapi::kFileSystemTypeNativeMedia,
66 path,
67 extension_misc::kMediaFileSystemPathPart);
68 CHECK(!fsid.empty());
69 return fsid;
70 }
71
72 // TODO(vandebo) handle device_type == case SystemMonitor::TYPE_MTP.
73 NOTREACHED();
74 return std::string();
75 }
76
77 class ExtensionGalleriesHost : public content::NotificationObserver {
78 public:
79 typedef base::Callback<void(void)> NoReferenecesCallback;
80
81 explicit ExtensionGalleriesHost(const NoReferencesCallback& callback)
82 : callback_(callback) {
83 }
84 virtual ~ExtensionGalleriesHost() {
85 DCHECK(rph_refs_.empty());
86 DCHECK(pref_id_map_.empty());
87 }
88
89 // Lookup the galleries for this extension, turn those into file system ids
90 // and return the information needed for the renderer to create those file
91 // system objects.
92 std::vector<MediaFSInfo> GetMediaFileSystems(
93 const MediaGalleryPrefIdSet& galleries,
94 const MediaGalleriesPrefInfoMap& galleries_info) {
95 std::vector<MediaFSInfo> result;
96 for (std::set<MediaGalleryPrefId>::const_iterator id = galleries.begin();
97 id != galleries.end();
98 ++id) {
99 PrefIdFsInfoMap::const_iterator existing_info = pref_id_map_.find(id);
100 if (existing_info != pref_id_map_.end()) {
101 result.append(*existing_info);
102 continue;
103 }
104 // TODO(vandebo): For MTP, path is empty.
105 MediaFsInfo new_entry;
106 new_entry.name = galleries_info[*id].display_name;
107 new_entry.path = FilePath path = DeviceIdToPath(
108 galleries_info[*id].device_id).Append(galleries_info[*id].path);
109 // TODO(vandebo): Get type out of galleries_info.
110 new_entry.fsid = RegisterPathAsFileSystem(SystemMonitor::TYPE_PATH,
111 galleries_info[*id].device_id,
112 galleries_info[*id].path);
113 result.append(new_entry);
114 pref_id_map_[pref_id] = new_entry;
115 }
116 return result;
117 }
118
119 // If this extension has created a file system id for the given gallery
120 // then revoke it.
121 void RevokeGalleryByPrefId(MediaGalleryPrefId id) {
122 PrefIdFsInfoMap::iterator gallery = pref_id_map_.find(id);
123 if (gallery == pref_id_map_.end())
124 return;
125
126 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
127 isolated_context->RevokeFileSystem(gallery->fsid);
128
129 pref_id_map_.erase(gallery);
130 }
131
132 // Indicate that the passed render process will reference the file system
133 // ids created by this class. It is safe to call this multiple times with
134 // the same RVH.
135 void ReferenceFromRVH(const content::RenderViewHost* rvh) {
136 WebContents* contents = WebContents::FromRenderViewHost(rvh);
137 if (registrar_.IsRegistered(this,
138 content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
139 content::Source<WebContents>(contents))) {
140 return;
141 }
142 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
143 content::Source<WebContents>(contents));
144 registrar_.Add(
145 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
146 content::Source<NavigationController>(&contents->GetController()));
147
148 content::RenderProcessHost* rph = contents->GetRenderProcessHost();
149 rph_refs_[rph].insert(contents);
150 if (rph_refs[rph].size() == 1) {
151 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
152 content::Source<content::RenderProcessHost>(rph));
153 }
154 }
155
156 // NotificationObserver implementation.
157 virtual void Observe(int type,
158 const NotificationSource& source,
159 const NotificationDetails& details) {
160 switch (type) {
161 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: {
162 OnRendererProcessClosed(
163 content::Source<content::RenderProcessHost>(source).ptr());
164 break;
165 }
166 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
167 OnWebContentsDestroyedOrNavigated(
168 content::Source<WebContents>(source).ptr());
169 break;
170 }
171 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
172 NavigationController* controller =
173 content::Source<NavigationController>(source).ptr();
174 WebContents* contents = controller->GetWebContents();
175 OnWebContentsDestroyedOrNavigated(contents);
176 break;
177 }
178 default: {
179 NOTREACHED();
180 break;
181 }
182 }
183 }
184
185 private:
186 typedef std::map<MediaGalleriesPrefId, MediaFSInfo> PrefIdFsInfoMap;
187 typedef std::map<const content::RenderProcessHost*,
188 std::set<const WebContent*> > RenderProcessHostRefCount;
189
190 void OnRendererProcessClosed(const contents::RenderProcessHost* rph) {
191 std::set<const Content*> dead_rvhs = rph_refs_[rph];
192 DCHECK(!dead_rvhs.empty());
193
194 for (std::set<const Content*>::const_iterator it = dead_rvhs.begin();
195 it != dead_rvhs.end();
196 ++it) {
197 OnWebContentsDestroyedOrNavigated(*it);
198 }
199 DCHECK(rph_refs_.find(rph) == rph_refs_.end());
200 }
201
202 void OnWebContentsDestroyedOrNavigated(const WebContents* contents) {
203 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
204 content::Source<WebContents>(contents));
205 registrar_.Remove(
206 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
207 content::Source<NavigationController>(&contents->GetController()));
208
209 content::RenderProcessHost* rph = contents->GetRenderProcessHost();
210 rph_refs_[rph].erase(contents);
211 if (rph_refs_[rph].empty()) {
212 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
213 content::Source<content::RenderProcessHost>(rph));
214 rph_refs_.erase(rph);
215 }
216
217 if (rph_refs_.empty()) {
218 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
219 for (PrefIdFsInfoMap::const_iterator it = pref_id_map_.begin();
220 it != pref_id_map_.end();
221 ++it) {
222 isolated_context->RevokeFileSystem(it->fsid);
223 }
224 pref_id_map_.clear();
225 callback_.Run();
226 }
227 }
228
229 // A callback to call when the last RVH reference goes away.
230 const NoReferencesCallback& callback_;
231
232 // A map from the gallery preferences id to the file system id.
233 PrefIdFsInfoMap pref_id_map_;
234
235 // The set of render processes and web contents that may have references to
236 // the file system ids this instance manages.
237 RenderProcessHostRefCount rph_refs_;
238
239 // A registrar for listening notifications.
240 content::NotificationRegistrar registrar_;
241
242 DISALLOW_COPY_AND_ASSIGN(ExtensionGalleriesHost);
243 };
244
55 } // namespace 245 } // namespace
56 246
57 247
58 /****************** 248 /******************
59 * Public methods 249 * Public methods
60 ******************/ 250 ******************/
61 251
62 // static 252 // static
63 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() { 253 MediaFileSystemRegistry* MediaFileSystemRegistry::GetInstance() {
64 return g_media_file_system_registry.Pointer(); 254 return g_media_file_system_registry.Pointer();
65 } 255 }
66 256
67 std::vector<MediaFileSystemRegistry::MediaFSInfo> 257 std::vector<MediaFileSystemRegistry::MediaFSInfo>
68 MediaFileSystemRegistry::GetMediaFileSystemsForExtension( 258 MediaFileSystemRegistry::GetMediaFileSystemsForExtension(
69 const content::RenderProcessHost* rph, 259 const content::RenderViewHost* rvh,
70 const extensions::Extension& extension) { 260 const extensions::Extension* extension) {
71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
72 262
73 std::vector<MediaFSInfo> results; 263 Profile* profile =
74 std::pair<ChildIdToMediaFSMap::iterator, bool> ret = 264 Profile::FromBrowserContext(rvh->GetProcess()->GetBrowserContext());
75 media_fs_map_.insert(std::make_pair(rph, MediaPathToFSIDMap())); 265 MediaGalleriesPreferences* preferences =
76 ChildIdToMediaFSMap::iterator& child_it = ret.first; 266 MediaGalleriesPreferencesFactory::GetForProfile(profile);
77 if (ret.second) { 267 MediaGalleryPrefIdSet galleries =
78 // Never seen a GetMediaFileSystems call from this RPH. Initialize its 268 preferences->GalleriesForExtension(extension);
79 // file system mappings. 269 if (galleries.empty())
80 RegisterForRPHGoneNotifications(rph); 270 return std::vector<MediaFileSystemRegistry::MediaFSInfo>();
81 FilePath pictures_path; 271
82 // TODO(vandebo) file system galleries need a unique id as well. 272 ExtensionGalleriesHost* extension_host =
83 if (PathService::Get(chrome::DIR_USER_PICTURES, &pictures_path) && 273 extension_host_map[profile][extension].get();
84 IsGalleryPermittedForExtension(extension, pictures_path.value())) { 274 if (!extension_host) {
85 std::string fsid = RegisterPathAsFileSystem(pictures_path); 275 extension_host_map_[profile][extension].reset(new ExtensionGalleriesHost(
86 child_it->second.insert(std::make_pair(pictures_path, fsid)); 276 *extension,
87 } 277 base::Bind(&MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty,
278 base::Unretained(this), profile, extension)));
279 extension_host = extension_host_map[profile][extension].get();
88 } 280 }
281 extension_host->ReferenceFromRVH(rvh);
89 282
90 // TODO(thestig) Handle overlap between devices and media directories. 283 return extension_host->GetMediaFileSystems(galleries,
91 SystemMonitor* monitor = SystemMonitor::Get(); 284 preferences->known_galleries());
92 const std::vector<SystemMonitor::MediaDeviceInfo> media_devices =
93 monitor->GetAttachedMediaDevices();
94 for (size_t i = 0; i < media_devices.size(); ++i) {
95 MediaStorageUtil::Type type;
96 MediaStorageUtil::CrackDeviceId(media_devices[i].unique_id, &type, NULL);
97 // TODO(vandebo) Handle MTP devices.
98 if (type != MediaStorageUtil::USB_MTP &&
99 IsGalleryPermittedForExtension(extension, media_devices[i].location)) {
100 device_id_map_.insert(std::make_pair(media_devices[i].unique_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 } 285 }
121 286
122 void MediaFileSystemRegistry::OnMediaDeviceDetached(const std::string& id) { 287 void MediaFileSystemRegistry::OnMediaDeviceDetached(const std::string& id) {
123 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 288 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
124 289
125 DeviceIdToInfoMap::iterator it = device_id_map_.find(id); 290 // Since revoking a gallery in the ExtensionGalleriesHost may cause it
126 if (it == device_id_map_.end()) 291 // to be removed from the map and therefore invalidate any iterator pointing
127 return; 292 // to it, we first make a list of all the ExtensionGalleriesHost*, pref_id
293 // pairs to invalidate and then invalidate them in a second step.
294 struct InvalidatedGallery {
295 ExtensionGalleriesHost* extension_host;
296 MediaGalleriesPrefId pref_id;
297 };
298 std::vector<InvalidatedGallery> invalidated_galleries;
128 299
129 FilePath path(it->second.location); 300 for (ExtensionGalleriesHostMap::const_iterator extension_host_map =
130 RevokeMediaFileSystem(path); 301 extension_host_map_.begin();
131 device_id_map_.erase(it); 302 extension_host_map != extension_host_map_.end();
132 } 303 ++extension_host_map) {
304 MediaGalleriesPreferences* preferences =
305 MediaGalleriesPreferencesFactory::GetForProfile(
306 extension_host_map.first);
307 MediaGalleryPrefIdSet detached_galleries =
308 preferences->LookUpGalleriesByDeviceId(id);
309 for (ExtensionHostMap::const_iterator extension_host =
310 extension_host_map.second.begin();
311 extension_host_map.second.end();
312 ++extension_host) {
313 for (MediaGalleryPrefIdSet::const_iterator pref_id =
314 detached_galleries.begin();
315 pref_id != detached_galleries.end();
316 ++pref_id) {
317 InvalidatedGallery gallery;
318 gallery.extension_host = extesion_host.second.get();
319 gallery.pref_id = *pref_id;
320 invalidated_galleries.push_back(gallery);
321 }
322 }
323 }
133 324
134 void MediaFileSystemRegistry::Observe( 325 for (std::vector<InvalidatedGallery>::const_iterator it =
135 int type, 326 invalidated_galleries.begin();
136 const content::NotificationSource& source, 327 it != invalidated_galleries.end();
137 const content::NotificationDetails& details) { 328 ++it) {
138 DCHECK(type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED || 329 it->extension_host->RevokeGalleryByPrefId(it->pref_id);
139 type == content::NOTIFICATION_RENDERER_PROCESS_TERMINATED); 330 }
140 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 331
141 const RenderProcessHost* rph = 332 // TODO(kmadhusu, vandebo): Clean up this code. http://crbug.com/140340.
142 content::Source<content::RenderProcessHost>(source).ptr(); 333 // FIXME - from the device id, we need the device location.
143 ChildIdToMediaFSMap::iterator child_it = media_fs_map_.find(rph); 334 #if defined(SUPPORT_MEDIA_FILESYSTEM)
144 CHECK(child_it != media_fs_map_.end()); 335 //fileapi::MediaDeviceMapService::GetInstance()->RemoveMediaDevice(
145 // No need to revoke the isolated file systems. The RPH will do that. 336 // device_location);
146 media_fs_map_.erase(child_it); 337 #endif
147 UnregisterForRPHGoneNotifications(rph);
148 } 338 }
149 339
150 std::string MediaFileSystemRegistry::GetDeviceIdFromPath( 340 std::string MediaFileSystemRegistry::GetDeviceIdFromPath(
151 const FilePath& path) const { 341 const FilePath& path) const {
152 // TODO(vandebo) Do something better here, at least iterate system monitor 342 // TODO(vandebo) Do something better here, at least iterate system monitor
153 // attached media devices looking for a match. If not, return the path. 343 // attached media devices looking for a match. If not, return the path.
154 return path.AsUTF8Unsafe(); 344 return path.AsUTF8Unsafe();
155 } 345 }
156 346
157 /****************** 347 /******************
158 * Private methods 348 * Private methods
159 ******************/ 349 ******************/
160 350
161 MediaFileSystemRegistry::MediaFileSystemRegistry() { 351 MediaFileSystemRegistry::MediaFileSystemRegistry() {
162 // SystemMonitor may be NULL in unit tests. 352 // SystemMonitor may be NULL in unit tests.
163 SystemMonitor* system_monitor = SystemMonitor::Get(); 353 SystemMonitor* system_monitor = SystemMonitor::Get();
164 if (system_monitor) 354 if (system_monitor)
165 system_monitor->AddDevicesChangedObserver(this); 355 system_monitor->AddDevicesChangedObserver(this);
166 } 356 }
167 357
168 MediaFileSystemRegistry::~MediaFileSystemRegistry() { 358 MediaFileSystemRegistry::~MediaFileSystemRegistry() {
169 // SystemMonitor may be NULL in unit tests. 359 // SystemMonitor may be NULL in unit tests.
170 SystemMonitor* system_monitor = SystemMonitor::Get(); 360 SystemMonitor* system_monitor = SystemMonitor::Get();
171 if (system_monitor) 361 if (system_monitor)
172 system_monitor->RemoveDevicesChangedObserver(this); 362 system_monitor->RemoveDevicesChangedObserver(this);
173 } 363 }
174 364
175 void MediaFileSystemRegistry::RegisterForRPHGoneNotifications( 365 void MediaFileSystemRegistry::OnExtensionGalleriesHostEmpty(
176 const content::RenderProcessHost* rph) { 366 const Profile* profile,
177 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 367 const extensions::Extension* extension) {
178 content::Source<RenderProcessHost>(rph)); 368 ExtensionHostMap extension_hosts = extension_host_map_[profile];
179 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 369 DCHECK(!extension_hosts.empty());
180 content::Source<RenderProcessHost>(rph)); 370 ExtensionHostMap::size_type erase_count = extension_hosts.erase(extension);
181 } 371 DCHECK_EQ(1, erase_count);
182 372 if (extension_hosts.empty())
183 void MediaFileSystemRegistry::UnregisterForRPHGoneNotifications( 373 extension_host_map_.erase(profile);
184 const content::RenderProcessHost* rph) {
185 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
186 content::Source<RenderProcessHost>(rph));
187 registrar_.Remove(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
188 content::Source<RenderProcessHost>(rph));
189 }
190
191 std::string MediaFileSystemRegistry::RegisterPathAsFileSystem(
192 const FilePath& path) {
193 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
194
195 // Sanity checks for |path|.
196 CHECK(path.IsAbsolute());
197 CHECK(!path.ReferencesParent());
198
199 // The directory name is not exposed to the js layer and we simply use
200 // a fixed name (as we only register a single directory per file system).
201 std::string register_name(extension_misc::kMediaFileSystemPathPart);
202 const std::string fsid =
203 IsolatedContext::GetInstance()->RegisterFileSystemForPath(
204 fileapi::kFileSystemTypeNativeMedia, path, &register_name);
205 CHECK(!fsid.empty());
206 return fsid;
207 }
208
209 void MediaFileSystemRegistry::RevokeMediaFileSystem(const FilePath& path) {
210 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
211
212 IsolatedContext* isolated_context = IsolatedContext::GetInstance();
213 isolated_context->RevokeFileSystemByPath(path);
214
215 for (ChildIdToMediaFSMap::iterator child_it = media_fs_map_.begin();
216 child_it != media_fs_map_.end();
217 ++child_it) {
218 MediaPathToFSIDMap& child_map = child_it->second;
219 MediaPathToFSIDMap::iterator media_path_it = child_map.find(path);
220 if (media_path_it == child_map.end())
221 continue;
222
223 child_map.erase(media_path_it);
224 }
225 } 374 }
226 375
227 } // namespace chrome 376 } // namespace chrome
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698