OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/android/ntp/content_suggestions_notifier_service.h" | 5 #include "chrome/browser/android/ntp/content_suggestions_notifier_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/android/application_status_listener.h" | 9 #include "base/android/application_status_listener.h" |
10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 Profile* profile, | 70 Profile* profile, |
71 PrefService* prefs) | 71 PrefService* prefs) |
72 : service_(service), | 72 : service_(service), |
73 profile_(profile), | 73 profile_(profile), |
74 prefs_(prefs), | 74 prefs_(prefs), |
75 app_status_listener_(base::Bind(&NotifyingObserver::AppStatusChanged, | 75 app_status_listener_(base::Bind(&NotifyingObserver::AppStatusChanged, |
76 base::Unretained(this))), | 76 base::Unretained(this))), |
77 weak_ptr_factory_(this) {} | 77 weak_ptr_factory_(this) {} |
78 | 78 |
79 void OnNewSuggestions(Category category) override { | 79 void OnNewSuggestions(Category category) override { |
80 if (!ShouldNotifyInState(app_status_listener_.GetState()) || | 80 if (!ShouldNotifyInState(app_status_listener_.GetState())) { |
81 ContentSuggestionsNotificationHelper::IsDisabledForProfile(profile_)) { | 81 DVLOG(1) << "Suppressed notification because Chrome is frontmost"; |
82 DVLOG(1) << "notification suppressed"; | 82 return; |
| 83 } else if (ContentSuggestionsNotificationHelper::IsDisabledForProfile( |
| 84 profile_)) { |
| 85 DVLOG(1) << "Suppressed notification due to opt-out"; |
83 return; | 86 return; |
84 } | 87 } |
85 const ContentSuggestion* suggestion = GetSuggestionToNotifyAbout(category); | 88 const ContentSuggestion* suggestion = GetSuggestionToNotifyAbout(category); |
86 if (!suggestion) { | 89 if (!suggestion) { |
87 return; | 90 return; |
88 } | 91 } |
89 base::Time timeout_at = suggestion->notification_extra() | 92 base::Time timeout_at = suggestion->notification_extra() |
90 ? suggestion->notification_extra()->deadline | 93 ? suggestion->notification_extra()->deadline |
91 : base::Time::Max(); | 94 : base::Time::Max(); |
92 service_->FetchSuggestionImage( | 95 service_->FetchSuggestionImage( |
(...skipping 12 matching lines...) Expand all Loading... |
105 switch (new_status) { | 108 switch (new_status) { |
106 case CategoryStatus::AVAILABLE: | 109 case CategoryStatus::AVAILABLE: |
107 case CategoryStatus::AVAILABLE_LOADING: | 110 case CategoryStatus::AVAILABLE_LOADING: |
108 break; // nothing to do | 111 break; // nothing to do |
109 case CategoryStatus::INITIALIZING: | 112 case CategoryStatus::INITIALIZING: |
110 case CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED: | 113 case CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED: |
111 case CategoryStatus::CATEGORY_EXPLICITLY_DISABLED: | 114 case CategoryStatus::CATEGORY_EXPLICITLY_DISABLED: |
112 case CategoryStatus::LOADING_ERROR: | 115 case CategoryStatus::LOADING_ERROR: |
113 case CategoryStatus::NOT_PROVIDED: | 116 case CategoryStatus::NOT_PROVIDED: |
114 case CategoryStatus::SIGNED_OUT: | 117 case CategoryStatus::SIGNED_OUT: |
115 ContentSuggestionsNotificationHelper::HideAllNotifications(); | 118 ContentSuggestionsNotificationHelper::HideAllNotifications( |
116 RecordContentSuggestionsNotificationAction( | |
117 CONTENT_SUGGESTIONS_HIDE_DISABLED); | 119 CONTENT_SUGGESTIONS_HIDE_DISABLED); |
118 break; | 120 break; |
119 } | 121 } |
120 } | 122 } |
121 | 123 |
122 void OnSuggestionInvalidated( | 124 void OnSuggestionInvalidated( |
123 const ContentSuggestion::ID& suggestion_id) override { | 125 const ContentSuggestion::ID& suggestion_id) override { |
124 // TODO(sfiera): handle concurrent notifications and non-articles properly. | 126 // TODO(sfiera): handle concurrent notifications and non-articles properly. |
125 if (suggestion_id.category().IsKnownCategory(KnownCategories::ARTICLES) && | 127 if (suggestion_id.category().IsKnownCategory(KnownCategories::ARTICLES) && |
126 (suggestion_id.id_within_category() == | 128 (suggestion_id.id_within_category() == |
127 prefs_->GetString(kNotificationIDWithinCategory))) { | 129 prefs_->GetString(kNotificationIDWithinCategory))) { |
128 ContentSuggestionsNotificationHelper::HideAllNotifications(); | 130 ContentSuggestionsNotificationHelper::HideNotification( |
129 RecordContentSuggestionsNotificationAction( | 131 suggestion_id, CONTENT_SUGGESTIONS_HIDE_EXPIRY); |
130 CONTENT_SUGGESTIONS_HIDE_EXPIRY); | |
131 } | 132 } |
132 } | 133 } |
133 | 134 |
134 void OnFullRefreshRequired() override { | 135 void OnFullRefreshRequired() override { |
135 ContentSuggestionsNotificationHelper::HideAllNotifications(); | 136 ContentSuggestionsNotificationHelper::HideAllNotifications( |
136 RecordContentSuggestionsNotificationAction(CONTENT_SUGGESTIONS_HIDE_EXPIRY); | 137 CONTENT_SUGGESTIONS_HIDE_EXPIRY); |
137 } | 138 } |
138 | 139 |
139 void ContentSuggestionsServiceShutdown() override { | 140 void ContentSuggestionsServiceShutdown() override { |
140 ContentSuggestionsNotificationHelper::HideAllNotifications(); | 141 ContentSuggestionsNotificationHelper::HideAllNotifications( |
141 RecordContentSuggestionsNotificationAction( | |
142 CONTENT_SUGGESTIONS_HIDE_SHUTDOWN); | 142 CONTENT_SUGGESTIONS_HIDE_SHUTDOWN); |
143 } | 143 } |
144 | 144 |
145 private: | 145 private: |
146 const ContentSuggestion* GetSuggestionToNotifyAbout(Category category) { | 146 const ContentSuggestion* GetSuggestionToNotifyAbout(Category category) { |
147 const auto& suggestions = service_->GetSuggestionsForCategory(category); | 147 const auto& suggestions = service_->GetSuggestionsForCategory(category); |
148 // TODO(sfiera): replace with AlwaysNotifyAboutContentSuggestions(). | 148 // TODO(sfiera): replace with AlwaysNotifyAboutContentSuggestions(). |
149 if (variations::GetVariationParamByFeatureAsBool( | 149 if (variations::GetVariationParamByFeatureAsBool( |
150 kContentSuggestionsNotificationsFeature, | 150 kContentSuggestionsNotificationsFeature, |
151 kContentSuggestionsNotificationsAlwaysNotifyParam, false)) { | 151 kContentSuggestionsNotificationsAlwaysNotifyParam, false)) { |
152 if (category.IsKnownCategory(KnownCategories::ARTICLES) && | 152 if (category.IsKnownCategory(KnownCategories::ARTICLES) && |
153 !suggestions.empty()) { | 153 !suggestions.empty()) { |
154 return &suggestions[0]; | 154 return &suggestions[0]; |
155 } | 155 } |
156 return nullptr; | 156 return nullptr; |
157 } | 157 } |
158 | 158 |
159 for (const ContentSuggestion& suggestion : suggestions) { | 159 for (const ContentSuggestion& suggestion : suggestions) { |
160 if (suggestion.notification_extra()) { | 160 if (suggestion.notification_extra()) { |
161 return &suggestion; | 161 return &suggestion; |
162 } | 162 } |
163 } | 163 } |
164 return nullptr; | 164 return nullptr; |
165 } | 165 } |
166 | 166 |
167 void AppStatusChanged(base::android::ApplicationState state) { | 167 void AppStatusChanged(base::android::ApplicationState state) { |
168 if (!ShouldNotifyInState(state)) { | 168 if (!ShouldNotifyInState(state)) { |
169 ContentSuggestionsNotificationHelper::HideAllNotifications(); | 169 ContentSuggestionsNotificationHelper::HideAllNotifications( |
170 RecordContentSuggestionsNotificationAction( | |
171 CONTENT_SUGGESTIONS_HIDE_FRONTMOST); | 170 CONTENT_SUGGESTIONS_HIDE_FRONTMOST); |
172 } | 171 } |
173 } | 172 } |
174 | 173 |
175 void ImageFetched(const ContentSuggestion::ID& id, | 174 void ImageFetched(const ContentSuggestion::ID& id, |
176 const GURL& url, | 175 const GURL& url, |
177 const base::string16& title, | 176 const base::string16& title, |
178 const base::string16& publisher, | 177 const base::string16& publisher, |
179 base::Time timeout_at, | 178 base::Time timeout_at, |
180 const gfx::Image& image) { | 179 const gfx::Image& image) { |
181 if (!ShouldNotifyInState(app_status_listener_.GetState())) { | 180 if (!ShouldNotifyInState(app_status_listener_.GetState())) { |
182 return; // Became foreground while we were fetching the image; forget it. | 181 return; // Became foreground while we were fetching the image; forget it. |
183 } | 182 } |
184 // check if suggestion is still valid. | 183 // check if suggestion is still valid. |
185 DVLOG(1) << "Fetched " << image.Size().width() << "x" | 184 DVLOG(1) << "Fetched " << image.Size().width() << "x" |
186 << image.Size().height() << " image for " << url.spec(); | 185 << image.Size().height() << " image for " << url.spec(); |
187 prefs_->SetString(kNotificationIDWithinCategory, id.id_within_category()); | 186 prefs_->ClearPref(kNotificationIDWithinCategory); |
188 ContentSuggestionsNotificationHelper::SendNotification( | 187 if (ContentSuggestionsNotificationHelper::SendNotification( |
189 url, title, publisher, CropSquare(image), timeout_at); | 188 id, url, title, publisher, CropSquare(image), timeout_at)) { |
190 RecordContentSuggestionsNotificationImpression( | 189 RecordContentSuggestionsNotificationImpression( |
191 id.category().IsKnownCategory(KnownCategories::ARTICLES) | 190 id.category().IsKnownCategory(KnownCategories::ARTICLES) |
192 ? CONTENT_SUGGESTIONS_ARTICLE | 191 ? CONTENT_SUGGESTIONS_ARTICLE |
193 : CONTENT_SUGGESTIONS_NONARTICLE); | 192 : CONTENT_SUGGESTIONS_NONARTICLE); |
| 193 } |
194 } | 194 } |
195 | 195 |
196 ContentSuggestionsService* const service_; | 196 ContentSuggestionsService* const service_; |
197 Profile* const profile_; | 197 Profile* const profile_; |
198 PrefService* const prefs_; | 198 PrefService* const prefs_; |
199 base::android::ApplicationStatusListener app_status_listener_; | 199 base::android::ApplicationStatusListener app_status_listener_; |
200 | 200 |
201 base::WeakPtrFactory<NotifyingObserver> weak_ptr_factory_; | 201 base::WeakPtrFactory<NotifyingObserver> weak_ptr_factory_; |
202 | 202 |
203 DISALLOW_COPY_AND_ASSIGN(NotifyingObserver); | 203 DISALLOW_COPY_AND_ASSIGN(NotifyingObserver); |
(...skipping 12 matching lines...) Expand all Loading... |
216 | 216 |
217 ContentSuggestionsNotifierService::~ContentSuggestionsNotifierService() = | 217 ContentSuggestionsNotifierService::~ContentSuggestionsNotifierService() = |
218 default; | 218 default; |
219 | 219 |
220 void ContentSuggestionsNotifierService::RegisterProfilePrefs( | 220 void ContentSuggestionsNotifierService::RegisterProfilePrefs( |
221 user_prefs::PrefRegistrySyncable* registry) { | 221 user_prefs::PrefRegistrySyncable* registry) { |
222 registry->RegisterStringPref(kNotificationIDWithinCategory, std::string()); | 222 registry->RegisterStringPref(kNotificationIDWithinCategory, std::string()); |
223 registry->RegisterIntegerPref( | 223 registry->RegisterIntegerPref( |
224 prefs::kContentSuggestionsConsecutiveIgnoredPrefName, 0); | 224 prefs::kContentSuggestionsConsecutiveIgnoredPrefName, 0); |
225 } | 225 } |
OLD | NEW |