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

Side by Side Diff: chrome/browser/intents/cws_intents_registry.cc

Issue 12225076: Delete most web intents code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 10 months 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
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/intents/cws_intents_registry.h"
6
7 #include "base/callback.h"
8 #include "base/json/json_string_value_serializer.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h"
11 #include "base/string16.h"
12 #include "base/utf_string_conversions.h"
13 #include "chrome/common/extensions/extension_l10n_util.h"
14 #include "chrome/common/extensions/message_bundle.h"
15 #include "chrome/browser/net/chrome_url_request_context.h"
16 #include "chrome/browser/webdata/web_data_service.h"
17 #include "google_apis/google_api_keys.h"
18 #include "net/base/load_flags.h"
19 #include "net/base/mime_util.h"
20 #include "net/base/url_util.h"
21 #include "net/url_request/url_fetcher.h"
22
23 namespace {
24
25 // Limit for the number of suggestions we fix from CWS. Ideally, the registry
26 // simply get all of them, but there is a) chunking on the CWS side, and b)
27 // there is a cost with suggestions fetched. (Network overhead for favicons,
28 // roundtrips to registry to check if installed).
29 //
30 // Since the picker limits the number of suggestions displayed to 5, 15 means
31 // the suggestion list only has the potential to be shorter than that once the
32 // user has at least 10 installed handlers for the particular action/type.
33 //
34 // TODO(groby): Adopt number of suggestions dynamically so the picker can
35 // always display 5 suggestions unless there are less than 5 viable extensions
36 // in the CWS.
37 const char kMaxSuggestions[] = "15";
38
39 // URL for CWS intents API.
40 const char kCWSIntentServiceURL[] =
41 "https://www.googleapis.com/chromewebstore/v1.1b/items/intent";
42
43 // Determines if a string is a candidate for localization.
44 bool ShouldLocalize(const std::string& value) {
45 std::string::size_type index = 0;
46 index = value.find(extensions::MessageBundle::kMessageBegin);
47 if (index == std::string::npos)
48 return false;
49
50 index = value.find(extensions::MessageBundle::kMessageEnd, index);
51 return (index != std::string::npos);
52 }
53
54 // Parses a JSON |response| from the CWS into a list of suggested extensions,
55 // stored in |intents|. |intents| must not be NULL.
56 void ParseResponse(const std::string& response,
57 CWSIntentsRegistry::IntentExtensionList* intents) {
58 std::string error;
59 scoped_ptr<Value> parsed_response;
60 JSONStringValueSerializer serializer(response);
61 parsed_response.reset(serializer.Deserialize(NULL, &error));
62 if (parsed_response.get() == NULL)
63 return;
64
65 DictionaryValue* response_dict = NULL;
66 if (!parsed_response->GetAsDictionary(&response_dict) || !response_dict)
67 return;
68
69 ListValue* items;
70 if (!response_dict->GetList("items", &items))
71 return;
72
73 for (ListValue::const_iterator iter(items->begin());
74 iter != items->end(); ++iter) {
75 DictionaryValue* item = static_cast<DictionaryValue*>(*iter);
76
77 // All fields are mandatory - skip this result if any field isn't found.
78 CWSIntentsRegistry::IntentExtensionInfo info;
79 if (!item->GetString("id", &info.id))
80 continue;
81
82 if (!item->GetInteger("num_ratings", &info.num_ratings))
83 continue;
84
85 if (!item->GetDouble("average_rating", &info.average_rating))
86 continue;
87
88 if (!item->GetString("manifest", &info.manifest))
89 continue;
90
91 std::string manifest_utf8 = UTF16ToUTF8(info.manifest);
92 JSONStringValueSerializer manifest_serializer(manifest_utf8);
93 scoped_ptr<Value> manifest_value;
94 manifest_value.reset(manifest_serializer.Deserialize(NULL, &error));
95 if (manifest_value.get() == NULL)
96 continue;
97
98 DictionaryValue* manifest_dict;
99 if (!manifest_value->GetAsDictionary(&manifest_dict) ||
100 !manifest_dict->GetString("name", &info.name))
101 continue;
102
103 string16 url_string;
104 if (!item->GetString("icon_url", &url_string))
105 continue;
106 info.icon_url = GURL(url_string);
107
108 // Need to parse CWS reply, since it is not pre-l10n'd.
109 ListValue* all_locales = NULL;
110 if (ShouldLocalize(UTF16ToUTF8(info.name)) &&
111 item->GetList("locale_data", &all_locales)) {
112 std::map<std::string, std::string> localized_title;
113
114 for (ListValue::const_iterator locale_iter(all_locales->begin());
115 locale_iter != all_locales->end(); ++locale_iter) {
116 DictionaryValue* locale = static_cast<DictionaryValue*>(*locale_iter);
117
118 std::string locale_id, title;
119 if (!locale->GetString("locale_string", &locale_id) ||
120 !locale->GetString("title", &title))
121 continue;
122
123 localized_title[locale_id] = title;
124 }
125
126 std::vector<std::string> valid_locales;
127 extension_l10n_util::GetAllFallbackLocales(
128 extension_l10n_util::CurrentLocaleOrDefault(),
129 "all",
130 &valid_locales);
131 for (std::vector<std::string>::iterator iter = valid_locales.begin();
132 iter != valid_locales.end(); ++iter) {
133 if (localized_title.count(*iter)) {
134 info.name = UTF8ToUTF16(localized_title[*iter]);
135 break;
136 }
137 }
138 }
139
140 intents->push_back(info);
141 }
142 }
143
144 } // namespace
145
146 // Internal object representing all data associated with a single query.
147 struct CWSIntentsRegistry::IntentsQuery {
148 IntentsQuery();
149 ~IntentsQuery();
150
151 // Underlying URL request query.
152 scoped_ptr<net::URLFetcher> url_fetcher;
153
154 // The callback - invoked on completed retrieval.
155 ResultsCallback callback;
156 };
157
158 CWSIntentsRegistry::IntentsQuery::IntentsQuery() {
159 }
160
161 CWSIntentsRegistry::IntentsQuery::~IntentsQuery() {
162 }
163
164 CWSIntentsRegistry::IntentExtensionInfo::IntentExtensionInfo()
165 : num_ratings(0),
166 average_rating(0) {
167 }
168
169 CWSIntentsRegistry::IntentExtensionInfo::~IntentExtensionInfo() {
170 }
171
172 CWSIntentsRegistry::CWSIntentsRegistry(net::URLRequestContextGetter* context)
173 : request_context_(context) {
174 }
175
176 CWSIntentsRegistry::~CWSIntentsRegistry() {
177 // Cancel all pending queries, since we can't handle them any more.
178 STLDeleteValues(&queries_);
179 }
180
181 void CWSIntentsRegistry::OnURLFetchComplete(const net::URLFetcher* source) {
182 DCHECK(source);
183
184 URLFetcherHandle handle = reinterpret_cast<URLFetcherHandle>(source);
185 QueryMap::iterator it = queries_.find(handle);
186 DCHECK(it != queries_.end());
187 scoped_ptr<IntentsQuery> query(it->second);
188 DCHECK(query.get() != NULL);
189 queries_.erase(it);
190
191 std::string response;
192 source->GetResponseAsString(&response);
193
194 // TODO(groby): Do we really only accept 200, or any 2xx codes?
195 IntentExtensionList intents;
196 if (source->GetResponseCode() == 200)
197 ParseResponse(response, &intents);
198
199 if (!query->callback.is_null())
200 query->callback.Run(intents);
201 }
202
203 void CWSIntentsRegistry::GetIntentServices(const string16& action,
204 const string16& mimetype,
205 const ResultsCallback& cb) {
206 scoped_ptr<IntentsQuery> query(new IntentsQuery);
207 query->callback = cb;
208 query->url_fetcher.reset(net::URLFetcher::Create(
209 0, BuildQueryURL(action,mimetype), net::URLFetcher::GET, this));
210
211 if (query->url_fetcher.get() == NULL)
212 return;
213
214 query->url_fetcher->SetRequestContext(request_context_);
215 query->url_fetcher->SetLoadFlags(
216 net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES);
217
218 URLFetcherHandle handle = reinterpret_cast<URLFetcherHandle>(
219 query->url_fetcher.get());
220 queries_[handle] = query.release();
221 queries_[handle]->url_fetcher->Start();
222 }
223
224 // static
225 GURL CWSIntentsRegistry::BuildQueryURL(const string16& action,
226 const string16& type) {
227 GURL request(kCWSIntentServiceURL);
228 request = net::AppendQueryParameter(request, "intent", UTF16ToUTF8(action));
229 request = net::AppendQueryParameter(request, "mime_types", UTF16ToUTF8(type));
230 request = net::AppendQueryParameter(request, "start_index", "0");
231 request = net::AppendQueryParameter(request, "num_results", kMaxSuggestions);
232 request = net::AppendQueryParameter(request, "key", google_apis::GetAPIKey());
233
234 return request;
235 }
OLDNEW
« no previous file with comments | « chrome/browser/intents/cws_intents_registry.h ('k') | chrome/browser/intents/cws_intents_registry_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698