OLD | NEW |
| (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/callback.h" | |
7 #include "base/location.h" | |
8 #include "base/memory/ref_counted.h" | |
9 #include "base/single_thread_task_runner.h" | |
10 #include "base/thread_task_runner_handle.h" | |
11 #include "chrome/browser/browser_process.h" | |
12 #include "chrome/browser/invalidation/gcm_network_channel_delegate_impl.h" | |
13 #include "chrome/browser/profiles/profile_manager.h" | |
14 #include "chrome/browser/services/gcm/gcm_profile_service.h" | |
15 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" | |
16 #include "chrome/browser/signin/profile_oauth2_token_service.h" | |
17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | |
18 #include "chrome/browser/signin/profile_oauth2_token_service_request.h" | |
19 #include "chrome/browser/signin/signin_manager.h" | |
20 #include "chrome/browser/signin/signin_manager_factory.h" | |
21 #include "content/public/browser/browser_thread.h" | |
22 #include "google_apis/gaia/gaia_constants.h" | |
23 | |
24 namespace invalidation { | |
25 | |
26 namespace { | |
27 | |
28 // For 3rd party developers SenderId should come from application dashboard when | |
29 // server side application is registered with Google. Android invalidations use | |
30 // legacy format where gmail account can be specificed. Below value is copied | |
31 // from Android. | |
32 const char kInvalidationsSenderId[] = "ipc.invalidation@gmail.com"; | |
33 // In Android world AppId is provided by operating system and should | |
34 // match package name and hash of application. In desktop world these values | |
35 // are arbitrary and not verified/enforced by registration service (yet). | |
36 const char kInvalidationsAppId[] = "com.google.chrome.invalidations"; | |
37 | |
38 // In each call to Register object of RegisterCall will be created. | |
39 // Its purpose is to pass context (profile and callback) around between threads | |
40 // and async call to GCMProfilkeService::Register. | |
41 class RegisterCall : public base::RefCountedThreadSafe<RegisterCall> { | |
42 public: | |
43 RegisterCall(Profile* profile, | |
44 syncer::GCMNetworkChannelDelegate::RegisterCallback callback); | |
45 | |
46 void RegisterOnUIThread(); | |
47 | |
48 void RegisterFinishedOnUIThread(const std::string& registration_id, | |
49 gcm::GCMClient::Result result); | |
50 void RegisterFinished(const std::string& registration_id, | |
51 gcm::GCMClient::Result result); | |
52 | |
53 private: | |
54 friend class base::RefCountedThreadSafe<RegisterCall>; | |
55 virtual ~RegisterCall(); | |
56 | |
57 Profile* profile_; | |
58 syncer::GCMNetworkChannelDelegate::RegisterCallback callback_; | |
59 scoped_refptr<base::SingleThreadTaskRunner> origin_thread_task_runner_; | |
60 | |
61 DISALLOW_COPY_AND_ASSIGN(RegisterCall); | |
62 }; | |
63 | |
64 RegisterCall::RegisterCall( | |
65 Profile* profile, | |
66 syncer::GCMNetworkChannelDelegate::RegisterCallback callback) | |
67 : profile_(profile), | |
68 callback_(callback), | |
69 origin_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} | |
70 | |
71 RegisterCall::~RegisterCall() {} | |
72 | |
73 void RegisterCall::RegisterOnUIThread() { | |
74 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
75 // No-op if Profile was destroyed or GCMClient is disabled. | |
76 if (!g_browser_process->profile_manager()->IsValidProfile(profile_)) | |
77 return; | |
78 | |
79 gcm::GCMProfileService* gcm_profile_service = | |
80 gcm::GCMProfileServiceFactory::GetForProfile(profile_); | |
81 if (gcm_profile_service == NULL) | |
82 return; | |
83 | |
84 std::vector<std::string> sender_ids; | |
85 sender_ids.push_back(kInvalidationsSenderId); | |
86 gcm_profile_service->Register( | |
87 kInvalidationsAppId, | |
88 sender_ids, | |
89 base::Bind(&RegisterCall::RegisterFinishedOnUIThread, this)); | |
90 } | |
91 | |
92 void RegisterCall::RegisterFinishedOnUIThread( | |
93 const std::string& registration_id, | |
94 gcm::GCMClient::Result result) { | |
95 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
96 origin_thread_task_runner_->PostTask( | |
97 FROM_HERE, | |
98 base::Bind( | |
99 &RegisterCall::RegisterFinished, this, registration_id, result)); | |
100 } | |
101 | |
102 void RegisterCall::RegisterFinished(const std::string& registration_id, | |
103 gcm::GCMClient::Result result) { | |
104 DCHECK(origin_thread_task_runner_->BelongsToCurrentThread()); | |
105 callback_.Run(registration_id, result); | |
106 } | |
107 | |
108 } // namespace | |
109 | |
110 GCMNetworkChannelDelegateImpl::GCMNetworkChannelDelegateImpl(Profile* profile) | |
111 : OAuth2TokenService::Consumer("gcm_network_channel"), | |
112 profile_(profile), | |
113 ui_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) { | |
114 // Stash account_id. It is needed in RequestToken call on IO thread. | |
115 SigninManagerBase* signin_manager = | |
116 SigninManagerFactory::GetForProfile(profile_); | |
117 account_id_ = signin_manager->GetAuthenticatedAccountId(); | |
118 } | |
119 | |
120 GCMNetworkChannelDelegateImpl::~GCMNetworkChannelDelegateImpl() {} | |
121 | |
122 void GCMNetworkChannelDelegateImpl::Register(RegisterCallback callback) { | |
123 scoped_refptr<RegisterCall> call(new RegisterCall(profile_, callback)); | |
124 ui_thread_task_runner_->PostTask( | |
125 FROM_HERE, base::Bind(&RegisterCall::RegisterOnUIThread, call)); | |
126 } | |
127 | |
128 void GCMNetworkChannelDelegateImpl::RequestToken( | |
129 RequestTokenCallback callback) { | |
130 if (access_token_request_ != NULL) { | |
131 // Report previous request as cancelled. | |
132 GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED); | |
133 std::string access_token; | |
134 base::MessageLoop::current()->PostTask( | |
135 FROM_HERE, base::Bind(request_token_callback_, error, access_token)); | |
136 } | |
137 request_token_callback_ = callback; | |
138 OAuth2TokenService::ScopeSet scopes; | |
139 scopes.insert(GaiaConstants::kChromeSyncOAuth2Scope); | |
140 access_token_request_.reset(ProfileOAuth2TokenServiceRequest::CreateAndStart( | |
141 profile_, account_id_, scopes, this)); | |
142 } | |
143 | |
144 void GCMNetworkChannelDelegateImpl::InvalidateToken(const std::string& token) { | |
145 ui_thread_task_runner_->PostTask( | |
146 FROM_HERE, | |
147 base::Bind(&GCMNetworkChannelDelegateImpl::InvalidateTokenOnUIThread, | |
148 profile_, | |
149 token)); | |
150 } | |
151 | |
152 void GCMNetworkChannelDelegateImpl::OnGetTokenSuccess( | |
153 const OAuth2TokenService::Request* request, | |
154 const std::string& access_token, | |
155 const base::Time& expiration_time) { | |
156 DCHECK_EQ(access_token_request_, request); | |
157 request_token_callback_.Run(GoogleServiceAuthError::AuthErrorNone(), | |
158 access_token); | |
159 request_token_callback_.Reset(); | |
160 access_token_request_.reset(); | |
161 } | |
162 | |
163 void GCMNetworkChannelDelegateImpl::OnGetTokenFailure( | |
164 const OAuth2TokenService::Request* request, | |
165 const GoogleServiceAuthError& error) { | |
166 DCHECK_EQ(access_token_request_, request); | |
167 request_token_callback_.Run(error, std::string()); | |
168 request_token_callback_.Reset(); | |
169 access_token_request_.reset(); | |
170 } | |
171 | |
172 void GCMNetworkChannelDelegateImpl::InvalidateTokenOnUIThread( | |
173 Profile* profile, | |
174 const std::string& token) { | |
175 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
176 if (!g_browser_process->profile_manager()->IsValidProfile(profile)) | |
177 return; | |
178 | |
179 ProfileOAuth2TokenService* oauth2_token_service = | |
180 ProfileOAuth2TokenServiceFactory::GetForProfile(profile); | |
181 SigninManagerBase* signin_manager = | |
182 SigninManagerFactory::GetForProfile(profile); | |
183 std::string account_id = signin_manager->GetAuthenticatedAccountId(); | |
184 OAuth2TokenService::ScopeSet scopes; | |
185 scopes.insert(GaiaConstants::kGoogleTalkOAuth2Scope); | |
186 oauth2_token_service->InvalidateToken(account_id, scopes, token); | |
187 } | |
188 | |
189 } // namespace invalidation | |
OLD | NEW |