blob: 76e7c45d6e0efe71556ac3ab96f3671b43b74e95 [file] [log] [blame]
hironod36c21d2016-06-21 01:25:221// 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 Staded6d837f2017-09-29 02:51:025#include "chrome/browser/notifications/web_page_notifier_controller.h"
hironod36c21d2016-06-21 01:25:226
Evan Stadeecfc48c2019-06-17 21:35:237#include "ash/public/cpp/notifier_metadata.h"
Sebastien Marchandf1349f52019-01-25 03:16:418#include "base/bind.h"
hironod36c21d2016-06-21 01:25:229#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 Beverloodd4ef1e2018-06-21 15:41:0413#include "chrome/browser/notifications/notification_permission_context.h"
hironod36c21d2016-06-21 01:25:2214#include "chrome/browser/notifications/notifier_state_tracker.h"
15#include "chrome/browser/notifications/notifier_state_tracker_factory.h"
Clark DuValla11361ad32020-02-20 22:14:2716#include "chrome/browser/profiles/profile.h"
hironod36c21d2016-06-21 01:25:2217#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 Staded6d837f2017-09-29 02:51:0221WebPageNotifierController::WebPageNotifierController(Observer* observer)
hironod36c21d2016-06-21 01:25:2222 : observer_(observer) {}
23
Evan Staded6d837f2017-09-29 02:51:0224WebPageNotifierController::~WebPageNotifierController() {}
hironod36c21d2016-06-21 01:25:2225
Evan Stadeecfc48c2019-06-17 21:35:2326std::vector<ash::NotifierMetadata> WebPageNotifierController::GetNotifierList(
27 Profile* profile) {
28 std::vector<ash::NotifierMetadata> notifiers;
hironod36c21d2016-06-21 01:25:2229
30 ContentSettingsForOneType settings;
Peter Beverloodd4ef1e2018-06-21 15:41:0431 HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType(
Darin Fisher42f5e7d2019-10-30 07:15:4532 ContentSettingsType::NOTIFICATIONS,
Peter Beverloodd4ef1e2018-06-21 15:41:0433 content_settings::ResourceIdentifier(), &settings);
hironod36c21d2016-06-21 01:25:2234
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 Ohkubo39c81292017-12-14 02:32:3954 content_settings::SettingInfo info;
55 HostContentSettingsMapFactory::GetForProfile(profile)->GetWebsiteSetting(
Darin Fisher42f5e7d2019-10-30 07:15:4556 url, GURL(), ContentSettingsType::NOTIFICATIONS, std::string(), &info);
Evan Stadeecfc48c2019-06-17 21:35:2357 notifiers.emplace_back(
Tetsui Ohkuboc27a5dc2018-01-11 05:56:5258 notifier_id, name,
Evan Stade55575d82017-11-02 00:52:3659 notifier_state_tracker->IsNotifierEnabled(notifier_id),
Tetsui Ohkubo39c81292017-12-14 02:32:3960 info.source == content_settings::SETTING_SOURCE_POLICY,
Evan Stadeecfc48c2019-06-17 21:35:2361 gfx::ImageSkia());
Evan Stade844ad7f2017-09-20 18:05:3162 patterns_[url_pattern] = iter->primary_pattern;
hironod36c21d2016-06-21 01:25:2263 // 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 Stade844ad7f2017-09-20 18:05:3167 url,
Evan Staded6d837f2017-09-29 02:51:0268 base::Bind(&WebPageNotifierController::OnFaviconLoaded,
Evan Stade844ad7f2017-09-20 18:05:3169 base::Unretained(this), url),
hironod36c21d2016-06-21 01:25:2270 favicon_tracker_.get());
71 }
72
73 return notifiers;
74}
75
Evan Staded6d837f2017-09-29 02:51:0276void WebPageNotifierController::SetNotifierEnabled(
hironod36c21d2016-06-21 01:25:2277 Profile* profile,
Evan Stade844ad7f2017-09-20 18:05:3178 const message_center::NotifierId& notifier_id,
hironod36c21d2016-06-21 01:25:2279 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 Fisher42f5e7d2019-10-30 07:15:4585 ->GetDefaultContentSetting(ContentSettingsType::NOTIFICATIONS, NULL);
hironod36c21d2016-06-21 01:25:2286
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 Stade844ad7f2017-09-20 18:05:3199 if (notifier_id.url.is_valid()) {
Peter Beverloodd4ef1e2018-06-21 15:41:04100 NotificationPermissionContext::UpdatePermission(
101 profile, notifier_id.url,
102 enabled ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
hironod36c21d2016-06-21 01:25:22103 } else {
Evan Stade844ad7f2017-09-20 18:05:31104 LOG(ERROR) << "Invalid url pattern: "
105 << notifier_id.url.possibly_invalid_spec();
hironod36c21d2016-06-21 01:25:22106 }
107 } else {
108 ContentSettingsPattern pattern;
109
Evan Stade844ad7f2017-09-20 18:05:31110 const auto& iter = patterns_.find(notifier_id.url.possibly_invalid_spec());
hironod36c21d2016-06-21 01:25:22111 if (iter != patterns_.end()) {
112 pattern = iter->second;
Evan Stade844ad7f2017-09-20 18:05:31113 } else if (notifier_id.url.is_valid()) {
114 pattern = ContentSettingsPattern::FromURLNoWildcard(notifier_id.url);
hironod36c21d2016-06-21 01:25:22115 } else {
Evan Stade844ad7f2017-09-20 18:05:31116 LOG(ERROR) << "Invalid url pattern: "
117 << notifier_id.url.possibly_invalid_spec();
hironod36c21d2016-06-21 01:25:22118 }
119
120 if (pattern.IsValid()) {
121 // Note that we don't use
Peter Beverloodd4ef1e2018-06-21 15:41:04122 // NotificationPermissionContext::UpdatePermission()
hironod36c21d2016-06-21 01:25:22123 // 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 Fisher42f5e7d2019-10-30 07:15:45128 ContentSettingsType::NOTIFICATIONS,
hironod36c21d2016-06-21 01:25:22129 content_settings::ResourceIdentifier(), CONTENT_SETTING_DEFAULT);
130 }
131 }
132
Evan Stade844ad7f2017-09-20 18:05:31133 observer_->OnNotifierEnabledChanged(notifier_id, enabled);
hironod36c21d2016-06-21 01:25:22134}
135
Evan Staded6d837f2017-09-29 02:51:02136void WebPageNotifierController::OnFaviconLoaded(
hironod36c21d2016-06-21 01:25:22137 const GURL& url,
138 const favicon_base::FaviconImageResult& favicon_result) {
139 observer_->OnIconImageUpdated(message_center::NotifierId(url),
Evan Stade55575d82017-11-02 00:52:36140 favicon_result.image.AsImageSkia());
hironod36c21d2016-06-21 01:25:22141}