OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/gcm/fake_gcm_profile_service.h" | 5 #include "chrome/browser/gcm/fake_gcm_profile_service.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/format_macros.h" | 10 #include "base/format_macros.h" |
11 #include "base/location.h" | 11 #include "base/location.h" |
12 #include "base/macros.h" | 12 #include "base/macros.h" |
13 #include "base/memory/weak_ptr.h" | |
13 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/stringprintf.h" | 16 #include "base/strings/stringprintf.h" |
16 #include "base/threading/thread_task_runner_handle.h" | 17 #include "base/threading/thread_task_runner_handle.h" |
18 #include "base/time/time.h" | |
17 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
18 #include "components/gcm_driver/fake_gcm_client_factory.h" | 20 #include "components/gcm_driver/fake_gcm_client_factory.h" |
21 #include "components/gcm_driver/gcm_backoff_policy.h" | |
19 #include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h" | 22 #include "components/gcm_driver/instance_id/fake_gcm_driver_for_instance_id.h" |
20 #include "content/public/browser/browser_context.h" | 23 #include "content/public/browser/browser_context.h" |
21 | 24 |
22 namespace gcm { | 25 namespace gcm { |
23 | 26 |
24 namespace { | 27 namespace { |
25 | 28 |
26 class CustomFakeGCMDriver : public instance_id::FakeGCMDriverForInstanceID { | 29 using ResultCallback = base::Callback<void(GCMClient::Result result)>; |
30 | |
31 void FailAfterMaxBackoff(ResultCallback callback) { | |
32 // Worst-case backoff, where the device never comes back online so all retries | |
33 // fail. | |
34 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
35 FROM_HERE, | |
36 // GCMClientImpl::{OnRegisterCompleted,OnUnregisterCompleted} both map | |
37 // {RegistrationRequest,UnregistrationRequest}::REACHED_MAX_RETRIES | |
38 // respectively to GCMClient::SERVER_ERROR. | |
39 base::Bind(callback, GCMClient::SERVER_ERROR), | |
40 base::TimeDelta::FromMilliseconds( | |
41 GetGCMBackoffPolicy().maximum_backoff_ms)); | |
42 } | |
43 | |
44 } // namespace | |
45 | |
46 class FakeGCMProfileService::CustomFakeGCMDriver | |
47 : public instance_id::FakeGCMDriverForInstanceID { | |
27 public: | 48 public: |
28 explicit CustomFakeGCMDriver(FakeGCMProfileService* service); | 49 explicit CustomFakeGCMDriver(FakeGCMProfileService* service); |
29 ~CustomFakeGCMDriver() override; | 50 ~CustomFakeGCMDriver() override; |
30 | 51 |
31 void OnRegisterFinished(const std::string& app_id, | 52 void OnRegisterFinished(const std::string& app_id, |
32 const std::string& registration_id, | 53 const std::string& registration_id, |
33 GCMClient::Result result); | 54 GCMClient::Result result); |
34 void OnUnregisterFinished(const std::string& app_id, | |
35 GCMClient::Result result); | |
36 void OnSendFinished(const std::string& app_id, | 55 void OnSendFinished(const std::string& app_id, |
37 const std::string& message_id, | 56 const std::string& message_id, |
38 GCMClient::Result result); | 57 GCMClient::Result result); |
39 | 58 |
40 void OnDispatchMessage(const std::string& app_id, | 59 void OnDispatchMessage(const std::string& app_id, |
41 const IncomingMessage& message); | 60 const IncomingMessage& message); |
42 | 61 |
43 protected: | 62 protected: |
44 // FakeGCMDriverForInstanceID overrides: | 63 // FakeGCMDriver overrides: |
45 void RegisterImpl(const std::string& app_id, | 64 void RegisterImpl(const std::string& app_id, |
46 const std::vector<std::string>& sender_ids) override; | 65 const std::vector<std::string>& sender_ids) override; |
47 void UnregisterImpl(const std::string& app_id) override; | 66 void UnregisterImpl(const std::string& app_id) override; |
48 void UnregisterWithSenderIdImpl(const std::string& app_id, | 67 void UnregisterWithSenderIdImpl(const std::string& app_id, |
49 const std::string& sender_id) override; | 68 const std::string& sender_id) override; |
50 void SendImpl(const std::string& app_id, | 69 void SendImpl(const std::string& app_id, |
51 const std::string& receiver_id, | 70 const std::string& receiver_id, |
52 const OutgoingMessage& message) override; | 71 const OutgoingMessage& message) override; |
53 | 72 |
73 // FakeGCMDriverForInstanceID overrides: | |
74 void GetToken(const std::string& app_id, | |
75 const std::string& authorized_entity, | |
76 const std::string& scope, | |
77 const std::map<std::string, std::string>& options, | |
78 const GetTokenCallback& callback) override; | |
79 void DeleteToken(const std::string& app_id, | |
80 const std::string& authorized_entity, | |
81 const std::string& scope, | |
82 const DeleteTokenCallback& callback) override; | |
83 | |
54 private: | 84 private: |
85 void DoRegister(const std::string& app_id, | |
86 const std::vector<std::string>& sender_ids, | |
87 const std::string& registration_id); | |
88 void DoSend(const std::string& app_id, | |
89 const std::string& receiver_id, | |
90 const OutgoingMessage& message); | |
91 | |
55 FakeGCMProfileService* service_; | 92 FakeGCMProfileService* service_; |
56 | 93 |
94 // Used to give each registration a unique registration id. Does not decrease | |
95 // when unregister is called. | |
96 int registration_count_ = 0; | |
97 | |
98 base::WeakPtrFactory<CustomFakeGCMDriver> weak_factory_; // Must be last. | |
99 | |
57 DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver); | 100 DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver); |
58 }; | 101 }; |
59 | 102 |
60 CustomFakeGCMDriver::CustomFakeGCMDriver(FakeGCMProfileService* service) | 103 FakeGCMProfileService::CustomFakeGCMDriver::CustomFakeGCMDriver( |
104 FakeGCMProfileService* service) | |
61 : instance_id::FakeGCMDriverForInstanceID( | 105 : instance_id::FakeGCMDriverForInstanceID( |
62 base::ThreadTaskRunnerHandle::Get()), | 106 base::ThreadTaskRunnerHandle::Get()), |
63 service_(service) {} | 107 service_(service), |
108 weak_factory_(this) {} | |
64 | 109 |
65 CustomFakeGCMDriver::~CustomFakeGCMDriver() { | 110 FakeGCMProfileService::CustomFakeGCMDriver::~CustomFakeGCMDriver() {} |
111 | |
112 void FakeGCMProfileService::CustomFakeGCMDriver::RegisterImpl( | |
113 const std::string& app_id, | |
114 const std::vector<std::string>& sender_ids) { | |
115 if (service_->is_offline_) { | |
116 FailAfterMaxBackoff(base::Bind(&CustomFakeGCMDriver::RegisterFinished, | |
117 weak_factory_.GetWeakPtr(), app_id, | |
118 std::string() /* registration_id */)); | |
119 return; | |
120 } | |
121 | |
122 // Generate fake registration IDs, encoding the number of sender IDs (used by | |
123 // GcmApiTest.RegisterValidation), then an incrementing count (even for the | |
124 // same app_id - there's no caching) so tests can distinguish registrations. | |
125 std::string registration_id = base::StringPrintf( | |
126 "%" PRIuS "-%d", sender_ids.size(), registration_count_); | |
127 ++registration_count_; | |
128 | |
129 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
130 FROM_HERE, | |
131 base::Bind(&CustomFakeGCMDriver::DoRegister, base::Unretained(this), | |
Peter Beverloo
2017/02/07 18:11:08
Here and elsewhere - why is it safe to use |this|?
johnme
2017/02/08 14:14:36
Done (the existing code used |this| for immediate
| |
132 app_id, sender_ids, registration_id)); | |
66 } | 133 } |
67 | 134 |
68 void CustomFakeGCMDriver::RegisterImpl( | 135 void FakeGCMProfileService::CustomFakeGCMDriver::DoRegister( |
69 const std::string& app_id, | 136 const std::string& app_id, |
70 const std::vector<std::string>& sender_ids) { | 137 const std::vector<std::string>& sender_ids, |
71 base::ThreadTaskRunnerHandle::Get()->PostTask( | 138 const std::string& registration_id) { |
72 FROM_HERE, base::Bind(&FakeGCMProfileService::RegisterFinished, | 139 if (service_->collect_) { |
73 base::Unretained(service_), app_id, sender_ids)); | 140 service_->last_registered_app_id_ = app_id; |
141 service_->last_registered_sender_ids_ = sender_ids; | |
142 } | |
143 RegisterFinished(app_id, registration_id, GCMClient::SUCCESS); | |
74 } | 144 } |
75 | 145 |
76 void CustomFakeGCMDriver::UnregisterImpl(const std::string& app_id) { | 146 void FakeGCMProfileService::CustomFakeGCMDriver::UnregisterImpl( |
147 const std::string& app_id) { | |
148 if (service_->is_offline_) { | |
149 FailAfterMaxBackoff(base::Bind(&CustomFakeGCMDriver::UnregisterFinished, | |
150 weak_factory_.GetWeakPtr(), app_id)); | |
151 return; | |
152 } | |
153 | |
154 GCMClient::Result result = GCMClient::SUCCESS; | |
155 if (!service_->unregister_responses_.empty()) { | |
156 result = service_->unregister_responses_.front(); | |
157 service_->unregister_responses_.pop_front(); | |
158 } | |
77 base::ThreadTaskRunnerHandle::Get()->PostTask( | 159 base::ThreadTaskRunnerHandle::Get()->PostTask( |
78 FROM_HERE, base::Bind(&FakeGCMProfileService::UnregisterFinished, | 160 FROM_HERE, base::Bind(&CustomFakeGCMDriver::UnregisterFinished, |
79 base::Unretained(service_), app_id)); | 161 base::Unretained(this), app_id, result)); |
80 } | 162 } |
81 | 163 |
82 void CustomFakeGCMDriver::UnregisterWithSenderIdImpl( | 164 void FakeGCMProfileService::CustomFakeGCMDriver::UnregisterWithSenderIdImpl( |
83 const std::string& app_id, | 165 const std::string& app_id, |
84 const std::string& sender_id) {} | 166 const std::string& sender_id) { |
167 NOTREACHED() << "This Android-specific method is not yet faked."; | |
168 } | |
85 | 169 |
86 void CustomFakeGCMDriver::SendImpl(const std::string& app_id, | 170 void FakeGCMProfileService::CustomFakeGCMDriver::SendImpl( |
87 const std::string& receiver_id, | 171 const std::string& app_id, |
88 const OutgoingMessage& message) { | 172 const std::string& receiver_id, |
173 const OutgoingMessage& message) { | |
174 if (service_->is_offline_) { | |
175 FailAfterMaxBackoff(base::Bind(&CustomFakeGCMDriver::SendFinished, | |
176 weak_factory_.GetWeakPtr(), app_id, | |
177 message.id)); | |
178 return; | |
179 } | |
180 | |
89 base::ThreadTaskRunnerHandle::Get()->PostTask( | 181 base::ThreadTaskRunnerHandle::Get()->PostTask( |
90 FROM_HERE, | 182 FROM_HERE, |
91 base::Bind(&FakeGCMProfileService::SendFinished, | 183 base::Bind(&CustomFakeGCMDriver::DoSend, base::Unretained(this), app_id, |
92 base::Unretained(service_), app_id, receiver_id, message)); | 184 receiver_id, message)); |
93 } | 185 } |
94 | 186 |
95 void CustomFakeGCMDriver::OnRegisterFinished( | 187 void FakeGCMProfileService::CustomFakeGCMDriver::DoSend( |
96 const std::string& app_id, | 188 const std::string& app_id, |
97 const std::string& registration_id, | 189 const std::string& receiver_id, |
98 GCMClient::Result result) { | 190 const OutgoingMessage& message) { |
99 RegisterFinished(app_id, registration_id, result); | 191 if (service_->collect_) { |
192 service_->last_sent_message_ = message; | |
193 service_->last_receiver_id_ = receiver_id; | |
194 } | |
195 SendFinished(app_id, message.id, GCMClient::SUCCESS); | |
100 } | 196 } |
101 | 197 |
102 void CustomFakeGCMDriver::OnUnregisterFinished(const std::string& app_id, | 198 void FakeGCMProfileService::CustomFakeGCMDriver::GetToken( |
103 GCMClient::Result result) { | 199 const std::string& app_id, |
104 UnregisterFinished(app_id, result); | 200 const std::string& authorized_entity, |
201 const std::string& scope, | |
202 const std::map<std::string, std::string>& options, | |
203 const GetTokenCallback& callback) { | |
204 if (service_->is_offline_) { | |
205 FailAfterMaxBackoff(base::Bind(callback, std::string() /* token */)); | |
206 return; | |
207 } | |
208 | |
209 instance_id::FakeGCMDriverForInstanceID::GetToken(app_id, authorized_entity, | |
210 scope, options, callback); | |
105 } | 211 } |
106 | 212 |
107 void CustomFakeGCMDriver::OnSendFinished(const std::string& app_id, | 213 void FakeGCMProfileService::CustomFakeGCMDriver::DeleteToken( |
108 const std::string& message_id, | 214 const std::string& app_id, |
109 GCMClient::Result result) { | 215 const std::string& authorized_entity, |
110 SendFinished(app_id, message_id, result); | 216 const std::string& scope, |
217 const DeleteTokenCallback& callback) { | |
218 if (service_->is_offline_) { | |
219 FailAfterMaxBackoff(callback); | |
220 return; | |
221 } | |
222 | |
223 instance_id::FakeGCMDriverForInstanceID::DeleteToken( | |
224 app_id, authorized_entity, scope, callback); | |
111 } | 225 } |
112 | 226 |
113 void CustomFakeGCMDriver::OnDispatchMessage(const std::string& app_id, | 227 void FakeGCMProfileService::CustomFakeGCMDriver::OnDispatchMessage( |
114 const IncomingMessage& message) { | 228 const std::string& app_id, |
229 const IncomingMessage& message) { | |
115 DispatchMessage(app_id, message); | 230 DispatchMessage(app_id, message); |
116 } | 231 } |
117 | 232 |
118 } // namespace | |
119 | |
120 // static | 233 // static |
121 std::unique_ptr<KeyedService> FakeGCMProfileService::Build( | 234 std::unique_ptr<KeyedService> FakeGCMProfileService::Build( |
122 content::BrowserContext* context) { | 235 content::BrowserContext* context) { |
123 Profile* profile = static_cast<Profile*>(context); | 236 Profile* profile = static_cast<Profile*>(context); |
124 std::unique_ptr<FakeGCMProfileService> service( | 237 std::unique_ptr<FakeGCMProfileService> service( |
125 new FakeGCMProfileService(profile)); | 238 new FakeGCMProfileService(profile)); |
126 service->SetDriverForTesting(new CustomFakeGCMDriver(service.get())); | 239 service->SetDriverForTesting(new CustomFakeGCMDriver(service.get())); |
127 return std::move(service); | 240 return std::move(service); |
128 } | 241 } |
129 | 242 |
130 FakeGCMProfileService::FakeGCMProfileService(Profile* profile) | 243 FakeGCMProfileService::FakeGCMProfileService(Profile* profile) {} |
131 : collect_(false), | |
132 registration_count_(0) { | |
133 } | |
134 | 244 |
135 FakeGCMProfileService::~FakeGCMProfileService() {} | 245 FakeGCMProfileService::~FakeGCMProfileService() {} |
136 | 246 |
137 void FakeGCMProfileService::RegisterFinished( | |
138 const std::string& app_id, | |
139 const std::vector<std::string>& sender_ids) { | |
140 if (collect_) { | |
141 last_registered_app_id_ = app_id; | |
142 last_registered_sender_ids_ = sender_ids; | |
143 } | |
144 | |
145 // Generate fake registration IDs, encoding the number of sender IDs (used by | |
146 // GcmApiTest.RegisterValidation), then an incrementing count (even for the | |
147 // same app_id - there's no caching) so tests can distinguish registrations. | |
148 std::string registration_id = base::StringPrintf("%" PRIuS "-%d", | |
149 sender_ids.size(), | |
150 registration_count_); | |
151 ++registration_count_; | |
152 | |
153 CustomFakeGCMDriver* custom_driver = | |
154 static_cast<CustomFakeGCMDriver*>(driver()); | |
155 custom_driver->OnRegisterFinished( | |
156 app_id, registration_id, GCMClient::SUCCESS); | |
157 } | |
158 | |
159 void FakeGCMProfileService::UnregisterFinished(const std::string& app_id) { | |
160 GCMClient::Result result = GCMClient::SUCCESS; | |
161 if (!unregister_responses_.empty()) { | |
162 result = unregister_responses_.front(); | |
163 unregister_responses_.pop_front(); | |
164 } | |
165 | |
166 CustomFakeGCMDriver* custom_driver = | |
167 static_cast<CustomFakeGCMDriver*>(driver()); | |
168 custom_driver->OnUnregisterFinished(app_id, result); | |
169 | |
170 if (!unregister_callback_.is_null()) | |
171 unregister_callback_.Run(app_id); | |
172 } | |
173 | |
174 void FakeGCMProfileService::SendFinished(const std::string& app_id, | |
175 const std::string& receiver_id, | |
176 const OutgoingMessage& message) { | |
177 if (collect_) { | |
178 last_sent_message_ = message; | |
179 last_receiver_id_ = receiver_id; | |
180 } | |
181 | |
182 CustomFakeGCMDriver* custom_driver = | |
183 static_cast<CustomFakeGCMDriver*>(driver()); | |
184 custom_driver->OnSendFinished(app_id, message.id, GCMClient::SUCCESS); | |
185 } | |
186 | |
187 void FakeGCMProfileService::AddExpectedUnregisterResponse( | 247 void FakeGCMProfileService::AddExpectedUnregisterResponse( |
188 GCMClient::Result result) { | 248 GCMClient::Result result) { |
189 unregister_responses_.push_back(result); | 249 unregister_responses_.push_back(result); |
190 } | 250 } |
191 | 251 |
192 void FakeGCMProfileService::SetUnregisterCallback( | |
193 const UnregisterCallback& callback) { | |
194 unregister_callback_ = callback; | |
195 } | |
196 | |
197 void FakeGCMProfileService::DispatchMessage(const std::string& app_id, | 252 void FakeGCMProfileService::DispatchMessage(const std::string& app_id, |
198 const IncomingMessage& message) { | 253 const IncomingMessage& message) { |
199 CustomFakeGCMDriver* custom_driver = | 254 CustomFakeGCMDriver* custom_driver = |
200 static_cast<CustomFakeGCMDriver*>(driver()); | 255 static_cast<CustomFakeGCMDriver*>(driver()); |
201 custom_driver->OnDispatchMessage(app_id, message); | 256 custom_driver->OnDispatchMessage(app_id, message); |
202 } | 257 } |
203 | 258 |
204 } // namespace gcm | 259 } // namespace gcm |
OLD | NEW |