| 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 "content/public/browser/browser_thread.h" | |
| 20 #include "google_apis/gaia/gaia_constants.h" | |
| 21 | |
| 22 namespace invalidation { | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 // For 3rd party developers SenderId should come from application dashboard when | |
| 27 // server side application is registered with Google. Android invalidations use | |
| 28 // legacy format where gmail account can be specificed. Below value is copied | |
| 29 // from Android. | |
| 30 const char kInvalidationsSenderId[] = "ipc.invalidation@gmail.com"; | |
| 31 // In Android world AppId and Cert are provided by operating system and should | |
| 32 // match package name and hash of application. In desktop world these values | |
| 33 // are arbitrary and not verified/enforced by registration service (yet). | |
| 34 const char kInvalidationsAppId[] = "com.google.chrome.invalidations"; | |
| 35 const char kInvalidationsCert[] = "ABC"; | |
| 36 | |
| 37 // In each call to Register object of RegisterCall will be created. | |
| 38 // Its purpose is to pass context (profile and callback) around between threads | |
| 39 // and async call to GCMProfilkeService::Register. | |
| 40 class RegisterCall : public base::RefCountedThreadSafe<RegisterCall> { | |
| 41 public: | |
| 42 RegisterCall(Profile* profile, | |
| 43 syncer::GCMNetworkChannelDelegate::RegisterCallback callback); | |
| 44 | |
| 45 void RegisterOnUIThread(); | |
| 46 | |
| 47 void RegisterFinishedOnUIThread(const std::string& registration_id, | |
| 48 gcm::GCMClient::Result result); | |
| 49 void RegisterFinished(const std::string& registration_id, | |
| 50 gcm::GCMClient::Result result); | |
| 51 | |
| 52 private: | |
| 53 friend class base::RefCountedThreadSafe<RegisterCall>; | |
| 54 virtual ~RegisterCall(); | |
| 55 | |
| 56 Profile* profile_; | |
| 57 syncer::GCMNetworkChannelDelegate::RegisterCallback callback_; | |
| 58 scoped_refptr<base::SingleThreadTaskRunner> origin_thread_task_runner_; | |
| 59 | |
| 60 DISALLOW_COPY_AND_ASSIGN(RegisterCall); | |
| 61 }; | |
| 62 | |
| 63 RegisterCall::RegisterCall( | |
| 64 Profile* profile, | |
| 65 syncer::GCMNetworkChannelDelegate::RegisterCallback callback) | |
| 66 : profile_(profile), | |
| 67 callback_(callback), | |
| 68 origin_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} | |
| 69 | |
| 70 RegisterCall::~RegisterCall() {} | |
| 71 | |
| 72 void RegisterCall::RegisterOnUIThread() { | |
| 73 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 74 // No-op if Profile was destroyed or GCMClient is disabled. | |
| 75 if (!g_browser_process->profile_manager()->IsValidProfile(profile_)) | |
| 76 return; | |
| 77 | |
| 78 gcm::GCMProfileService* gcm_profile_service = | |
| 79 gcm::GCMProfileServiceFactory::GetForProfile(profile_); | |
| 80 if (gcm_profile_service == NULL) | |
| 81 return; | |
| 82 | |
| 83 std::vector<std::string> sender_ids; | |
| 84 sender_ids.push_back(kInvalidationsSenderId); | |
| 85 gcm_profile_service->Register( | |
| 86 kInvalidationsAppId, | |
| 87 sender_ids, | |
| 88 kInvalidationsCert, | |
| 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 ProfileOAuth2TokenService* oauth2_token_service = | |
| 116 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
| 117 account_id_ = oauth2_token_service->GetPrimaryAccountId(); | |
| 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 std::string account_id = oauth2_token_service->GetPrimaryAccountId(); | |
| 182 OAuth2TokenService::ScopeSet scopes; | |
| 183 scopes.insert(GaiaConstants::kGoogleTalkOAuth2Scope); | |
| 184 oauth2_token_service->InvalidateToken(account_id, scopes, token); | |
| 185 } | |
| 186 | |
| 187 } // namespace invalidation | |
| OLD | NEW |