| Index: chrome/browser/intents/web_intents_registry.cc
|
| diff --git a/chrome/browser/intents/web_intents_registry.cc b/chrome/browser/intents/web_intents_registry.cc
|
| index 2df590b2881c22ff6d5f4ccc7e8a741e3d34d8a1..87a09858f51c55f43757c8b6408a51d0fa9eff64 100644
|
| --- a/chrome/browser/intents/web_intents_registry.cc
|
| +++ b/chrome/browser/intents/web_intents_registry.cc
|
| @@ -6,7 +6,10 @@
|
|
|
| #include "base/callback.h"
|
| #include "base/utf_string_conversions.h"
|
| +#include "chrome/browser/intents/default_web_intent_service.h"
|
| #include "chrome/browser/webdata/web_data_service.h"
|
| +#include "chrome/common/extensions/extension_set.h"
|
| +#include "googleurl/src/gurl.h"
|
| #include "net/base/mime_util.h"
|
|
|
| namespace {
|
| @@ -44,6 +47,24 @@ struct WebIntentsRegistry::IntentsQuery {
|
| // The MIME type that was requested for this service query.
|
| // Suppports wild cards.
|
| string16 type_;
|
| +
|
| + // The url of the invoking page.
|
| + GURL url_;
|
| +
|
| + // Create a new IntentsQuery for services with the specified action/type.
|
| + IntentsQuery(QueryID id, Consumer* consumer,
|
| + const string16& action, const string16& type)
|
| + : query_id_(id), consumer_(consumer), action_(action), type_(type) {}
|
| +
|
| + // Create a new IntentsQuery for all intent services or for existence checks.
|
| + IntentsQuery(QueryID id, Consumer* consumer)
|
| + : query_id_(id), consumer_(consumer), type_(ASCIIToUTF16("*")) {}
|
| +
|
| + // Create a new IntentsQuery for default services.
|
| + IntentsQuery(QueryID id, Consumer* consumer,
|
| + const string16& action, const string16& type, const GURL& url)
|
| + : query_id_(id), consumer_(consumer),
|
| + action_(action), type_(type), url_(url) {}
|
| };
|
|
|
| WebIntentsRegistry::WebIntentsRegistry() : next_query_id_(0) {}
|
| @@ -67,6 +88,10 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone(
|
| WebDataService::Handle h,
|
| const WDTypedResult* result) {
|
| DCHECK(result);
|
| + if (result->GetType() == WEB_INTENTS_DEFAULTS_RESULT) {
|
| + OnWebDataServiceDefaultsRequestDone(h, result);
|
| + return;
|
| + }
|
| DCHECK(result->GetType() == WEB_INTENTS_RESULT);
|
|
|
| QueryMap::iterator it = queries_.find(h);
|
| @@ -109,16 +134,74 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone(
|
| delete query;
|
| }
|
|
|
| +const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) {
|
| + const ExtensionSet* extensions = extension_service_->extensions();
|
| + if (!extensions)
|
| + return NULL;
|
| +
|
| + // Use the unsafe ExtensionURLInfo constructor: we don't care if the extension
|
| + // is running or not.
|
| + GURL gurl(url);
|
| + ExtensionURLInfo info(gurl);
|
| + return extensions->GetExtensionOrAppByURL(info);
|
| +}
|
| +
|
| +void WebIntentsRegistry::OnWebDataServiceDefaultsRequestDone(
|
| + WebDataService::Handle h,
|
| + const WDTypedResult* result) {
|
| + QueryMap::iterator it = queries_.find(h);
|
| + DCHECK(it != queries_.end());
|
| +
|
| + IntentsQuery* query(it->second);
|
| + DCHECK(query);
|
| + queries_.erase(it);
|
| +
|
| + std::vector<DefaultWebIntentService> services = static_cast<
|
| + const WDResult<std::vector<DefaultWebIntentService> >*>(result)->
|
| + GetValue();
|
| +
|
| + DefaultWebIntentService default_service;
|
| + std::vector<DefaultWebIntentService>::iterator iter(services.begin());
|
| + for (; iter != services.end(); ++iter) {
|
| + if (!MimeTypesAreEqual(iter->type, query->type_)) {
|
| + continue;
|
| + }
|
| + if (!iter->url_pattern.MatchesURL(query->url_)) {
|
| + continue;
|
| + }
|
| + const Extension* extension = ExtensionForURL(iter->service_url);
|
| + if (extension != NULL &&
|
| + !extension_service_->IsExtensionEnabled(extension->id())) {
|
| + continue;
|
| + }
|
| +
|
| + // Found a match. If it is better than default_service, use it.
|
| + // Currently the metric is that if the new value is user-set,
|
| + // prefer it. If the present value is suppressed, prefer it.
|
| + // If the new value has a more specific pattern, prefer it.
|
| + if (default_service.user_date <= 0 && iter->user_date >= 0)
|
| + default_service = *iter;
|
| + else if (default_service.suppression > 0 && iter->suppression <= 0)
|
| + default_service = *iter;
|
| + else if (default_service.url_pattern.match_all_urls() &&
|
| + !iter->url_pattern.match_all_urls())
|
| + default_service = *iter;
|
| + else if (iter->url_pattern < default_service.url_pattern)
|
| + default_service = *iter;
|
| + }
|
| +
|
| + query->consumer_->OnIntentsDefaultsQueryDone(query->query_id_,
|
| + default_service);
|
| + delete query;
|
| +}
|
| +
|
| WebIntentsRegistry::QueryID WebIntentsRegistry::GetIntentServices(
|
| const string16& action, const string16& mimetype, Consumer* consumer) {
|
| DCHECK(consumer);
|
| DCHECK(wds_.get());
|
|
|
| - IntentsQuery* query = new IntentsQuery;
|
| - query->query_id_ = next_query_id_++;
|
| - query->consumer_ = consumer;
|
| - query->action_ = action;
|
| - query->type_ = mimetype;
|
| + IntentsQuery* query =
|
| + new IntentsQuery(next_query_id_++, consumer, action, mimetype);
|
| query->pending_query_ = wds_->GetWebIntentServices(action, this);
|
| queries_[query->pending_query_] = query;
|
|
|
| @@ -130,10 +213,7 @@ WebIntentsRegistry::QueryID WebIntentsRegistry::GetAllIntentServices(
|
| DCHECK(consumer);
|
| DCHECK(wds_.get());
|
|
|
| - IntentsQuery* query = new IntentsQuery;
|
| - query->query_id_ = next_query_id_++;
|
| - query->consumer_ = consumer;
|
| - query->type_ = ASCIIToUTF16("*");
|
| + IntentsQuery* query = new IntentsQuery(next_query_id_++, consumer);
|
| query->pending_query_ = wds_->GetAllWebIntentServices(this);
|
| queries_[query->pending_query_] = query;
|
|
|
| @@ -168,6 +248,10 @@ class ServiceCheckConsumer : public WebIntentsRegistry::Consumer {
|
| callback_.Run(false);
|
| }
|
|
|
| + virtual void OnIntentsDefaultsQueryDone(
|
| + WebIntentsRegistry::QueryID query_id,
|
| + const DefaultWebIntentService& default_service) {}
|
| +
|
| private:
|
| base::Callback<void(bool)> callback_;
|
| WebIntentServiceData service_;
|
| @@ -176,10 +260,8 @@ class ServiceCheckConsumer : public WebIntentsRegistry::Consumer {
|
| WebIntentsRegistry::QueryID WebIntentsRegistry::IntentServiceExists(
|
| const WebIntentServiceData& service,
|
| const base::Callback<void(bool)>& callback) {
|
| - IntentsQuery* query = new IntentsQuery;
|
| - query->query_id_ = next_query_id_++;
|
| - query->type_ = ASCIIToUTF16("*");
|
| - query->consumer_ = new ServiceCheckConsumer(service, callback);
|
| + IntentsQuery* query = new IntentsQuery(
|
| + next_query_id_++, new ServiceCheckConsumer(service, callback));
|
| query->pending_query_ = wds_->GetWebIntentServicesForURL(
|
| UTF8ToUTF16(service.service_url.spec()), this);
|
| queries_[query->pending_query_] = query;
|
| @@ -187,6 +269,32 @@ WebIntentsRegistry::QueryID WebIntentsRegistry::IntentServiceExists(
|
| return query->query_id_;
|
| }
|
|
|
| +void WebIntentsRegistry::RegisterDefaultIntentService(
|
| + const DefaultWebIntentService& default_service) {
|
| + DCHECK(wds_.get());
|
| + wds_->AddDefaultWebIntentService(default_service);
|
| +}
|
| +
|
| +void WebIntentsRegistry::UnregisterDefaultIntentService(
|
| + const DefaultWebIntentService& default_service) {
|
| + DCHECK(wds_.get());
|
| + wds_->RemoveDefaultWebIntentService(default_service);
|
| +}
|
| +
|
| +WebIntentsRegistry::QueryID WebIntentsRegistry::GetDefaultIntentService(
|
| + const string16& action,
|
| + const string16& type,
|
| + const GURL& invoking_url,
|
| + Consumer* consumer) {
|
| + IntentsQuery* query =
|
| + new IntentsQuery(next_query_id_++, consumer, action, type, invoking_url);
|
| + query->pending_query_ =
|
| + wds_->GetDefaultWebIntentServicesForAction(action, this);
|
| + queries_[query->pending_query_] = query;
|
| +
|
| + return query->query_id_;
|
| +}
|
| +
|
| void WebIntentsRegistry::RegisterIntentService(
|
| const WebIntentServiceData& service) {
|
| DCHECK(wds_.get());
|
|
|