| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/push_messaging/push_messaging_notification_manager.h" | 5 #include "chrome/browser/push_messaging/push_messaging_notification_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <bitset> | 9 #include <bitset> |
| 10 | 10 |
| 11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/notifications/platform_notification_service_impl.h" | 14 #include "chrome/browser/notifications/platform_notification_service_impl.h" |
| 15 #include "chrome/browser/profiles/profile.h" | 15 #include "chrome/browser/profiles/profile.h" |
| 16 #include "chrome/browser/push_messaging/background_budget_service.h" |
| 16 #include "chrome/browser/push_messaging/push_messaging_constants.h" | 17 #include "chrome/browser/push_messaging/push_messaging_constants.h" |
| 17 #include "chrome/common/features.h" | 18 #include "chrome/common/features.h" |
| 18 #include "chrome/common/pref_names.h" | 19 #include "chrome/common/pref_names.h" |
| 19 #include "chrome/grit/generated_resources.h" | 20 #include "chrome/grit/generated_resources.h" |
| 20 #include "components/prefs/pref_service.h" | 21 #include "components/prefs/pref_service.h" |
| 21 #include "components/rappor/rappor_utils.h" | 22 #include "components/rappor/rappor_utils.h" |
| 22 #include "components/url_formatter/elide_url.h" | 23 #include "components/url_formatter/elide_url.h" |
| 23 #include "content/public/browser/browser_context.h" | 24 #include "content/public/browser/browser_context.h" |
| 24 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| 25 #include "content/public/browser/platform_notification_context.h" | 26 #include "content/public/browser/platform_notification_context.h" |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 notification_data.icon = GURL(); | 79 notification_data.icon = GURL(); |
| 79 notification_data.silent = true; | 80 notification_data.silent = true; |
| 80 | 81 |
| 81 NotificationDatabaseData database_data; | 82 NotificationDatabaseData database_data; |
| 82 database_data.origin = origin; | 83 database_data.origin = origin; |
| 83 database_data.service_worker_registration_id = service_worker_registration_id; | 84 database_data.service_worker_registration_id = service_worker_registration_id; |
| 84 database_data.notification_data = notification_data; | 85 database_data.notification_data = notification_data; |
| 85 return database_data; | 86 return database_data; |
| 86 } | 87 } |
| 87 | 88 |
| 88 void IgnoreResult(bool unused) {} | |
| 89 | |
| 90 } // namespace | 89 } // namespace |
| 91 | 90 |
| 92 PushMessagingNotificationManager::PushMessagingNotificationManager( | 91 PushMessagingNotificationManager::PushMessagingNotificationManager( |
| 93 Profile* profile) | 92 Profile* profile) |
| 94 : profile_(profile), weak_factory_(this) {} | 93 : profile_(profile), weak_factory_(this) {} |
| 95 | 94 |
| 96 PushMessagingNotificationManager::~PushMessagingNotificationManager() {} | 95 PushMessagingNotificationManager::~PushMessagingNotificationManager() {} |
| 97 | 96 |
| 98 void PushMessagingNotificationManager::EnforceUserVisibleOnlyRequirements( | 97 void PushMessagingNotificationManager::EnforceUserVisibleOnlyRequirements( |
| 99 const GURL& origin, | 98 const GURL& origin, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 185 profile_, notification_database_data.notification_id, | 184 profile_, notification_database_data.notification_id, |
| 186 notification_database_data.origin, false /* by_user */); | 185 notification_database_data.origin, false /* by_user */); |
| 187 | 186 |
| 188 break; | 187 break; |
| 189 } | 188 } |
| 190 } | 189 } |
| 191 | 190 |
| 192 // Don't track push messages that didn't show a notification but were exempt | 191 // Don't track push messages that didn't show a notification but were exempt |
| 193 // from needing to do so. | 192 // from needing to do so. |
| 194 if (notification_shown || notification_needed) { | 193 if (notification_shown || notification_needed) { |
| 195 ServiceWorkerContext* service_worker_context = | 194 std::string notification_history = |
| 196 GetStoragePartition(profile_, origin)->GetServiceWorkerContext(); | 195 BackgroundBudgetService::GetBudget(profile_, origin); |
| 197 | 196 DidGetBudget(origin, service_worker_registration_id, notification_shown, |
| 198 PushMessagingService::GetNotificationsShownByLastFewPushes( | 197 notification_needed, message_handled_closure, |
| 199 service_worker_context, service_worker_registration_id, | 198 notification_history); |
| 200 base::Bind(&PushMessagingNotificationManager:: | |
| 201 DidGetNotificationsShownAndNeeded, | |
| 202 weak_factory_.GetWeakPtr(), origin, | |
| 203 service_worker_registration_id, notification_shown, | |
| 204 notification_needed, message_handled_closure)); | |
| 205 } else { | 199 } else { |
| 206 RecordUserVisibleStatus( | 200 RecordUserVisibleStatus( |
| 207 content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_AND_NOT_SHOWN); | 201 content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_AND_NOT_SHOWN); |
| 208 message_handled_closure.Run(); | 202 message_handled_closure.Run(); |
| 209 } | 203 } |
| 210 } | 204 } |
| 211 | 205 |
| 212 bool PushMessagingNotificationManager::IsTabVisible( | 206 bool PushMessagingNotificationManager::IsTabVisible( |
| 213 Profile* profile, | 207 Profile* profile, |
| 214 WebContents* active_web_contents, | 208 WebContents* active_web_contents, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 235 | 229 |
| 236 // view-source: pages are considered to be controlled Service Worker clients | 230 // view-source: pages are considered to be controlled Service Worker clients |
| 237 // and thus should be considered when checking the visible URL. However, the | 231 // and thus should be considered when checking the visible URL. However, the |
| 238 // prefix has to be removed before the origins can be compared. | 232 // prefix has to be removed before the origins can be compared. |
| 239 if (visible_url.SchemeIs(content::kViewSourceScheme)) | 233 if (visible_url.SchemeIs(content::kViewSourceScheme)) |
| 240 visible_url = GURL(visible_url.GetContent()); | 234 visible_url = GURL(visible_url.GetContent()); |
| 241 | 235 |
| 242 return visible_url.GetOrigin() == origin; | 236 return visible_url.GetOrigin() == origin; |
| 243 } | 237 } |
| 244 | 238 |
| 245 void PushMessagingNotificationManager::DidGetNotificationsShownAndNeeded( | 239 void PushMessagingNotificationManager::DidGetBudget( |
| 246 const GURL& origin, | 240 const GURL& origin, |
| 247 int64_t service_worker_registration_id, | 241 int64_t service_worker_registration_id, |
| 248 bool notification_shown, | 242 bool notification_shown, |
| 249 bool notification_needed, | 243 bool notification_needed, |
| 250 const base::Closure& message_handled_closure, | 244 const base::Closure& message_handled_closure, |
| 251 const std::string& data, | 245 const std::string& data) { |
| 252 bool success, | |
| 253 bool not_found) { | |
| 254 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 246 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 255 ServiceWorkerContext* service_worker_context = | |
| 256 GetStoragePartition(profile_, origin)->GetServiceWorkerContext(); | |
| 257 | 247 |
| 258 // We remember whether the last (up to) 10 pushes showed notifications. | 248 // We remember whether the last (up to) 10 pushes showed notifications. |
| 259 const size_t MISSED_NOTIFICATIONS_LENGTH = 10; | 249 const size_t MISSED_NOTIFICATIONS_LENGTH = 10; |
| 260 // data is a string like "0001000", where '0' means shown, and '1' means | 250 // data is a string like "0001000", where '0' means shown, and '1' means |
| 261 // needed but not shown. We manipulate it in bitset form. | 251 // needed but not shown. We manipulate it in bitset form. |
| 262 std::bitset<MISSED_NOTIFICATIONS_LENGTH> missed_notifications(data); | 252 std::bitset<MISSED_NOTIFICATIONS_LENGTH> missed_notifications(data); |
| 263 | 253 |
| 264 DCHECK(notification_shown || notification_needed); // Caller must ensure this | 254 DCHECK(notification_shown || notification_needed); // Caller must ensure this |
| 265 bool needed_but_not_shown = notification_needed && !notification_shown; | 255 bool needed_but_not_shown = notification_needed && !notification_shown; |
| 266 | 256 |
| 267 // New entries go at the end, and old ones are shifted off the beginning once | 257 // New entries go at the end, and old ones are shifted off the beginning once |
| 268 // the history length is exceeded. | 258 // the history length is exceeded. |
| 269 missed_notifications <<= 1; | 259 missed_notifications <<= 1; |
| 270 missed_notifications[0] = needed_but_not_shown; | 260 missed_notifications[0] = needed_but_not_shown; |
| 271 std::string updated_data(missed_notifications. | 261 std::string updated_data(missed_notifications. |
| 272 to_string<char, std::string::traits_type, std::string::allocator_type>()); | 262 to_string<char, std::string::traits_type, std::string::allocator_type>()); |
| 273 PushMessagingService::SetNotificationsShownByLastFewPushes( | 263 BackgroundBudgetService::StoreBudget(profile_, origin, updated_data); |
| 274 service_worker_context, service_worker_registration_id, origin, | |
| 275 updated_data, | |
| 276 base::Bind(&IgnoreResult)); // This is a heuristic; ignore failure. | |
| 277 | 264 |
| 278 if (notification_shown) { | 265 if (notification_shown) { |
| 279 RecordUserVisibleStatus( | 266 RecordUserVisibleStatus( |
| 280 notification_needed | 267 notification_needed |
| 281 ? content::PUSH_USER_VISIBLE_STATUS_REQUIRED_AND_SHOWN | 268 ? content::PUSH_USER_VISIBLE_STATUS_REQUIRED_AND_SHOWN |
| 282 : content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_BUT_SHOWN); | 269 : content::PUSH_USER_VISIBLE_STATUS_NOT_REQUIRED_BUT_SHOWN); |
| 283 message_handled_closure.Run(); | 270 message_handled_closure.Run(); |
| 284 return; | 271 return; |
| 285 } | 272 } |
| 286 DCHECK(needed_but_not_shown); | 273 DCHECK(needed_but_not_shown); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 message_handled_closure.Run(); | 330 message_handled_closure.Run(); |
| 344 return; | 331 return; |
| 345 } | 332 } |
| 346 | 333 |
| 347 PlatformNotificationServiceImpl::GetInstance()->DisplayPersistentNotification( | 334 PlatformNotificationServiceImpl::GetInstance()->DisplayPersistentNotification( |
| 348 profile_, persistent_notification_id, origin, notification_data, | 335 profile_, persistent_notification_id, origin, notification_data, |
| 349 NotificationResources()); | 336 NotificationResources()); |
| 350 | 337 |
| 351 message_handled_closure.Run(); | 338 message_handled_closure.Run(); |
| 352 } | 339 } |
| OLD | NEW |