Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
| 12 #include "base/i18n/string_compare.h" | 12 #include "base/i18n/string_compare.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/task/cancelable_task_tracker.h" | 14 #include "base/task/cancelable_task_tracker.h" |
| 15 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 16 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 17 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/chrome_notification_types.h" | 18 #include "chrome/browser/chrome_notification_types.h" |
| 19 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 19 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 20 #include "chrome/browser/extensions/extension_app_icon_loader.h" | 20 #include "chrome/browser/extensions/extension_app_icon_loader.h" |
| 21 #include "chrome/browser/favicon/favicon_service_factory.h" | 21 #include "chrome/browser/favicon/favicon_service_factory.h" |
| 22 #include "chrome/browser/notifications/desktop_notification_profile_util.h" | 22 #include "chrome/browser/notifications/desktop_notification_profile_util.h" |
| 23 #include "chrome/browser/notifications/notifier_source.h" | |
| 23 #include "chrome/browser/notifications/notifier_state_tracker.h" | 24 #include "chrome/browser/notifications/notifier_state_tracker.h" |
| 24 #include "chrome/browser/notifications/notifier_state_tracker_factory.h" | 25 #include "chrome/browser/notifications/notifier_state_tracker_factory.h" |
| 25 #include "chrome/browser/profiles/profile.h" | 26 #include "chrome/browser/profiles/profile.h" |
| 26 #include "chrome/browser/profiles/profile_attributes_entry.h" | 27 #include "chrome/browser/profiles/profile_attributes_entry.h" |
| 27 #include "chrome/browser/profiles/profile_attributes_storage.h" | 28 #include "chrome/browser/profiles/profile_attributes_storage.h" |
| 28 #include "chrome/browser/profiles/profile_manager.h" | 29 #include "chrome/browser/profiles/profile_manager.h" |
| 29 #include "chrome/common/extensions/api/notifications.h" | 30 #include "chrome/common/extensions/api/notifications.h" |
| 30 #include "chrome/common/extensions/extension_constants.h" | 31 #include "chrome/common/extensions/extension_constants.h" |
| 31 #include "components/content_settings/core/browser/host_content_settings_map.h" | 32 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 32 #include "components/favicon/core/favicon_service.h" | 33 #include "components/favicon/core/favicon_service.h" |
| 33 #include "components/favicon_base/favicon_types.h" | 34 #include "components/favicon_base/favicon_types.h" |
| 34 #include "components/history/core/browser/history_types.h" | 35 #include "components/history/core/browser/history_types.h" |
| 35 #include "content/public/browser/notification_service.h" | 36 #include "content/public/browser/notification_service.h" |
| 36 #include "content/public/browser/notification_source.h" | 37 #include "content/public/browser/notification_source.h" |
| 37 #include "extensions/browser/event_router.h" | 38 #include "extensions/browser/event_router.h" |
| 38 #include "extensions/browser/extension_registry.h" | 39 #include "extensions/browser/extension_registry.h" |
| 39 #include "extensions/common/constants.h" | 40 #include "extensions/common/constants.h" |
| 40 #include "extensions/common/extension.h" | 41 #include "extensions/common/extension.h" |
| 41 #include "extensions/common/permissions/permissions_data.h" | 42 #include "extensions/common/permissions/permissions_data.h" |
| 42 #include "grit/theme_resources.h" | 43 #include "grit/theme_resources.h" |
| 43 #include "ui/base/l10n/l10n_util.h" | 44 #include "ui/base/l10n/l10n_util.h" |
| 44 #include "ui/base/resource/resource_bundle.h" | 45 #include "ui/base/resource/resource_bundle.h" |
| 45 #include "ui/gfx/image/image.h" | 46 #include "ui/gfx/image/image.h" |
| 46 #include "ui/message_center/message_center_style.h" | 47 #include "ui/message_center/message_center_style.h" |
| 47 #include "ui/strings/grit/ui_strings.h" | 48 #include "ui/strings/grit/ui_strings.h" |
| 48 | 49 |
| 49 #if defined(OS_CHROMEOS) | 50 #if defined(OS_CHROMEOS) |
| 50 #include "ash/system/system_notifier.h" | 51 #include "ash/system/system_notifier.h" |
| 51 #include "chrome/browser/chromeos/profiles/profile_helper.h" | 52 #include "chrome/browser/chromeos/profiles/profile_helper.h" |
| 52 #include "chrome/browser/notifications/arc_notifier_manager.h" | 53 #include "chrome/browser/notifications/arc_notifier_source.h" |
| 53 #include "components/arc/arc_bridge_service.h" | |
| 54 #endif | 54 #endif |
| 55 | 55 |
| 56 using message_center::Notifier; | 56 using message_center::Notifier; |
| 57 using message_center::NotifierId; | 57 using message_center::NotifierId; |
| 58 | 58 |
| 59 namespace message_center { | 59 namespace message_center { |
| 60 | 60 |
| 61 class ProfileNotifierGroup : public message_center::NotifierGroup { | 61 class ProfileNotifierGroup : public message_center::NotifierGroup { |
| 62 public: | 62 public: |
| 63 ProfileNotifierGroup(const gfx::Image& icon, | 63 ProfileNotifierGroup(const gfx::Image& icon, |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 91 const base::string16& display_name, | 91 const base::string16& display_name, |
| 92 const base::string16& login_info, | 92 const base::string16& login_info, |
| 93 Profile* profile) | 93 Profile* profile) |
| 94 : message_center::NotifierGroup(icon, display_name, login_info), | 94 : message_center::NotifierGroup(icon, display_name, login_info), |
| 95 profile_(profile) { | 95 profile_(profile) { |
| 96 } | 96 } |
| 97 | 97 |
| 98 } // namespace message_center | 98 } // namespace message_center |
| 99 | 99 |
| 100 namespace { | 100 namespace { |
| 101 | |
| 101 class NotifierComparator { | 102 class NotifierComparator { |
| 102 public: | 103 public: |
| 103 explicit NotifierComparator(icu::Collator* collator) : collator_(collator) {} | 104 explicit NotifierComparator(icu::Collator* collator) : collator_(collator) {} |
| 104 | 105 |
| 105 bool operator() (Notifier* n1, Notifier* n2) { | 106 bool operator() (Notifier* n1, Notifier* n2) { |
| 106 if (n1->notifier_id.type != n2->notifier_id.type) | 107 if (n1->notifier_id.type != n2->notifier_id.type) |
| 107 return n1->notifier_id.type < n2->notifier_id.type; | 108 return n1->notifier_id.type < n2->notifier_id.type; |
| 108 | 109 |
| 109 if (collator_) { | 110 if (collator_) { |
| 110 return base::i18n::CompareString16WithCollator(*collator_, n1->name, | 111 return base::i18n::CompareString16WithCollator(*collator_, n1->name, |
| 111 n2->name) == UCOL_LESS; | 112 n2->name) == UCOL_LESS; |
| 112 } | 113 } |
| 113 return n1->name < n2->name; | 114 return n1->name < n2->name; |
| 114 } | 115 } |
| 115 | 116 |
| 116 private: | 117 private: |
| 117 icu::Collator* collator_; | 118 icu::Collator* collator_; |
| 118 }; | 119 }; |
| 119 | 120 |
| 121 class ApplicationNotifiereSource : public NotifierSource, | |
|
dewittj
2016/06/16 19:45:36
I think this deserves its own h/cc files. Probabl
hirono
2016/06/17 04:56:46
Separating files is done. The names of source clas
| |
| 122 public AppIconLoaderDelegate { | |
| 123 public: | |
| 124 explicit ApplicationNotifiereSource( | |
|
dewittj
2016/06/16 19:45:36
This should be spelled ApplicationNotifierSource,
hirono
2016/06/17 04:56:46
Oops, yes!
| |
| 125 message_center::NotifierSettingsObserver* parent) | |
| 126 : NotifierSource(parent) {} | |
| 127 | |
| 128 std::vector<std::unique_ptr<message_center::Notifier>> GetNotifierList( | |
| 129 Profile* profile) override { | |
| 130 std::vector<std::unique_ptr<message_center::Notifier>> notifiers; | |
| 131 NotifierStateTracker* const notifier_state_tracker = | |
| 132 NotifierStateTrackerFactory::GetForProfile(profile); | |
| 133 const extensions::ExtensionSet& extension_set = | |
| 134 extensions::ExtensionRegistry::Get(profile)->enabled_extensions(); | |
| 135 // The extension icon size has to be 32x32 at least to load bigger icons if | |
| 136 // the icon doesn't exist for the specified size, and in that case it falls | |
| 137 // back to the default icon. The fetched icon will be resized in the | |
| 138 // settings dialog. See chrome/browser/extensions/extension_icon_image.cc | |
| 139 // and crbug.com/222931 | |
| 140 app_icon_loader_.reset(new extensions::ExtensionAppIconLoader( | |
| 141 profile, extension_misc::EXTENSION_ICON_SMALL, this)); | |
| 142 for (extensions::ExtensionSet::const_iterator iter = extension_set.begin(); | |
| 143 iter != extension_set.end(); ++iter) { | |
| 144 const extensions::Extension* extension = iter->get(); | |
| 145 if (!extension->permissions_data()->HasAPIPermission( | |
| 146 extensions::APIPermission::kNotifications)) { | |
| 147 continue; | |
| 148 } | |
| 149 | |
| 150 // Hosted apps are no longer able to affect the notifications permission | |
| 151 // state for web notifications. | |
| 152 // TODO(dewittj): Deprecate the 'notifications' permission for hosted | |
| 153 // apps. | |
| 154 if (extension->is_hosted_app()) | |
| 155 continue; | |
| 156 | |
| 157 NotifierId notifier_id(NotifierId::APPLICATION, extension->id()); | |
| 158 notifiers.emplace_back( | |
| 159 new Notifier(notifier_id, base::UTF8ToUTF16(extension->name()), | |
| 160 notifier_state_tracker->IsNotifierEnabled(notifier_id))); | |
| 161 app_icon_loader_->FetchImage(extension->id()); | |
| 162 } | |
| 163 | |
| 164 return notifiers; | |
| 165 } | |
| 166 | |
| 167 void SetNotifierEnabled(Profile* profile, | |
| 168 const message_center::Notifier& notifier, | |
| 169 bool enabled) override { | |
| 170 NotifierStateTrackerFactory::GetForProfile(profile)->SetNotifierEnabled( | |
| 171 notifier.notifier_id, enabled); | |
| 172 parent_->NotifierEnabledChanged(notifier.notifier_id, enabled); | |
| 173 } | |
| 174 | |
| 175 message_center::NotifierId::NotifierType GetNotifierType() override { | |
| 176 return NotifierId::APPLICATION; | |
| 177 } | |
| 178 | |
| 179 private: | |
| 180 // Overridden from AppIconLoaderDelegate. | |
| 181 void OnAppImageUpdated(const std::string& id, | |
| 182 const gfx::ImageSkia& image) override { | |
| 183 parent_->UpdateIconImage(NotifierId(NotifierId::APPLICATION, id), | |
| 184 gfx::Image(image)); | |
| 185 } | |
| 186 | |
| 187 std::unique_ptr<AppIconLoader> app_icon_loader_; | |
| 188 }; | |
| 189 | |
| 190 class WebPageNotifiereSource : public NotifierSource { | |
| 191 public: | |
| 192 explicit WebPageNotifiereSource( | |
| 193 message_center::NotifierSettingsObserver* parent) | |
| 194 : NotifierSource(parent) {} | |
| 195 | |
| 196 std::vector<std::unique_ptr<message_center::Notifier>> GetNotifierList( | |
| 197 Profile* profile) override { | |
| 198 std::vector<std::unique_ptr<message_center::Notifier>> notifiers; | |
| 199 NotifierStateTracker* const notifier_state_tracker = | |
| 200 NotifierStateTrackerFactory::GetForProfile(profile); | |
| 201 ContentSettingsForOneType settings; | |
| 202 DesktopNotificationProfileUtil::GetNotificationsSettings(profile, | |
| 203 &settings); | |
| 204 | |
| 205 favicon::FaviconService* const favicon_service = | |
| 206 FaviconServiceFactory::GetForProfile( | |
| 207 profile, ServiceAccessType::EXPLICIT_ACCESS); | |
| 208 favicon_tracker_.reset(new base::CancelableTaskTracker()); | |
| 209 patterns_.clear(); | |
| 210 for (ContentSettingsForOneType::const_iterator iter = settings.begin(); | |
| 211 iter != settings.end(); ++iter) { | |
| 212 if (iter->primary_pattern == ContentSettingsPattern::Wildcard() && | |
| 213 iter->secondary_pattern == ContentSettingsPattern::Wildcard() && | |
| 214 iter->source != "preference") { | |
| 215 continue; | |
| 216 } | |
| 217 | |
| 218 std::string url_pattern = iter->primary_pattern.ToString(); | |
| 219 base::string16 name = base::UTF8ToUTF16(url_pattern); | |
| 220 GURL url(url_pattern); | |
| 221 NotifierId notifier_id(url); | |
| 222 notifiers.emplace_back( | |
| 223 new Notifier(notifier_id, name, | |
| 224 notifier_state_tracker->IsNotifierEnabled(notifier_id))); | |
| 225 patterns_[name] = iter->primary_pattern; | |
| 226 // Note that favicon service obtains the favicon from history. This means | |
| 227 // that it will fail to obtain the image if there are no history data for | |
| 228 // that URL. | |
| 229 favicon_service->GetFaviconImageForPageURL( | |
| 230 url, base::Bind(&WebPageNotifiereSource::OnFaviconLoaded, | |
| 231 base::Unretained(this), url), | |
| 232 favicon_tracker_.get()); | |
| 233 } | |
| 234 | |
| 235 return notifiers; | |
| 236 } | |
| 237 | |
| 238 void SetNotifierEnabled(Profile* profile, | |
| 239 const message_center::Notifier& notifier, | |
| 240 bool enabled) override { | |
| 241 // WEB_PAGE notifier cannot handle in DesktopNotificationService | |
| 242 // since it has the exact URL pattern. | |
| 243 // TODO(mukai): fix this. | |
| 244 ContentSetting default_setting = | |
| 245 HostContentSettingsMapFactory::GetForProfile(profile) | |
| 246 ->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, | |
| 247 NULL); | |
| 248 | |
| 249 DCHECK(default_setting == CONTENT_SETTING_ALLOW || | |
| 250 default_setting == CONTENT_SETTING_BLOCK || | |
| 251 default_setting == CONTENT_SETTING_ASK); | |
| 252 | |
| 253 // The content setting for notifications needs to clear when it changes to | |
| 254 // the default value or get explicitly set when it differs from the | |
| 255 // default. | |
| 256 bool differs_from_default_value = | |
| 257 (default_setting != CONTENT_SETTING_ALLOW && enabled) || | |
| 258 (default_setting == CONTENT_SETTING_ALLOW && !enabled); | |
| 259 | |
| 260 if (differs_from_default_value) { | |
| 261 if (notifier.notifier_id.url.is_valid()) { | |
| 262 if (enabled) { | |
| 263 DesktopNotificationProfileUtil::GrantPermission( | |
| 264 profile, notifier.notifier_id.url); | |
| 265 } else { | |
| 266 DesktopNotificationProfileUtil::DenyPermission( | |
| 267 profile, notifier.notifier_id.url); | |
| 268 } | |
| 269 } else { | |
| 270 LOG(ERROR) << "Invalid url pattern: " | |
| 271 << notifier.notifier_id.url.spec(); | |
| 272 } | |
| 273 } else { | |
| 274 ContentSettingsPattern pattern; | |
| 275 | |
| 276 const auto& iter = patterns_.find(notifier.name); | |
| 277 if (iter != patterns_.end()) { | |
| 278 pattern = iter->second; | |
| 279 } else if (notifier.notifier_id.url.is_valid()) { | |
| 280 pattern = | |
| 281 ContentSettingsPattern::FromURLNoWildcard(notifier.notifier_id.url); | |
| 282 } else { | |
| 283 LOG(ERROR) << "Invalid url pattern: " | |
| 284 << notifier.notifier_id.url.spec(); | |
| 285 } | |
| 286 | |
| 287 if (pattern.IsValid()) { | |
| 288 // Note that we don't use | |
| 289 // DesktopNotificationProfileUtil::ClearSetting() | |
| 290 // here because pattern might be from user manual input and not match | |
| 291 // the default one used by ClearSetting(). | |
| 292 HostContentSettingsMapFactory::GetForProfile(profile) | |
| 293 ->SetContentSettingCustomScope( | |
| 294 pattern, ContentSettingsPattern::Wildcard(), | |
| 295 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, | |
| 296 content_settings::ResourceIdentifier(), | |
| 297 CONTENT_SETTING_DEFAULT); | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 parent_->NotifierEnabledChanged(notifier.notifier_id, enabled); | |
| 302 } | |
| 303 | |
| 304 void OnNotifierSettingsClosing() override { | |
| 305 DCHECK(favicon_tracker_.get()); | |
| 306 favicon_tracker_->TryCancelAll(); | |
| 307 patterns_.clear(); | |
| 308 } | |
| 309 | |
| 310 message_center::NotifierId::NotifierType GetNotifierType() override { | |
| 311 return NotifierId::WEB_PAGE; | |
| 312 } | |
| 313 | |
| 314 private: | |
| 315 void OnFaviconLoaded(const GURL& url, | |
| 316 const favicon_base::FaviconImageResult& favicon_result) { | |
| 317 parent_->UpdateIconImage(NotifierId(url), favicon_result.image); | |
| 318 } | |
| 319 | |
| 320 std::map<base::string16, ContentSettingsPattern> patterns_; | |
| 321 | |
| 322 // The task tracker for loading favicons. | |
| 323 std::unique_ptr<base::CancelableTaskTracker> favicon_tracker_; | |
| 324 }; | |
| 325 | |
| 326 #if defined(OS_CHROMEOS) | |
| 327 class SystemComponentNotifierSource : public NotifierSource { | |
| 328 public: | |
| 329 explicit SystemComponentNotifierSource( | |
| 330 message_center::NotifierSettingsObserver* parent) | |
| 331 : NotifierSource(parent) {} | |
| 332 | |
| 333 std::vector<std::unique_ptr<message_center::Notifier>> GetNotifierList( | |
| 334 Profile* profile) override { | |
| 335 std::vector<std::unique_ptr<message_center::Notifier>> notifiers; | |
| 336 NotifierStateTracker* const notifier_state_tracker = | |
| 337 NotifierStateTrackerFactory::GetForProfile(profile); | |
| 338 | |
| 339 // Screenshot notification feature is only for ChromeOS. See | |
| 340 // crbug.com/238358 | |
| 341 const base::string16& screenshot_name = | |
| 342 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_NOTIFIER_SCREENSHOT_NAME); | |
| 343 NotifierId screenshot_notifier_id( | |
| 344 NotifierId::SYSTEM_COMPONENT, | |
| 345 ash::system_notifier::kNotifierScreenshot); | |
| 346 Notifier* const screenshot_notifier = new Notifier( | |
| 347 screenshot_notifier_id, screenshot_name, | |
| 348 notifier_state_tracker->IsNotifierEnabled(screenshot_notifier_id)); | |
| 349 screenshot_notifier->icon = | |
| 350 ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
| 351 IDR_SCREENSHOT_NOTIFICATION_ICON); | |
| 352 notifiers.emplace_back(screenshot_notifier); | |
| 353 return notifiers; | |
| 354 } | |
| 355 | |
| 356 void SetNotifierEnabled(Profile* profile, | |
| 357 const message_center::Notifier& notifier, | |
| 358 bool enabled) override { | |
| 359 NotifierStateTrackerFactory::GetForProfile(profile)->SetNotifierEnabled( | |
| 360 notifier.notifier_id, enabled); | |
| 361 parent_->NotifierEnabledChanged(notifier.notifier_id, enabled); | |
| 362 } | |
| 363 | |
| 364 message_center::NotifierId::NotifierType GetNotifierType() override { | |
| 365 return NotifierId::SYSTEM_COMPONENT; | |
| 366 } | |
| 367 }; | |
| 368 #endif | |
| 369 | |
| 120 } // namespace | 370 } // namespace |
| 121 | 371 |
| 122 MessageCenterSettingsController::MessageCenterSettingsController( | 372 MessageCenterSettingsController::MessageCenterSettingsController( |
| 123 ProfileAttributesStorage& profile_attributes_storage) | 373 ProfileAttributesStorage& profile_attributes_storage) |
| 124 : current_notifier_group_(0), | 374 : current_notifier_group_(0), |
| 125 profile_attributes_storage_(profile_attributes_storage), | 375 profile_attributes_storage_(profile_attributes_storage), |
| 126 weak_factory_(this) { | 376 weak_factory_(this) { |
| 127 // The following events all represent changes that may need to be reflected in | 377 // The following events all represent changes that may need to be reflected in |
| 128 // the profile selector context menu, so listen for them all. We'll just | 378 // the profile selector context menu, so listen for them all. We'll just |
| 129 // rebuild the list when we get any of them. | 379 // rebuild the list when we get any of them. |
| 130 registrar_.Add(this, | 380 registrar_.Add(this, |
| 131 chrome::NOTIFICATION_PROFILE_CREATED, | 381 chrome::NOTIFICATION_PROFILE_CREATED, |
| 132 content::NotificationService::AllBrowserContextsAndSources()); | 382 content::NotificationService::AllBrowserContextsAndSources()); |
| 133 registrar_.Add(this, | 383 registrar_.Add(this, |
| 134 chrome::NOTIFICATION_PROFILE_ADDED, | 384 chrome::NOTIFICATION_PROFILE_ADDED, |
| 135 content::NotificationService::AllBrowserContextsAndSources()); | 385 content::NotificationService::AllBrowserContextsAndSources()); |
| 136 registrar_.Add(this, | 386 registrar_.Add(this, |
| 137 chrome::NOTIFICATION_PROFILE_DESTROYED, | 387 chrome::NOTIFICATION_PROFILE_DESTROYED, |
| 138 content::NotificationService::AllBrowserContextsAndSources()); | 388 content::NotificationService::AllBrowserContextsAndSources()); |
| 139 profile_attributes_storage_.AddObserver(this); | 389 profile_attributes_storage_.AddObserver(this); |
| 140 RebuildNotifierGroups(false); | 390 RebuildNotifierGroups(false); |
| 141 | 391 |
| 392 sources_.insert(std::make_pair( | |
| 393 NotifierId::APPLICATION, | |
| 394 std::unique_ptr<NotifierSource>(new ApplicationNotifiereSource(this)))); | |
| 395 sources_.insert(std::make_pair( | |
| 396 NotifierId::WEB_PAGE, | |
| 397 std::unique_ptr<NotifierSource>(new WebPageNotifiereSource(this)))); | |
| 398 | |
| 142 #if defined(OS_CHROMEOS) | 399 #if defined(OS_CHROMEOS) |
| 143 // UserManager may not exist in some tests. | 400 // UserManager may not exist in some tests. |
| 144 if (user_manager::UserManager::IsInitialized()) | 401 if (user_manager::UserManager::IsInitialized()) |
| 145 user_manager::UserManager::Get()->AddSessionStateObserver(this); | 402 user_manager::UserManager::Get()->AddSessionStateObserver(this); |
| 146 // Check if ARC is enabled. | 403 // FOr system components. |
| 147 if (arc::ArcBridgeService::Get()) | 404 sources_.insert(std::make_pair(NotifierId::SYSTEM_COMPONENT, |
| 148 arc_notifier_manager_.reset(new arc::ArcNotifierManager()); | 405 std::unique_ptr<NotifierSource>( |
| 406 new SystemComponentNotifierSource(this)))); | |
| 407 sources_.insert(std::make_pair( | |
| 408 NotifierId::ARC_APPLICATION, | |
| 409 std::unique_ptr<NotifierSource>(new arc::ArcNotifierSource(this)))); | |
| 149 #endif | 410 #endif |
| 150 } | 411 } |
| 151 | 412 |
| 152 MessageCenterSettingsController::~MessageCenterSettingsController() { | 413 MessageCenterSettingsController::~MessageCenterSettingsController() { |
| 153 profile_attributes_storage_.RemoveObserver(this); | 414 profile_attributes_storage_.RemoveObserver(this); |
| 154 #if defined(OS_CHROMEOS) | 415 #if defined(OS_CHROMEOS) |
| 155 // UserManager may not exist in some tests. | 416 // UserManager may not exist in some tests. |
| 156 if (user_manager::UserManager::IsInitialized()) | 417 if (user_manager::UserManager::IsInitialized()) |
| 157 user_manager::UserManager::Get()->RemoveSessionStateObserver(this); | 418 user_manager::UserManager::Get()->RemoveSessionStateObserver(this); |
| 158 #endif | 419 #endif |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 188 DCHECK_LT(current_notifier_group_, notifier_groups_.size()); | 449 DCHECK_LT(current_notifier_group_, notifier_groups_.size()); |
| 189 return *(notifier_groups_[current_notifier_group_]); | 450 return *(notifier_groups_[current_notifier_group_]); |
| 190 } | 451 } |
| 191 | 452 |
| 192 void MessageCenterSettingsController::SwitchToNotifierGroup(size_t index) { | 453 void MessageCenterSettingsController::SwitchToNotifierGroup(size_t index) { |
| 193 DCHECK_LT(index, notifier_groups_.size()); | 454 DCHECK_LT(index, notifier_groups_.size()); |
| 194 if (current_notifier_group_ == index) | 455 if (current_notifier_group_ == index) |
| 195 return; | 456 return; |
| 196 | 457 |
| 197 current_notifier_group_ = index; | 458 current_notifier_group_ = index; |
| 198 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, | 459 NotifierGroupChanged(); |
| 199 observers_, | |
| 200 NotifierGroupChanged()); | |
| 201 } | 460 } |
| 202 | 461 |
| 203 void MessageCenterSettingsController::GetNotifierList( | 462 void MessageCenterSettingsController::GetNotifierList( |
| 204 std::vector<Notifier*>* notifiers) { | 463 std::vector<Notifier*>* notifiers) { |
| 205 DCHECK(notifiers); | 464 DCHECK(notifiers); |
| 206 if (notifier_groups_.size() <= current_notifier_group_) | 465 if (notifier_groups_.size() <= current_notifier_group_) |
| 207 return; | 466 return; |
| 208 // Temporarily use the last used profile to prevent chrome from crashing when | 467 // Temporarily use the last used profile to prevent chrome from crashing when |
| 209 // the default profile is not loaded. | 468 // the default profile is not loaded. |
| 210 Profile* profile = notifier_groups_[current_notifier_group_]->profile(); | 469 Profile* profile = notifier_groups_[current_notifier_group_]->profile(); |
| 211 | 470 |
| 212 NotifierStateTracker* notifier_state_tracker = | 471 for (auto& source : sources_) { |
| 213 NotifierStateTrackerFactory::GetForProfile(profile); | 472 auto source_notifiers = source.second->GetNotifierList(profile); |
| 214 | 473 for (auto& notifier : source_notifiers) { |
| 215 const extensions::ExtensionSet& extension_set = | |
| 216 extensions::ExtensionRegistry::Get(profile)->enabled_extensions(); | |
| 217 // The extension icon size has to be 32x32 at least to load bigger icons if | |
| 218 // the icon doesn't exist for the specified size, and in that case it falls | |
| 219 // back to the default icon. The fetched icon will be resized in the settings | |
| 220 // dialog. See chrome/browser/extensions/extension_icon_image.cc and | |
| 221 // crbug.com/222931 | |
| 222 app_icon_loader_.reset(new extensions::ExtensionAppIconLoader( | |
| 223 profile, extension_misc::EXTENSION_ICON_SMALL, this)); | |
| 224 for (extensions::ExtensionSet::const_iterator iter = extension_set.begin(); | |
| 225 iter != extension_set.end(); | |
| 226 ++iter) { | |
| 227 const extensions::Extension* extension = iter->get(); | |
| 228 if (!extension->permissions_data()->HasAPIPermission( | |
| 229 extensions::APIPermission::kNotifications)) { | |
| 230 continue; | |
| 231 } | |
| 232 | |
| 233 // Hosted apps are no longer able to affect the notifications permission | |
| 234 // state for web notifications. | |
| 235 // TODO(dewittj): Deprecate the 'notifications' permission for hosted apps. | |
| 236 if (extension->is_hosted_app()) | |
| 237 continue; | |
| 238 | |
| 239 NotifierId notifier_id(NotifierId::APPLICATION, extension->id()); | |
| 240 notifiers->push_back(new Notifier( | |
| 241 notifier_id, | |
| 242 base::UTF8ToUTF16(extension->name()), | |
| 243 notifier_state_tracker->IsNotifierEnabled(notifier_id))); | |
| 244 app_icon_loader_->FetchImage(extension->id()); | |
| 245 } | |
| 246 | |
| 247 ContentSettingsForOneType settings; | |
| 248 DesktopNotificationProfileUtil::GetNotificationsSettings(profile, &settings); | |
| 249 | |
| 250 favicon::FaviconService* favicon_service = | |
| 251 FaviconServiceFactory::GetForProfile(profile, | |
| 252 ServiceAccessType::EXPLICIT_ACCESS); | |
| 253 favicon_tracker_.reset(new base::CancelableTaskTracker()); | |
| 254 patterns_.clear(); | |
| 255 for (ContentSettingsForOneType::const_iterator iter = settings.begin(); | |
| 256 iter != settings.end(); ++iter) { | |
| 257 if (iter->primary_pattern == ContentSettingsPattern::Wildcard() && | |
| 258 iter->secondary_pattern == ContentSettingsPattern::Wildcard() && | |
| 259 iter->source != "preference") { | |
| 260 continue; | |
| 261 } | |
| 262 | |
| 263 std::string url_pattern = iter->primary_pattern.ToString(); | |
| 264 base::string16 name = base::UTF8ToUTF16(url_pattern); | |
| 265 GURL url(url_pattern); | |
| 266 NotifierId notifier_id(url); | |
| 267 notifiers->push_back(new Notifier( | |
| 268 notifier_id, | |
| 269 name, | |
| 270 notifier_state_tracker->IsNotifierEnabled(notifier_id))); | |
| 271 patterns_[name] = iter->primary_pattern; | |
| 272 // Note that favicon service obtains the favicon from history. This means | |
| 273 // that it will fail to obtain the image if there are no history data for | |
| 274 // that URL. | |
| 275 favicon_service->GetFaviconImageForPageURL( | |
| 276 url, | |
| 277 base::Bind(&MessageCenterSettingsController::OnFaviconLoaded, | |
| 278 base::Unretained(this), | |
| 279 url), | |
| 280 favicon_tracker_.get()); | |
| 281 } | |
| 282 | |
| 283 #if defined(OS_CHROMEOS) | |
| 284 // Add ARC++ apps. | |
| 285 if (arc_notifier_manager_) { | |
| 286 auto list = arc_notifier_manager_->GetNotifiers(profile); | |
| 287 for (auto& notifier : list) { | |
| 288 notifiers->push_back(notifier.release()); | 474 notifiers->push_back(notifier.release()); |
| 289 } | 475 } |
| 290 } | 476 } |
| 291 | 477 |
| 292 // Screenshot notification feature is only for ChromeOS. See crbug.com/238358 | |
| 293 const base::string16& screenshot_name = | |
| 294 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_NOTIFIER_SCREENSHOT_NAME); | |
| 295 NotifierId screenshot_notifier_id( | |
| 296 NotifierId::SYSTEM_COMPONENT, ash::system_notifier::kNotifierScreenshot); | |
| 297 Notifier* const screenshot_notifier = new Notifier( | |
| 298 screenshot_notifier_id, | |
| 299 screenshot_name, | |
| 300 notifier_state_tracker->IsNotifierEnabled(screenshot_notifier_id)); | |
| 301 screenshot_notifier->icon = | |
| 302 ui::ResourceBundle::GetSharedInstance().GetImageNamed( | |
| 303 IDR_SCREENSHOT_NOTIFICATION_ICON); | |
| 304 notifiers->push_back(screenshot_notifier); | |
| 305 #endif | |
| 306 | |
| 307 UErrorCode error = U_ZERO_ERROR; | 478 UErrorCode error = U_ZERO_ERROR; |
| 308 std::unique_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); | 479 std::unique_ptr<icu::Collator> collator(icu::Collator::createInstance(error)); |
| 309 std::unique_ptr<NotifierComparator> comparator( | 480 std::unique_ptr<NotifierComparator> comparator( |
| 310 new NotifierComparator(U_SUCCESS(error) ? collator.get() : NULL)); | 481 new NotifierComparator(U_SUCCESS(error) ? collator.get() : NULL)); |
| 311 | 482 |
| 312 std::sort(notifiers->begin(), notifiers->end(), *comparator); | 483 std::sort(notifiers->begin(), notifiers->end(), *comparator); |
| 313 } | 484 } |
| 314 | 485 |
| 315 void MessageCenterSettingsController::SetNotifierEnabled( | 486 void MessageCenterSettingsController::SetNotifierEnabled( |
| 316 const Notifier& notifier, | 487 const Notifier& notifier, |
| 317 bool enabled) { | 488 bool enabled) { |
| 318 DCHECK_LT(current_notifier_group_, notifier_groups_.size()); | 489 DCHECK_LT(current_notifier_group_, notifier_groups_.size()); |
| 319 Profile* profile = notifier_groups_[current_notifier_group_]->profile(); | 490 Profile* profile = notifier_groups_[current_notifier_group_]->profile(); |
| 320 | 491 |
| 321 switch (notifier.notifier_id.type) { | 492 if (!sources_.count(notifier.notifier_id.type)) { |
| 322 case NotifierId::WEB_PAGE: { | 493 NOTREACHED(); |
| 323 // WEB_PAGE notifier cannot handle in DesktopNotificationService | 494 return; |
| 324 // since it has the exact URL pattern. | 495 } |
| 325 // TODO(mukai): fix this. | |
| 326 ContentSetting default_setting = | |
| 327 HostContentSettingsMapFactory::GetForProfile(profile) | |
| 328 ->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, | |
| 329 NULL); | |
| 330 | 496 |
| 331 DCHECK(default_setting == CONTENT_SETTING_ALLOW || | 497 sources_[notifier.notifier_id.type]->SetNotifierEnabled(profile, notifier, |
| 332 default_setting == CONTENT_SETTING_BLOCK || | 498 enabled); |
| 333 default_setting == CONTENT_SETTING_ASK); | |
| 334 | |
| 335 // The content setting for notifications needs to clear when it changes to | |
| 336 // the default value or get explicitly set when it differs from the | |
| 337 // default. | |
| 338 bool differs_from_default_value = | |
| 339 (default_setting != CONTENT_SETTING_ALLOW && enabled) || | |
| 340 (default_setting == CONTENT_SETTING_ALLOW && !enabled); | |
| 341 | |
| 342 if (differs_from_default_value) { | |
| 343 if (notifier.notifier_id.url.is_valid()) { | |
| 344 if (enabled) { | |
| 345 DesktopNotificationProfileUtil::GrantPermission( | |
| 346 profile, notifier.notifier_id.url); | |
| 347 } else { | |
| 348 DesktopNotificationProfileUtil::DenyPermission( | |
| 349 profile, notifier.notifier_id.url); | |
| 350 } | |
| 351 } else { | |
| 352 LOG(ERROR) << "Invalid url pattern: " | |
| 353 << notifier.notifier_id.url.spec(); | |
| 354 } | |
| 355 } else { | |
| 356 ContentSettingsPattern pattern; | |
| 357 | |
| 358 const auto& iter = patterns_.find(notifier.name); | |
| 359 if (iter != patterns_.end()) { | |
| 360 pattern = iter->second; | |
| 361 } else if (notifier.notifier_id.url.is_valid()) { | |
| 362 pattern = ContentSettingsPattern::FromURLNoWildcard( | |
| 363 notifier.notifier_id.url); | |
| 364 } else { | |
| 365 LOG(ERROR) << "Invalid url pattern: " | |
| 366 << notifier.notifier_id.url.spec(); | |
| 367 } | |
| 368 | |
| 369 if (pattern.IsValid()) { | |
| 370 // Note that we don't use | |
| 371 // DesktopNotificationProfileUtil::ClearSetting() | |
| 372 // here because pattern might be from user manual input and not match | |
| 373 // the default one used by ClearSetting(). | |
| 374 HostContentSettingsMapFactory::GetForProfile(profile) | |
| 375 ->SetContentSettingCustomScope( | |
| 376 pattern, ContentSettingsPattern::Wildcard(), | |
| 377 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, | |
| 378 content_settings::ResourceIdentifier(), | |
| 379 CONTENT_SETTING_DEFAULT); | |
| 380 } | |
| 381 } | |
| 382 break; | |
| 383 } | |
| 384 case NotifierId::APPLICATION: | |
| 385 case NotifierId::SYSTEM_COMPONENT: { | |
| 386 NotifierStateTrackerFactory::GetForProfile(profile)->SetNotifierEnabled( | |
| 387 notifier.notifier_id, enabled); | |
| 388 break; | |
| 389 } | |
| 390 case NotifierId::ARC_APPLICATION: { | |
| 391 #if defined(OS_CHROMEOS) | |
| 392 if (arc_notifier_manager_) { | |
| 393 arc_notifier_manager_->SetNotifierEnabled(notifier.notifier_id.id, | |
| 394 enabled); | |
| 395 } | |
| 396 #else | |
| 397 NOTREACHED(); | |
| 398 #endif | |
| 399 break; | |
| 400 } | |
| 401 } | |
| 402 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, | |
| 403 observers_, | |
| 404 NotifierEnabledChanged(notifier.notifier_id, enabled)); | |
| 405 } | 499 } |
| 406 | 500 |
| 407 void MessageCenterSettingsController::OnNotifierSettingsClosing() { | 501 void MessageCenterSettingsController::OnNotifierSettingsClosing() { |
| 408 DCHECK(favicon_tracker_.get()); | 502 for (auto& source : sources_) { |
| 409 favicon_tracker_->TryCancelAll(); | 503 source.second->OnNotifierSettingsClosing(); |
| 410 patterns_.clear(); | 504 } |
| 411 } | 505 } |
| 412 | 506 |
| 413 bool MessageCenterSettingsController::NotifierHasAdvancedSettings( | 507 bool MessageCenterSettingsController::NotifierHasAdvancedSettings( |
| 414 const NotifierId& notifier_id) const { | 508 const NotifierId& notifier_id) const { |
| 415 // TODO(dewittj): Refactor this so that notifiers have a delegate that can | 509 // TODO(dewittj): Refactor this so that notifiers have a delegate that can |
| 416 // handle this in a more appropriate location. | 510 // handle this in a more appropriate location. |
| 417 if (notifier_id.type != NotifierId::APPLICATION) | 511 if (notifier_id.type != NotifierId::APPLICATION) |
| 418 return false; | 512 return false; |
| 419 | 513 |
| 420 const std::string& extension_id = notifier_id.id; | 514 const std::string& extension_id = notifier_id.id; |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 446 extensions::EventRouter* event_router = extensions::EventRouter::Get(profile); | 540 extensions::EventRouter* event_router = extensions::EventRouter::Get(profile); |
| 447 std::unique_ptr<base::ListValue> args(new base::ListValue()); | 541 std::unique_ptr<base::ListValue> args(new base::ListValue()); |
| 448 | 542 |
| 449 std::unique_ptr<extensions::Event> event(new extensions::Event( | 543 std::unique_ptr<extensions::Event> event(new extensions::Event( |
| 450 extensions::events::NOTIFICATIONS_ON_SHOW_SETTINGS, | 544 extensions::events::NOTIFICATIONS_ON_SHOW_SETTINGS, |
| 451 extensions::api::notifications::OnShowSettings::kEventName, | 545 extensions::api::notifications::OnShowSettings::kEventName, |
| 452 std::move(args))); | 546 std::move(args))); |
| 453 event_router->DispatchEventToExtension(extension_id, std::move(event)); | 547 event_router->DispatchEventToExtension(extension_id, std::move(event)); |
| 454 } | 548 } |
| 455 | 549 |
| 456 void MessageCenterSettingsController::OnFaviconLoaded( | |
| 457 const GURL& url, | |
| 458 const favicon_base::FaviconImageResult& favicon_result) { | |
| 459 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, | |
| 460 observers_, | |
| 461 UpdateIconImage(NotifierId(url), favicon_result.image)); | |
| 462 } | |
| 463 | |
| 464 | |
| 465 #if defined(OS_CHROMEOS) | 550 #if defined(OS_CHROMEOS) |
| 466 void MessageCenterSettingsController::ActiveUserChanged( | 551 void MessageCenterSettingsController::ActiveUserChanged( |
| 467 const user_manager::User* active_user) { | 552 const user_manager::User* active_user) { |
| 468 RebuildNotifierGroups(false); | 553 RebuildNotifierGroups(false); |
| 469 } | 554 } |
| 470 #endif | 555 #endif |
| 471 | 556 |
| 472 void MessageCenterSettingsController::OnAppImageUpdated( | |
| 473 const std::string& id, const gfx::ImageSkia& image) { | |
| 474 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, | |
| 475 observers_, | |
| 476 UpdateIconImage(NotifierId(NotifierId::APPLICATION, id), | |
| 477 gfx::Image(image))); | |
| 478 } | |
| 479 | |
| 480 void MessageCenterSettingsController::Observe( | 557 void MessageCenterSettingsController::Observe( |
| 481 int type, | 558 int type, |
| 482 const content::NotificationSource& source, | 559 const content::NotificationSource& source, |
| 483 const content::NotificationDetails& details) { | 560 const content::NotificationDetails& details) { |
| 484 // GetOffTheRecordProfile() may create a new off-the-record profile, but that | 561 // GetOffTheRecordProfile() may create a new off-the-record profile, but that |
| 485 // doesn't need to rebuild the groups. | 562 // doesn't need to rebuild the groups. |
| 486 if (type == chrome::NOTIFICATION_PROFILE_CREATED && | 563 if (type == chrome::NOTIFICATION_PROFILE_CREATED && |
| 487 content::Source<Profile>(source).ptr()->IsOffTheRecord()) { | 564 content::Source<Profile>(source).ptr()->IsOffTheRecord()) { |
| 488 return; | 565 return; |
| 489 } | 566 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 503 void MessageCenterSettingsController::OnProfileNameChanged( | 580 void MessageCenterSettingsController::OnProfileNameChanged( |
| 504 const base::FilePath& profile_path, | 581 const base::FilePath& profile_path, |
| 505 const base::string16& old_profile_name) { | 582 const base::string16& old_profile_name) { |
| 506 RebuildNotifierGroups(true); | 583 RebuildNotifierGroups(true); |
| 507 } | 584 } |
| 508 void MessageCenterSettingsController::OnProfileAuthInfoChanged( | 585 void MessageCenterSettingsController::OnProfileAuthInfoChanged( |
| 509 const base::FilePath& profile_path) { | 586 const base::FilePath& profile_path) { |
| 510 RebuildNotifierGroups(true); | 587 RebuildNotifierGroups(true); |
| 511 } | 588 } |
| 512 | 589 |
| 590 void MessageCenterSettingsController::UpdateIconImage( | |
| 591 const message_center::NotifierId& id, | |
| 592 const gfx::Image& image) { | |
| 593 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, observers_, | |
| 594 UpdateIconImage(id, image)); | |
| 595 } | |
| 596 | |
| 597 void MessageCenterSettingsController::NotifierGroupChanged() { | |
| 598 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, observers_, | |
| 599 NotifierGroupChanged()); | |
| 600 } | |
| 601 | |
| 602 void MessageCenterSettingsController::NotifierEnabledChanged( | |
| 603 const message_center::NotifierId& id, | |
| 604 bool enabled) { | |
| 605 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, observers_, | |
| 606 NotifierEnabledChanged(id, enabled)); | |
| 607 } | |
| 608 | |
| 513 #if defined(OS_CHROMEOS) | 609 #if defined(OS_CHROMEOS) |
| 514 void MessageCenterSettingsController::CreateNotifierGroupForGuestLogin() { | 610 void MessageCenterSettingsController::CreateNotifierGroupForGuestLogin() { |
| 515 // Already created. | 611 // Already created. |
| 516 if (!notifier_groups_.empty()) | 612 if (!notifier_groups_.empty()) |
| 517 return; | 613 return; |
| 518 | 614 |
| 519 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); | 615 user_manager::UserManager* user_manager = user_manager::UserManager::Get(); |
| 520 // |notifier_groups_| can be empty in login screen too. | 616 // |notifier_groups_| can be empty in login screen too. |
| 521 if (!user_manager->IsLoggedInAsGuest()) | 617 if (!user_manager->IsLoggedInAsGuest()) |
| 522 return; | 618 return; |
| 523 | 619 |
| 524 user_manager::User* user = user_manager->GetActiveUser(); | 620 user_manager::User* user = user_manager->GetActiveUser(); |
| 525 Profile* profile = | 621 Profile* profile = |
| 526 chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user); | 622 chromeos::ProfileHelper::Get()->GetProfileByUserUnsafe(user); |
| 527 DCHECK(profile); | 623 DCHECK(profile); |
| 528 | 624 |
| 529 std::unique_ptr<message_center::ProfileNotifierGroup> group( | 625 std::unique_ptr<message_center::ProfileNotifierGroup> group( |
| 530 new message_center::ProfileNotifierGroup( | 626 new message_center::ProfileNotifierGroup( |
| 531 gfx::Image(user->GetImage()), user->GetDisplayName(), | 627 gfx::Image(user->GetImage()), user->GetDisplayName(), |
| 532 user->GetDisplayName(), profile)); | 628 user->GetDisplayName(), profile)); |
| 533 | 629 |
| 534 notifier_groups_.push_back(std::move(group)); | 630 notifier_groups_.push_back(std::move(group)); |
| 535 | 631 NotifierGroupChanged(); |
| 536 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, | |
| 537 observers_, | |
| 538 NotifierGroupChanged()); | |
| 539 } | 632 } |
| 540 #endif | 633 #endif |
| 541 | 634 |
| 542 void MessageCenterSettingsController::RebuildNotifierGroups(bool notify) { | 635 void MessageCenterSettingsController::RebuildNotifierGroups(bool notify) { |
| 543 notifier_groups_.clear(); | 636 notifier_groups_.clear(); |
| 544 current_notifier_group_ = 0; | 637 current_notifier_group_ = 0; |
| 545 | 638 |
| 546 std::vector<ProfileAttributesEntry*> entries = | 639 std::vector<ProfileAttributesEntry*> entries = |
| 547 profile_attributes_storage_.GetAllProfilesAttributes(); | 640 profile_attributes_storage_.GetAllProfilesAttributes(); |
| 548 for (const auto entry : entries) { | 641 for (const auto entry : entries) { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 // another creating a primary profile, and causes an infinite loop. | 681 // another creating a primary profile, and causes an infinite loop. |
| 589 // Thus, it would be better to delay creating group for guest login. | 682 // Thus, it would be better to delay creating group for guest login. |
| 590 base::ThreadTaskRunnerHandle::Get()->PostTask( | 683 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 591 FROM_HERE, | 684 FROM_HERE, |
| 592 base::Bind( | 685 base::Bind( |
| 593 &MessageCenterSettingsController::CreateNotifierGroupForGuestLogin, | 686 &MessageCenterSettingsController::CreateNotifierGroupForGuestLogin, |
| 594 weak_factory_.GetWeakPtr())); | 687 weak_factory_.GetWeakPtr())); |
| 595 } | 688 } |
| 596 #endif | 689 #endif |
| 597 | 690 |
| 598 if (notify) { | 691 if (notify) |
| 599 FOR_EACH_OBSERVER(message_center::NotifierSettingsObserver, | 692 NotifierGroupChanged(); |
| 600 observers_, | |
| 601 NotifierGroupChanged()); | |
| 602 } | |
| 603 } | 693 } |
| OLD | NEW |