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) { | |
Rick Campbell
2011/11/11 21:18:58
I'll defer to others' judgement here, but I'm unco
Munjal (Google)
2011/11/14 23:03:15
Done.
| |
104 UnregisterForTokenServiceNotifications(); | |
105 // We successfully fetched tokens if success count is equal to the | |
106 // number of services we care about. | |
107 bool success = (fetch_token_success_count_ == 2); | |
108 EndFetchTokens(success); | |
109 } | |
110 } | |
111 | |
112 bool AppNotifyChannelSetup::ShouldFetchServiceTokens() const { | |
113 TokenService* token_service = profile_->GetTokenService(); | |
114 return !token_service->HasTokenForService(GaiaConstants::kLSOService) || | |
Rick Campbell
2011/11/11 21:18:58
Similarly here -- clearly related to the literal 2
Munjal (Google)
2011/11/14 23:03:15
Done.
| |
115 !token_service->HasTokenForService(GaiaConstants::kCWSService); | |
89 } | 116 } |
90 | 117 |
91 void AppNotifyChannelSetup::OnSyncSetupResult(bool enabled) { | 118 void AppNotifyChannelSetup::OnSyncSetupResult(bool enabled) { |
92 CHECK_EQ(LOGIN_STARTED, state_); | 119 EndLogin(enabled); |
93 if (enabled) { | |
94 state_ = LOGIN_DONE; | |
95 BeginRecordGrant(); | |
96 } else { | |
97 state_ = ERROR_STATE; | |
98 ReportResult("", kChannelSetupCanceledByUser); | |
99 } | |
100 } | 120 } |
101 | 121 |
102 void AppNotifyChannelSetup::OnURLFetchComplete(const URLFetcher* source) { | 122 void AppNotifyChannelSetup::OnURLFetchComplete(const URLFetcher* source) { |
103 CHECK(source); | 123 CHECK(source); |
104 | |
105 switch (state_) { | 124 switch (state_) { |
106 case RECORD_GRANT_STARTED: | 125 case RECORD_GRANT_STARTED: |
107 EndRecordGrant(source); | 126 EndRecordGrant(source); |
108 break; | 127 break; |
109 case CHANNEL_ID_SETUP_STARTED: | 128 case CHANNEL_ID_SETUP_STARTED: |
110 EndGetChannelId(source); | 129 EndGetChannelId(source); |
111 break; | 130 break; |
112 default: | 131 default: |
113 CHECK(false) << "Wrong state: " << state_; | 132 CHECK(false) << "Wrong state: " << state_; |
114 break; | 133 break; |
(...skipping 11 matching lines...) Expand all Loading... | |
126 // Always set flags to neither send nor save cookies. | 145 // Always set flags to neither send nor save cookies. |
127 fetcher->SetLoadFlags( | 146 fetcher->SetLoadFlags( |
128 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); | 147 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); |
129 fetcher->SetExtraRequestHeaders(MakeAuthorizationHeader(auth_token)); | 148 fetcher->SetExtraRequestHeaders(MakeAuthorizationHeader(auth_token)); |
130 if (!body.empty()) { | 149 if (!body.empty()) { |
131 fetcher->SetUploadData("application/x-www-form-urlencoded", body); | 150 fetcher->SetUploadData("application/x-www-form-urlencoded", body); |
132 } | 151 } |
133 return fetcher; | 152 return fetcher; |
134 } | 153 } |
135 | 154 |
155 // static | |
Rick Campbell
2011/11/11 21:18:58
Similarly here -- clearly related to the literal 2
Munjal (Google)
2011/11/14 23:03:15
Done.
| |
156 bool AppNotifyChannelSetup::IsGaiaServiceRelevant(const std::string& service) { | |
157 return service == GaiaConstants::kLSOService || | |
158 service == GaiaConstants::kCWSService; | |
159 } | |
160 | |
161 void AppNotifyChannelSetup::RegisterForTokenServiceNotifications() { | |
162 content::Source<TokenService> token_service(profile_->GetTokenService()); | |
163 registrar_.Add(this, | |
164 chrome::NOTIFICATION_TOKEN_AVAILABLE, | |
165 token_service); | |
166 registrar_.Add(this, | |
167 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, | |
168 token_service); | |
169 } | |
170 | |
171 void AppNotifyChannelSetup::UnregisterForTokenServiceNotifications() { | |
172 registrar_.RemoveAll(); | |
173 } | |
174 | |
175 bool AppNotifyChannelSetup::ShouldPromptForLogin() const { | |
176 std::string username = profile_->GetPrefs()->GetString( | |
177 prefs::kGoogleServicesUsername); | |
178 return username.empty(); | |
179 } | |
180 | |
181 void AppNotifyChannelSetup::BeginLogin() { | |
182 CHECK_EQ(INITIAL, state_); | |
183 if (ShouldPromptForLogin()) { | |
184 state_ = LOGIN_STARTED; | |
185 ui_->PromptSyncSetup(this); | |
186 // We'll get called back in OnSyncSetupResult | |
187 } else { | |
188 EndLogin(true); | |
189 } | |
190 } | |
191 | |
192 void AppNotifyChannelSetup::EndLogin(bool success) { | |
193 CHECK_EQ(LOGIN_STARTED, state_); | |
194 if (success) { | |
195 state_ = LOGIN_DONE; | |
196 BeginFetchTokens(); | |
197 } else { | |
198 state_ = ERROR_STATE; | |
199 ReportResult("", kChannelSetupCanceledByUser); | |
200 } | |
201 } | |
202 | |
203 void AppNotifyChannelSetup::BeginFetchTokens() { | |
204 CHECK_EQ(LOGIN_DONE, state_); | |
205 if (ShouldFetchServiceTokens()) { | |
206 // If a user is logged in already, and a new version of Chrome is released | |
207 // with new services added to Tokenservice, TokenService will not have | |
208 // tokens for the new services. | |
209 state_ = FETCH_TOKEN_STARTED; | |
210 RegisterForTokenServiceNotifications(); | |
211 profile_->GetTokenService()->StartFetchingMissingTokens(); | |
212 // Observe will get called with notifications from TokenService. | |
213 } else { | |
214 EndFetchTokens(true); | |
215 } | |
216 } | |
217 | |
218 void AppNotifyChannelSetup::EndFetchTokens(bool success) { | |
219 CHECK_EQ(FETCH_TOKEN_STARTED, state_); | |
220 if (success) { | |
221 state_ = FETCH_TOKEN_DONE; | |
222 BeginRecordGrant(); | |
223 } else { | |
224 state_ = ERROR_STATE; | |
225 ReportResult("", kChannelSetupInternalError); | |
226 } | |
227 } | |
228 | |
136 void AppNotifyChannelSetup::BeginRecordGrant() { | 229 void AppNotifyChannelSetup::BeginRecordGrant() { |
137 CHECK_EQ(LOGIN_DONE, state_); | 230 CHECK(FETCH_TOKEN_DONE == state_); |
138 state_ = RECORD_GRANT_STARTED; | 231 state_ = RECORD_GRANT_STARTED; |
139 | 232 |
140 GURL url = GetOAuth2IssueTokenURL(); | 233 GURL url = GetOAuth2IssueTokenURL(); |
141 std::string body = MakeOAuth2IssueTokenBody(client_id_, extension_id_); | 234 std::string body = MakeOAuth2IssueTokenBody(client_id_, extension_id_); |
142 | 235 |
143 url_fetcher_.reset(CreateURLFetcher(url, body, GetLSOAuthToken())); | 236 url_fetcher_.reset(CreateURLFetcher(url, body, GetLSOAuthToken())); |
144 url_fetcher_->Start(); | 237 url_fetcher_->Start(); |
145 } | 238 } |
146 | 239 |
147 void AppNotifyChannelSetup::EndRecordGrant(const URLFetcher* source) { | 240 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()); | 358 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); |
266 if (!dict->Get("id", &channel_id_value)) | 359 if (!dict->Get("id", &channel_id_value)) |
267 return false; | 360 return false; |
268 if (channel_id_value->GetType() != base::Value::TYPE_STRING) | 361 if (channel_id_value->GetType() != base::Value::TYPE_STRING) |
269 return false; | 362 return false; |
270 | 363 |
271 StringValue* channel_id = static_cast<StringValue*>(channel_id_value); | 364 StringValue* channel_id = static_cast<StringValue*>(channel_id_value); |
272 channel_id->GetAsString(result); | 365 channel_id->GetAsString(result); |
273 return true; | 366 return true; |
274 } | 367 } |
OLD | NEW |