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

Side by Side Diff: components/gcm_driver/gcm_driver.cc

Issue 683913005: [GCM] Support registration before unregistration finishes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add more comments Created 6 years, 1 month 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 "components/gcm_driver/gcm_driver.h" 5 #include "components/gcm_driver/gcm_driver.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/metrics/field_trial.h" 10 #include "base/metrics/field_trial.h"
11 #include "components/gcm_driver/gcm_app_handler.h" 11 #include "components/gcm_driver/gcm_app_handler.h"
12 12
13 namespace gcm { 13 namespace gcm {
14 14
15 namespace { 15 namespace {
16 const char kGCMFieldTrialName[] = "GCM"; 16 const char kGCMFieldTrialName[] = "GCM";
17 const char kGCMFieldTrialEnabledGroupName[] = "Enabled"; 17 const char kGCMFieldTrialEnabledGroupName[] = "Enabled";
18 } // namespace 18 } // namespace
19 19
20 // static 20 // static
21 bool GCMDriver::IsAllowedForAllUsers() { 21 bool GCMDriver::IsAllowedForAllUsers() {
22 std::string group_name = 22 std::string group_name =
23 base::FieldTrialList::FindFullName(kGCMFieldTrialName); 23 base::FieldTrialList::FindFullName(kGCMFieldTrialName);
24 return group_name == kGCMFieldTrialEnabledGroupName; 24 return group_name == kGCMFieldTrialEnabledGroupName;
25 } 25 }
26 26
27 GCMDriver::GCMDriver() { 27 GCMDriver::GCMDriver() : weak_ptr_factory_(this) {
28 } 28 }
29 29
30 GCMDriver::~GCMDriver() { 30 GCMDriver::~GCMDriver() {
31 } 31 }
32 32
33 void GCMDriver::Register(const std::string& app_id, 33 void GCMDriver::Register(const std::string& app_id,
34 const std::vector<std::string>& sender_ids, 34 const std::vector<std::string>& sender_ids,
35 const RegisterCallback& callback) { 35 const RegisterCallback& callback) {
36 DCHECK(!app_id.empty()); 36 DCHECK(!app_id.empty());
37 DCHECK(!sender_ids.empty()); 37 DCHECK(!sender_ids.empty());
38 DCHECK(!callback.is_null()); 38 DCHECK(!callback.is_null());
39 39
40 GCMClient::Result result = EnsureStarted(); 40 GCMClient::Result result = EnsureStarted();
41 if (result != GCMClient::SUCCESS) { 41 if (result != GCMClient::SUCCESS) {
42 callback.Run(std::string(), result); 42 callback.Run(std::string(), result);
43 return; 43 return;
44 } 44 }
45 45
46 // If previous un/register operation is still in progress, bail out. 46 // If previous register operation is still in progress, bail out.
47 if (IsAsyncOperationPending(app_id)) { 47 if (register_callbacks_.find(app_id) != register_callbacks_.end()) {
48 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING); 48 callback.Run(std::string(), GCMClient::ASYNC_OPERATION_PENDING);
49 return; 49 return;
50 } 50 }
51 51
52 // Normalize the sender IDs by making them sorted. 52 // Normalize the sender IDs by making them sorted.
53 std::vector<std::string> normalized_sender_ids = sender_ids; 53 std::vector<std::string> normalized_sender_ids = sender_ids;
54 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end()); 54 std::sort(normalized_sender_ids.begin(), normalized_sender_ids.end());
55 55
56 register_callbacks_[app_id] = callback; 56 register_callbacks_[app_id] = callback;
57 57
58 // If previous unregister operation is still in progress, wait until it
59 // finishes. We don't want to throw ASYNC_OPERATION_PENDING when the user
60 // uninstalls an app (ungistering) and then reinstalls the app again
61 // (registering).
62 std::map<std::string, UnregisterCallback>::iterator unregister_iter =
63 unregister_callbacks_.find(app_id);
64 if (unregister_iter != unregister_callbacks_.end()) {
65 // Replace the original unregister callback with an intermediate callback
66 // that will invoke the original unregister callback and trigger the pending
67 // registration after the unregistration finishes.
68 // Note that some parameters to RegisterAfterUnregister are specified here
69 // when the callback is created (base::Bind supports the partial binding
70 // of parameters).
71 unregister_iter->second = base::Bind(
72 &GCMDriver::RegisterAfterUnregister,
73 weak_ptr_factory_.GetWeakPtr(),
74 app_id,
75 normalized_sender_ids,
76 unregister_iter->second);
77 return;
78 }
79
58 RegisterImpl(app_id, normalized_sender_ids); 80 RegisterImpl(app_id, normalized_sender_ids);
59 } 81 }
60 82
61 void GCMDriver::Unregister(const std::string& app_id, 83 void GCMDriver::Unregister(const std::string& app_id,
62 const UnregisterCallback& callback) { 84 const UnregisterCallback& callback) {
63 DCHECK(!app_id.empty()); 85 DCHECK(!app_id.empty());
64 DCHECK(!callback.is_null()); 86 DCHECK(!callback.is_null());
65 87
66 GCMClient::Result result = EnsureStarted(); 88 GCMClient::Result result = EnsureStarted();
67 if (result != GCMClient::SUCCESS) { 89 if (result != GCMClient::SUCCESS) {
68 callback.Run(result); 90 callback.Run(result);
69 return; 91 return;
70 } 92 }
71 93
72 // If previous un/register operation is still in progress, bail out. 94 // If previous un/register operation is still in progress, bail out.
73 if (IsAsyncOperationPending(app_id)) { 95 if (register_callbacks_.find(app_id) != register_callbacks_.end() ||
96 unregister_callbacks_.find(app_id) != unregister_callbacks_.end()) {
74 callback.Run(GCMClient::ASYNC_OPERATION_PENDING); 97 callback.Run(GCMClient::ASYNC_OPERATION_PENDING);
75 return; 98 return;
76 } 99 }
77 100
78 unregister_callbacks_[app_id] = callback; 101 unregister_callbacks_[app_id] = callback;
79 102
80 UnregisterImpl(app_id); 103 UnregisterImpl(app_id);
81 } 104 }
82 105
83 void GCMDriver::Send(const std::string& app_id, 106 void GCMDriver::Send(const std::string& app_id,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 bool GCMDriver::HasRegisterCallback(const std::string& app_id) { 214 bool GCMDriver::HasRegisterCallback(const std::string& app_id) {
192 return register_callbacks_.find(app_id) != register_callbacks_.end(); 215 return register_callbacks_.find(app_id) != register_callbacks_.end();
193 } 216 }
194 217
195 void GCMDriver::ClearCallbacks() { 218 void GCMDriver::ClearCallbacks() {
196 register_callbacks_.clear(); 219 register_callbacks_.clear();
197 unregister_callbacks_.clear(); 220 unregister_callbacks_.clear();
198 send_callbacks_.clear(); 221 send_callbacks_.clear();
199 } 222 }
200 223
201 bool GCMDriver::IsAsyncOperationPending(const std::string& app_id) const { 224 void GCMDriver::RegisterAfterUnregister(
202 return register_callbacks_.find(app_id) != register_callbacks_.end() || 225 const std::string& app_id,
203 unregister_callbacks_.find(app_id) != unregister_callbacks_.end(); 226 const std::vector<std::string>& normalized_sender_ids,
227 const UnregisterCallback& unregister_callback,
228 GCMClient::Result result) {
229 // Invoke the original unregister callback.
230 unregister_callback.Run(result);
231
232 // Trigger the pending registration.
233 DCHECK(register_callbacks_.find(app_id) != register_callbacks_.end());
234 RegisterImpl(app_id, normalized_sender_ids);
204 } 235 }
205 236
206 } // namespace gcm 237 } // namespace gcm
OLDNEW
« no previous file with comments | « components/gcm_driver/gcm_driver.h ('k') | components/gcm_driver/gcm_driver_desktop_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698