blob: 4eeb877b498732de1ef846b02d938cb0bdc5bc22 [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
Sebastien Marchandf1349f52019-01-25 03:16:417#include "base/bind.h"
hironod36c21d2016-06-21 01:25:228#include "base/strings/utf_string_conversions.h"
9#include "base/task/cancelable_task_tracker.h"
10#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
11#include "chrome/browser/favicon/favicon_service_factory.h"
Peter Beverloodd4ef1e2018-06-21 15:41:0412#include "chrome/browser/notifications/notification_permission_context.h"
hironod36c21d2016-06-21 01:25:2213#include "chrome/browser/notifications/notifier_state_tracker.h"
14#include "chrome/browser/notifications/notifier_state_tracker_factory.h"
15#include "components/content_settings/core/browser/host_content_settings_map.h"
16#include "components/content_settings/core/common/content_settings.h"
17#include "components/favicon/core/favicon_service.h"
18
Evan Staded6d837f2017-09-29 02:51:0219WebPageNotifierController::WebPageNotifierController(Observer* observer)
hironod36c21d2016-06-21 01:25:2220 : observer_(observer) {}
21
Evan Staded6d837f2017-09-29 02:51:0222WebPageNotifierController::~WebPageNotifierController() {}
hironod36c21d2016-06-21 01:25:2223
Evan Stade55575d82017-11-02 00:52:3624std::vector<ash::mojom::NotifierUiDataPtr>
Evan Staded6d837f2017-09-29 02:51:0225WebPageNotifierController::GetNotifierList(Profile* profile) {
Evan Stade55575d82017-11-02 00:52:3626 std::vector<ash::mojom::NotifierUiDataPtr> notifiers;
hironod36c21d2016-06-21 01:25:2227
28 ContentSettingsForOneType settings;
Peter Beverloodd4ef1e2018-06-21 15:41:0429 HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType(
30 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
31 content_settings::ResourceIdentifier(), &settings);
hironod36c21d2016-06-21 01:25:2232
33 favicon::FaviconService* const favicon_service =
34 FaviconServiceFactory::GetForProfile(profile,
35 ServiceAccessType::EXPLICIT_ACCESS);
36 favicon_tracker_.reset(new base::CancelableTaskTracker());
37 patterns_.clear();
38 for (ContentSettingsForOneType::const_iterator iter = settings.begin();
39 iter != settings.end(); ++iter) {
40 if (iter->primary_pattern == ContentSettingsPattern::Wildcard() &&
41 iter->secondary_pattern == ContentSettingsPattern::Wildcard() &&
42 iter->source != "preference") {
43 continue;
44 }
45
46 std::string url_pattern = iter->primary_pattern.ToString();
47 base::string16 name = base::UTF8ToUTF16(url_pattern);
48 GURL url(url_pattern);
49 message_center::NotifierId notifier_id(url);
50 NotifierStateTracker* const notifier_state_tracker =
51 NotifierStateTrackerFactory::GetForProfile(profile);
Tetsui Ohkubo39c81292017-12-14 02:32:3952 content_settings::SettingInfo info;
53 HostContentSettingsMapFactory::GetForProfile(profile)->GetWebsiteSetting(
54 url, GURL(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string(), &info);
Evan Stade55575d82017-11-02 00:52:3655 notifiers.push_back(ash::mojom::NotifierUiData::New(
Tetsui Ohkuboc27a5dc2018-01-11 05:56:5256 notifier_id, name,
Evan Stade55575d82017-11-02 00:52:3657 notifier_state_tracker->IsNotifierEnabled(notifier_id),
Tetsui Ohkubo39c81292017-12-14 02:32:3958 info.source == content_settings::SETTING_SOURCE_POLICY,
Evan Stade55575d82017-11-02 00:52:3659 gfx::ImageSkia()));
Evan Stade844ad7f2017-09-20 18:05:3160 patterns_[url_pattern] = iter->primary_pattern;
hironod36c21d2016-06-21 01:25:2261 // Note that favicon service obtains the favicon from history. This means
62 // that it will fail to obtain the image if there are no history data for
63 // that URL.
64 favicon_service->GetFaviconImageForPageURL(
Evan Stade844ad7f2017-09-20 18:05:3165 url,
Evan Staded6d837f2017-09-29 02:51:0266 base::Bind(&WebPageNotifierController::OnFaviconLoaded,
Evan Stade844ad7f2017-09-20 18:05:3167 base::Unretained(this), url),
hironod36c21d2016-06-21 01:25:2268 favicon_tracker_.get());
69 }
70
71 return notifiers;
72}
73
Evan Staded6d837f2017-09-29 02:51:0274void WebPageNotifierController::SetNotifierEnabled(
hironod36c21d2016-06-21 01:25:2275 Profile* profile,
Evan Stade844ad7f2017-09-20 18:05:3176 const message_center::NotifierId& notifier_id,
hironod36c21d2016-06-21 01:25:2277 bool enabled) {
78 // WEB_PAGE notifier cannot handle in DesktopNotificationService
79 // since it has the exact URL pattern.
80 // TODO(mukai): fix this.
81 ContentSetting default_setting =
82 HostContentSettingsMapFactory::GetForProfile(profile)
83 ->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_NOTIFICATIONS, NULL);
84
85 DCHECK(default_setting == CONTENT_SETTING_ALLOW ||
86 default_setting == CONTENT_SETTING_BLOCK ||
87 default_setting == CONTENT_SETTING_ASK);
88
89 // The content setting for notifications needs to clear when it changes to
90 // the default value or get explicitly set when it differs from the
91 // default.
92 bool differs_from_default_value =
93 (default_setting != CONTENT_SETTING_ALLOW && enabled) ||
94 (default_setting == CONTENT_SETTING_ALLOW && !enabled);
95
96 if (differs_from_default_value) {
Evan Stade844ad7f2017-09-20 18:05:3197 if (notifier_id.url.is_valid()) {
Peter Beverloodd4ef1e2018-06-21 15:41:0498 NotificationPermissionContext::UpdatePermission(
99 profile, notifier_id.url,
100 enabled ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
hironod36c21d2016-06-21 01:25:22101 } else {
Evan Stade844ad7f2017-09-20 18:05:31102 LOG(ERROR) << "Invalid url pattern: "
103 << notifier_id.url.possibly_invalid_spec();
hironod36c21d2016-06-21 01:25:22104 }
105 } else {
106 ContentSettingsPattern pattern;
107
Evan Stade844ad7f2017-09-20 18:05:31108 const auto& iter = patterns_.find(notifier_id.url.possibly_invalid_spec());
hironod36c21d2016-06-21 01:25:22109 if (iter != patterns_.end()) {
110 pattern = iter->second;
Evan Stade844ad7f2017-09-20 18:05:31111 } else if (notifier_id.url.is_valid()) {
112 pattern = ContentSettingsPattern::FromURLNoWildcard(notifier_id.url);
hironod36c21d2016-06-21 01:25:22113 } else {
Evan Stade844ad7f2017-09-20 18:05:31114 LOG(ERROR) << "Invalid url pattern: "
115 << notifier_id.url.possibly_invalid_spec();
hironod36c21d2016-06-21 01:25:22116 }
117
118 if (pattern.IsValid()) {
119 // Note that we don't use
Peter Beverloodd4ef1e2018-06-21 15:41:04120 // NotificationPermissionContext::UpdatePermission()
hironod36c21d2016-06-21 01:25:22121 // here because pattern might be from user manual input and not match
122 // the default one used by ClearSetting().
123 HostContentSettingsMapFactory::GetForProfile(profile)
124 ->SetContentSettingCustomScope(
125 pattern, ContentSettingsPattern::Wildcard(),
126 CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
127 content_settings::ResourceIdentifier(), CONTENT_SETTING_DEFAULT);
128 }
129 }
130
Evan Stade844ad7f2017-09-20 18:05:31131 observer_->OnNotifierEnabledChanged(notifier_id, enabled);
hironod36c21d2016-06-21 01:25:22132}
133
Evan Staded6d837f2017-09-29 02:51:02134void WebPageNotifierController::OnFaviconLoaded(
hironod36c21d2016-06-21 01:25:22135 const GURL& url,
136 const favicon_base::FaviconImageResult& favicon_result) {
137 observer_->OnIconImageUpdated(message_center::NotifierId(url),
Evan Stade55575d82017-11-02 00:52:36138 favicon_result.image.AsImageSkia());
hironod36c21d2016-06-21 01:25:22139}