| Index: chrome/browser/notifications/desktop_notification_service.cc
|
| ===================================================================
|
| --- chrome/browser/notifications/desktop_notification_service.cc (revision 98940)
|
| +++ chrome/browser/notifications/desktop_notification_service.cc (working copy)
|
| @@ -7,8 +7,6 @@
|
| #include "base/metrics/histogram.h"
|
| #include "base/threading/thread.h"
|
| #include "base/utf_string_conversions.h"
|
| -#include "chrome/browser/content_settings/content_settings_details.h"
|
| -#include "chrome/browser/content_settings/content_settings_pattern.h"
|
| #include "chrome/browser/content_settings/content_settings_provider.h"
|
| #include "chrome/browser/content_settings/host_content_settings_map.h"
|
| #include "chrome/browser/extensions/extension_service.h"
|
| @@ -16,6 +14,7 @@
|
| #include "chrome/browser/notifications/notification.h"
|
| #include "chrome/browser/notifications/notification_object_proxy.h"
|
| #include "chrome/browser/notifications/notification_ui_manager.h"
|
| +#include "chrome/browser/notifications/notifications_prefs_cache.h"
|
| #include "chrome/browser/prefs/pref_service.h"
|
| #include "chrome/browser/prefs/scoped_user_pref_update.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| @@ -46,6 +45,45 @@
|
|
|
| const ContentSetting kDefaultSetting = CONTENT_SETTING_ASK;
|
|
|
| +namespace {
|
| +
|
| +typedef content_settings::ProviderInterface::Rules Rules;
|
| +
|
| +void GetOriginsWithSettingFromContentSettingsRules(
|
| + const Rules& content_setting_rules,
|
| + ContentSetting setting,
|
| + std::vector<GURL>* origins) {
|
| + origins->clear();
|
| +
|
| + for (Rules::const_iterator rule = content_setting_rules.begin();
|
| + rule != content_setting_rules.end();
|
| + ++rule) {
|
| + if (setting == rule->content_setting) {
|
| + std::string url_str = rule->primary_pattern.ToString();
|
| + if (!rule->primary_pattern.IsValid()) {
|
| + // TODO(markusheintz): This will be removed in one of the next
|
| + // refactoring steps as this entire function will disapear.
|
| + LOG(DFATAL) << "Ignoring invalid content settings pattern: "
|
| + << url_str;
|
| + } else if (url_str.find(ContentSettingsPattern::kDomainWildcard) == 0) {
|
| + // TODO(markusheintz): This must be changed once the UI code is
|
| + // refactored and content_settings patterns are fully supported for
|
| + // notifications settings.
|
| + LOG(DFATAL) << "Ignoring unsupported content settings pattern: "
|
| + << url_str << ". Content settings patterns other than "
|
| + << "hostnames (e.g. wildcard patterns) are not supported "
|
| + << "for notification content settings yet.";
|
| + } else {
|
| + origins->push_back(
|
| + content_settings::NotificationProvider::ToGURL(
|
| + rule->primary_pattern));
|
| + }
|
| + }
|
| + }
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| // NotificationPermissionInfoBarDelegate --------------------------------------
|
|
|
| // The delegate for the infobar shown when an origin requests notification
|
| @@ -214,6 +252,8 @@
|
| NotificationUIManager* ui_manager)
|
| : profile_(profile),
|
| ui_manager_(ui_manager) {
|
| + prefs_registrar_.Init(profile_->GetPrefs());
|
| + InitPrefs();
|
| StartObserving();
|
| }
|
|
|
| @@ -221,45 +261,114 @@
|
| StopObserving();
|
| }
|
|
|
| +void DesktopNotificationService::RegisterUserPrefs(PrefService* user_prefs) {
|
| + content_settings::NotificationProvider::RegisterUserPrefs(user_prefs);
|
| +}
|
| +
|
| +// Initialize the cache with the allowed and denied origins, or
|
| +// create the preferences if they don't exist yet.
|
| +void DesktopNotificationService::InitPrefs() {
|
| + provider_.reset(new content_settings::NotificationProvider(profile_));
|
| +
|
| + std::vector<GURL> allowed_origins;
|
| + std::vector<GURL> denied_origins;
|
| + ContentSetting default_content_setting = CONTENT_SETTING_DEFAULT;
|
| +
|
| + if (!profile_->IsOffTheRecord()) {
|
| + default_content_setting =
|
| + profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
|
| + CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
|
| + allowed_origins = GetAllowedOrigins();
|
| + denied_origins = GetBlockedOrigins();
|
| + }
|
| +
|
| + prefs_cache_ = new NotificationsPrefsCache();
|
| + prefs_cache_->SetCacheDefaultContentSetting(default_content_setting);
|
| + prefs_cache_->SetCacheAllowedOrigins(allowed_origins);
|
| + prefs_cache_->SetCacheDeniedOrigins(denied_origins);
|
| + prefs_cache_->set_is_initialized(true);
|
| +}
|
| +
|
| void DesktopNotificationService::StartObserving() {
|
| if (!profile_->IsOffTheRecord()) {
|
| + prefs_registrar_.Add(prefs::kDesktopNotificationAllowedOrigins, this);
|
| + prefs_registrar_.Add(prefs::kDesktopNotificationDeniedOrigins, this);
|
| notification_registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
|
| NotificationService::AllSources());
|
| + notification_registrar_.Add(
|
| + this,
|
| + chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED,
|
| + Source<HostContentSettingsMap>(profile_->GetHostContentSettingsMap()));
|
| }
|
| notification_registrar_.Add(this, chrome::NOTIFICATION_PROFILE_DESTROYED,
|
| Source<Profile>(profile_));
|
| }
|
|
|
| void DesktopNotificationService::StopObserving() {
|
| + if (!profile_->IsOffTheRecord()) {
|
| + prefs_registrar_.RemoveAll();
|
| + }
|
| notification_registrar_.RemoveAll();
|
| }
|
|
|
| void DesktopNotificationService::GrantPermission(const GURL& origin) {
|
| - ContentSettingsPattern primary_pattern =
|
| - ContentSettingsPattern::FromURLNoWildcard(origin);
|
| - profile_->GetHostContentSettingsMap()->SetContentSetting(
|
| - primary_pattern,
|
| - ContentSettingsPattern::Wildcard(),
|
| + ContentSettingsPattern pattern =
|
| + content_settings::NotificationProvider::ToContentSettingsPattern(origin);
|
| + provider_->SetContentSetting(
|
| + pattern,
|
| + pattern,
|
| CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| NO_RESOURCE_IDENTIFIER,
|
| CONTENT_SETTING_ALLOW);
|
| +
|
| + // Schedule a cache update on the IO thread.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(
|
| + prefs_cache_.get(),
|
| + &NotificationsPrefsCache::CacheAllowedOrigin,
|
| + origin));
|
| }
|
|
|
| void DesktopNotificationService::DenyPermission(const GURL& origin) {
|
| - ContentSettingsPattern primary_pattern =
|
| - ContentSettingsPattern::FromURLNoWildcard(origin);
|
| - profile_->GetHostContentSettingsMap()->SetContentSetting(
|
| - primary_pattern,
|
| - ContentSettingsPattern::Wildcard(),
|
| + // Update content settings
|
| + ContentSettingsPattern pattern =
|
| + content_settings::NotificationProvider::ToContentSettingsPattern(origin);
|
| + provider_->SetContentSetting(
|
| + pattern,
|
| + pattern,
|
| CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| NO_RESOURCE_IDENTIFIER,
|
| CONTENT_SETTING_BLOCK);
|
| +
|
| + // Schedule a cache update on the IO thread.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(
|
| + prefs_cache_.get(),
|
| + &NotificationsPrefsCache::CacheDeniedOrigin,
|
| + origin));
|
| }
|
|
|
| void DesktopNotificationService::Observe(int type,
|
| const NotificationSource& source,
|
| const NotificationDetails& details) {
|
| - if (chrome::NOTIFICATION_EXTENSION_UNLOADED == type) {
|
| + if (chrome::NOTIFICATION_PREF_CHANGED == type) {
|
| + const std::string& name = *Details<std::string>(details).ptr();
|
| + OnPrefsChanged(name);
|
| + } else if (chrome::NOTIFICATION_CONTENT_SETTINGS_CHANGED == type) {
|
| + // TODO(markusheintz): Check if content settings type default was changed;
|
| + const ContentSetting default_content_setting =
|
| + profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
|
| + CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
|
| + // Schedule a cache update on the IO thread.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(
|
| + prefs_cache_.get(),
|
| + &NotificationsPrefsCache::SetCacheDefaultContentSetting,
|
| + default_content_setting));
|
| + } else if (chrome::NOTIFICATION_EXTENSION_UNLOADED == type) {
|
| // Remove all notifications currently shown or queued by the extension
|
| // which was unloaded.
|
| const Extension* extension =
|
| @@ -271,6 +380,30 @@
|
| }
|
| }
|
|
|
| +void DesktopNotificationService::OnPrefsChanged(const std::string& pref_name) {
|
| + if (pref_name == prefs::kDesktopNotificationAllowedOrigins) {
|
| + // Schedule a cache update on the IO thread.
|
| + std::vector<GURL> allowed_origins(GetAllowedOrigins());
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(
|
| + prefs_cache_.get(),
|
| + &NotificationsPrefsCache::SetCacheAllowedOrigins,
|
| + allowed_origins));
|
| + } else if (pref_name == prefs::kDesktopNotificationDeniedOrigins) {
|
| + // Schedule a cache update on the IO thread.
|
| + std::vector<GURL> denied_origins(GetBlockedOrigins());
|
| + BrowserThread::PostTask(
|
| + BrowserThread::IO, FROM_HERE,
|
| + NewRunnableMethod(
|
| + prefs_cache_.get(),
|
| + &NotificationsPrefsCache::SetCacheDeniedOrigins,
|
| + denied_origins));
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| ContentSetting DesktopNotificationService::GetDefaultContentSetting() {
|
| return profile_->GetHostContentSettingsMap()->GetDefaultContentSetting(
|
| CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
|
| @@ -292,36 +425,70 @@
|
| CONTENT_SETTINGS_TYPE_NOTIFICATIONS, CONTENT_SETTING_DEFAULT);
|
| }
|
|
|
| -void DesktopNotificationService::GetNotificationsSettings(
|
| - HostContentSettingsMap::SettingsForOneType* settings) {
|
| - profile_->GetHostContentSettingsMap()->GetSettingsForOneType(
|
| +std::vector<GURL> DesktopNotificationService::GetAllowedOrigins() {
|
| + content_settings::ProviderInterface::Rules content_setting_rules;
|
| + provider_->GetAllContentSettingsRules(
|
| CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| NO_RESOURCE_IDENTIFIER,
|
| - settings);
|
| + &content_setting_rules);
|
| + std::vector<GURL> allowed_origins;
|
| +
|
| + GetOriginsWithSettingFromContentSettingsRules(
|
| + content_setting_rules, CONTENT_SETTING_ALLOW, &allowed_origins);
|
| +
|
| + return allowed_origins;
|
| }
|
|
|
| -void DesktopNotificationService::ClearSetting(
|
| - const ContentSettingsPattern& pattern) {
|
| - profile_->GetHostContentSettingsMap()->SetContentSetting(
|
| +std::vector<GURL> DesktopNotificationService::GetBlockedOrigins() {
|
| + content_settings::ProviderInterface::Rules content_settings_rules;
|
| + provider_->GetAllContentSettingsRules(
|
| + CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| + NO_RESOURCE_IDENTIFIER,
|
| + &content_settings_rules);
|
| + std::vector<GURL> denied_origins;
|
| +
|
| + GetOriginsWithSettingFromContentSettingsRules(
|
| + content_settings_rules, CONTENT_SETTING_BLOCK, &denied_origins);
|
| +
|
| + return denied_origins;
|
| +}
|
| +
|
| +void DesktopNotificationService::ResetAllowedOrigin(const GURL& origin) {
|
| + ContentSettingsPattern pattern =
|
| + ContentSettingsPattern::FromURLNoWildcard(origin);
|
| + provider_->SetContentSetting(
|
| pattern,
|
| - ContentSettingsPattern::Wildcard(),
|
| + pattern,
|
| CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| NO_RESOURCE_IDENTIFIER,
|
| CONTENT_SETTING_DEFAULT);
|
| }
|
|
|
| +void DesktopNotificationService::ResetBlockedOrigin(const GURL& origin) {
|
| + ContentSettingsPattern pattern =
|
| + ContentSettingsPattern::FromURLNoWildcard(origin);
|
| + provider_->SetContentSetting(
|
| + pattern,
|
| + pattern,
|
| + CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| + NO_RESOURCE_IDENTIFIER,
|
| + CONTENT_SETTING_DEFAULT);
|
| +}
|
| +
|
| void DesktopNotificationService::ResetAllOrigins() {
|
| - profile_->GetHostContentSettingsMap()->ClearSettingsForOneType(
|
| - CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
|
| + provider_->ClearAllContentSettingsRules(CONTENT_SETTINGS_TYPE_NOTIFICATIONS);
|
| }
|
|
|
| ContentSetting DesktopNotificationService::GetContentSetting(
|
| const GURL& origin) {
|
| - return profile_->GetHostContentSettingsMap()->GetContentSetting(
|
| + ContentSetting provided_setting = provider_->GetContentSetting(
|
| origin,
|
| origin,
|
| CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| NO_RESOURCE_IDENTIFIER);
|
| + if (CONTENT_SETTING_DEFAULT == provided_setting)
|
| + return GetDefaultContentSetting();
|
| + return provided_setting;
|
| }
|
|
|
| void DesktopNotificationService::RequestPermission(
|
| @@ -372,6 +539,7 @@
|
| return ui_manager_->CancelById(proxy->id());
|
| }
|
|
|
| +
|
| bool DesktopNotificationService::ShowDesktopNotification(
|
| const DesktopNotificationHostMsg_Show_Params& params,
|
| int process_id, int route_id, DesktopNotificationSource source) {
|
| @@ -421,20 +589,5 @@
|
| WebKit::WebNotificationPresenter::Permission
|
| DesktopNotificationService::HasPermission(const GURL& origin) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| - HostContentSettingsMap* host_content_settings_map =
|
| - profile_->GetHostContentSettingsMap();
|
| - ContentSetting setting = host_content_settings_map->GetContentSetting(
|
| - origin,
|
| - origin,
|
| - CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
|
| - NO_RESOURCE_IDENTIFIER);
|
| -
|
| - if (setting == CONTENT_SETTING_ALLOW)
|
| - return WebKit::WebNotificationPresenter::PermissionAllowed;
|
| - if (setting == CONTENT_SETTING_BLOCK)
|
| - return WebKit::WebNotificationPresenter::PermissionDenied;
|
| - if (setting == CONTENT_SETTING_ASK)
|
| - return WebKit::WebNotificationPresenter::PermissionNotAllowed;
|
| - NOTREACHED() << "Invalid notifications settings value: " << setting;
|
| - return WebKit::WebNotificationPresenter::PermissionNotAllowed;
|
| + return prefs_cache()->HasPermission(origin.GetOrigin());
|
| }
|
|
|