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 | |
Sebastien Marchand | f1349f5 | 2019-01-25 03:16:41 | [diff] [blame^] | 7 | #include "base/bind.h" |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 8 | #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 Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 12 | #include "chrome/browser/notifications/notification_permission_context.h" |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 13 | #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 Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 19 | WebPageNotifierController::WebPageNotifierController(Observer* observer) |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 20 | : observer_(observer) {} |
| 21 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 22 | WebPageNotifierController::~WebPageNotifierController() {} |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 23 | |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 24 | std::vector<ash::mojom::NotifierUiDataPtr> |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 25 | WebPageNotifierController::GetNotifierList(Profile* profile) { |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 26 | std::vector<ash::mojom::NotifierUiDataPtr> notifiers; |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 27 | |
| 28 | ContentSettingsForOneType settings; |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 29 | HostContentSettingsMapFactory::GetForProfile(profile)->GetSettingsForOneType( |
| 30 | CONTENT_SETTINGS_TYPE_NOTIFICATIONS, |
| 31 | content_settings::ResourceIdentifier(), &settings); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 32 | |
| 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 Ohkubo | 39c8129 | 2017-12-14 02:32:39 | [diff] [blame] | 52 | content_settings::SettingInfo info; |
| 53 | HostContentSettingsMapFactory::GetForProfile(profile)->GetWebsiteSetting( |
| 54 | url, GURL(), CONTENT_SETTINGS_TYPE_NOTIFICATIONS, std::string(), &info); |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 55 | notifiers.push_back(ash::mojom::NotifierUiData::New( |
Tetsui Ohkubo | c27a5dc | 2018-01-11 05:56:52 | [diff] [blame] | 56 | notifier_id, name, |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 57 | notifier_state_tracker->IsNotifierEnabled(notifier_id), |
Tetsui Ohkubo | 39c8129 | 2017-12-14 02:32:39 | [diff] [blame] | 58 | info.source == content_settings::SETTING_SOURCE_POLICY, |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 59 | gfx::ImageSkia())); |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 60 | patterns_[url_pattern] = iter->primary_pattern; |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 61 | // 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 Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 65 | url, |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 66 | base::Bind(&WebPageNotifierController::OnFaviconLoaded, |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 67 | base::Unretained(this), url), |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 68 | favicon_tracker_.get()); |
| 69 | } |
| 70 | |
| 71 | return notifiers; |
| 72 | } |
| 73 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 74 | void WebPageNotifierController::SetNotifierEnabled( |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 75 | Profile* profile, |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 76 | const message_center::NotifierId& notifier_id, |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 77 | 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 Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 97 | if (notifier_id.url.is_valid()) { |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 98 | NotificationPermissionContext::UpdatePermission( |
| 99 | profile, notifier_id.url, |
| 100 | enabled ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 101 | } else { |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 102 | LOG(ERROR) << "Invalid url pattern: " |
| 103 | << notifier_id.url.possibly_invalid_spec(); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 104 | } |
| 105 | } else { |
| 106 | ContentSettingsPattern pattern; |
| 107 | |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 108 | const auto& iter = patterns_.find(notifier_id.url.possibly_invalid_spec()); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 109 | if (iter != patterns_.end()) { |
| 110 | pattern = iter->second; |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 111 | } else if (notifier_id.url.is_valid()) { |
| 112 | pattern = ContentSettingsPattern::FromURLNoWildcard(notifier_id.url); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 113 | } else { |
Evan Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 114 | LOG(ERROR) << "Invalid url pattern: " |
| 115 | << notifier_id.url.possibly_invalid_spec(); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 116 | } |
| 117 | |
| 118 | if (pattern.IsValid()) { |
| 119 | // Note that we don't use |
Peter Beverloo | dd4ef1e | 2018-06-21 15:41:04 | [diff] [blame] | 120 | // NotificationPermissionContext::UpdatePermission() |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 121 | // 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 Stade | 844ad7f | 2017-09-20 18:05:31 | [diff] [blame] | 131 | observer_->OnNotifierEnabledChanged(notifier_id, enabled); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 132 | } |
| 133 | |
Evan Stade | d6d837f | 2017-09-29 02:51:02 | [diff] [blame] | 134 | void WebPageNotifierController::OnFaviconLoaded( |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 135 | const GURL& url, |
| 136 | const favicon_base::FaviconImageResult& favicon_result) { |
| 137 | observer_->OnIconImageUpdated(message_center::NotifierId(url), |
Evan Stade | 55575d8 | 2017-11-02 00:52:36 | [diff] [blame] | 138 | favicon_result.image.AsImageSkia()); |
hirono | d36c21d | 2016-06-21 01:25:22 | [diff] [blame] | 139 | } |