blob: bfa86eb481015118236a482d45d0cd158580865e [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2016 The Chromium Authors
hironod36c21d2016-06-21 01:25:222// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Evan Staded6d837f2017-09-29 02:51:025#include "chrome/browser/notifications/web_page_notifier_controller.h"
hironod36c21d2016-06-21 01:25:226
Peter Boström6b701822021-04-15 03:53:087#include <memory>
8
Evan Stadeecfc48c2019-06-17 21:35:239#include "ash/public/cpp/notifier_metadata.h"
Sebastien Marchandf1349f52019-01-25 03:16:4110#include "base/bind.h"
Kent Tamura49b48d5c2020-07-14 05:55:4111#include "base/logging.h"
hironod36c21d2016-06-21 01:25:2212#include "base/strings/utf_string_conversions.h"
13#include "base/task/cancelable_task_tracker.h"
14#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
15#include "chrome/browser/favicon/favicon_service_factory.h"
Peter Beverloodd4ef1e2018-06-21 15:41:0416#include "chrome/browser/notifications/notification_permission_context.h"
hironod36c21d2016-06-21 01:25:2217#include "chrome/browser/notifications/notifier_state_tracker.h"
18#include "chrome/browser/notifications/notifier_state_tracker_factory.h"
Clark DuValla11361ad32020-02-20 22:14:2719#include "chrome/browser/profiles/profile.h"
hironod36c21d2016-06-21 01:25:2220#include "components/content_settings/core/browser/host_content_settings_map.h"
21#include "components/content_settings/core/common/content_settings.h"
22#include "components/favicon/core/favicon_service.h"
23
Evan Staded6d837f2017-09-29 02:51:0224WebPageNotifierController::WebPageNotifierController(Observer* observer)
hironod36c21d2016-06-21 01:25:2225 : observer_(observer) {}
26
Evan Staded6d837f2017-09-29 02:51:0227WebPageNotifierController::~WebPageNotifierController() {}
hironod36c21d2016-06-21 01:25:2228
Evan Stadeecfc48c2019-06-17 21:35:2329std::vector<ash::NotifierMetadata> WebPageNotifierController::GetNotifierList(
30 Profile* profile) {
31 std::vector<ash::NotifierMetadata> notifiers;
hironod36c21d2016-06-21 01:25:2232
33 ContentSettingsForOneType settings;
Peter Beverloodd4ef1e2018-06-21 15:41:0434 HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType(
Illia Klimov48f643c2020-11-05 20:06:1435 ContentSettingsType::NOTIFICATIONS, &settings);
hironod36c21d2016-06-21 01:25:2236
37 favicon::FaviconService* const favicon_service =
38 FaviconServiceFactory::GetForProfile(profile,
39 ServiceAccessType::EXPLICIT_ACCESS);
Peter Boström6b701822021-04-15 03:53:0840 favicon_tracker_ = std::make_unique<base::CancelableTaskTracker>();
hironod36c21d2016-06-21 01:25:2241 patterns_.clear();
42 for (ContentSettingsForOneType::const_iterator iter = settings.begin();
43 iter != settings.end(); ++iter) {
44 if (iter->primary_pattern == ContentSettingsPattern::Wildcard() &&
45 iter->secondary_pattern == ContentSettingsPattern::Wildcard() &&
46 iter->source != "preference") {
47 continue;
48 }
49
50 std::string url_pattern = iter->primary_pattern.ToString();
Jan Wilken Dörriedec99122021-03-11 18:02:3051 std::u16string name = base::UTF8ToUTF16(url_pattern);
hironod36c21d2016-06-21 01:25:2252 GURL url(url_pattern);
53 message_center::NotifierId notifier_id(url);
54 NotifierStateTracker* const notifier_state_tracker =
55 NotifierStateTrackerFactory::GetForProfile(profile);
Tetsui Ohkubo39c81292017-12-14 02:32:3956 content_settings::SettingInfo info;
57 HostContentSettingsMapFactory::GetForProfile(profile)->GetWebsiteSetting(
Illia Klimov48f643c2020-11-05 20:06:1458 url, GURL(), ContentSettingsType::NOTIFICATIONS, &info);
Evan Stadeecfc48c2019-06-17 21:35:2359 notifiers.emplace_back(
Tetsui Ohkuboc27a5dc2018-01-11 05:56:5260 notifier_id, name,
Evan Stade55575d82017-11-02 00:52:3661 notifier_state_tracker->IsNotifierEnabled(notifier_id),
Tetsui Ohkubo39c81292017-12-14 02:32:3962 info.source == content_settings::SETTING_SOURCE_POLICY,
Evan Stadeecfc48c2019-06-17 21:35:2363 gfx::ImageSkia());
Evan Stade844ad7f2017-09-20 18:05:3164 patterns_[url_pattern] = iter->primary_pattern;
hironod36c21d2016-06-21 01:25:2265 // Note that favicon service obtains the favicon from history. This means
66 // that it will fail to obtain the image if there are no history data for
67 // that URL.
68 favicon_service->GetFaviconImageForPageURL(
Evan Stade844ad7f2017-09-20 18:05:3169 url,
Jan Wilken Dörrie8b2247e2020-04-20 10:04:4070 base::BindOnce(&WebPageNotifierController::OnFaviconLoaded,
71 base::Unretained(this), url),
hironod36c21d2016-06-21 01:25:2272 favicon_tracker_.get());
73 }
74
75 return notifiers;
76}
77
Evan Staded6d837f2017-09-29 02:51:0278void WebPageNotifierController::SetNotifierEnabled(
hironod36c21d2016-06-21 01:25:2279 Profile* profile,
Evan Stade844ad7f2017-09-20 18:05:3180 const message_center::NotifierId& notifier_id,
hironod36c21d2016-06-21 01:25:2281 bool enabled) {
82 // WEB_PAGE notifier cannot handle in DesktopNotificationService
83 // since it has the exact URL pattern.
84 // TODO(mukai): fix this.
85 ContentSetting default_setting =
86 HostContentSettingsMapFactory::GetForProfile(profile)
Claudio DeSouzac2c9f0f2022-09-02 23:59:1887 ->GetDefaultContentSetting(ContentSettingsType::NOTIFICATIONS,
88 nullptr);
hironod36c21d2016-06-21 01:25:2289
90 DCHECK(default_setting == CONTENT_SETTING_ALLOW ||
91 default_setting == CONTENT_SETTING_BLOCK ||
92 default_setting == CONTENT_SETTING_ASK);
93
94 // The content setting for notifications needs to clear when it changes to
95 // the default value or get explicitly set when it differs from the
96 // default.
97 bool differs_from_default_value =
98 (default_setting != CONTENT_SETTING_ALLOW && enabled) ||
99 (default_setting == CONTENT_SETTING_ALLOW && !enabled);
100
101 if (differs_from_default_value) {
Evan Stade844ad7f2017-09-20 18:05:31102 if (notifier_id.url.is_valid()) {
Peter Beverloodd4ef1e2018-06-21 15:41:04103 NotificationPermissionContext::UpdatePermission(
104 profile, notifier_id.url,
105 enabled ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
hironod36c21d2016-06-21 01:25:22106 } else {
Evan Stade844ad7f2017-09-20 18:05:31107 LOG(ERROR) << "Invalid url pattern: "
108 << notifier_id.url.possibly_invalid_spec();
hironod36c21d2016-06-21 01:25:22109 }
110 } else {
111 ContentSettingsPattern pattern;
112
Evan Stade844ad7f2017-09-20 18:05:31113 const auto& iter = patterns_.find(notifier_id.url.possibly_invalid_spec());
hironod36c21d2016-06-21 01:25:22114 if (iter != patterns_.end()) {
115 pattern = iter->second;
Evan Stade844ad7f2017-09-20 18:05:31116 } else if (notifier_id.url.is_valid()) {
117 pattern = ContentSettingsPattern::FromURLNoWildcard(notifier_id.url);
hironod36c21d2016-06-21 01:25:22118 } else {
Evan Stade844ad7f2017-09-20 18:05:31119 LOG(ERROR) << "Invalid url pattern: "
120 << notifier_id.url.possibly_invalid_spec();
hironod36c21d2016-06-21 01:25:22121 }
122
123 if (pattern.IsValid()) {
124 // Note that we don't use
Peter Beverloodd4ef1e2018-06-21 15:41:04125 // NotificationPermissionContext::UpdatePermission()
hironod36c21d2016-06-21 01:25:22126 // here because pattern might be from user manual input and not match
127 // the default one used by ClearSetting().
128 HostContentSettingsMapFactory::GetForProfile(profile)
129 ->SetContentSettingCustomScope(
130 pattern, ContentSettingsPattern::Wildcard(),
Illia Klimov48f643c2020-11-05 20:06:14131 ContentSettingsType::NOTIFICATIONS, CONTENT_SETTING_DEFAULT);
hironod36c21d2016-06-21 01:25:22132 }
133 }
134
Evan Stade844ad7f2017-09-20 18:05:31135 observer_->OnNotifierEnabledChanged(notifier_id, enabled);
hironod36c21d2016-06-21 01:25:22136}
137
Evan Staded6d837f2017-09-29 02:51:02138void WebPageNotifierController::OnFaviconLoaded(
hironod36c21d2016-06-21 01:25:22139 const GURL& url,
140 const favicon_base::FaviconImageResult& favicon_result) {
141 observer_->OnIconImageUpdated(message_center::NotifierId(url),
Evan Stade55575d82017-11-02 00:52:36142 favicon_result.image.AsImageSkia());
hironod36c21d2016-06-21 01:25:22143}