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

Side by Side Diff: chrome/browser/notifications/message_center_settings_controller.cc

Issue 19699014: Crash on message center settings change fixed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 5 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 | « chrome/browser/notifications/message_center_settings_controller.h ('k') | 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) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 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 #include "chrome/browser/notifications/message_center_settings_controller.h" 5 #include "chrome/browser/notifications/message_center_settings_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/i18n/string_compare.h" 10 #include "base/i18n/string_compare.h"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/app_icon_loader_impl.h" 13 #include "chrome/browser/extensions/app_icon_loader_impl.h"
13 #include "chrome/browser/extensions/extension_service.h" 14 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/favicon/favicon_service.h" 15 #include "chrome/browser/favicon/favicon_service.h"
15 #include "chrome/browser/favicon/favicon_service_factory.h" 16 #include "chrome/browser/favicon/favicon_service_factory.h"
16 #include "chrome/browser/history/history_types.h" 17 #include "chrome/browser/history/history_types.h"
17 #include "chrome/browser/notifications/desktop_notification_service.h" 18 #include "chrome/browser/notifications/desktop_notification_service.h"
18 #include "chrome/browser/notifications/desktop_notification_service_factory.h" 19 #include "chrome/browser/notifications/desktop_notification_service_factory.h"
19 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h" 20 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service.h"
20 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_fac tory.h" 21 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_service_fac tory.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/browser/profiles/profile_manager.h" 22 #include "chrome/browser/profiles/profile_manager.h"
23 #include "chrome/common/cancelable_task_tracker.h" 23 #include "chrome/common/cancelable_task_tracker.h"
24 #include "chrome/common/extensions/extension_constants.h" 24 #include "chrome/common/extensions/extension_constants.h"
25 #include "chrome/common/favicon/favicon_types.h" 25 #include "chrome/common/favicon/favicon_types.h"
26 #include "content/public/browser/notification_service.h"
27 #include "content/public/browser/notification_source.h"
26 #include "grit/theme_resources.h" 28 #include "grit/theme_resources.h"
27 #include "grit/ui_strings.h" 29 #include "grit/ui_strings.h"
28 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/resource/resource_bundle.h" 31 #include "ui/base/resource/resource_bundle.h"
30 #include "ui/gfx/image/image.h" 32 #include "ui/gfx/image/image.h"
31 #include "ui/message_center/message_center_style.h" 33 #include "ui/message_center/message_center_style.h"
32 34
33 #if defined(USE_ASH) 35 #if defined(USE_ASH)
34 #include "ash/shell.h" 36 #include "ash/shell.h"
35 #include "ash/system/web_notification/web_notification_tray.h" 37 #include "ash/system/web_notification/web_notification_tray.h"
(...skipping 16 matching lines...) Expand all
52 private: 54 private:
53 icu::Collator* collator_; 55 icu::Collator* collator_;
54 }; 56 };
55 57
56 bool SimpleCompareNotifiers(Notifier* n1, Notifier* n2) { 58 bool SimpleCompareNotifiers(Notifier* n1, Notifier* n2) {
57 return n1->name < n2->name; 59 return n1->name < n2->name;
58 } 60 }
59 61
60 } // namespace 62 } // namespace
61 63
62 MessageCenterSettingsController::MessageCenterSettingsController() { 64 MessageCenterSettingsController::MessageCenterSettingsController()
65 : profile_(NULL) {
66 // We set the profile associated with the settings at the beginning and fail
67 // silently if this profile is destroyed later. This is a temporary fix for
68 // http://crbug.com/263193
69 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
70 content::NotificationService::AllSources());
63 } 71 }
64 72
65 MessageCenterSettingsController::~MessageCenterSettingsController() { 73 MessageCenterSettingsController::~MessageCenterSettingsController() {
66 } 74 }
67 75
68 void MessageCenterSettingsController::AddObserver( 76 void MessageCenterSettingsController::AddObserver(
69 message_center::NotifierSettingsObserver* observer) { 77 message_center::NotifierSettingsObserver* observer) {
70 observers_.AddObserver(observer); 78 observers_.AddObserver(observer);
71 } 79 }
72 80
73 void MessageCenterSettingsController::RemoveObserver( 81 void MessageCenterSettingsController::RemoveObserver(
74 message_center::NotifierSettingsObserver* observer) { 82 message_center::NotifierSettingsObserver* observer) {
75 observers_.RemoveObserver(observer); 83 observers_.RemoveObserver(observer);
76 } 84 }
77 85
78 void MessageCenterSettingsController::GetNotifierList( 86 void MessageCenterSettingsController::GetNotifierList(
79 std::vector<Notifier*>* notifiers) { 87 std::vector<Notifier*>* notifiers) {
80 DCHECK(notifiers); 88 DCHECK(notifiers);
81 // TODO(mukai): Fix this for multi-profile. 89 // TODO(mukai): Fix this for multi-profile.
82 // Temporarily use the last used profile to prevent chrome from crashing when 90 // Temporarily use the last used profile to prevent chrome from crashing when
83 // the default profile is not loaded. 91 // the default profile is not loaded.
84 Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy(); 92 profile_ = ProfileManager::GetLastUsedProfileAllowedByPolicy();
85 DesktopNotificationService* notification_service = 93 DesktopNotificationService* notification_service =
86 DesktopNotificationServiceFactory::GetForProfile(profile); 94 DesktopNotificationServiceFactory::GetForProfile(profile_);
87 95
88 UErrorCode error; 96 UErrorCode error;
89 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); 97 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(error));
90 scoped_ptr<NotifierComparator> comparator; 98 scoped_ptr<NotifierComparator> comparator;
91 if (!U_FAILURE(error)) 99 if (!U_FAILURE(error))
92 comparator.reset(new NotifierComparator(collator.get())); 100 comparator.reset(new NotifierComparator(collator.get()));
93 101
94 ExtensionService* extension_service = profile->GetExtensionService(); 102 ExtensionService* extension_service = profile_->GetExtensionService();
95 const ExtensionSet* extension_set = extension_service->extensions(); 103 const ExtensionSet* extension_set = extension_service->extensions();
96 // The extension icon size has to be 32x32 at least to load bigger icons if 104 // The extension icon size has to be 32x32 at least to load bigger icons if
97 // the icon doesn't exist for the specified size, and in that case it falls 105 // the icon doesn't exist for the specified size, and in that case it falls
98 // back to the default icon. The fetched icon will be resized in the settings 106 // back to the default icon. The fetched icon will be resized in the settings
99 // dialog. See chrome/browser/extensions/extension_icon_image.cc and 107 // dialog. See chrome/browser/extensions/extension_icon_image.cc and
100 // crbug.com/222931 108 // crbug.com/222931
101 app_icon_loader_.reset(new extensions::AppIconLoaderImpl( 109 app_icon_loader_.reset(new extensions::AppIconLoaderImpl(
102 profile, extension_misc::EXTENSION_ICON_SMALL, this)); 110 profile_, extension_misc::EXTENSION_ICON_SMALL, this));
103 for (ExtensionSet::const_iterator iter = extension_set->begin(); 111 for (ExtensionSet::const_iterator iter = extension_set->begin();
104 iter != extension_set->end(); ++iter) { 112 iter != extension_set->end(); ++iter) {
105 const extensions::Extension* extension = iter->get(); 113 const extensions::Extension* extension = iter->get();
106 if (!extension->HasAPIPermission( 114 if (!extension->HasAPIPermission(
107 extensions::APIPermission::kNotification)) { 115 extensions::APIPermission::kNotification)) {
108 continue; 116 continue;
109 } 117 }
110 118
111 NotifierId notifier_id(NotifierId::APPLICATION, extension->id()); 119 NotifierId notifier_id(NotifierId::APPLICATION, extension->id());
112 notifiers->push_back(new Notifier( 120 notifiers->push_back(new Notifier(
113 notifier_id, 121 notifier_id,
114 UTF8ToUTF16(extension->name()), 122 UTF8ToUTF16(extension->name()),
115 notification_service->IsNotifierEnabled(notifier_id))); 123 notification_service->IsNotifierEnabled(notifier_id)));
116 app_icon_loader_->FetchImage(extension->id()); 124 app_icon_loader_->FetchImage(extension->id());
117 } 125 }
118 126
119 if (notifier::ChromeNotifierServiceFactory::UseSyncedNotifications( 127 if (notifier::ChromeNotifierServiceFactory::UseSyncedNotifications(
120 CommandLine::ForCurrentProcess())) { 128 CommandLine::ForCurrentProcess())) {
121 notifier::ChromeNotifierService* sync_notifier_service = 129 notifier::ChromeNotifierService* sync_notifier_service =
122 notifier::ChromeNotifierServiceFactory::GetInstance()->GetForProfile( 130 notifier::ChromeNotifierServiceFactory::GetInstance()->GetForProfile(
123 profile, Profile::EXPLICIT_ACCESS); 131 profile_, Profile::EXPLICIT_ACCESS);
124 sync_notifier_service->GetSyncedNotificationServices(notifiers); 132 sync_notifier_service->GetSyncedNotificationServices(notifiers);
125 133
126 if (comparator) 134 if (comparator)
127 std::sort(notifiers->begin(), notifiers->end(), *comparator); 135 std::sort(notifiers->begin(), notifiers->end(), *comparator);
128 else 136 else
129 std::sort(notifiers->begin(), notifiers->end(), SimpleCompareNotifiers); 137 std::sort(notifiers->begin(), notifiers->end(), SimpleCompareNotifiers);
130 } 138 }
131 139
132 int app_count = notifiers->size(); 140 int app_count = notifiers->size();
133 141
134 ContentSettingsForOneType settings; 142 ContentSettingsForOneType settings;
135 notification_service->GetNotificationsSettings(&settings); 143 notification_service->GetNotificationsSettings(&settings);
136 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile( 144 FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
137 profile, Profile::EXPLICIT_ACCESS); 145 profile_, Profile::EXPLICIT_ACCESS);
138 favicon_tracker_.reset(new CancelableTaskTracker()); 146 favicon_tracker_.reset(new CancelableTaskTracker());
139 patterns_.clear(); 147 patterns_.clear();
140 for (ContentSettingsForOneType::const_iterator iter = settings.begin(); 148 for (ContentSettingsForOneType::const_iterator iter = settings.begin();
141 iter != settings.end(); ++iter) { 149 iter != settings.end(); ++iter) {
142 if (iter->primary_pattern == ContentSettingsPattern::Wildcard() && 150 if (iter->primary_pattern == ContentSettingsPattern::Wildcard() &&
143 iter->secondary_pattern == ContentSettingsPattern::Wildcard() && 151 iter->secondary_pattern == ContentSettingsPattern::Wildcard() &&
144 iter->source != "preference") { 152 iter->source != "preference") {
145 continue; 153 continue;
146 } 154 }
147 155
148 std::string url_pattern = iter->primary_pattern.ToString(); 156 std::string url_pattern = iter->primary_pattern.ToString();
149 string16 name = UTF8ToUTF16(url_pattern); 157 string16 name = UTF8ToUTF16(url_pattern);
150 GURL url(url_pattern); 158 GURL url(url_pattern);
151 NotifierId notifier_id(url); 159 NotifierId notifier_id(url);
152 notifiers->push_back(new Notifier( 160 notifiers->push_back(new Notifier(
153 notifier_id, 161 notifier_id,
154 name, 162 name,
155 notification_service->IsNotifierEnabled(notifier_id))); 163 notification_service->IsNotifierEnabled(notifier_id)));
156 patterns_[name] = iter->primary_pattern; 164 patterns_[name] = iter->primary_pattern;
157 FaviconService::FaviconForURLParams favicon_params( 165 FaviconService::FaviconForURLParams favicon_params(
158 profile, url, chrome::FAVICON | chrome::TOUCH_ICON, 166 profile_, url, chrome::FAVICON | chrome::TOUCH_ICON,
159 message_center::kSettingsIconSize); 167 message_center::kSettingsIconSize);
160 // Note that favicon service obtains the favicon from history. This means 168 // Note that favicon service obtains the favicon from history. This means
161 // that it will fail to obtain the image if there are no history data for 169 // that it will fail to obtain the image if there are no history data for
162 // that URL. 170 // that URL.
163 favicon_service->GetFaviconImageForURL( 171 favicon_service->GetFaviconImageForURL(
164 favicon_params, 172 favicon_params,
165 base::Bind(&MessageCenterSettingsController::OnFaviconLoaded, 173 base::Bind(&MessageCenterSettingsController::OnFaviconLoaded,
166 base::Unretained(this), url), 174 base::Unretained(this), url),
167 favicon_tracker_.get()); 175 favicon_tracker_.get());
168 } 176 }
(...skipping 18 matching lines...) Expand all
187 } else { 195 } else {
188 std::sort(notifiers->begin() + app_count, notifiers->end(), 196 std::sort(notifiers->begin() + app_count, notifiers->end(),
189 SimpleCompareNotifiers); 197 SimpleCompareNotifiers);
190 } 198 }
191 } 199 }
192 200
193 void MessageCenterSettingsController::SetNotifierEnabled( 201 void MessageCenterSettingsController::SetNotifierEnabled(
194 const Notifier& notifier, 202 const Notifier& notifier,
195 bool enabled) { 203 bool enabled) {
196 // TODO(mukai): Fix this for multi-profile. 204 // TODO(mukai): Fix this for multi-profile.
197 Profile* profile = ProfileManager::GetDefaultProfile(); 205 // If the profile has been destroyed, fail silently.
206 if (!profile_)
207 return;
198 DesktopNotificationService* notification_service = 208 DesktopNotificationService* notification_service =
199 DesktopNotificationServiceFactory::GetForProfile(profile); 209 DesktopNotificationServiceFactory::GetForProfile(profile_);
200 210
201 if (notifier.notifier_id.type == NotifierId::WEB_PAGE) { 211 if (notifier.notifier_id.type == NotifierId::WEB_PAGE) {
202 // WEB_PAGE notifier cannot handle in DesktopNotificationService 212 // WEB_PAGE notifier cannot handle in DesktopNotificationService
203 // since it has the exact URL pattern. 213 // since it has the exact URL pattern.
204 // TODO(mukai): fix this. 214 // TODO(mukai): fix this.
205 ContentSetting default_setting = 215 ContentSetting default_setting =
206 notification_service->GetDefaultContentSetting(NULL); 216 notification_service->GetDefaultContentSetting(NULL);
207 DCHECK(default_setting == CONTENT_SETTING_ALLOW || 217 DCHECK(default_setting == CONTENT_SETTING_ALLOW ||
208 default_setting == CONTENT_SETTING_BLOCK || 218 default_setting == CONTENT_SETTING_BLOCK ||
209 default_setting == CONTENT_SETTING_ASK); 219 default_setting == CONTENT_SETTING_ASK);
(...skipping 16 matching lines...) Expand all
226 } else { 236 } else {
227 LOG(ERROR) << "Invalid url pattern: " 237 LOG(ERROR) << "Invalid url pattern: "
228 << notifier.notifier_id.url.spec(); 238 << notifier.notifier_id.url.spec();
229 } 239 }
230 } 240 }
231 } else { 241 } else {
232 notification_service->SetNotifierEnabled(notifier.notifier_id, enabled); 242 notification_service->SetNotifierEnabled(notifier.notifier_id, enabled);
233 if (notifier.notifier_id.type == NotifierId::SYNCED_NOTIFICATION_SERVICE) { 243 if (notifier.notifier_id.type == NotifierId::SYNCED_NOTIFICATION_SERVICE) {
234 notifier::ChromeNotifierService* notifier_service = 244 notifier::ChromeNotifierService* notifier_service =
235 notifier::ChromeNotifierServiceFactory::GetInstance()->GetForProfile( 245 notifier::ChromeNotifierServiceFactory::GetInstance()->GetForProfile(
236 profile, Profile::EXPLICIT_ACCESS); 246 profile_, Profile::EXPLICIT_ACCESS);
237 notifier_service->OnSyncedNotificationServiceEnabled( 247 notifier_service->OnSyncedNotificationServiceEnabled(
238 notifier.notifier_id.id, enabled); 248 notifier.notifier_id.id, enabled);
239 } 249 }
240 } 250 }
241 } 251 }
242 252
243 void MessageCenterSettingsController::OnNotifierSettingsClosing() { 253 void MessageCenterSettingsController::OnNotifierSettingsClosing() {
244 DCHECK(favicon_tracker_.get()); 254 DCHECK(favicon_tracker_.get());
245 favicon_tracker_->TryCancelAll(); 255 favicon_tracker_->TryCancelAll();
246 patterns_.clear(); 256 patterns_.clear();
247 } 257 }
248 258
259 void MessageCenterSettingsController::Observe(
260 int type,
261 const content::NotificationSource& source,
262 const content::NotificationDetails& details) {
263 if (type == chrome::NOTIFICATION_PROFILE_DESTROYED &&
264 content::Source<Profile>(source).ptr() == profile_) {
265 // Our profile just got destroyed, so we delete our pointer to it.
266 profile_ = NULL;
267 }
268 }
269
249 void MessageCenterSettingsController::OnFaviconLoaded( 270 void MessageCenterSettingsController::OnFaviconLoaded(
250 const GURL& url, 271 const GURL& url,
251 const chrome::FaviconImageResult& favicon_result) { 272 const chrome::FaviconImageResult& favicon_result) {
252 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, 273 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver,
253 observers_, 274 observers_,
254 UpdateIconImage(NotifierId(url), favicon_result.image)); 275 UpdateIconImage(NotifierId(url), favicon_result.image));
255 } 276 }
256 277
257 278
258 void MessageCenterSettingsController::SetAppImage(const std::string& id, 279 void MessageCenterSettingsController::SetAppImage(const std::string& id,
259 const gfx::ImageSkia& image) { 280 const gfx::ImageSkia& image) {
260 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, 281 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver,
261 observers_, 282 observers_,
262 UpdateIconImage(NotifierId(NotifierId::APPLICATION, id), 283 UpdateIconImage(NotifierId(NotifierId::APPLICATION, id),
263 gfx::Image(image))); 284 gfx::Image(image)));
264 } 285 }
OLDNEW
« no previous file with comments | « chrome/browser/notifications/message_center_settings_controller.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698