hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 1 | // Copyright (c) 2016 The Chromium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 5 | #include "chrome/browser/notifications/web_page_notifier_controller.h" |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 6 | |
Evan Stade | ecfc48c | 2019-06-17 21:35:23 | [diff] [blame] | 7 | #include "ash/public/cpp/notifier_metadata.h" |
Sebastien Marchand | f1349f5 | 2019-01-25 03:16:41 | [diff] [blame] | 8 | #include "base/bind.h" |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 9 | #include "base/strings/utf_string_conversions.h" |
| 10 | #include "base/task/cancelable_task_tracker.h" |
| 11 | #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 12 | #include "chrome/browser/favicon/favicon_service_factory.h" |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 13 | #include "chrome/browser/notifications/notification_permission_context.h" |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 14 | #include "chrome/browser/notifications/notifier_state_tracker.h" |
| 15 | #include "chrome/browser/notifications/notifier_state_tracker_factory.h" |
Clark DuVall | a11361ad3 | 2020-02-20 22:14:27 | [diff] [blame^] | 16 | #include "chrome/browser/profiles/profile.h" |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 17 | #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 18 | #include "components/content_settings/core/common/content_settings.h" |
| 19 | #include "components/favicon/core/favicon_service.h" |
| 20 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 21 | WebPageNotifierController::WebPageNotifierController(Observer* observer) |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 22 | : observer_(observer) {} |
| 23 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 24 | WebPageNotifierController::~WebPageNotifierController() {} |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 25 | |
Evan Stade | ecfc48c | 2019-06-17 21:35:23 | [diff] [blame] | 26 | std::vector<ash::NotifierMetadata> WebPageNotifierController::GetNotifierList( |
| 27 | Profile* profile) { |
| 28 | std::vector<ash::NotifierMetadata> notifiers; |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 29 | |
| 30 | ContentSettingsForOneType settings; |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 31 | HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType( |
Darin Fisher | 42f5e7d | 2019-10-30 07:15:45 | [diff] [blame] | 32 | ContentSettingsType::NOTIFICATIONS, |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 33 | content_settings::ResourceIdentifier(), &settings); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 34 | |
| 35 | favicon::FaviconService* const favicon_service = |
| 36 | FaviconServiceFactory::GetForProfile(profile, |
| 37 | ServiceAccessType::EXPLICIT_ACCESS); |
| 38 | favicon_tracker_.reset(new base::CancelableTaskTracker()); |
| 39 | patterns_.clear(); |
| 40 | for (ContentSettingsForOneType::const_iterator iter = settings.begin(); |
| 41 | iter != settings.end(); ++iter) { |
| 42 | if (iter->primary_pattern == ContentSettingsPattern::Wildcard() && |
| 43 | iter->secondary_pattern == ContentSettingsPattern::Wildcard() && |
| 44 | iter->source != "preference") { |
| 45 | continue; |
| 46 | } |
| 47 | |
| 48 | std::string url_pattern = iter->primary_pattern.ToString(); |
| 49 | base::string16 name = base::UTF8ToUTF16(url_pattern); |
| 50 | GURL url(url_pattern); |
| 51 | message_center::NotifierId notifier_id(url); |
| 52 | NotifierStateTracker* const notifier_state_tracker = |
| 53 | NotifierStateTrackerFactory::GetForProfile(profile); |
Tetsui Ohkubo | 39c8129 | 2017-12-14 02:32:39 | [diff] [blame] | 54 | content_settings::SettingInfo info; |
| 55 | HostContentSettingsMapFactory::GetForProfile(profile)->GetWebsiteSetting( |
Darin Fisher | 42f5e7d | 2019-10-30 07:15:45 | [diff] [blame] | 56 | url, GURL(), ContentSettingsType::NOTIFICATIONS, std::string(), &info); |
Evan Stade | ecfc48c | 2019-06-17 21:35:23 | [diff] [blame] | 57 | notifiers.emplace_back( |
Tetsui Ohkubo | c27a5dc | 2018-01-11 05:56:52 | [diff] [blame] | 58 | notifier_id, name, |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 59 | notifier_state_tracker->IsNotifierEnabled(notifier_id), |
Tetsui Ohkubo | 39c8129 | 2017-12-14 02:32:39 | [diff] [blame] | 60 | info.source == content_settings::SETTING_SOURCE_POLICY, |
Evan Stade | ecfc48c | 2019-06-17 21:35:23 | [diff] [blame] | 61 | gfx::ImageSkia()); |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 62 | patterns_[url_pattern] = iter->primary_pattern; |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 63 | // Note that favicon service obtains the favicon from history. This means |
| 64 | // that it will fail to obtain the image if there are no history data for |
| 65 | // that URL. |
| 66 | favicon_service->GetFaviconImageForPageURL( |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 67 | url, |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 68 | base::Bind(&WebPageNotifierController::OnFaviconLoaded, |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 69 | base::Unretained(this), url), |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 70 | favicon_tracker_.get()); |
| 71 | } |
| 72 | |
| 73 | return notifiers; |
| 74 | } |
| 75 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 76 | void WebPageNotifierController::SetNotifierEnabled( |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 77 | Profile* profile, |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 78 | const message_center::NotifierId& notifier_id, |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 79 | bool enabled) { |
| 80 | // WEB_PAGE notifier cannot handle in DesktopNotificationService |
| 81 | // since it has the exact URL pattern. |
| 82 | // TODO(mukai): fix this. |
| 83 | ContentSetting default_setting = |
| 84 | HostContentSettingsMapFactory::GetForProfile(profile) |
Darin Fisher | 42f5e7d | 2019-10-30 07:15:45 | [diff] [blame] | 85 | ->GetDefaultContentSetting(ContentSettingsType::NOTIFICATIONS, NULL); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 86 | |
| 87 | DCHECK(default_setting == CONTENT_SETTING_ALLOW || |
| 88 | default_setting == CONTENT_SETTING_BLOCK || |
| 89 | default_setting == CONTENT_SETTING_ASK); |
| 90 | |
| 91 | // The content setting for notifications needs to clear when it changes to |
| 92 | // the default value or get explicitly set when it differs from the |
| 93 | // default. |
| 94 | bool differs_from_default_value = |
| 95 | (default_setting != CONTENT_SETTING_ALLOW && enabled) || |
| 96 | (default_setting == CONTENT_SETTING_ALLOW && !enabled); |
| 97 | |
| 98 | if (differs_from_default_value) { |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 99 | if (notifier_id.url.is_valid()) { |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 100 | NotificationPermissionContext::UpdatePermission( |
| 101 | profile, notifier_id.url, |
| 102 | enabled ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 103 | } else { |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 104 | LOG(ERROR) << "Invalid url pattern: " |
| 105 | << notifier_id.url.possibly_invalid_spec(); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 106 | } |
| 107 | } else { |
| 108 | ContentSettingsPattern pattern; |
| 109 | |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 110 | const auto& iter = patterns_.find(notifier_id.url.possibly_invalid_spec()); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 111 | if (iter != patterns_.end()) { |
| 112 | pattern = iter->second; |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 113 | } else if (notifier_id.url.is_valid()) { |
| 114 | pattern = ContentSettingsPattern::FromURLNoWildcard(notifier_id.url); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 115 | } else { |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 116 | LOG(ERROR) << "Invalid url pattern: " |
| 117 | << notifier_id.url.possibly_invalid_spec(); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | if (pattern.IsValid()) { |
| 121 | // Note that we don't use |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 122 | // NotificationPermissionContext::UpdatePermission() |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 123 | // here because pattern might be from user manual input and not match |
| 124 | // the default one used by ClearSetting(). |
| 125 | HostContentSettingsMapFactory::GetForProfile(profile) |
| 126 | ->SetContentSettingCustomScope( |
| 127 | pattern, ContentSettingsPattern::Wildcard(), |
Darin Fisher | 42f5e7d | 2019-10-30 07:15:45 | [diff] [blame] | 128 | ContentSettingsType::NOTIFICATIONS, |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 129 | content_settings::ResourceIdentifier(), CONTENT_SETTING_DEFAULT); |
| 130 | } |
| 131 | } |
| 132 | |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 133 | observer_->OnNotifierEnabledChanged(notifier_id, enabled); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 134 | } |
| 135 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 136 | void WebPageNotifierController::OnFaviconLoaded( |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 137 | const GURL& url, |
| 138 | const favicon_base::FaviconImageResult& favicon_result) { |
| 139 | observer_->OnIconImageUpdated(message_center::NotifierId(url), |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 140 | favicon_result.image.AsImageSkia()); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 141 | } |