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

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: rebase 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 terminated a call
Lei Zhang 2014/01/09 22:49:48 s/terminated/destroyed/
Avi (use Gerrit) 2014/01/10 15:42:24 Done.
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);
89 RenderProcessHost* rph = contents->GetRenderProcessHost();
90 RPHReferenceState* state = NULL;
91 if (!ContainsKey(refs_, rph)) {
92 state = new RPHReferenceState;
93 refs_[rph] = state;
94 state->registrar.Add(
95 this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
96 content::Source<RenderProcessHost>(rph));
97 } else {
98 state = refs_[rph];
99 }
100
101 if (state->web_contents_set.insert(contents).second) {
102 state->registrar.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
103 content::Source<WebContents>(contents));
104 state->registrar.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
105 content::Source<NavigationController>(&contents->GetController()));
106 }
107 }
108 73
109 private: 74 private:
110 struct RPHReferenceState { 75 class RPHWebContentsObserver : public content::WebContentsObserver {
111 content::NotificationRegistrar registrar; 76 public:
112 std::set<const WebContents*> web_contents_set; 77 RPHWebContentsObserver(RPHReferenceManager* manager,
78 WebContents* web_contents);
79
80 private:
81 // content::WebContentsObserver
82 virtual void WebContentsDestroyed(WebContents* web_contents) OVERRIDE;
83 virtual void NavigationEntryCommitted(
84 const content::LoadCommittedDetails& load_details) OVERRIDE;
85
86 RPHReferenceManager* manager_;
113 }; 87 };
Lei Zhang 2014/01/09 22:49:48 nit: blank line between class decl
Avi (use Gerrit) 2014/01/10 15:42:24 Done.
114 typedef std::map<const RenderProcessHost*, RPHReferenceState*> RPHRefCount; 88 class RPHObserver : public content::RenderProcessHostObserver {
89 public:
90 RPHObserver(RPHReferenceManager* manager, RenderProcessHost* host);
91 virtual ~RPHObserver();
115 92
116 // NotificationObserver implementation. 93 void AddWebContentsObserver(WebContents* web_contents);
117 virtual void Observe(int type, 94 void RemoveWebContentsObserver(WebContents* web_contents);
118 const content::NotificationSource& source, 95 size_t ObserverCount() { return observed_web_contentses_.size(); }
Lei Zhang 2014/01/09 22:49:48 We only need to know if |observed_web_contentses_|
Avi (use Gerrit) 2014/01/10 15:42:24 Done.
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 96
149 void OnRendererProcessTerminated(const RenderProcessHost* rph) { 97 private:
150 RPHRefCount::iterator rph_info = refs_.find(rph); 98 virtual void RenderProcessHostDestroyed(RenderProcessHost* host) OVERRIDE;
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 99
159 delete rph_info->second; 100 RPHReferenceManager* manager_;
160 refs_.erase(rph_info); 101 RenderProcessHost* host_;
161 if (refs_.empty()) 102 typedef std::map<WebContents*, RPHWebContentsObserver*> WCObserverMap;
162 no_references_callback_.Run(); 103 WCObserverMap observed_web_contentses_;
163 } 104 };
105 typedef std::map<const RenderProcessHost*, RPHObserver*> RPHObserverMap;
164 106
165 void OnWebContentsDestroyedOrNavigated(const WebContents* contents) { 107 // Handlers for observed events.
166 RenderProcessHost* rph = contents->GetRenderProcessHost(); 108 void OnRenderProcessHostDestroyed(RenderProcessHost* rph);
167 RPHRefCount::iterator rph_info = refs_.find(rph); 109 void OnWebContentsDestroyedOrNavigated(WebContents* contents);
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 110
182 // A callback to call when the last RVH reference goes away. 111 // A callback to call when the last RVH reference goes away.
183 base::Closure no_references_callback_; 112 base::Closure no_references_callback_;
184 113
185 // The set of render processes and web contents that may have references to 114 // The set of render processes and web contents that may have references to
186 // the file system ids this instance manages. 115 // the file system ids this instance manages.
187 RPHRefCount refs_; 116 RPHObserverMap observer_map_;
188 }; 117 };
189 118
119 RPHReferenceManager::RPHReferenceManager(
120 const base::Closure& no_references_callback)
121 : no_references_callback_(no_references_callback) {
122 }
123
124 RPHReferenceManager::~RPHReferenceManager() {
125 Reset();
126 }
127
128 void RPHReferenceManager::ReferenceFromRVH(const content::RenderViewHost* rvh) {
129 WebContents* contents = WebContents::FromRenderViewHost(rvh);
130 RenderProcessHost* rph = contents->GetRenderProcessHost();
131 RPHObserver* state = NULL;
132 if (!ContainsKey(observer_map_, rph)) {
133 state = new RPHObserver(this, rph);
134 observer_map_[rph] = state;
135 } else {
136 state = observer_map_[rph];
137 }
138
139 state->AddWebContentsObserver(contents);
140 }
141
142 RPHReferenceManager::RPHWebContentsObserver::RPHWebContentsObserver(
143 RPHReferenceManager* manager,
144 WebContents* web_contents)
145 : content::WebContentsObserver(web_contents),
146 manager_(manager) {
147 }
148
149 void RPHReferenceManager::RPHWebContentsObserver::WebContentsDestroyed(
150 WebContents* web_contents) {
151 manager_->OnWebContentsDestroyedOrNavigated(web_contents);
152 }
153
154 void RPHReferenceManager::RPHWebContentsObserver::NavigationEntryCommitted(
155 const content::LoadCommittedDetails& load_details) {
156 if (load_details.is_in_page)
157 return;
158
159 manager_->OnWebContentsDestroyedOrNavigated(web_contents());
160 }
161
162 RPHReferenceManager::RPHObserver::RPHObserver(
163 RPHReferenceManager* manager, RenderProcessHost* host)
164 : manager_(manager),
165 host_(host) {
166 host->AddObserver(this);
167 }
168
169 RPHReferenceManager::RPHObserver::~RPHObserver() {
170 STLDeleteValues(&observed_web_contentses_);
171 if (host_)
172 host_->RemoveObserver(this);
173 }
174
175 void RPHReferenceManager::RPHObserver::AddWebContentsObserver(
176 WebContents* web_contents) {
177 if (observed_web_contentses_.find(web_contents)
Lei Zhang 2014/01/09 22:49:48 nit: ContainsKey()
178 != observed_web_contentses_.end()) {
179 return;
180 }
181
182 RPHWebContentsObserver* observer =
183 new RPHWebContentsObserver(manager_, web_contents);
184 observed_web_contentses_[web_contents] = observer;
185 }
186
187 void RPHReferenceManager::RPHObserver::RemoveWebContentsObserver(
188 WebContents* web_contents) {
189 WCObserverMap::iterator wco_iter =
190 observed_web_contentses_.find(web_contents);
191 DCHECK(wco_iter != observed_web_contentses_.end());
192 delete wco_iter->second;
193 observed_web_contentses_.erase(wco_iter);
194 }
195
196 void RPHReferenceManager::RPHObserver::RenderProcessHostDestroyed(
197 RenderProcessHost* host) {
198 host_ = NULL;
199 manager_->OnRenderProcessHostDestroyed(host);
200 }
201
202 void RPHReferenceManager::OnRenderProcessHostDestroyed(
203 RenderProcessHost* rph) {
204 RPHObserverMap::iterator rph_info = observer_map_.find(rph);
205 // This could be a potential problem if the RPH is navigated to a page on the
206 // same renderer (triggering OnWebContentsDestroyedOrNavigated()) and then the
207 // renderer crashes.
208 if (rph_info == observer_map_.end()) {
209 NOTREACHED();
210 return;
211 }
212 delete rph_info->second;
213 observer_map_.erase(rph_info);
214 if (observer_map_.empty())
215 no_references_callback_.Run();
216 }
217
218 void RPHReferenceManager::OnWebContentsDestroyedOrNavigated(
219 WebContents* contents) {
220 RenderProcessHost* rph = contents->GetRenderProcessHost();
221 RPHObserverMap::iterator rph_info = observer_map_.find(rph);
222 DCHECK(rph_info != observer_map_.end());
223
224 rph_info->second->RemoveWebContentsObserver(contents);
225 if (!rph_info->second->ObserverCount())
226 OnRenderProcessHostDestroyed(rph);
227 }
228
190 } // namespace 229 } // namespace
191 230
192 MediaFileSystemInfo::MediaFileSystemInfo(const base::string16& fs_name, 231 MediaFileSystemInfo::MediaFileSystemInfo(const base::string16& fs_name,
193 const base::FilePath& fs_path, 232 const base::FilePath& fs_path,
194 const std::string& filesystem_id, 233 const std::string& filesystem_id,
195 MediaGalleryPrefId pref_id, 234 MediaGalleryPrefId pref_id,
196 const std::string& transient_device_id, 235 const std::string& transient_device_id,
197 bool removable, 236 bool removable,
198 bool media_device) 237 bool media_device)
199 : name(fs_name), 238 : name(fs_name),
(...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after
683 DCHECK_EQ(1U, erase_count); 722 DCHECK_EQ(1U, erase_count);
684 if (extension_hosts->second.empty()) { 723 if (extension_hosts->second.empty()) {
685 // When a profile has no ExtensionGalleriesHosts left, remove the 724 // When a profile has no ExtensionGalleriesHosts left, remove the
686 // matching gallery-change-watcher since it is no longer needed. Leave the 725 // matching gallery-change-watcher since it is no longer needed. Leave the
687 // |extension_hosts| entry alone, since it indicates the profile has been 726 // |extension_hosts| entry alone, since it indicates the profile has been
688 // previously used. 727 // previously used.
689 MediaGalleriesPreferences* preferences = GetPreferences(profile); 728 MediaGalleriesPreferences* preferences = GetPreferences(profile);
690 preferences->RemoveGalleryChangeObserver(this); 729 preferences->RemoveGalleryChangeObserver(this);
691 } 730 }
692 } 731 }
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