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

Side by Side Diff: chrome/browser/extensions/app_notify_channel_setup.cc

Issue 8526015: Integrate AppNotifyChannelSetup with TokenService. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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 | Annotate | Revision Log
OLDNEW
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 10 matching lines...) Expand all
39 "force=true" 42 "force=true"
40 "&response_type=token" 43 "&response_type=token"
41 "&scope=%s" 44 "&scope=%s"
42 "&client_id=%s" 45 "&client_id=%s"
43 "&origin=%s"; 46 "&origin=%s";
44 static const char kOAuth2IssueTokenScope[] = 47 static const char kOAuth2IssueTokenScope[] =
45 "https://www.googleapis.com/auth/chromewebstore.notification"; 48 "https://www.googleapis.com/auth/chromewebstore.notification";
46 static const char kCWSChannelServiceURL[] = 49 static const char kCWSChannelServiceURL[] =
47 "https://www-googleapis-staging.sandbox.google.com/chromewebstore/" 50 "https://www-googleapis-staging.sandbox.google.com/chromewebstore/"
48 "v1internal/channels/app_id/oauth_client_id"; 51 "v1internal/channels/app_id/oauth_client_id";
52 static const int kRelevantGaiaServicesCount = 2;
53 static const char* kRelevantGaiaServices[kRelevantGaiaServicesCount] = {
Rick Campbell 2011/11/16 18:13:35 Probably better to let the dimension be implicit a
Munjal (Google) 2011/11/16 19:54:46 Done.
54 GaiaConstants::kCWSService,
55 GaiaConstants::kLSOService,
56 };
49 } // namespace. 57 } // namespace.
50 58
51 AppNotifyChannelSetup::AppNotifyChannelSetup( 59 AppNotifyChannelSetup::AppNotifyChannelSetup(
52 Profile* profile, 60 Profile* profile,
53 const std::string& extension_id, 61 const std::string& extension_id,
54 const std::string& client_id, 62 const std::string& client_id,
55 const GURL& requestor_url, 63 const GURL& requestor_url,
56 int return_route_id, 64 int return_route_id,
57 int callback_id, 65 int callback_id,
58 AppNotifyChannelUI* ui, 66 AppNotifyChannelUI* ui,
59 base::WeakPtr<AppNotifyChannelSetup::Delegate> delegate) 67 base::WeakPtr<AppNotifyChannelSetup::Delegate> delegate)
60 : profile_(profile), 68 : profile_(profile),
61 extension_id_(extension_id), 69 extension_id_(extension_id),
62 client_id_(client_id), 70 client_id_(client_id),
63 requestor_url_(requestor_url), 71 requestor_url_(requestor_url),
64 return_route_id_(return_route_id), 72 return_route_id_(return_route_id),
65 callback_id_(callback_id), 73 callback_id_(callback_id),
66 delegate_(delegate), 74 delegate_(delegate),
67 ui_(ui), 75 ui_(ui),
68 state_(INITIAL) {} 76 state_(INITIAL),
77 fetch_token_success_count_(0),
78 fetch_token_fail_count_(0) {}
69 79
70 AppNotifyChannelSetup::~AppNotifyChannelSetup() {} 80 AppNotifyChannelSetup::~AppNotifyChannelSetup() {}
71 81
72 void AppNotifyChannelSetup::Start() { 82 void AppNotifyChannelSetup::Start() {
73 AddRef(); // Balanced in ReportResult. 83 AddRef(); // Balanced in ReportResult.
84 BeginLogin();
85 }
74 86
75 CHECK_EQ(INITIAL, state_); 87 void AppNotifyChannelSetup::Observe(
76 88 int type,
77 // Check if the user is logged in to the browser. 89 const content::NotificationSource& source,
78 std::string username = profile_->GetPrefs()->GetString( 90 const content::NotificationDetails& details) {
79 prefs::kGoogleServicesUsername); 91 if (type == chrome::NOTIFICATION_TOKEN_AVAILABLE) {
80 92 TokenService::TokenAvailableDetails* tok_details =
81 if (username.empty()) { 93 content::Details<TokenService::TokenAvailableDetails>(details).ptr();
82 state_ = LOGIN_STARTED; 94 if (IsGaiaServiceRelevant(tok_details->service()))
83 ui_->PromptSyncSetup(this); 95 ++fetch_token_success_count_;
84 return; // We'll get called back in OnSyncSetupResult 96 } else if (type == chrome::NOTIFICATION_TOKEN_REQUEST_FAILED) {
97 TokenService::TokenRequestFailedDetails* error_details =
98 content::Details<TokenService::TokenRequestFailedDetails>(
99 details).ptr();
100 if (IsGaiaServiceRelevant(error_details->service()))
101 ++fetch_token_fail_count_;
102 } else {
103 CHECK(false) << "Received a notification not registered for.";
85 } 104 }
86 105
87 state_ = LOGIN_DONE; 106 // If we already got fetch results (success + failure) for all services
88 BeginRecordGrant(); 107 // we care about, we are done with fetching tokens.
108 if (fetch_token_success_count_ + fetch_token_fail_count_ ==
109 kRelevantGaiaServicesCount) {
110 UnregisterForTokenServiceNotifications();
111 // We successfully fetched tokens if success count is equal to the
112 // number of services we care about.
113 bool success = (fetch_token_success_count_ == kRelevantGaiaServicesCount);
114 EndFetchTokens(success);
115 }
116 }
117
118 bool AppNotifyChannelSetup::ShouldFetchServiceTokens() const {
119 TokenService* token_service = profile_->GetTokenService();
120 for (int i = 0; i < kRelevantGaiaServicesCount; ++i) {
121 if (!token_service->HasTokenForService(kRelevantGaiaServices[i]))
122 return true;
123 }
124 return false;
89 } 125 }
90 126
91 void AppNotifyChannelSetup::OnSyncSetupResult(bool enabled) { 127 void AppNotifyChannelSetup::OnSyncSetupResult(bool enabled) {
92 CHECK_EQ(LOGIN_STARTED, state_); 128 EndLogin(enabled);
93 if (enabled) {
94 state_ = LOGIN_DONE;
95 BeginRecordGrant();
96 } else {
97 state_ = ERROR_STATE;
98 ReportResult("", kChannelSetupCanceledByUser);
99 }
100 } 129 }
101 130
102 void AppNotifyChannelSetup::OnURLFetchComplete(const URLFetcher* source) { 131 void AppNotifyChannelSetup::OnURLFetchComplete(const URLFetcher* source) {
103 CHECK(source); 132 CHECK(source);
104
105 switch (state_) { 133 switch (state_) {
106 case RECORD_GRANT_STARTED: 134 case RECORD_GRANT_STARTED:
107 EndRecordGrant(source); 135 EndRecordGrant(source);
108 break; 136 break;
109 case CHANNEL_ID_SETUP_STARTED: 137 case CHANNEL_ID_SETUP_STARTED:
110 EndGetChannelId(source); 138 EndGetChannelId(source);
111 break; 139 break;
112 default: 140 default:
113 CHECK(false) << "Wrong state: " << state_; 141 CHECK(false) << "Wrong state: " << state_;
114 break; 142 break;
(...skipping 11 matching lines...) Expand all
126 // Always set flags to neither send nor save cookies. 154 // Always set flags to neither send nor save cookies.
127 fetcher->SetLoadFlags( 155 fetcher->SetLoadFlags(
128 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES); 156 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
129 fetcher->SetExtraRequestHeaders(MakeAuthorizationHeader(auth_token)); 157 fetcher->SetExtraRequestHeaders(MakeAuthorizationHeader(auth_token));
130 if (!body.empty()) { 158 if (!body.empty()) {
131 fetcher->SetUploadData("application/x-www-form-urlencoded", body); 159 fetcher->SetUploadData("application/x-www-form-urlencoded", body);
132 } 160 }
133 return fetcher; 161 return fetcher;
134 } 162 }
135 163
164 // static
165 bool AppNotifyChannelSetup::IsGaiaServiceRelevant(const std::string& service) {
166 for (int i = 0; i < kRelevantGaiaServicesCount; ++i) {
167 if (service == kRelevantGaiaServices[i])
168 return true;
169 }
170 return false;
171 }
172
173 void AppNotifyChannelSetup::RegisterForTokenServiceNotifications() {
174 content::Source<TokenService> token_service(profile_->GetTokenService());
175 registrar_.Add(this,
176 chrome::NOTIFICATION_TOKEN_AVAILABLE,
177 token_service);
178 registrar_.Add(this,
179 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED,
180 token_service);
181 }
182
183 void AppNotifyChannelSetup::UnregisterForTokenServiceNotifications() {
184 registrar_.RemoveAll();
185 }
186
187 bool AppNotifyChannelSetup::ShouldPromptForLogin() const {
188 std::string username = profile_->GetPrefs()->GetString(
189 prefs::kGoogleServicesUsername);
190 return username.empty();
191 }
192
193 void AppNotifyChannelSetup::BeginLogin() {
194 CHECK_EQ(INITIAL, state_);
195 state_ = LOGIN_STARTED;
196 if (ShouldPromptForLogin()) {
197 ui_->PromptSyncSetup(this);
198 // We'll get called back in OnSyncSetupResult
199 } else {
200 EndLogin(true);
201 }
202 }
203
204 void AppNotifyChannelSetup::EndLogin(bool success) {
205 CHECK_EQ(LOGIN_STARTED, state_);
206 if (success) {
207 state_ = LOGIN_DONE;
208 BeginFetchTokens();
209 } else {
210 state_ = ERROR_STATE;
211 ReportResult("", kChannelSetupCanceledByUser);
212 }
213 }
214
215 void AppNotifyChannelSetup::BeginFetchTokens() {
216 CHECK_EQ(LOGIN_DONE, state_);
217 state_ = FETCH_TOKEN_STARTED;
218 if (ShouldFetchServiceTokens()) {
219 // If a user is logged in already, and a new version of Chrome is released
220 // with new services added to Tokenservice, TokenService will not have
221 // tokens for the new services.
222 RegisterForTokenServiceNotifications();
223 profile_->GetTokenService()->StartFetchingMissingTokens();
224 // Observe will get called with notifications from TokenService.
225 } else {
226 EndFetchTokens(true);
227 }
228 }
229
230 void AppNotifyChannelSetup::EndFetchTokens(bool success) {
231 CHECK_EQ(FETCH_TOKEN_STARTED, state_);
232 if (success) {
233 state_ = FETCH_TOKEN_DONE;
234 BeginRecordGrant();
235 } else {
236 state_ = ERROR_STATE;
237 ReportResult("", kChannelSetupInternalError);
238 }
239 }
240
136 void AppNotifyChannelSetup::BeginRecordGrant() { 241 void AppNotifyChannelSetup::BeginRecordGrant() {
137 CHECK_EQ(LOGIN_DONE, state_); 242 CHECK(FETCH_TOKEN_DONE == state_);
138 state_ = RECORD_GRANT_STARTED; 243 state_ = RECORD_GRANT_STARTED;
139 244
140 GURL url = GetOAuth2IssueTokenURL(); 245 GURL url = GetOAuth2IssueTokenURL();
141 std::string body = MakeOAuth2IssueTokenBody(client_id_, extension_id_); 246 std::string body = MakeOAuth2IssueTokenBody(client_id_, extension_id_);
142 247
143 url_fetcher_.reset(CreateURLFetcher(url, body, GetLSOAuthToken())); 248 url_fetcher_.reset(CreateURLFetcher(url, body, GetLSOAuthToken()));
144 url_fetcher_->Start(); 249 url_fetcher_->Start();
145 } 250 }
146 251
147 void AppNotifyChannelSetup::EndRecordGrant(const URLFetcher* source) { 252 void AppNotifyChannelSetup::EndRecordGrant(const URLFetcher* source) {
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); 370 DictionaryValue* dict = static_cast<DictionaryValue*>(value.get());
266 if (!dict->Get("id", &channel_id_value)) 371 if (!dict->Get("id", &channel_id_value))
267 return false; 372 return false;
268 if (channel_id_value->GetType() != base::Value::TYPE_STRING) 373 if (channel_id_value->GetType() != base::Value::TYPE_STRING)
269 return false; 374 return false;
270 375
271 StringValue* channel_id = static_cast<StringValue*>(channel_id_value); 376 StringValue* channel_id = static_cast<StringValue*>(channel_id_value);
272 channel_id->GetAsString(result); 377 channel_id->GetAsString(result);
273 return true; 378 return true;
274 } 379 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/app_notify_channel_setup.h ('k') | chrome/browser/extensions/app_notify_channel_setup_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698