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

Side by Side Diff: chrome/browser/invalidation/gcm_invalidation_bridge.cc

Issue 186623006: Refactor GCMNetworkChannelDelegateImpl (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 9 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/bind.h"
6 #include "base/location.h"
7 #include "base/single_thread_task_runner.h"
8 #include "base/thread_task_runner_handle.h"
9 #include "chrome/browser/invalidation/gcm_invalidation_bridge.h"
10 #include "chrome/browser/services/gcm/gcm_profile_service.h"
11 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
12 #include "chrome/browser/signin/profile_oauth2_token_service.h"
13 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
14 #include "google_apis/gaia/gaia_constants.h"
15
16 namespace invalidation {
17 namespace {
18 // For 3rd party developers SenderId should come from application dashboard when
19 // server side application is registered with Google. Android invalidations use
20 // legacy format where gmail account can be specificed. Below value is copied
21 // from Android.
22 const char kInvalidationsSenderId[] = "ipc.invalidation@gmail.com";
23 // In Android world AppId and Cert are provided by operating system and should
24 // match package name and hash of application. In desktop world these values
25 // are arbitrary and not verified/enforced by registration service (yet).
26 const char kInvalidationsAppId[] = "com.google.chrome.invalidations";
27 const char kInvalidationsCert[] = "ABC";
28
29 } // namespace
30
31 // Core should be very simple class that implements GCMNetwrokChannelDelegate
32 // and passes all calls to GCMInvalidationBridge. All calls should be serialized
33 // through GCMInvalidationBridge to avoid race conditions.
34 class GCMInvalidationBridge::Core : public syncer::GCMNetworkChannelDelegate,
35 public base::NonThreadSafe {
36 public:
37 Core(base::WeakPtr<GCMInvalidationBridge> bridge,
38 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner);
39 virtual ~Core();
40
41 // syncer::GCMNetworkChannelDelegate implementation.
42 virtual void Initialize() OVERRIDE;
43 virtual void RequestToken(RequestTokenCallback callback) OVERRIDE;
44 virtual void InvalidateToken(const std::string& token) OVERRIDE;
45 virtual void Register(RegisterCallback callback) OVERRIDE;
46
47 void RequestTokenFinished(RequestTokenCallback callback,
48 const GoogleServiceAuthError& error,
49 const std::string& token);
50
51 void RegisterFinished(RegisterCallback callback,
52 const std::string& registration_id,
53 gcm::GCMClient::Result result);
54
55 private:
56 base::WeakPtr<GCMInvalidationBridge> bridge_;
57 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner_;
58
59 base::WeakPtrFactory<Core> weak_factory_;
60
61 DISALLOW_COPY_AND_ASSIGN(Core);
62 };
63
64 GCMInvalidationBridge::Core::Core(
65 base::WeakPtr<GCMInvalidationBridge> bridge,
66 scoped_refptr<base::SingleThreadTaskRunner> ui_thread_task_runner)
67 : bridge_(bridge),
68 ui_thread_task_runner_(ui_thread_task_runner),
69 weak_factory_(this) {
70 // Core is created on UI thread but all calls happen on IO thread.
71 DetachFromThread();
rlarocque 2014/03/04 19:43:06 Neat. I didn't know about this trick. I'll have
72 }
73
74 GCMInvalidationBridge::Core::~Core() {}
75
76 void GCMInvalidationBridge::Core::Initialize() {
77 DCHECK(CalledOnValidThread());
78 // Pass core WeapPtr and TaskRunner to GCMInvalidationBridge for it to be able
79 // to post back.
80 ui_thread_task_runner_->PostTask(
rlarocque 2014/03/04 19:43:06 Is this necessary? I think it would be safe to ge
pavely 2014/03/04 20:14:42 This was deliberate. I need to pass TaskRunner of
rlarocque 2014/03/04 21:30:19 OK, that works. Just making sure that there was a
81 FROM_HERE,
82 base::Bind(&GCMInvalidationBridge::CoreInitializationDone,
83 bridge_,
84 weak_factory_.GetWeakPtr(),
85 base::ThreadTaskRunnerHandle::Get()));
86 }
87
88 void GCMInvalidationBridge::Core::RequestToken(RequestTokenCallback callback) {
89 DCHECK(CalledOnValidThread());
90 ui_thread_task_runner_->PostTask(
91 FROM_HERE,
92 base::Bind(&GCMInvalidationBridge::RequestToken, bridge_, callback));
93 }
94
95 void GCMInvalidationBridge::Core::InvalidateToken(const std::string& token) {
96 DCHECK(CalledOnValidThread());
97 ui_thread_task_runner_->PostTask(
98 FROM_HERE,
99 base::Bind(&GCMInvalidationBridge::InvalidateToken, bridge_, token));
100 }
101
102 void GCMInvalidationBridge::Core::Register(RegisterCallback callback) {
103 DCHECK(CalledOnValidThread());
104 ui_thread_task_runner_->PostTask(
105 FROM_HERE,
106 base::Bind(&GCMInvalidationBridge::Register, bridge_, callback));
107 }
108
109 void GCMInvalidationBridge::Core::RequestTokenFinished(
110 RequestTokenCallback callback,
111 const GoogleServiceAuthError& error,
112 const std::string& token) {
113 DCHECK(CalledOnValidThread());
114 callback.Run(error, token);
115 }
116
117 void GCMInvalidationBridge::Core::RegisterFinished(
118 RegisterCallback callback,
119 const std::string& registration_id,
120 gcm::GCMClient::Result result) {
121 DCHECK(CalledOnValidThread());
122 callback.Run(registration_id, result);
123 }
124
125 GCMInvalidationBridge::GCMInvalidationBridge(Profile* profile)
126 : OAuth2TokenService::Consumer("gcm_network_channel"),
127 profile_(profile),
128 weak_factory_(this) {}
129
130 GCMInvalidationBridge::~GCMInvalidationBridge() {}
131
132 scoped_ptr<syncer::GCMNetworkChannelDelegate>
133 GCMInvalidationBridge::CreateDelegate() {
134 DCHECK(CalledOnValidThread());
135 scoped_ptr<syncer::GCMNetworkChannelDelegate> core(new Core(
136 weak_factory_.GetWeakPtr(), base::ThreadTaskRunnerHandle::Get()));
137 return core.Pass();
138 }
139
140 void GCMInvalidationBridge::CoreInitializationDone(
141 base::WeakPtr<Core> core,
142 scoped_refptr<base::SingleThreadTaskRunner> core_thread_task_runner) {
143 DCHECK(CalledOnValidThread());
144 core_ = core;
145 core_thread_task_runner_ = core_thread_task_runner;
146 }
147
148 void GCMInvalidationBridge::RequestToken(
149 syncer::GCMNetworkChannelDelegate::RequestTokenCallback callback) {
150 DCHECK(CalledOnValidThread());
151 if (access_token_request_ != NULL) {
152 // Report previous request as cancelled.
153 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
154 std::string access_token;
155 core_thread_task_runner_->PostTask(
156 FROM_HERE,
157 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
158 core_,
159 request_token_callback_,
160 error,
161 access_token));
162 }
163 ProfileOAuth2TokenService* token_service =
164 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
165 request_token_callback_ = callback;
166 std::string account_id = token_service->GetPrimaryAccountId();
167 OAuth2TokenService::ScopeSet scopes;
168 scopes.insert(GaiaConstants::kGoogleTalkOAuth2Scope);
169 access_token_request_ = token_service->StartRequest(account_id, scopes, this);
170 }
171
172 void GCMInvalidationBridge::OnGetTokenSuccess(
173 const OAuth2TokenService::Request* request,
174 const std::string& access_token,
175 const base::Time& expiration_time) {
176 DCHECK(CalledOnValidThread());
177 DCHECK_EQ(access_token_request_, request);
178 core_thread_task_runner_->PostTask(
179 FROM_HERE,
180 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
181 core_,
182 request_token_callback_,
183 GoogleServiceAuthError::AuthErrorNone(),
184 access_token));
185 request_token_callback_.Reset();
186 access_token_request_.reset();
187 }
188
189 void GCMInvalidationBridge::OnGetTokenFailure(
190 const OAuth2TokenService::Request* request,
191 const GoogleServiceAuthError& error) {
192 DCHECK(CalledOnValidThread());
193 DCHECK_EQ(access_token_request_, request);
194 core_thread_task_runner_->PostTask(
195 FROM_HERE,
196 base::Bind(&GCMInvalidationBridge::Core::RequestTokenFinished,
197 core_,
198 request_token_callback_,
199 error,
200 std::string()));
201 request_token_callback_.Reset();
202 access_token_request_.reset();
203 }
204
205 void GCMInvalidationBridge::InvalidateToken(const std::string& token) {
206 ProfileOAuth2TokenService* token_service =
207 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
208 DCHECK(CalledOnValidThread());
209 std::string account_id = token_service->GetPrimaryAccountId();
210 OAuth2TokenService::ScopeSet scopes;
211 scopes.insert(GaiaConstants::kGoogleTalkOAuth2Scope);
212 token_service->InvalidateToken(account_id, scopes, token);
213 }
214
215 void GCMInvalidationBridge::Register(
216 syncer::GCMNetworkChannelDelegate::RegisterCallback callback) {
217 DCHECK(CalledOnValidThread());
218 // No-op if GCMClient is disabled.
219 gcm::GCMProfileService* gcm_profile_service =
220 gcm::GCMProfileServiceFactory::GetForProfile(profile_);
221 if (gcm_profile_service == NULL)
222 return;
223
224 std::vector<std::string> sender_ids;
225 sender_ids.push_back(kInvalidationsSenderId);
226 gcm_profile_service->Register(
227 kInvalidationsAppId,
228 sender_ids,
229 kInvalidationsCert,
230 base::Bind(&GCMInvalidationBridge::RegisterFinished,
231 weak_factory_.GetWeakPtr(),
232 callback));
233 }
234
235 void GCMInvalidationBridge::RegisterFinished(
236 syncer::GCMNetworkChannelDelegate::RegisterCallback callback,
237 const std::string& registration_id,
238 gcm::GCMClient::Result result) {
239 DCHECK(CalledOnValidThread());
240 core_thread_task_runner_->PostTask(
241 FROM_HERE,
242 base::Bind(&GCMInvalidationBridge::Core::RegisterFinished,
243 core_,
244 callback,
245 registration_id,
246 result));
247 }
248
249 } // namespace invalidation
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698