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

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