Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(707)

Side by Side Diff: chrome/browser/services/gcm/push_messaging_service_impl.cc

Issue 930083002: Unregister with push service and SW database when permission is lost. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/services/gcm/push_messaging_service_impl.h" 5 #include "chrome/browser/services/gcm/push_messaging_service_impl.h"
6 6
7 #include <bitset> 7 #include <bitset>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/metrics/histogram.h" 13 #include "base/metrics/histogram.h"
14 #include "base/prefs/pref_service.h" 14 #include "base/prefs/pref_service.h"
15 #include "base/strings/string_util.h" 15 #include "base/strings/string_util.h"
16 #include "base/strings/utf_string_conversions.h" 16 #include "base/strings/utf_string_conversions.h"
17 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/notifications/notification_ui_manager.h" 18 #include "chrome/browser/notifications/notification_ui_manager.h"
19 #include "chrome/browser/notifications/platform_notification_service_impl.h" 19 #include "chrome/browser/notifications/platform_notification_service_impl.h"
20 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/services/gcm/gcm_profile_service.h" 21 #include "chrome/browser/services/gcm/gcm_profile_service.h"
22 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" 22 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
23 #include "chrome/browser/services/gcm/push_messaging_application_id.h" 23 #include "chrome/browser/services/gcm/push_messaging_application_id.h"
24 #include "chrome/browser/services/gcm/push_messaging_constants.h" 24 #include "chrome/browser/services/gcm/push_messaging_constants.h"
25 #include "chrome/browser/services/gcm/push_messaging_permission_context.h" 25 #include "chrome/browser/services/gcm/push_messaging_permission_context.h"
26 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory. h" 26 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory. h"
27 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/pref_names.h" 28 #include "chrome/common/pref_names.h"
29 #include "chrome/grit/generated_resources.h" 29 #include "chrome/grit/generated_resources.h"
30 #include "components/content_settings/core/browser/host_content_settings_map.h"
30 #include "components/content_settings/core/common/permission_request_id.h" 31 #include "components/content_settings/core/common/permission_request_id.h"
31 #include "components/gcm_driver/gcm_driver.h" 32 #include "components/gcm_driver/gcm_driver.h"
32 #include "components/pref_registry/pref_registry_syncable.h" 33 #include "components/pref_registry/pref_registry_syncable.h"
33 #include "content/public/browser/browser_context.h" 34 #include "content/public/browser/browser_context.h"
35 #include "content/public/browser/browser_thread.h"
34 #include "content/public/browser/render_frame_host.h" 36 #include "content/public/browser/render_frame_host.h"
35 #include "content/public/browser/service_worker_context.h" 37 #include "content/public/browser/service_worker_context.h"
36 #include "content/public/browser/storage_partition.h" 38 #include "content/public/browser/storage_partition.h"
37 #include "content/public/browser/web_contents.h" 39 #include "content/public/browser/web_contents.h"
38 #include "content/public/common/child_process_host.h" 40 #include "content/public/common/child_process_host.h"
39 #include "content/public/common/content_switches.h" 41 #include "content/public/common/content_switches.h"
40 #include "content/public/common/platform_notification_data.h" 42 #include "content/public/common/platform_notification_data.h"
41 #include "content/public/common/push_messaging_status.h" 43 #include "content/public/common/push_messaging_status.h"
42 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" 44 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
43 #include "third_party/skia/include/core/SkBitmap.h" 45 #include "third_party/skia/include/core/SkBitmap.h"
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 118 }
117 119
118 PushMessagingServiceImpl::PushMessagingServiceImpl( 120 PushMessagingServiceImpl::PushMessagingServiceImpl(
119 GCMProfileService* gcm_profile_service, 121 GCMProfileService* gcm_profile_service,
120 Profile* profile) 122 Profile* profile)
121 : gcm_profile_service_(gcm_profile_service), 123 : gcm_profile_service_(gcm_profile_service),
122 profile_(profile), 124 profile_(profile),
123 push_registration_count_(0), 125 push_registration_count_(0),
124 pending_push_registration_count_(0), 126 pending_push_registration_count_(0),
125 weak_factory_(this) { 127 weak_factory_(this) {
128 // In some tests, we might end up with |profile_| being null at this point.
129 // When that is the case |profile_| will be set in SetProfileForTesting(), at
130 // which point the service will start to observe HostContentSettingsMap.
131 if (profile_)
132 profile_->GetHostContentSettingsMap()->AddObserver(this);
126 } 133 }
127 134
128 PushMessagingServiceImpl::~PushMessagingServiceImpl() { 135 PushMessagingServiceImpl::~PushMessagingServiceImpl() {
129 // TODO(johnme): If it's possible for this to be destroyed before GCMDriver, 136 // TODO(johnme): If it's possible for this to be destroyed before GCMDriver,
130 // then we should call RemoveAppHandler. 137 // then we should call RemoveAppHandler.
138 profile_->GetHostContentSettingsMap()->RemoveObserver(this);
131 } 139 }
132 140
133 void PushMessagingServiceImpl::IncreasePushRegistrationCount(int add, 141 void PushMessagingServiceImpl::IncreasePushRegistrationCount(int add,
134 bool is_pending) { 142 bool is_pending) {
135 DCHECK(add > 0); 143 DCHECK(add > 0);
136 if (push_registration_count_ + pending_push_registration_count_ == 0) { 144 if (push_registration_count_ + pending_push_registration_count_ == 0) {
137 gcm_profile_service_->driver()->AddAppHandler( 145 gcm_profile_service_->driver()->AddAppHandler(
138 kPushMessagingApplicationIdPrefix, this); 146 kPushMessagingApplicationIdPrefix, this);
139 } 147 }
140 if (is_pending) { 148 if (is_pending) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 profile_, 228 profile_,
221 application_id.origin(), 229 application_id.origin(),
222 application_id.service_worker_registration_id(), 230 application_id.service_worker_registration_id(),
223 data, 231 data,
224 base::Bind(&PushMessagingServiceImpl::DeliverMessageCallback, 232 base::Bind(&PushMessagingServiceImpl::DeliverMessageCallback,
225 weak_factory_.GetWeakPtr(), 233 weak_factory_.GetWeakPtr(),
226 application_id.app_id_guid(), application_id.origin(), 234 application_id.app_id_guid(), application_id.origin(),
227 application_id.service_worker_registration_id(), message)); 235 application_id.service_worker_registration_id(), message));
228 } 236 }
229 237
238 void PushMessagingServiceImpl::OnContentSettingChanged(
239 const ContentSettingsPattern& primary_pattern,
240 const ContentSettingsPattern& secondary_pattern,
241 ContentSettingsType content_type,
242 std::string resource_identifier) {
243 if (content_type != CONTENT_SETTINGS_TYPE_PUSH_MESSAGING &&
244 content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS) {
245 return;
246 }
247
248 for (const auto& id : PushMessagingApplicationId::GetAll(profile_)) {
249 // If |primary_pattern| is not valid, we should always check for a
250 // permission change because it can happen for example when the entire
251 // Push or Notifications permissions are cleared.
252 // Otherwise, the permission should be checked if the pattern matches the
253 // origin.
254 if (primary_pattern.IsValid() && !primary_pattern.Matches(id.origin()))
255 continue;
256
257 if (HasPermission(id.origin()))
258 continue;
259
260 // Unregister the PushMessagingApplicationId with the push service.
261 Unregister(id.app_id_guid(), true /* retry */, UnregisterCallback());
262
263 // Clear the associated service worker push registration id.
264 PushMessagingService::ClearPushRegistrationID(
265 profile_, id.origin(), id.service_worker_registration_id());
266 }
267 }
268
230 void PushMessagingServiceImpl::SetProfileForTesting(Profile* profile) { 269 void PushMessagingServiceImpl::SetProfileForTesting(Profile* profile) {
231 profile_ = profile; 270 profile_ = profile;
271 profile_->GetHostContentSettingsMap()->AddObserver(this);
232 } 272 }
233 273
234 void PushMessagingServiceImpl::DeliverMessageCallback( 274 void PushMessagingServiceImpl::DeliverMessageCallback(
235 const std::string& app_id_guid, 275 const std::string& app_id_guid,
236 const GURL& requesting_origin, 276 const GURL& requesting_origin,
237 int64 service_worker_registration_id, 277 int64 service_worker_registration_id,
238 const GCMClient::IncomingMessage& message, 278 const GCMClient::IncomingMessage& message,
239 content::PushDeliveryStatus status) { 279 content::PushDeliveryStatus status) {
240 // TODO(mvanouwerkerk): UMA logging. 280 // TODO(mvanouwerkerk): UMA logging.
241 // TODO(mvanouwerkerk): Show a warning in the developer console of the 281 // TODO(mvanouwerkerk): Show a warning in the developer console of the
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
610 void PushMessagingServiceImpl::Unregister( 650 void PushMessagingServiceImpl::Unregister(
611 const GURL& requesting_origin, 651 const GURL& requesting_origin,
612 int64 service_worker_registration_id, 652 int64 service_worker_registration_id,
613 bool retry_on_failure, 653 bool retry_on_failure,
614 const content::PushMessagingService::UnregisterCallback& callback) { 654 const content::PushMessagingService::UnregisterCallback& callback) {
615 DCHECK(gcm_profile_service_->driver()); 655 DCHECK(gcm_profile_service_->driver());
616 656
617 PushMessagingApplicationId application_id = PushMessagingApplicationId::Get( 657 PushMessagingApplicationId application_id = PushMessagingApplicationId::Get(
618 profile_, requesting_origin, service_worker_registration_id); 658 profile_, requesting_origin, service_worker_registration_id);
619 if (!application_id.IsValid()) { 659 if (!application_id.IsValid()) {
620 callback.Run( 660 if (!callback.is_null()) {
621 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED); 661 callback.Run(
662 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
663 }
622 return; 664 return;
623 } 665 }
624 666
625 Unregister(application_id.app_id_guid(), retry_on_failure, callback); 667 Unregister(application_id.app_id_guid(), retry_on_failure, callback);
626 } 668 }
627 669
628 void PushMessagingServiceImpl::Unregister( 670 void PushMessagingServiceImpl::Unregister(
629 const std::string& app_id_guid, 671 const std::string& app_id_guid,
630 bool retry_on_failure, 672 bool retry_on_failure,
631 const content::PushMessagingService::UnregisterCallback& callback) { 673 const content::PushMessagingService::UnregisterCallback& callback) {
(...skipping 18 matching lines...) Expand all
650 } 692 }
651 693
652 void PushMessagingServiceImpl::DidUnregister( 694 void PushMessagingServiceImpl::DidUnregister(
653 const std::string& app_id_guid, 695 const std::string& app_id_guid,
654 bool retry_on_failure, 696 bool retry_on_failure,
655 const content::PushMessagingService::UnregisterCallback& callback, 697 const content::PushMessagingService::UnregisterCallback& callback,
656 GCMClient::Result result) { 698 GCMClient::Result result) {
657 if (result == GCMClient::SUCCESS) { 699 if (result == GCMClient::SUCCESS) {
658 PushMessagingApplicationId application_id = 700 PushMessagingApplicationId application_id =
659 PushMessagingApplicationId::Get(profile_, app_id_guid); 701 PushMessagingApplicationId::Get(profile_, app_id_guid);
660 if (application_id.IsValid()) 702 if (!application_id.IsValid()) {
661 application_id.DeleteFromDisk(profile_); 703 if (!callback.is_null()) {
704 callback.Run(
705 content::PUSH_UNREGISTRATION_STATUS_SUCCESS_WAS_NOT_REGISTERED);
706 }
707 return;
708 }
709
710 application_id.DeleteFromDisk(profile_);
662 DecreasePushRegistrationCount(1, false /* was_pending */); 711 DecreasePushRegistrationCount(1, false /* was_pending */);
663 } 712 }
664 713
665 // Internal calls pass a null callback. 714 // Internal calls pass a null callback.
666 if (!callback.is_null()) { 715 if (!callback.is_null()) {
667 switch (result) { 716 switch (result) {
668 case GCMClient::SUCCESS: 717 case GCMClient::SUCCESS:
669 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTER); 718 callback.Run(content::PUSH_UNREGISTRATION_STATUS_SUCCESS_UNREGISTER);
670 break; 719 break;
671 case GCMClient::NETWORK_ERROR: 720 case GCMClient::NETWORK_ERROR:
(...skipping 22 matching lines...) Expand all
694 bool PushMessagingServiceImpl::HasPermission(const GURL& origin) { 743 bool PushMessagingServiceImpl::HasPermission(const GURL& origin) {
695 gcm::PushMessagingPermissionContext* permission_context = 744 gcm::PushMessagingPermissionContext* permission_context =
696 gcm::PushMessagingPermissionContextFactory::GetForProfile(profile_); 745 gcm::PushMessagingPermissionContextFactory::GetForProfile(profile_);
697 DCHECK(permission_context); 746 DCHECK(permission_context);
698 747
699 return permission_context->GetPermissionStatus(origin, origin) == 748 return permission_context->GetPermissionStatus(origin, origin) ==
700 CONTENT_SETTING_ALLOW; 749 CONTENT_SETTING_ALLOW;
701 } 750 }
702 751
703 } // namespace gcm 752 } // namespace gcm
OLDNEW
« no previous file with comments | « chrome/browser/services/gcm/push_messaging_service_impl.h ('k') | chrome/test/data/push_messaging/push_test.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698