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

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

Issue 129743003: Remove notifications from MediaFileSystemRegistry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: windows dislikes shortening to bool Created 6 years, 11 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
6
7 #include "chrome/browser/media_galleries/media_file_system_registry.h" 5 #include "chrome/browser/media_galleries/media_file_system_registry.h"
8 6
9 #include <set> 7 #include <set>
10 #include <vector> 8 #include <vector>
11 9
12 #include "base/bind.h" 10 #include "base/bind.h"
13 #include "base/callback.h" 11 #include "base/callback.h"
14 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
15 #include "base/prefs/pref_service.h" 13 #include "base/prefs/pref_service.h"
16 #include "base/stl_util.h" 14 #include "base/stl_util.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/extensions/extension_system.h" 16 #include "chrome/browser/extensions/extension_system.h"
20 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h" 17 #include "chrome/browser/media_galleries/fileapi/mtp_device_map_service.h"
21 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h" 18 #include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
22 #include "chrome/browser/media_galleries/media_file_system_context.h" 19 #include "chrome/browser/media_galleries/media_file_system_context.h"
23 #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h" 20 #include "chrome/browser/media_galleries/media_galleries_dialog_controller.h"
24 #include "chrome/browser/media_galleries/media_galleries_histograms.h" 21 #include "chrome/browser/media_galleries/media_galleries_histograms.h"
25 #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h" 22 #include "chrome/browser/media_galleries/media_galleries_preferences_factory.h"
26 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
27 #include "chrome/browser/storage_monitor/media_storage_util.h" 24 #include "chrome/browser/storage_monitor/media_storage_util.h"
28 #include "chrome/browser/storage_monitor/storage_monitor.h" 25 #include "chrome/browser/storage_monitor/storage_monitor.h"
29 #include "chrome/common/chrome_paths.h" 26 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/extensions/extension_constants.h" 27 #include "chrome/common/extensions/extension_constants.h"
31 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
32 #include "content/public/browser/browser_thread.h" 29 #include "content/public/browser/browser_thread.h"
33 #include "content/public/browser/navigation_details.h" 30 #include "content/public/browser/navigation_details.h"
34 #include "content/public/browser/notification_details.h"
35 #include "content/public/browser/notification_observer.h"
36 #include "content/public/browser/notification_registrar.h"
37 #include "content/public/browser/notification_source.h"
38 #include "content/public/browser/notification_types.h"
39 #include "content/public/browser/render_process_host.h" 31 #include "content/public/browser/render_process_host.h"
32 #include "content/public/browser/render_process_host_observer.h"
40 #include "content/public/browser/render_view_host.h" 33 #include "content/public/browser/render_view_host.h"
41 #include "content/public/browser/web_contents.h" 34 #include "content/public/browser/web_contents.h"
35 #include "content/public/browser/web_contents_observer.h"
42 #include "extensions/common/extension.h" 36 #include "extensions/common/extension.h"
43 #include "extensions/common/extension_set.h" 37 #include "extensions/common/extension_set.h"
44 #include "webkit/browser/fileapi/isolated_context.h" 38 #include "webkit/browser/fileapi/isolated_context.h"
45 #include "webkit/common/fileapi/file_system_types.h" 39 #include "webkit/common/fileapi/file_system_types.h"
46 40
47 using content::BrowserThread; 41 using content::BrowserThread;
48 using content::NavigationController; 42 using content::NavigationController;
49 using content::RenderProcessHost; 43 using content::RenderProcessHost;
50 using content::WebContents; 44 using content::WebContents;
51 using fileapi::IsolatedContext; 45 using fileapi::IsolatedContext;
52 46
53 namespace { 47 namespace {
54 48
55 struct InvalidatedGalleriesInfo { 49 struct InvalidatedGalleriesInfo {
56 std::set<ExtensionGalleriesHost*> extension_hosts; 50 std::set<ExtensionGalleriesHost*> extension_hosts;
57 std::set<MediaGalleryPrefId> pref_ids; 51 std::set<MediaGalleryPrefId> pref_ids;
58 }; 52 };
59 53
60 // Tracks the liveness of multiple RenderProcessHosts that the caller is 54 // Tracks the liveness of multiple RenderProcessHosts that the caller is
61 // interested in. Once all of the RPHs have closed or been terminated a call 55 // interested in. Once all of the RPHs have closed or been destroyed a call
62 // back informs the caller. 56 // back informs the caller.
63 class RPHReferenceManager : public content::NotificationObserver { 57 class RPHReferenceManager {
64 public: 58 public:
65 // |no_references_callback| is called when the last RenderViewHost reference 59 // |no_references_callback| is called when the last RenderViewHost reference
66 // goes away. RenderViewHost references are added through ReferenceFromRVH(). 60 // goes away. RenderViewHost references are added through ReferenceFromRVH().
67 explicit RPHReferenceManager(const base::Closure& no_references_callback) 61 explicit RPHReferenceManager(const base::Closure& no_references_callback);
68 : no_references_callback_(no_references_callback) { 62 virtual ~RPHReferenceManager();
69 }
70
71 virtual ~RPHReferenceManager() {
72 Reset();
73 }
74 63
75 // Remove all references, but don't call |no_references_callback|. 64 // Remove all references, but don't call |no_references_callback|.
76 void Reset() { 65 void Reset() { STLDeleteValues(&observer_map_); }
77 STLDeleteValues(&refs_);
78 }
79 66
80 // Returns true if there are no references; 67 // Returns true if there are no references;
81 bool empty() const { 68 bool empty() const { return observer_map_.empty(); }
82 return refs_.empty();
83 }
84 69
85 // Adds a reference to the passed |rvh|. Calling this multiple times with 70 // Adds a reference to the passed |rvh|. Calling this multiple times with
86 // the same |rvh| is a no-op. 71 // the same |rvh| is a no-op.
87 void ReferenceFromRVH(const content::RenderViewHost* rvh) { 72 void ReferenceFromRVH(const content::RenderViewHost* rvh);
88 WebContents* contents = WebContents::FromRenderViewHost(rvh); 73
89 RenderProcessHost* rph = contents->GetRenderProcessHost(); 74 private:
90 RPHReferenceState* state = NULL; 75 class RPHWebContentsObserver : public content::WebContentsObserver {
91 if (!ContainsKey(refs_, rph)) { 76 public:
92 state = new RPHReferenceState; 77 RPHWebContentsObserver(RPHReferenceManager* manager,
93 refs_[rph] = state; 78 WebContents* web_contents);
94 state->registrar.Add( 79
95 this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 80 private:
96 content::Source<RenderProcessHost>(rph)); 81 // content::WebContentsObserver
97 } else { 82 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
98 state = refs_[rph]; 83 virtual void NavigationEntryCommitted(
84 const content::LoadCommittedDetails& load_details) OVERRIDE;
85
86 RPHReferenceManager* manager_;
87 };
88
89 class RPHObserver : public content::RenderProcessHostObserver {
90 public:
91 RPHObserver(RPHReferenceManager* manager, RenderProcessHost* host);
92 virtual ~RPHObserver();
93
94 void AddWebContentsObserver(WebContents* web_contents);
95 void RemoveWebContentsObserver(WebContents* web_contents);
96 bool HasWebContentsObservers() {
97 return observed_web_contentses_.size() > 0;
99 } 98 }
100 99
101 if (state->web_contents_set.insert(contents).second) { 100 private:
102 state->registrar.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 101 virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE;
103 content::Source<WebContents>(contents));
104 state->registrar.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
105 content::Source<NavigationController>(&contents->GetController()));
106 }
107 }
108 102
109 private: 103 RPHReferenceManager* manager_;
110 struct RPHReferenceState { 104 RenderProcessHost* host_;
111 content::NotificationRegistrar registrar; 105 typedef std::map<WebContents*, RPHWebContentsObserver*> WCObserverMap;
112 std::set<const WebContents*> web_contents_set; 106 WCObserverMap observed_web_contentses_;
113 }; 107 };
114 typedef std::map<const RenderProcessHost*, RPHReferenceState*> RPHRefCount; 108 typedef std::map<const RenderProcessHost*, RPHObserver*> RPHObserverMap;
115 109
116 // NotificationObserver implementation. 110 // Handlers for observed events.
117 virtual void Observe(int type, 111 void OnRenderProcessHostDestroyed(RenderProcessHost* rph);
118 const content::NotificationSource& source, 112 void OnWebContentsDestroyedOrNavigated(WebContents* contents);
119 const content::NotificationDetails& details) OVERRIDE {
120 switch (type) {
121 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
122 OnRendererProcessTerminated(
123 content::Source<RenderProcessHost>(source).ptr());
124 break;
125 }
126 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
127 OnWebContentsDestroyedOrNavigated(
128 content::Source<WebContents>(source).ptr());
129 break;
130 }
131 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
132 content::LoadCommittedDetails* load_details =
133 content::Details<content::LoadCommittedDetails>(details).ptr();
134 if (load_details->is_in_page)
135 break;
136 NavigationController* controller =
137 content::Source<NavigationController>(source).ptr();
138 WebContents* contents = controller->GetWebContents();
139 OnWebContentsDestroyedOrNavigated(contents);
140 break;
141 }
142 default: {
143 NOTREACHED();
144 break;
145 }
146 }
147 }
148
149 void OnRendererProcessTerminated(const RenderProcessHost* rph) {
150 RPHRefCount::iterator rph_info = refs_.find(rph);
151 // This could be a potential problem if the RPH is navigated to
152 // a page on the same renderer (triggering OWCDON()) and then
153 // the renderer crashes.
154 if (rph_info == refs_.end()) {
155 NOTREACHED();
156 return;
157 }
158
159 delete rph_info->second;
160 refs_.erase(rph_info);
161 if (refs_.empty())
162 no_references_callback_.Run();
163 }
164
165 void OnWebContentsDestroyedOrNavigated(const WebContents* contents) {
166 RenderProcessHost* rph = contents->GetRenderProcessHost();
167 RPHRefCount::iterator rph_info = refs_.find(rph);
168 DCHECK(rph_info != refs_.end());
169
170 rph_info->second->registrar.Remove(
171 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
172 content::Source<WebContents>(contents));
173 rph_info->second->registrar.Remove(
174 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
175 content::Source<NavigationController>(&contents->GetController()));
176
177 rph_info->second->web_contents_set.erase(contents);
178 if (rph_info->second->web_contents_set.empty())
179 OnRendererProcessTerminated(rph);
180 }
181 113
182 // A callback to call when the last RVH reference goes away. 114 // A callback to call when the last RVH reference goes away.
183 base::Closure no_references_callback_; 115 base::Closure no_references_callback_;
184 116
185 // The set of render processes and web contents that may have references to 117 // The set of render processes and web contents that may have references to
186 // the file system ids this instance manages. 118 // the file system ids this instance manages.
187 RPHRefCount refs_; 119 RPHObserverMap observer_map_;
188 }; 120 };
189 121
122 RPHReferenceManager::RPHReferenceManager(
123 const base::Closure& no_references_callback)
124 : no_references_callback_(no_references_callback) {
125 }
126
127 RPHReferenceManager::~RPHReferenceManager() {
128 Reset();
129 }
130
131 void RPHReferenceManager::ReferenceFromRVH(const content::RenderViewHost* rvh) {
132 WebContents* contents = WebContents::FromRenderViewHost(rvh);
133 RenderProcessHost* rph = contents->GetRenderProcessHost();
134 RPHObserver* state = NULL;
135 if (!ContainsKey(observer_map_, rph)) {
136 state = new RPHObserver(this, rph);
137 observer_map_[rph] = state;
138 } else {
139 state = observer_map_[rph];
140 }
141
142 state->AddWebContentsObserver(contents);
143 }
144
145 RPHReferenceManager::RPHWebContentsObserver::RPHWebContentsObserver(
146 RPHReferenceManager* manager,
147 WebContents* web_contents)
148 : content::WebContentsObserver(web_contents),
149 manager_(manager) {
150 }
151
152 void RPHReferenceManager::RPHWebContentsObserver::WebContentsDestroyed(
153 WebContents* web_contents) {
154 manager_->OnWebContentsDestroyedOrNavigated(web_contents);
155 }
156
157 void RPHReferenceManager::RPHWebContentsObserver::NavigationEntryCommitted(
158 const content::LoadCommittedDetails& load_details) {
159 if (load_details.is_in_page)
160 return;
161
162 manager_->OnWebContentsDestroyedOrNavigated(web_contents());
163 }
164
165 RPHReferenceManager::RPHObserver::RPHObserver(
166 RPHReferenceManager* manager, RenderProcessHost* host)
167 : manager_(manager),
168 host_(host) {
169 host->AddObserver(this);
170 }
171
172 RPHReferenceManager::RPHObserver::~RPHObserver() {
173 STLDeleteValues(&observed_web_contentses_);
174 if (host_)
175 host_->RemoveObserver(this);
176 }
177
178 void RPHReferenceManager::RPHObserver::AddWebContentsObserver(
179 WebContents* web_contents) {
180 if (ContainsKey(observed_web_contentses_, web_contents))
181 return;
182
183 RPHWebContentsObserver* observer =
184 new RPHWebContentsObserver(manager_, web_contents);
185 observed_web_contentses_[web_contents] = observer;
186 }
187
188 void RPHReferenceManager::RPHObserver::RemoveWebContentsObserver(
189 WebContents* web_contents) {
190 WCObserverMap::iterator wco_iter =
191 observed_web_contentses_.find(web_contents);
192 DCHECK(wco_iter != observed_web_contentses_.end());
193 delete wco_iter->second;
194 observed_web_contentses_.erase(wco_iter);
195 }
196
197 void RPHReferenceManager::RPHObserver::RenderProcessHostDestroyed(
198 RenderProcessHost* host) {
199 host_ = NULL;
200 manager_->OnRenderProcessHostDestroyed(host);
201 }
202
203 void RPHReferenceManager::OnRenderProcessHostDestroyed(
204 RenderProcessHost* rph) {
205 RPHObserverMap::iterator rph_info = observer_map_.find(rph);
206 // This could be a potential problem if the RPH is navigated to a page on the
207 // same renderer (triggering OnWebContentsDestroyedOrNavigated()) and then the
208 // renderer crashes.
209 if (rph_info == observer_map_.end()) {
210 NOTREACHED();
211 return;
212 }
213 delete rph_info->second;
214 observer_map_.erase(rph_info);
215 if (observer_map_.empty())
216 no_references_callback_.Run();
217 }
218
219 void RPHReferenceManager::OnWebContentsDestroyedOrNavigated(
220 WebContents* contents) {
221 RenderProcessHost* rph = contents->GetRenderProcessHost();
222 RPHObserverMap::iterator rph_info = observer_map_.find(rph);
223 DCHECK(rph_info != observer_map_.end());
224
225 rph_info->second->RemoveWebContentsObserver(contents);
226 if (!rph_info->second->HasWebContentsObservers())
227 OnRenderProcessHostDestroyed(rph);
228 }
229
190 } // namespace 230 } // namespace
191 231
192 MediaFileSystemInfo::MediaFileSystemInfo(const base::string16& fs_name, 232 MediaFileSystemInfo::MediaFileSystemInfo(const base::string16& fs_name,
193 const base::FilePath& fs_path, 233 const base::FilePath& fs_path,
194 const std::string& filesystem_id, 234 const std::string& filesystem_id,
195 MediaGalleryPrefId pref_id, 235 MediaGalleryPrefId pref_id,
196 const std::string& transient_device_id, 236 const std::string& transient_device_id,
197 bool removable, 237 bool removable,
198 bool media_device) 238 bool media_device)
199 : name(fs_name), 239 : name(fs_name),
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 DCHECK_EQ(1U, erase_count); 723 DCHECK_EQ(1U, erase_count);
684 if (extension_hosts->second.empty()) { 724 if (extension_hosts->second.empty()) {
685 // When a profile has no ExtensionGalleriesHosts left, remove the 725 // When a profile has no ExtensionGalleriesHosts left, remove the
686 // matching gallery-change-watcher since it is no longer needed. Leave the 726 // matching gallery-change-watcher since it is no longer needed. Leave the
687 // |extension_hosts| entry alone, since it indicates the profile has been 727 // |extension_hosts| entry alone, since it indicates the profile has been
688 // previously used. 728 // previously used.
689 MediaGalleriesPreferences* preferences = GetPreferences(profile); 729 MediaGalleriesPreferences* preferences = GetPreferences(profile);
690 preferences->RemoveGalleryChangeObserver(this); 730 preferences->RemoveGalleryChangeObserver(this);
691 } 731 }
692 } 732 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698