OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/interests/interests_fetcher.h" | 5 #include "chrome/browser/interests/interests_fetcher.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
(...skipping 13 matching lines...) Expand all Loading... |
24 const int kNumRetries = 1; | 24 const int kNumRetries = 1; |
25 const char kIdInterests[] = "interests"; | 25 const char kIdInterests[] = "interests"; |
26 const char kIdInterestName[] = "name"; | 26 const char kIdInterestName[] = "name"; |
27 const char kIdInterestImageUrl[] = "imageUrl"; | 27 const char kIdInterestImageUrl[] = "imageUrl"; |
28 const char kIdInterestRelevance[] = "relevance"; | 28 const char kIdInterestRelevance[] = "relevance"; |
29 | 29 |
30 const char kApiScope[] = "https://www.googleapis.com/auth/googlenow"; | 30 const char kApiScope[] = "https://www.googleapis.com/auth/googlenow"; |
31 | 31 |
32 const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; | 32 const char kAuthorizationHeaderFormat[] = "Authorization: Bearer %s"; |
33 | 33 |
34 std::vector<InterestsFetcher::Interest> EmptyResponse() { | |
35 return std::vector<InterestsFetcher::Interest>(); | |
36 } | |
37 | |
38 GURL GetInterestsURL() { | 34 GURL GetInterestsURL() { |
39 const base::CommandLine* command_line = | 35 const base::CommandLine* command_line = |
40 base::CommandLine::ForCurrentProcess(); | 36 base::CommandLine::ForCurrentProcess(); |
41 return GURL(command_line->GetSwitchValueASCII(switches::kInterestsURL)); | 37 return GURL(command_line->GetSwitchValueASCII(switches::kInterestsURL)); |
42 } | 38 } |
43 | 39 |
44 } // namespace | 40 } // namespace |
45 | 41 |
46 InterestsFetcher::Interest::Interest(const std::string& name, | 42 InterestsFetcher::Interest::Interest(const std::string& name, |
47 const GURL& image_url, | 43 const GURL& image_url, |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 const InterestsFetcher::InterestsCallback& callback) { | 82 const InterestsFetcher::InterestsCallback& callback) { |
87 DCHECK(callback_.is_null()); | 83 DCHECK(callback_.is_null()); |
88 callback_ = callback; | 84 callback_ = callback; |
89 StartOAuth2Request(); | 85 StartOAuth2Request(); |
90 } | 86 } |
91 | 87 |
92 void InterestsFetcher::OnURLFetchComplete(const net::URLFetcher* source) { | 88 void InterestsFetcher::OnURLFetchComplete(const net::URLFetcher* source) { |
93 const net::URLRequestStatus& status = source->GetStatus(); | 89 const net::URLRequestStatus& status = source->GetStatus(); |
94 if (!status.is_success()) { | 90 if (!status.is_success()) { |
95 VLOG(2) << "Network error " << status.error(); | 91 VLOG(2) << "Network error " << status.error(); |
96 callback_.Run(EmptyResponse()); | 92 callback_.Run(nullptr); |
97 return; | 93 return; |
98 } | 94 } |
99 | 95 |
100 int response_code = source->GetResponseCode(); | 96 int response_code = source->GetResponseCode(); |
101 // If we get an authorization error, refresh token and retry once. | 97 // If we get an authorization error, refresh token and retry once. |
102 if (response_code == net::HTTP_UNAUTHORIZED && !access_token_expired_) { | 98 if (response_code == net::HTTP_UNAUTHORIZED && !access_token_expired_) { |
103 access_token_expired_ = true; | 99 access_token_expired_ = true; |
104 token_service_->InvalidateAccessToken(account_id_, | 100 token_service_->InvalidateAccessToken(account_id_, |
105 GetApiScopes(), | 101 GetApiScopes(), |
106 access_token_); | 102 access_token_); |
107 StartOAuth2Request(); | 103 StartOAuth2Request(); |
108 return; | 104 return; |
109 } | 105 } |
110 | 106 |
111 if (response_code != net::HTTP_OK) { | 107 if (response_code != net::HTTP_OK) { |
112 VLOG(2) << "HTTP error " << response_code; | 108 VLOG(2) << "HTTP error " << response_code; |
113 callback_.Run(EmptyResponse()); | 109 callback_.Run(nullptr); |
114 return; | 110 return; |
115 } | 111 } |
116 | 112 |
117 std::string response_body; | 113 std::string response_body; |
118 source->GetResponseAsString(&response_body); | 114 source->GetResponseAsString(&response_body); |
119 | 115 |
120 callback_.Run(ExtractInterests(response_body)); | 116 callback_.Run(ExtractInterests(response_body)); |
121 } | 117 } |
122 | 118 |
123 void InterestsFetcher::OnGetTokenSuccess( | 119 void InterestsFetcher::OnGetTokenSuccess( |
(...skipping 12 matching lines...) Expand all Loading... |
136 base::StringPrintf(kAuthorizationHeaderFormat, access_token_.c_str())); | 132 base::StringPrintf(kAuthorizationHeaderFormat, access_token_.c_str())); |
137 | 133 |
138 fetcher_->Start(); | 134 fetcher_->Start(); |
139 } | 135 } |
140 | 136 |
141 void InterestsFetcher::OnGetTokenFailure( | 137 void InterestsFetcher::OnGetTokenFailure( |
142 const OAuth2TokenService::Request* request, | 138 const OAuth2TokenService::Request* request, |
143 const GoogleServiceAuthError& error) { | 139 const GoogleServiceAuthError& error) { |
144 DLOG(WARNING) << error.ToString(); | 140 DLOG(WARNING) << error.ToString(); |
145 | 141 |
146 callback_.Run(EmptyResponse()); | 142 callback_.Run(nullptr); |
147 } | 143 } |
148 | 144 |
149 void InterestsFetcher::StartOAuth2Request() { | 145 void InterestsFetcher::StartOAuth2Request() { |
150 oauth_request_ = | 146 oauth_request_ = |
151 token_service_->StartRequest(account_id_, GetApiScopes(), this); | 147 token_service_->StartRequest(account_id_, GetApiScopes(), this); |
152 } | 148 } |
153 | 149 |
154 OAuth2TokenService::ScopeSet InterestsFetcher::GetApiScopes() { | 150 OAuth2TokenService::ScopeSet InterestsFetcher::GetApiScopes() { |
155 OAuth2TokenService::ScopeSet scopes; | 151 OAuth2TokenService::ScopeSet scopes; |
156 scopes.insert(kApiScope); | 152 scopes.insert(kApiScope); |
157 return scopes; | 153 return scopes; |
158 } | 154 } |
159 | 155 |
160 scoped_ptr<net::URLFetcher> InterestsFetcher::CreateFetcher() { | 156 scoped_ptr<net::URLFetcher> InterestsFetcher::CreateFetcher() { |
161 return | 157 return |
162 net::URLFetcher::Create(0, GetInterestsURL(), net::URLFetcher::GET, this); | 158 net::URLFetcher::Create(0, GetInterestsURL(), net::URLFetcher::GET, this); |
163 } | 159 } |
164 | 160 |
165 std::vector<InterestsFetcher::Interest> InterestsFetcher::ExtractInterests( | 161 scoped_ptr<std::vector<InterestsFetcher::Interest>> |
166 const std::string& response) { | 162 InterestsFetcher::ExtractInterests(const std::string& response) { |
167 scoped_ptr<base::Value> value = base::JSONReader::Read(response); | 163 scoped_ptr<base::Value> value = base::JSONReader::Read(response); |
168 DVLOG(2) << response; | 164 DVLOG(2) << response; |
169 | 165 |
170 const base::DictionaryValue* dict = nullptr; | 166 const base::DictionaryValue* dict = nullptr; |
171 if (!value || !value->GetAsDictionary(&dict)) { | 167 if (!value || !value->GetAsDictionary(&dict)) { |
172 DLOG(WARNING) << "Failed to parse global dictionary."; | 168 DLOG(WARNING) << "Failed to parse global dictionary."; |
173 return EmptyResponse(); | 169 return nullptr; |
174 } | 170 } |
175 | 171 |
176 const base::ListValue* interests_list = nullptr; | 172 const base::ListValue* interests_list = nullptr; |
177 if (!dict->GetList(kIdInterests, &interests_list)) { | 173 if (!dict->GetList(kIdInterests, &interests_list)) { |
178 DLOG(WARNING) << "Failed to parse interests list."; | 174 DLOG(WARNING) << "Failed to parse interests list."; |
179 return EmptyResponse(); | 175 return nullptr; |
180 } | 176 } |
181 | 177 |
182 std::vector<Interest> res; | 178 scoped_ptr<std::vector<Interest>> res(new std::vector<Interest>()); |
183 for (const base::Value* entry : *interests_list) { | 179 for (const base::Value* entry : *interests_list) { |
184 const base::DictionaryValue* interest_dict = nullptr; | 180 const base::DictionaryValue* interest_dict = nullptr; |
185 if (!entry->GetAsDictionary(&interest_dict)) { | 181 if (!entry->GetAsDictionary(&interest_dict)) { |
186 DLOG(WARNING) << "Failed to parse interest dictionary."; | 182 DLOG(WARNING) << "Failed to parse interest dictionary."; |
187 continue; | 183 continue; |
188 } | 184 } |
189 | 185 |
190 // Extract the parts of the interest. | 186 // Extract the parts of the interest. |
191 std::string name; | 187 std::string name; |
192 std::string image_url; | 188 std::string image_url; |
193 double relevance = 0; | 189 double relevance = 0; |
194 | 190 |
195 if (!interest_dict->GetString(kIdInterestName, &name)) { | 191 if (!interest_dict->GetString(kIdInterestName, &name)) { |
196 DLOG(WARNING) << "Failed to parse interest name."; | 192 DLOG(WARNING) << "Failed to parse interest name."; |
197 continue; | 193 continue; |
198 } | 194 } |
199 | 195 |
200 if (!interest_dict->GetString(kIdInterestImageUrl, &image_url)) { | 196 if (!interest_dict->GetString(kIdInterestImageUrl, &image_url)) { |
201 DLOG(WARNING) << "Failed to parse interest image URL."; | 197 DLOG(WARNING) << "Failed to parse interest image URL."; |
202 // image_url is not mandatory, however warn if omitted. | 198 // image_url is not mandatory, however warn if omitted. |
203 } | 199 } |
204 | 200 |
205 if (!interest_dict->GetDouble(kIdInterestRelevance, &relevance)) { | 201 if (!interest_dict->GetDouble(kIdInterestRelevance, &relevance)) { |
206 DLOG(WARNING) << "Failed to parse interest relevance."; | 202 DLOG(WARNING) << "Failed to parse interest relevance."; |
207 continue; | 203 continue; |
208 } | 204 } |
209 | 205 |
210 res.push_back(Interest{name, GURL(image_url), relevance}); | 206 res->push_back(Interest{name, GURL(image_url), relevance}); |
211 } | 207 } |
212 | 208 |
213 return res; | 209 return res; |
214 } | 210 } |
OLD | NEW |