OLD | NEW |
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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/location.h" | 6 #include "base/location.h" |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/memory/ptr_util.h" | 8 #include "base/memory/ptr_util.h" |
9 #include "base/single_thread_task_runner.h" | 9 #include "base/single_thread_task_runner.h" |
10 #include "base/threading/thread_task_runner_handle.h" | 10 #include "base/threading/thread_task_runner_handle.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 const char kInvalidationsAppId[] = "com.google.chrome.invalidations"; | 28 const char kInvalidationsAppId[] = "com.google.chrome.invalidations"; |
29 | 29 |
30 // Cacheinvalidation specific gcm message keys. | 30 // Cacheinvalidation specific gcm message keys. |
31 const char kContentKey[] = "content"; | 31 const char kContentKey[] = "content"; |
32 const char kEchoTokenKey[] = "echo-token"; | 32 const char kEchoTokenKey[] = "echo-token"; |
33 } // namespace | 33 } // namespace |
34 | 34 |
35 // Core should be very simple class that implements GCMNetwrokChannelDelegate | 35 // Core should be very simple class that implements GCMNetwrokChannelDelegate |
36 // and passes all calls to GCMInvalidationBridge. All calls should be serialized | 36 // and passes all calls to GCMInvalidationBridge. All calls should be serialized |
37 // through GCMInvalidationBridge to avoid race conditions. | 37 // through GCMInvalidationBridge to avoid race conditions. |
38 class GCMInvalidationBridge::Core : public syncer::GCMNetworkChannelDelegate, | 38 class GCMInvalidationBridge::Core : public syncer::GCMNetworkChannelDelegate { |
39 public base::NonThreadSafe { | |
40 public: | 39 public: |
41 Core(base::WeakPtr<GCMInvalidationBridge> bridge, | 40 Core(base::WeakPtr<GCMInvalidationBridge> bridge, |
42 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner); | 41 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner); |
43 ~Core() override; | 42 ~Core() override; |
44 | 43 |
45 // syncer::GCMNetworkChannelDelegate implementation. | 44 // syncer::GCMNetworkChannelDelegate implementation. |
46 void Initialize(ConnectionStateCallback connection_state_callback, | 45 void Initialize(ConnectionStateCallback connection_state_callback, |
47 base::Closure store_reset_callback) override; | 46 base::Closure store_reset_callback) override; |
48 void RequestToken(RequestTokenCallback callback) override; | 47 void RequestToken(RequestTokenCallback callback) override; |
49 void InvalidateToken(const std::string& token) override; | 48 void InvalidateToken(const std::string& token) override; |
(...skipping 15 matching lines...) Expand all Loading... |
65 void OnStoreReset(); | 64 void OnStoreReset(); |
66 | 65 |
67 private: | 66 private: |
68 base::WeakPtr<GCMInvalidationBridge> bridge_; | 67 base::WeakPtr<GCMInvalidationBridge> bridge_; |
69 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_; | 68 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_; |
70 | 69 |
71 MessageCallback message_callback_; | 70 MessageCallback message_callback_; |
72 ConnectionStateCallback connection_state_callback_; | 71 ConnectionStateCallback connection_state_callback_; |
73 base::Closure store_reset_callback_; | 72 base::Closure store_reset_callback_; |
74 | 73 |
| 74 SEQUENCE_CHECKER(sequence_checker_); |
| 75 |
75 base::WeakPtrFactory<Core> weak_factory_; | 76 base::WeakPtrFactory<Core> weak_factory_; |
76 | 77 |
77 DISALLOW_COPY_AND_ASSIGN(Core); | 78 DISALLOW_COPY_AND_ASSIGN(Core); |
78 }; | 79 }; |
79 | 80 |
80 GCMInvalidationBridge::Core::Core( | 81 GCMInvalidationBridge::Core::Core( |
81 base::WeakPtr<GCMInvalidationBridge> bridge, | 82 base::WeakPtr<GCMInvalidationBridge> bridge, |
82 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) | 83 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner) |
83 : bridge_(bridge), | 84 : bridge_(bridge), |
84 ui_thread_task_runner_(ui_thread_task_runner), | 85 ui_thread_task_runner_(ui_thread_task_runner), |
85 weak_factory_(this) { | 86 weak_factory_(this) { |
86 // Core is created on UI thread but all calls happen on IO thread. | 87 // Core is created on UI thread but all calls happen on IO thread. |
87 DetachFromThread(); | 88 DETACH_FROM_SEQUENCE(sequence_checker_); |
88 } | 89 } |
89 | 90 |
90 GCMInvalidationBridge::Core::~Core() {} | 91 GCMInvalidationBridge::Core::~Core() {} |
91 | 92 |
92 void GCMInvalidationBridge::Core::Initialize( | 93 void GCMInvalidationBridge::Core::Initialize( |
93 ConnectionStateCallback connection_state_callback, | 94 ConnectionStateCallback connection_state_callback, |
94 base::Closure store_reset_callback) { | 95 base::Closure store_reset_callback) { |
95 DCHECK(CalledOnValidThread()); | 96 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
96 connection_state_callback_ = connection_state_callback; | 97 connection_state_callback_ = connection_state_callback; |
97 store_reset_callback_ = store_reset_callback; | 98 store_reset_callback_ = store_reset_callback; |
98 // Pass core WeapPtr and TaskRunner to GCMInvalidationBridge for it to be able | 99 // Pass core WeapPtr and TaskRunner to GCMInvalidationBridge for it to be able |
99 // to post back. | 100 // to post back. |
100 ui_thread_task_runner_->PostTask( | 101 ui_thread_task_runner_->PostTask( |
101 FROM_HERE, | 102 FROM_HERE, |
102 base::Bind(&GCMInvalidationBridge::CoreInitializationDone, | 103 base::Bind(&GCMInvalidationBridge::CoreInitializationDone, |
103 bridge_, | 104 bridge_, |
104 weak_factory_.GetWeakPtr(), | 105 weak_factory_.GetWeakPtr(), |
105 base::ThreadTaskRunnerHandle::Get())); | 106 base::ThreadTaskRunnerHandle::Get())); |
106 } | 107 } |
107 | 108 |
108 void GCMInvalidationBridge::Core::RequestToken(RequestTokenCallback callback) { | 109 void GCMInvalidationBridge::Core::RequestToken(RequestTokenCallback callback) { |
109 DCHECK(CalledOnValidThread()); | 110 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
110 ui_thread_task_runner_->PostTask( | 111 ui_thread_task_runner_->PostTask( |
111 FROM_HERE, | 112 FROM_HERE, |
112 base::Bind(&GCMInvalidationBridge::RequestToken, bridge_, callback)); | 113 base::Bind(&GCMInvalidationBridge::RequestToken, bridge_, callback)); |
113 } | 114 } |
114 | 115 |
115 void GCMInvalidationBridge::Core::InvalidateToken(const std::string& token) { | 116 void GCMInvalidationBridge::Core::InvalidateToken(const std::string& token) { |
116 DCHECK(CalledOnValidThread()); | 117 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
117 ui_thread_task_runner_->PostTask( | 118 ui_thread_task_runner_->PostTask( |
118 FROM_HERE, | 119 FROM_HERE, |
119 base::Bind(&GCMInvalidationBridge::InvalidateToken, bridge_, token)); | 120 base::Bind(&GCMInvalidationBridge::InvalidateToken, bridge_, token)); |
120 } | 121 } |
121 | 122 |
122 void GCMInvalidationBridge::Core::Register(RegisterCallback callback) { | 123 void GCMInvalidationBridge::Core::Register(RegisterCallback callback) { |
123 DCHECK(CalledOnValidThread()); | 124 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
124 ui_thread_task_runner_->PostTask( | 125 ui_thread_task_runner_->PostTask( |
125 FROM_HERE, | 126 FROM_HERE, |
126 base::Bind(&GCMInvalidationBridge::Register, bridge_, callback)); | 127 base::Bind(&GCMInvalidationBridge::Register, bridge_, callback)); |
127 } | 128 } |
128 | 129 |
129 void GCMInvalidationBridge::Core::SetMessageReceiver(MessageCallback callback) { | 130 void GCMInvalidationBridge::Core::SetMessageReceiver(MessageCallback callback) { |
130 message_callback_ = callback; | 131 message_callback_ = callback; |
131 ui_thread_task_runner_->PostTask( | 132 ui_thread_task_runner_->PostTask( |
132 FROM_HERE, | 133 FROM_HERE, |
133 base::Bind(&GCMInvalidationBridge::SubscribeForIncomingMessages, | 134 base::Bind(&GCMInvalidationBridge::SubscribeForIncomingMessages, |
134 bridge_)); | 135 bridge_)); |
135 } | 136 } |
136 | 137 |
137 void GCMInvalidationBridge::Core::RequestTokenFinished( | 138 void GCMInvalidationBridge::Core::RequestTokenFinished( |
138 RequestTokenCallback callback, | 139 RequestTokenCallback callback, |
139 const GoogleServiceAuthError& error, | 140 const GoogleServiceAuthError& error, |
140 const std::string& token) { | 141 const std::string& token) { |
141 DCHECK(CalledOnValidThread()); | 142 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
142 callback.Run(error, token); | 143 callback.Run(error, token); |
143 } | 144 } |
144 | 145 |
145 void GCMInvalidationBridge::Core::RegisterFinished( | 146 void GCMInvalidationBridge::Core::RegisterFinished( |
146 RegisterCallback callback, | 147 RegisterCallback callback, |
147 const std::string& registration_id, | 148 const std::string& registration_id, |
148 gcm::GCMClient::Result result) { | 149 gcm::GCMClient::Result result) { |
149 DCHECK(CalledOnValidThread()); | 150 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
150 callback.Run(registration_id, result); | 151 callback.Run(registration_id, result); |
151 } | 152 } |
152 | 153 |
153 void GCMInvalidationBridge::Core::OnIncomingMessage( | 154 void GCMInvalidationBridge::Core::OnIncomingMessage( |
154 const std::string& message, | 155 const std::string& message, |
155 const std::string& echo_token) { | 156 const std::string& echo_token) { |
156 DCHECK(!message_callback_.is_null()); | 157 DCHECK(!message_callback_.is_null()); |
157 message_callback_.Run(message, echo_token); | 158 message_callback_.Run(message, echo_token); |
158 } | 159 } |
159 | 160 |
(...skipping 12 matching lines...) Expand all Loading... |
172 GCMInvalidationBridge::GCMInvalidationBridge( | 173 GCMInvalidationBridge::GCMInvalidationBridge( |
173 gcm::GCMDriver* gcm_driver, | 174 gcm::GCMDriver* gcm_driver, |
174 IdentityProvider* identity_provider) | 175 IdentityProvider* identity_provider) |
175 : OAuth2TokenService::Consumer("gcm_network_channel"), | 176 : OAuth2TokenService::Consumer("gcm_network_channel"), |
176 gcm_driver_(gcm_driver), | 177 gcm_driver_(gcm_driver), |
177 identity_provider_(identity_provider), | 178 identity_provider_(identity_provider), |
178 subscribed_for_incoming_messages_(false), | 179 subscribed_for_incoming_messages_(false), |
179 weak_factory_(this) {} | 180 weak_factory_(this) {} |
180 | 181 |
181 GCMInvalidationBridge::~GCMInvalidationBridge() { | 182 GCMInvalidationBridge::~GCMInvalidationBridge() { |
| 183 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
182 if (subscribed_for_incoming_messages_) { | 184 if (subscribed_for_incoming_messages_) { |
183 gcm_driver_->RemoveAppHandler(kInvalidationsAppId); | 185 gcm_driver_->RemoveAppHandler(kInvalidationsAppId); |
184 gcm_driver_->RemoveConnectionObserver(this); | 186 gcm_driver_->RemoveConnectionObserver(this); |
185 } | 187 } |
186 } | 188 } |
187 | 189 |
188 std::unique_ptr<syncer::GCMNetworkChannelDelegate> | 190 std::unique_ptr<syncer::GCMNetworkChannelDelegate> |
189 GCMInvalidationBridge::CreateDelegate() { | 191 GCMInvalidationBridge::CreateDelegate() { |
190 DCHECK(CalledOnValidThread()); | 192 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
191 return base::MakeUnique<Core>(weak_factory_.GetWeakPtr(), | 193 return base::MakeUnique<Core>(weak_factory_.GetWeakPtr(), |
192 base::ThreadTaskRunnerHandle::Get()); | 194 base::ThreadTaskRunnerHandle::Get()); |
193 } | 195 } |
194 | 196 |
195 void GCMInvalidationBridge::CoreInitializationDone( | 197 void GCMInvalidationBridge::CoreInitializationDone( |
196 base::WeakPtr<Core> core, | 198 base::WeakPtr<Core> core, |
197 scoped_refptr<base::SingleThreadTaskRunner> core_thread_task_runner) { | 199 scoped_refptr<base::SingleThreadTaskRunner> core_thread_task_runner) { |
198 DCHECK(CalledOnValidThread()); | 200 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
199 core_ = core; | 201 core_ = core; |
200 core_thread_task_runner_ = core_thread_task_runner; | 202 core_thread_task_runner_ = core_thread_task_runner; |
201 } | 203 } |
202 | 204 |
203 void GCMInvalidationBridge::RequestToken( | 205 void GCMInvalidationBridge::RequestToken( |
204 syncer::GCMNetworkChannelDelegate::RequestTokenCallback callback) { | 206 syncer::GCMNetworkChannelDelegate::RequestTokenCallback callback) { |
205 DCHECK(CalledOnValidThread()); | 207 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
206 if (access_token_request_ != NULL) { | 208 if (access_token_request_ != NULL) { |
207 // Report previous request as cancelled. | 209 // Report previous request as cancelled. |
208 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED); | 210 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED); |
209 std::string access_token; | 211 std::string access_token; |
210 core_thread_task_runner_->PostTask( | 212 core_thread_task_runner_->PostTask( |
211 FROM_HERE, | 213 FROM_HERE, |
212 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, | 214 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, |
213 core_, | 215 core_, |
214 request_token_callback_, | 216 request_token_callback_, |
215 error, | 217 error, |
216 access_token)); | 218 access_token)); |
217 } | 219 } |
218 request_token_callback_ = callback; | 220 request_token_callback_ = callback; |
219 OAuth2TokenService::ScopeSet scopes; | 221 OAuth2TokenService::ScopeSet scopes; |
220 scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope); | 222 scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope); |
221 access_token_request_ = identity_provider_->GetTokenService()->StartRequest( | 223 access_token_request_ = identity_provider_->GetTokenService()->StartRequest( |
222 identity_provider_->GetActiveAccountId(), scopes, this); | 224 identity_provider_->GetActiveAccountId(), scopes, this); |
223 } | 225 } |
224 | 226 |
225 void GCMInvalidationBridge::OnGetTokenSuccess( | 227 void GCMInvalidationBridge::OnGetTokenSuccess( |
226 const OAuth2TokenService::Request* request, | 228 const OAuth2TokenService::Request* request, |
227 const std::string& access_token, | 229 const std::string& access_token, |
228 const base::Time& expiration_time) { | 230 const base::Time& expiration_time) { |
229 DCHECK(CalledOnValidThread()); | 231 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
230 DCHECK_EQ(access_token_request_.get(), request); | 232 DCHECK_EQ(access_token_request_.get(), request); |
231 core_thread_task_runner_->PostTask( | 233 core_thread_task_runner_->PostTask( |
232 FROM_HERE, | 234 FROM_HERE, |
233 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, | 235 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, |
234 core_, | 236 core_, |
235 request_token_callback_, | 237 request_token_callback_, |
236 GoogleServiceAuthError::AuthErrorNone(), | 238 GoogleServiceAuthError::AuthErrorNone(), |
237 access_token)); | 239 access_token)); |
238 request_token_callback_.Reset(); | 240 request_token_callback_.Reset(); |
239 access_token_request_.reset(); | 241 access_token_request_.reset(); |
240 } | 242 } |
241 | 243 |
242 void GCMInvalidationBridge::OnGetTokenFailure( | 244 void GCMInvalidationBridge::OnGetTokenFailure( |
243 const OAuth2TokenService::Request* request, | 245 const OAuth2TokenService::Request* request, |
244 const GoogleServiceAuthError& error) { | 246 const GoogleServiceAuthError& error) { |
245 DCHECK(CalledOnValidThread()); | 247 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
246 DCHECK_EQ(access_token_request_.get(), request); | 248 DCHECK_EQ(access_token_request_.get(), request); |
247 core_thread_task_runner_->PostTask( | 249 core_thread_task_runner_->PostTask( |
248 FROM_HERE, | 250 FROM_HERE, |
249 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, | 251 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished, |
250 core_, | 252 core_, |
251 request_token_callback_, | 253 request_token_callback_, |
252 error, | 254 error, |
253 std::string())); | 255 std::string())); |
254 request_token_callback_.Reset(); | 256 request_token_callback_.Reset(); |
255 access_token_request_.reset(); | 257 access_token_request_.reset(); |
256 } | 258 } |
257 | 259 |
258 void GCMInvalidationBridge::InvalidateToken(const std::string& token) { | 260 void GCMInvalidationBridge::InvalidateToken(const std::string& token) { |
259 DCHECK(CalledOnValidThread()); | 261 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
260 OAuth2TokenService::ScopeSet scopes; | 262 OAuth2TokenService::ScopeSet scopes; |
261 scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope); | 263 scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope); |
262 identity_provider_->GetTokenService()->InvalidateAccessToken( | 264 identity_provider_->GetTokenService()->InvalidateAccessToken( |
263 identity_provider_->GetActiveAccountId(), scopes, token); | 265 identity_provider_->GetActiveAccountId(), scopes, token); |
264 } | 266 } |
265 | 267 |
266 void GCMInvalidationBridge::Register( | 268 void GCMInvalidationBridge::Register( |
267 syncer::GCMNetworkChannelDelegate::RegisterCallback callback) { | 269 syncer::GCMNetworkChannelDelegate::RegisterCallback callback) { |
268 DCHECK(CalledOnValidThread()); | 270 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
269 // No-op if GCMClient is disabled. | 271 // No-op if GCMClient is disabled. |
270 if (gcm_driver_ == NULL) | 272 if (gcm_driver_ == NULL) |
271 return; | 273 return; |
272 | 274 |
273 std::vector<std::string> sender_ids; | 275 std::vector<std::string> sender_ids; |
274 sender_ids.push_back(kInvalidationsSenderId); | 276 sender_ids.push_back(kInvalidationsSenderId); |
275 gcm_driver_->Register(kInvalidationsAppId, | 277 gcm_driver_->Register(kInvalidationsAppId, |
276 sender_ids, | 278 sender_ids, |
277 base::Bind(&GCMInvalidationBridge::RegisterFinished, | 279 base::Bind(&GCMInvalidationBridge::RegisterFinished, |
278 weak_factory_.GetWeakPtr(), | 280 weak_factory_.GetWeakPtr(), |
279 callback)); | 281 callback)); |
280 } | 282 } |
281 | 283 |
282 void GCMInvalidationBridge::RegisterFinished( | 284 void GCMInvalidationBridge::RegisterFinished( |
283 syncer::GCMNetworkChannelDelegate::RegisterCallback callback, | 285 syncer::GCMNetworkChannelDelegate::RegisterCallback callback, |
284 const std::string& registration_id, | 286 const std::string& registration_id, |
285 gcm::GCMClient::Result result) { | 287 gcm::GCMClient::Result result) { |
286 DCHECK(CalledOnValidThread()); | 288 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
287 core_thread_task_runner_->PostTask( | 289 core_thread_task_runner_->PostTask( |
288 FROM_HERE, | 290 FROM_HERE, |
289 base::Bind(&GCMInvalidationBridge::Core::RegisterFinished, | 291 base::Bind(&GCMInvalidationBridge::Core::RegisterFinished, |
290 core_, | 292 core_, |
291 callback, | 293 callback, |
292 registration_id, | 294 registration_id, |
293 result)); | 295 result)); |
294 } | 296 } |
295 | 297 |
296 void GCMInvalidationBridge::Unregister() { | 298 void GCMInvalidationBridge::Unregister() { |
297 DCHECK(CalledOnValidThread()); | 299 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
298 // No-op if GCMClient is disabled. | 300 // No-op if GCMClient is disabled. |
299 if (gcm_driver_ == NULL) | 301 if (gcm_driver_ == NULL) |
300 return; | 302 return; |
301 | 303 |
302 gcm_driver_->Unregister( | 304 gcm_driver_->Unregister( |
303 kInvalidationsAppId, | 305 kInvalidationsAppId, |
304 base::Bind(&GCMInvalidationBridge::UnregisterFinishedNoOp)); | 306 base::Bind(&GCMInvalidationBridge::UnregisterFinishedNoOp)); |
305 } | 307 } |
306 | 308 |
307 // static | 309 // static |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 | 387 |
386 void GCMInvalidationBridge::OnDisconnected() { | 388 void GCMInvalidationBridge::OnDisconnected() { |
387 core_thread_task_runner_->PostTask( | 389 core_thread_task_runner_->PostTask( |
388 FROM_HERE, | 390 FROM_HERE, |
389 base::Bind(&GCMInvalidationBridge::Core::OnConnectionStateChanged, | 391 base::Bind(&GCMInvalidationBridge::Core::OnConnectionStateChanged, |
390 core_, | 392 core_, |
391 false)); | 393 false)); |
392 } | 394 } |
393 | 395 |
394 } // namespace invalidation | 396 } // namespace invalidation |
OLD | NEW |