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

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

Issue 10827056: Use IntentsQuery as the WDS consumer. By unencumbering WebIntentsRegistry of this responsibility we… (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Respond to review comments. Created 8 years, 5 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
« no previous file with comments | « chrome/browser/intents/web_intents_registry.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/intents/web_intents_registry.h" 5 #include "chrome/browser/intents/web_intents_registry.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 const string16& action, 77 const string16& action,
78 IntentServiceList* matching_services) { 78 IntentServiceList* matching_services) {
79 const IntentServiceList& services = extension.intents_services(); 79 const IntentServiceList& services = extension.intents_services();
80 for (IntentServiceList::const_iterator i = services.begin(); 80 for (IntentServiceList::const_iterator i = services.begin();
81 i != services.end(); ++i) { 81 i != services.end(); ++i) {
82 if (action.empty() || action == i->action) 82 if (action.empty() || action == i->action)
83 matching_services->push_back(*i); 83 matching_services->push_back(*i);
84 } 84 }
85 } 85 }
86 86
87 // Removes all services from |matching_services| that do not match |mimetype|. 87 // Removes all services from |matching_services| that do not match |type|.
88 // Wildcards are supported, of the form '<type>/*' or '*'. 88 // Wildcards are supported, of the form '<type>/*' or '*'.
89 void FilterServicesByMimetype(const string16& mimetype, 89 void FilterServicesByType(const string16& type,
90 IntentServiceList* matching_services) { 90 IntentServiceList* matching_services) {
91 // Filter out all services not matching the query type. 91 // Filter out all services not matching the query type.
92 IntentServiceList::iterator iter(matching_services->begin()); 92 IntentServiceList::iterator iter(matching_services->begin());
93 while (iter != matching_services->end()) { 93 while (iter != matching_services->end()) {
94 if (WebIntentsTypesMatch(iter->type, mimetype)) 94 if (WebIntentsTypesMatch(iter->type, type))
95 ++iter; 95 ++iter;
96 else 96 else
97 iter = matching_services->erase(iter); 97 iter = matching_services->erase(iter);
98 } 98 }
99 } 99 }
100 100
101 // Callback for existence checks. Converts a callback for a list of services 101 // Callback for existence checks. Converts a callback for a list of services
102 // into a callback that returns true if the list contains a specific service. 102 // into a callback that returns true if the list contains a specific service.
103 void ExistenceCallback(const webkit_glue::WebIntentServiceData& service, 103 void ExistenceCallback(const webkit_glue::WebIntentServiceData& service,
104 const base::Callback<void(bool)>& callback, 104 const base::Callback<void(bool)>& callback,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 (lhs.action != rhs.action) || 144 (lhs.action != rhs.action) ||
145 (lhs.title != rhs.title) || 145 (lhs.title != rhs.title) ||
146 (lhs.disposition != rhs.disposition)); 146 (lhs.disposition != rhs.disposition));
147 } 147 }
148 148
149 } // namespace 149 } // namespace
150 150
151 using webkit_glue::WebIntentServiceData; 151 using webkit_glue::WebIntentServiceData;
152 152
153 // Internal object representing all data associated with a single query. 153 // Internal object representing all data associated with a single query.
154 struct WebIntentsRegistry::IntentsQuery { 154 struct WebIntentsRegistry::IntentsQuery : public WebDataServiceConsumer {
155
156 // Handle so we can call back into the WebIntentsRegistry when
157 // processing query results. The registry is guaranteed to be
158 // valid for the life of this object. We do not own this object.
159 WebIntentsRegistry* registry_;
160
155 // Underlying data query. 161 // Underlying data query.
156 WebDataService::Handle pending_query_; 162 WebDataService::Handle query_handle_;
157 163
158 // The callback for this particular query. 164 // The callback for this particular query.
159 QueryCallback callback_; 165 QueryCallback callback_;
160 166
161 // Callback for a query for defaults. 167 // Callback for a query for defaults.
162 DefaultQueryCallback default_callback_; 168 DefaultQueryCallback default_callback_;
163 169
164 // The particular action to filter for while searching through extensions. 170 // The particular action to filter for while searching through extensions.
165 // If |action_| is empty, return all extension-provided services. 171 // If |action_| is empty, return all extension-provided services.
166 string16 action_; 172 string16 action_;
167 173
168 // The MIME type that was requested for this service query. 174 // The MIME type that was requested for this service query.
169 // Suppports wild cards. 175 // Suppports wild cards.
170 string16 type_; 176 string16 type_;
171 177
172 // The url of the invoking page. 178 // The url of the invoking page.
173 GURL url_; 179 GURL url_;
174 180
175 // Create a new IntentsQuery for services with the specified action/type. 181 // Create a new IntentsQuery for services with the specified action/type.
176 IntentsQuery(const QueryCallback& callback, 182 IntentsQuery(WebIntentsRegistry* registry,
183 const QueryCallback& callback,
177 const string16& action, const string16& type) 184 const string16& action, const string16& type)
178 : callback_(callback), action_(action), type_(type) {} 185 : registry_(registry), callback_(callback), action_(action),
186 type_(type) {}
179 187
180 // Create a new IntentsQuery for all intent services or for existence checks. 188 // Create a new IntentsQuery for all intent services or for existence checks.
181 explicit IntentsQuery(const QueryCallback callback) 189 IntentsQuery(WebIntentsRegistry* registry,
182 : callback_(callback), type_(ASCIIToUTF16("*")) {} 190 const QueryCallback callback)
191 : registry_(registry), callback_(callback), type_(ASCIIToUTF16("*")) {}
183 192
184 // Create a new IntentsQuery for default services. 193 // Create a new IntentsQuery for default services.
185 IntentsQuery(const DefaultQueryCallback& callback, 194 IntentsQuery(WebIntentsRegistry* registry,
195 const DefaultQueryCallback& callback,
186 const string16& action, const string16& type, const GURL& url) 196 const string16& action, const string16& type, const GURL& url)
187 : default_callback_(callback), action_(action), type_(type), url_(url) {} 197 : registry_(registry), default_callback_(callback), action_(action),
198 type_(type), url_(url) {}
199
200 void OnWebDataServiceRequestDone(
201 WebDataService::Handle h,
202 const WDTypedResult* result) OVERRIDE {
203
204 // dispatch the request
205 if (result->GetType() == WEB_INTENTS_RESULT) {
206 registry_->OnWebIntentsResultReceived(this, result);
207 } else if (result->GetType() == WEB_INTENTS_DEFAULTS_RESULT) {
208 registry_->OnWebIntentsDefaultsResultReceived(this, result);
209 } else {
210 NOTREACHED();
211 }
212 }
188 }; 213 };
189 214
190 WebIntentsRegistry::WebIntentsRegistry() {} 215 WebIntentsRegistry::WebIntentsRegistry() {}
191 216
192 WebIntentsRegistry::~WebIntentsRegistry() { 217 WebIntentsRegistry::~WebIntentsRegistry() {
218
193 // Cancel all pending queries, since we can't handle them any more. 219 // Cancel all pending queries, since we can't handle them any more.
194 for (QueryMap::iterator it(queries_.begin()); it != queries_.end(); ++it) { 220 for (QueryVector::iterator it = pending_queries_.begin();
195 wds_->CancelRequest(it->first); 221 it != pending_queries_.end(); ++it) {
196 delete it->second; 222 IntentsQuery* query = *it;
223 wds_->CancelRequest(query->query_handle_);
224 delete query;
197 } 225 }
198 } 226 }
199 227
200 void WebIntentsRegistry::Initialize( 228 void WebIntentsRegistry::Initialize(
201 scoped_refptr<WebDataService> wds, 229 scoped_refptr<WebDataService> wds,
202 ExtensionServiceInterface* extension_service) { 230 ExtensionServiceInterface* extension_service) {
203 wds_ = wds; 231 wds_ = wds;
204 extension_service_ = extension_service; 232 extension_service_ = extension_service;
205 } 233 }
206 234
207 void WebIntentsRegistry::OnWebDataServiceRequestDone( 235 void WebIntentsRegistry::OnWebIntentsResultReceived(
208 WebDataService::Handle h, 236 IntentsQuery* query,
209 const WDTypedResult* result) { 237 const WDTypedResult* result) {
238 DCHECK(query);
210 DCHECK(result); 239 DCHECK(result);
211 if (result->GetType() == WEB_INTENTS_DEFAULTS_RESULT) {
212 OnWebDataServiceDefaultsRequestDone(h, result);
213 return;
214 }
215 DCHECK(result->GetType() == WEB_INTENTS_RESULT); 240 DCHECK(result->GetType() == WEB_INTENTS_RESULT);
216 241
217 QueryMap::iterator it = queries_.find(h); 242 ReleaseQuery(query);
218 DCHECK(it != queries_.end());
219
220 IntentsQuery* query(it->second);
221 DCHECK(query);
222 queries_.erase(it);
223 243
224 IntentServiceList matching_services = static_cast< 244 IntentServiceList matching_services = static_cast<
225 const WDResult<IntentServiceList>*>(result)->GetValue(); 245 const WDResult<IntentServiceList>*>(result)->GetValue();
226 246
227 // Loop over all services in all extensions, collect ones 247 // Loop over all services in all extensions, collect ones
228 // matching the query. 248 // matching the query.
229 if (extension_service_) { 249 if (extension_service_) {
230 const ExtensionSet* extensions = extension_service_->extensions(); 250 const ExtensionSet* extensions = extension_service_->extensions();
231 if (extensions) { 251 if (extensions) {
232 for (ExtensionSet::const_iterator i(extensions->begin()); 252 for (ExtensionSet::const_iterator i(extensions->begin());
233 i != extensions->end(); ++i) { 253 i != extensions->end(); ++i) {
234 AddMatchingServicesForExtension(**i, query->action_, 254 AddMatchingServicesForExtension(**i, query->action_,
235 &matching_services); 255 &matching_services);
236 } 256 }
237 } 257 }
238 } 258 }
239 259
240 // Filter out all services not matching the query type. 260 // Filter out all services not matching the query type.
241 FilterServicesByMimetype(query->type_, &matching_services); 261 FilterServicesByType(query->type_, &matching_services);
242 262
243 // Collapse intents that are equivalent for all but |type|. 263 // Collapse intents that are equivalent for all but |type|.
244 CollapseIntents(&matching_services); 264 CollapseIntents(&matching_services);
245 265
246 query->callback_.Run(matching_services); 266 query->callback_.Run(matching_services);
247 delete query; 267 delete query;
248 } 268 }
249 269
250 const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) { 270 void WebIntentsRegistry::OnWebIntentsDefaultsResultReceived(
251 const ExtensionSet* extensions = extension_service_->extensions(); 271 IntentsQuery* query,
252 if (!extensions) 272 const WDTypedResult* result) {
253 return NULL; 273 DCHECK(query);
274 DCHECK(result);
275 DCHECK(result->GetType() == WEB_INTENTS_DEFAULTS_RESULT);
254 276
255 // Use the unsafe ExtensionURLInfo constructor: we don't care if the extension 277 ReleaseQuery(query);
256 // is running or not.
257 GURL gurl(url);
258 ExtensionURLInfo info(gurl);
259 return extensions->GetExtensionOrAppByURL(info);
260 }
261
262 void WebIntentsRegistry::OnWebDataServiceDefaultsRequestDone(
263 WebDataService::Handle h,
264 const WDTypedResult* result) {
265 QueryMap::iterator it = queries_.find(h);
266 DCHECK(it != queries_.end());
267
268 IntentsQuery* query(it->second);
269 DCHECK(query);
270 queries_.erase(it);
271 278
272 std::vector<DefaultWebIntentService> services = static_cast< 279 std::vector<DefaultWebIntentService> services = static_cast<
273 const WDResult<std::vector<DefaultWebIntentService> >*>(result)-> 280 const WDResult<std::vector<DefaultWebIntentService> >*>(result)->
274 GetValue(); 281 GetValue();
275 282
276 DefaultWebIntentService default_service; 283 DefaultWebIntentService default_service;
277 std::vector<DefaultWebIntentService>::iterator iter(services.begin()); 284 std::vector<DefaultWebIntentService>::iterator iter(services.begin());
278 for (; iter != services.end(); ++iter) { 285 for (; iter != services.end(); ++iter) {
279 if (!WebIntentsTypesMatch(iter->type, query->type_)) { 286 if (!WebIntentsTypesMatch(iter->type, query->type_)) {
280 continue; 287 continue;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 break; 325 break;
319 } 326 }
320 } 327 }
321 } 328 }
322 329
323 query->default_callback_.Run(default_service); 330 query->default_callback_.Run(default_service);
324 delete query; 331 delete query;
325 } 332 }
326 333
327 void WebIntentsRegistry::GetIntentServices( 334 void WebIntentsRegistry::GetIntentServices(
328 const string16& action, const string16& mimetype, 335 const string16& action, const string16& type,
329 const QueryCallback& callback) { 336 const QueryCallback& callback) {
330 DCHECK(wds_.get()); 337 DCHECK(wds_.get());
331 DCHECK(!callback.is_null()); 338 DCHECK(!callback.is_null());
332 339
333 IntentsQuery* query = new IntentsQuery(callback, action, mimetype); 340 IntentsQuery* query = new IntentsQuery(this, callback, action, type);
334 query->pending_query_ = wds_->GetWebIntentServices(action, this); 341 query->query_handle_ = wds_->GetWebIntentServices(action, query);
335 queries_[query->pending_query_] = query; 342 TrackQuery(query);
336 } 343 }
337 344
338 void WebIntentsRegistry::GetAllIntentServices( 345 void WebIntentsRegistry::GetAllIntentServices(
339 const QueryCallback& callback) { 346 const QueryCallback& callback) {
340 DCHECK(wds_.get()); 347 DCHECK(wds_.get());
341 DCHECK(!callback.is_null()); 348 DCHECK(!callback.is_null());
342 349
343 IntentsQuery* query = new IntentsQuery(callback); 350 IntentsQuery* query = new IntentsQuery(this, callback);
344 query->pending_query_ = wds_->GetAllWebIntentServices(this); 351 query->query_handle_ = wds_->GetAllWebIntentServices(query);
345 queries_[query->pending_query_] = query; 352 TrackQuery(query);
346 } 353 }
347 354
348 void WebIntentsRegistry::IntentServiceExists( 355 void WebIntentsRegistry::IntentServiceExists(
349 const WebIntentServiceData& service, 356 const WebIntentServiceData& service,
350 const base::Callback<void(bool)>& callback) { 357 const base::Callback<void(bool)>& callback) {
351 DCHECK(!callback.is_null()); 358 DCHECK(!callback.is_null());
352 359
353 IntentsQuery* query = new IntentsQuery( 360 IntentsQuery* query = new IntentsQuery(
354 base::Bind(&ExistenceCallback, service, callback)); 361 this, base::Bind(&ExistenceCallback, service, callback));
355 query->pending_query_ = wds_->GetWebIntentServicesForURL( 362 query->query_handle_ = wds_->GetWebIntentServicesForURL(
356 UTF8ToUTF16(service.service_url.spec()), this); 363 UTF8ToUTF16(service.service_url.spec()), query);
357 queries_[query->pending_query_] = query; 364 TrackQuery(query);
358 } 365 }
359 366
360 void WebIntentsRegistry::GetIntentServicesForExtensionFilter( 367 void WebIntentsRegistry::GetIntentServicesForExtensionFilter(
361 const string16& action, 368 const string16& action,
362 const string16& mimetype, 369 const string16& type,
363 const std::string& extension_id, 370 const std::string& extension_id,
364 const QueryCallback& callback) { 371 const QueryCallback& callback) {
365 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); 372 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
366 DCHECK(!callback.is_null()); 373 DCHECK(!callback.is_null());
367 374
375 // This isn't a WDS query, so we don't track it,
376 // or claim the query later.
368 scoped_ptr<IntentsQuery> query( 377 scoped_ptr<IntentsQuery> query(
369 new IntentsQuery(callback, action, mimetype)); 378 new IntentsQuery(this, callback, action, type));
370 content::BrowserThread::PostTask( 379 content::BrowserThread::PostTask(
371 content::BrowserThread::UI, 380 content::BrowserThread::UI,
372 FROM_HERE, 381 FROM_HERE,
373 base::Bind(&WebIntentsRegistry::DoGetIntentServicesForExtensionFilter, 382 base::Bind(&WebIntentsRegistry::DoGetIntentServicesForExtensionFilter,
374 base::Unretained(this), 383 base::Unretained(this),
375 base::Passed(&query), extension_id)); 384 base::Passed(&query), extension_id));
376 } 385 }
377 386
378 void WebIntentsRegistry::DoGetIntentServicesForExtensionFilter( 387 void WebIntentsRegistry::DoGetIntentServicesForExtensionFilter(
379 scoped_ptr<IntentsQuery> query, 388 scoped_ptr<IntentsQuery> query,
380 const std::string& extension_id) { 389 const std::string& extension_id) {
381 IntentServiceList matching_services; 390 IntentServiceList matching_services;
382 391
383 if (extension_service_) { 392 if (extension_service_) {
384 const Extension* extension = 393 const Extension* extension =
385 extension_service_->GetExtensionById(extension_id, false); 394 extension_service_->GetExtensionById(extension_id, false);
386 AddMatchingServicesForExtension(*extension, 395 AddMatchingServicesForExtension(*extension,
387 query->action_, 396 query->action_,
388 &matching_services); 397 &matching_services);
389 FilterServicesByMimetype(query->type_, &matching_services); 398 FilterServicesByType(query->type_, &matching_services);
390 } 399 }
391 400
392 query->callback_.Run(matching_services); 401 query->callback_.Run(matching_services);
393 } 402 }
394 403
395 void WebIntentsRegistry::RegisterDefaultIntentService( 404 void WebIntentsRegistry::RegisterDefaultIntentService(
396 const DefaultWebIntentService& default_service) { 405 const DefaultWebIntentService& default_service) {
397 DCHECK(wds_.get()); 406 DCHECK(wds_.get());
398 wds_->AddDefaultWebIntentService(default_service); 407 wds_->AddDefaultWebIntentService(default_service);
399 } 408 }
400 409
401 void WebIntentsRegistry::UnregisterDefaultIntentService( 410 void WebIntentsRegistry::UnregisterDefaultIntentService(
402 const DefaultWebIntentService& default_service) { 411 const DefaultWebIntentService& default_service) {
403 DCHECK(wds_.get()); 412 DCHECK(wds_.get());
404 wds_->RemoveDefaultWebIntentService(default_service); 413 wds_->RemoveDefaultWebIntentService(default_service);
405 } 414 }
406 415
407 void WebIntentsRegistry::GetDefaultIntentService( 416 void WebIntentsRegistry::GetDefaultIntentService(
408 const string16& action, 417 const string16& action,
409 const string16& type, 418 const string16& type,
410 const GURL& invoking_url, 419 const GURL& invoking_url,
411 const DefaultQueryCallback& callback) { 420 const DefaultQueryCallback& callback) {
412 DCHECK(!callback.is_null()); 421 DCHECK(!callback.is_null());
413 422
414 IntentsQuery* query = 423 IntentsQuery* query =
415 new IntentsQuery(callback, action, type, invoking_url); 424 new IntentsQuery(this, callback, action, type, invoking_url);
416 query->pending_query_ = 425 query->query_handle_ =
417 wds_->GetDefaultWebIntentServicesForAction(action, this); 426 wds_->GetDefaultWebIntentServicesForAction(action, query);
418 queries_[query->pending_query_] = query; 427 TrackQuery(query);
419 } 428 }
420 429
421 void WebIntentsRegistry::RegisterIntentService( 430 void WebIntentsRegistry::RegisterIntentService(
422 const WebIntentServiceData& service) { 431 const WebIntentServiceData& service) {
423 DCHECK(wds_.get()); 432 DCHECK(wds_.get());
424 wds_->AddWebIntentService(service); 433 wds_->AddWebIntentService(service);
425 } 434 }
426 435
427 void WebIntentsRegistry::UnregisterIntentService( 436 void WebIntentsRegistry::UnregisterIntentService(
428 const WebIntentServiceData& service) { 437 const WebIntentServiceData& service) {
(...skipping 24 matching lines...) Expand all
453 if (write_iter != read_iter) 462 if (write_iter != read_iter)
454 *write_iter = *read_iter; 463 *write_iter = *read_iter;
455 } 464 }
456 ++read_iter; 465 ++read_iter;
457 } 466 }
458 467
459 // Cut off everything after the last intent copied to the list. 468 // Cut off everything after the last intent copied to the list.
460 if (++write_iter != services->end()) 469 if (++write_iter != services->end())
461 services->erase(write_iter, services->end()); 470 services->erase(write_iter, services->end());
462 } 471 }
472
473 const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) {
474 const ExtensionSet* extensions = extension_service_->extensions();
475 if (!extensions)
476 return NULL;
477
478 // Use the unsafe ExtensionURLInfo constructor: we don't care if the extension
479 // is running or not.
480 GURL gurl(url);
481 ExtensionURLInfo info(gurl);
482 return extensions->GetExtensionOrAppByURL(info);
483 }
484
485 void WebIntentsRegistry::TrackQuery(IntentsQuery* query) {
486 DCHECK(query);
487 pending_queries_.push_back(query);
488 }
489
490 void WebIntentsRegistry::ReleaseQuery(IntentsQuery* query) {
491 QueryVector::iterator it = std::find(
492 pending_queries_.begin(), pending_queries_.end(), query);
493 if (it != pending_queries_.end())
494 pending_queries_.erase(it);
495 else
496 NOTREACHED();
497 }
OLDNEW
« no previous file with comments | « chrome/browser/intents/web_intents_registry.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698