Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/extensions/app_notify_channel_setup.h" | 5 #include "chrome/browser/extensions/app_notify_channel_setup.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/json/json_reader.h" | 9 #include "base/json/json_reader.h" |
| 10 #include "base/stringprintf.h" | 10 #include "base/stringprintf.h" |
| 11 #include "chrome/browser/net/gaia/token_service.h" | 11 #include "chrome/browser/net/gaia/token_service.h" |
| 12 #include "chrome/browser/prefs/pref_service.h" | 12 #include "chrome/browser/prefs/pref_service.h" |
| 13 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
| 14 #include "chrome/common/chrome_notification_types.h" | |
| 14 #include "chrome/common/chrome_switches.h" | 15 #include "chrome/common/chrome_switches.h" |
| 15 #include "chrome/common/net/gaia/gaia_constants.h" | 16 #include "chrome/common/net/gaia/gaia_constants.h" |
| 16 #include "chrome/common/net/http_return.h" | 17 #include "chrome/common/net/http_return.h" |
| 17 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
| 18 #include "content/public/browser/browser_thread.h" | 19 #include "content/public/browser/browser_thread.h" |
| 20 #include "content/public/browser/notification_details.h" | |
| 21 #include "content/public/browser/notification_service.h" | |
| 19 #include "content/public/common/url_fetcher.h" | 22 #include "content/public/common/url_fetcher.h" |
| 20 #include "net/base/escape.h" | 23 #include "net/base/escape.h" |
| 21 #include "net/base/load_flags.h" | 24 #include "net/base/load_flags.h" |
| 22 #include "net/http/http_request_headers.h" | 25 #include "net/http/http_request_headers.h" |
| 23 #include "net/url_request/url_request_status.h" | 26 #include "net/url_request/url_request_status.h" |
| 24 | 27 |
| 25 using base::StringPrintf; | 28 using base::StringPrintf; |
| 26 using content::BrowserThread; | 29 using content::BrowserThread; |
| 27 using content::URLFetcher; | 30 using content::URLFetcher; |
| 28 | 31 |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 58 AppNotifyChannelUI* ui, | 61 AppNotifyChannelUI* ui, |
| 59 base::WeakPtr<AppNotifyChannelSetup::Delegate> delegate) | 62 base::WeakPtr<AppNotifyChannelSetup::Delegate> delegate) |
| 60 : profile_(profile), | 63 : profile_(profile), |
| 61 extension_id_(extension_id), | 64 extension_id_(extension_id), |
| 62 client_id_(client_id), | 65 client_id_(client_id), |
| 63 requestor_url_(requestor_url), | 66 requestor_url_(requestor_url), |
| 64 return_route_id_(return_route_id), | 67 return_route_id_(return_route_id), |
| 65 callback_id_(callback_id), | 68 callback_id_(callback_id), |
| 66 delegate_(delegate), | 69 delegate_(delegate), |
| 67 ui_(ui), | 70 ui_(ui), |
| 68 state_(INITIAL) {} | 71 state_(INITIAL), |
| 72 fetch_token_success_count_(0), | |
| 73 fetch_token_fail_count_(0) {} | |
| 69 | 74 |
| 70 AppNotifyChannelSetup::~AppNotifyChannelSetup() {} | 75 AppNotifyChannelSetup::~AppNotifyChannelSetup() {} |
| 71 | 76 |
| 72 void AppNotifyChannelSetup::Start() { | 77 void AppNotifyChannelSetup::Start() { |
| 73 AddRef(); // Balanced in ReportResult. | 78 AddRef(); // Balanced in ReportResult. |
| 79 BeginLogin(); | |
| 80 } | |
| 74 | 81 |
| 75 CHECK_EQ(INITIAL, state_); | 82 void AppNotifyChannelSetup::Observe( |
| 76 | 83 int type, |
| 77 // Check if the user is logged in to the browser. | 84 const content::NotificationSource& source, |
| 78 std::string username = profile_->GetPrefs()->GetString( | 85 const content::NotificationDetails& details) { |
| 79 prefs::kGoogleServicesUsername); | 86 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) { |
| 80 | 87 TokenService::TokenAvailableDetails* tok_details = |
| 81 if (username.empty()) { | 88 content::Details<TokenService::TokenAvailableDetails>(details).ptr(); |
| 82 state_ = LOGIN_STARTED; | 89 if (IsGaiaServiceRelevant(tok_details->service())) |
| 83 ui_->PromptSyncSetup(this); | 90 ++fetch_token_success_count_; |
| 84 return; // We'll get called back in OnSyncSetupResult | 91 } else if (type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED) { |
| 92 TokenService::TokenRequestFailedDetails* error_details = | |
| 93 content::Details<TokenService::TokenRequestFailedDetails>( | |
| 94 details).ptr(); | |
| 95 if (IsGaiaServiceRelevant(error_details->service())) | |
| 96 ++fetch_token_fail_count_; | |
| 97 } else { | |
| 98 CHECK(false) << "Received a notification not registered for."; | |
| 85 } | 99 } |
| 86 | 100 |
| 87 state_ = LOGIN_DONE; | 101 // If we already got fetch results (success + failure) for all services |
| 88 BeginRecordGrant(); | 102 // we care about, we are done with fetching tokens. |
| 103 if (fetch_token_success_count_ + fetch_token_fail_count_ == 2) { | |
| 104 // We successfully fetched tokens if success count is equal to the | |
| 105 // number of services we care about. | |
| 106 bool success = (fetch_token_success_count_ == 2); | |
| 107 EndFetchTokens(success); | |
| 108 } | |
| 109 } | |
| 110 | |
| 111 bool AppNotifyChannelSetup::ShouldFetchServiceTokens() const { | |
| 112 TokenService* token_service = profile_->GetTokenService(); | |
| 113 return !token_service->HasTokenForService(GaiaConstants::kLSOService) || | |
| 114 !token_service->HasTokenForService(GaiaConstants::kCWSService); | |
| 89 } | 115 } |
| 90 | 116 |
| 91 void AppNotifyChannelSetup::OnSyncSetupResult(bool enabled) { | 117 void AppNotifyChannelSetup::OnSyncSetupResult(bool enabled) { |
| 92 CHECK_EQ(LOGIN_STARTED, state_); | 118 EndLogin(enabled); |
| 93 if (enabled) { | |
| 94 state_ = LOGIN_DONE; | |
| 95 BeginRecordGrant(); | |
| 96 } else { | |
| 97 state_ = ERROR_STATE; | |
| 98 ReportResult("", kChannelSetupCanceledByUser); | |
| 99 } | |
| 100 } | 119 } |
| 101 | 120 |
| 102 void AppNotifyChannelSetup::OnURLFetchComplete(const URLFetcher* source) { | 121 void AppNotifyChannelSetup::OnURLFetchComplete(const URLFetcher* source) { |
| 103 CHECK(source); | 122 CHECK(source); |
| 104 | |
| 105 switch (state_) { | 123 switch (state_) { |
| 106 case RECORD_GRANT_STARTED: | 124 case RECORD_GRANT_STARTED: |
| 107 EndRecordGrant(source); | 125 EndRecordGrant(source); |
| 108 break; | 126 break; |
| 109 case CHANNEL_ID_SETUP_STARTED: | 127 case CHANNEL_ID_SETUP_STARTED: |
| 110 EndGetChannelId(source); | 128 EndGetChannelId(source); |
| 111 break; | 129 break; |
| 112 default: | 130 default: |
| 113 CHECK(false) << "Wrong state: " << state_; | 131 CHECK(false) << "Wrong state: " << state_; |
| 114 break; | 132 break; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 126 // Always set flags to neither send nor save cookies. | 144 // Always set flags to neither send nor save cookies. |
| 127 fetcher->SetLoadFlags( | 145 fetcher->SetLoadFlags( |
| 128 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); | 146 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); |
| 129 fetcher->SetExtraRequestHeaders(MakeAuthorizationHeader(auth_token)); | 147 fetcher->SetExtraRequestHeaders(MakeAuthorizationHeader(auth_token)); |
| 130 if (!body.empty()) { | 148 if (!body.empty()) { |
| 131 fetcher->SetUploadData("application/x-www-form-urlencoded", body); | 149 fetcher->SetUploadData("application/x-www-form-urlencoded", body); |
| 132 } | 150 } |
| 133 return fetcher; | 151 return fetcher; |
| 134 } | 152 } |
| 135 | 153 |
| 154 // static | |
| 155 bool AppNotifyChannelSetup::IsGaiaServiceRelevant(const std::string& service) { | |
| 156 return service == GaiaConstants::kLSOService || | |
| 157 service == GaiaConstants::kCWSService; | |
| 158 } | |
| 159 | |
| 160 void AppNotifyChannelSetup::RegisterForTokenServiceNotifications() { | |
| 161 content::Source<TokenService> token_service(profile_->GetTokenService()); | |
| 162 registrar_.Add(this, | |
| 163 chrome::NOTIFICATION_TOKEN_AVAILABLE, | |
| 164 token_service); | |
| 165 registrar_.Add(this, | |
| 166 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, | |
| 167 token_service); | |
| 168 } | |
| 169 | |
| 170 void AppNotifyChannelSetup::UnregisterForTokenServiceNotifications() { | |
|
asargent_no_longer_on_chrome
2011/11/11 01:23:04
You could probably skip having this entire method,
Munjal (Google)
2011/11/11 01:49:27
Done. I kept the Unregister* method just for a sli
| |
| 171 content::Source<TokenService> token_service(profile_->GetTokenService()); | |
| 172 registrar_.Remove(this, | |
| 173 chrome::NOTIFICATION_TOKEN_AVAILABLE, | |
| 174 token_service); | |
| 175 registrar_.Remove(this, | |
| 176 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, | |
| 177 token_service); | |
| 178 } | |
| 179 | |
| 180 bool AppNotifyChannelSetup::ShouldPromptForLogin() const { | |
| 181 std::string username = profile_->GetPrefs()->GetString( | |
| 182 prefs::kGoogleServicesUsername); | |
| 183 return username.empty(); | |
| 184 } | |
| 185 | |
| 186 void AppNotifyChannelSetup::BeginLogin() { | |
| 187 CHECK_EQ(INITIAL, state_); | |
| 188 if (ShouldPromptForLogin()) { | |
| 189 state_ = LOGIN_STARTED; | |
| 190 ui_->PromptSyncSetup(this); | |
| 191 // We'll get called back in OnSyncSetupResult | |
| 192 } else { | |
| 193 state_ = LOGIN_DONE; | |
| 194 BeginFetchTokens(); | |
| 195 } | |
| 196 } | |
| 197 | |
| 198 void AppNotifyChannelSetup::EndLogin(bool success) { | |
| 199 CHECK_EQ(LOGIN_STARTED, state_); | |
| 200 if (success) { | |
| 201 state_ = LOGIN_DONE; | |
| 202 BeginFetchTokens(); | |
| 203 } else { | |
| 204 state_ = ERROR_STATE; | |
| 205 ReportResult("", kChannelSetupCanceledByUser); | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 void AppNotifyChannelSetup::BeginFetchTokens() { | |
| 210 CHECK_EQ(LOGIN_DONE, state_); | |
| 211 if (ShouldFetchServiceTokens()) { | |
| 212 // If a user is logged in already, and a new version of Chrome is released | |
| 213 // with new services added to Tokenservice, TokenService will not have | |
| 214 // tokens for the new services. | |
| 215 state_ = FETCH_TOKEN_STARTED; | |
| 216 RegisterForTokenServiceNotifications(); | |
| 217 profile_->GetTokenService()->StartFetchingMissingTokens(); | |
| 218 // Observe will get called with notifications from TokenService. | |
| 219 } else { | |
| 220 state_ = FETCH_TOKEN_DONE; | |
| 221 BeginRecordGrant(); | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 void AppNotifyChannelSetup::EndFetchTokens(bool success) { | |
| 226 CHECK_EQ(FETCH_TOKEN_STARTED, state_); | |
| 227 UnregisterForTokenServiceNotifications(); | |
| 228 if (success) { | |
| 229 state_ = FETCH_TOKEN_DONE; | |
| 230 BeginRecordGrant(); | |
| 231 } else { | |
| 232 state_ = ERROR_STATE; | |
| 233 ReportResult("", kChannelSetupInternalError); | |
| 234 } | |
| 235 } | |
| 236 | |
| 136 void AppNotifyChannelSetup::BeginRecordGrant() { | 237 void AppNotifyChannelSetup::BeginRecordGrant() { |
| 137 CHECK_EQ(LOGIN_DONE, state_); | 238 CHECK(FETCH_TOKEN_DONE == state_); |
| 138 state_ = RECORD_GRANT_STARTED; | 239 state_ = RECORD_GRANT_STARTED; |
| 139 | 240 |
| 140 GURL url = GetOAuth2IssueTokenURL(); | 241 GURL url = GetOAuth2IssueTokenURL(); |
| 141 std::string body = MakeOAuth2IssueTokenBody(client_id_, extension_id_); | 242 std::string body = MakeOAuth2IssueTokenBody(client_id_, extension_id_); |
| 142 | 243 |
| 143 url_fetcher_.reset(CreateURLFetcher(url, body, GetLSOAuthToken())); | 244 url_fetcher_.reset(CreateURLFetcher(url, body, GetLSOAuthToken())); |
| 144 url_fetcher_->Start(); | 245 url_fetcher_->Start(); |
| 145 } | 246 } |
| 146 | 247 |
| 147 void AppNotifyChannelSetup::EndRecordGrant(const URLFetcher* source) { | 248 void AppNotifyChannelSetup::EndRecordGrant(const URLFetcher* source) { |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); | 366 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); |
| 266 if (!dict->Get("id", &channel_id_value)) | 367 if (!dict->Get("id", &channel_id_value)) |
| 267 return false; | 368 return false; |
| 268 if (channel_id_value->GetType() != base::Value::TYPE_STRING) | 369 if (channel_id_value->GetType() != base::Value::TYPE_STRING) |
| 269 return false; | 370 return false; |
| 270 | 371 |
| 271 StringValue* channel_id = static_cast<StringValue*>(channel_id_value); | 372 StringValue* channel_id = static_cast<StringValue*>(channel_id_value); |
| 272 channel_id->GetAsString(result); | 373 channel_id->GetAsString(result); |
| 273 return true; | 374 return true; |
| 274 } | 375 } |
| OLD | NEW |