Commit 43e58451 authored by smckay@chromium.org's avatar smckay@chromium.org

Use IntentsQuery as the WDS consumer. By unencumbering WebIntentsRegistry of...

Use IntentsQuery as the WDS consumer. By unencumbering WebIntentsRegistry of this responsibility we'll be able to more easily accommodate new request types.

BUG=137907
TEST=WebIntentsRegistryTest.*


Review URL: https://chromiumcodereview.appspot.com/10827056

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148714 0039d316-1c4b-4281-b951-d872f2087c98
parent b332977a
...@@ -84,14 +84,14 @@ void AddMatchingServicesForExtension(const Extension& extension, ...@@ -84,14 +84,14 @@ void AddMatchingServicesForExtension(const Extension& extension,
} }
} }
// Removes all services from |matching_services| that do not match |mimetype|. // Removes all services from |matching_services| that do not match |type|.
// Wildcards are supported, of the form '<type>/*' or '*'. // Wildcards are supported, of the form '<type>/*' or '*'.
void FilterServicesByMimetype(const string16& mimetype, void FilterServicesByType(const string16& type,
IntentServiceList* matching_services) { IntentServiceList* matching_services) {
// Filter out all services not matching the query type. // Filter out all services not matching the query type.
IntentServiceList::iterator iter(matching_services->begin()); IntentServiceList::iterator iter(matching_services->begin());
while (iter != matching_services->end()) { while (iter != matching_services->end()) {
if (WebIntentsTypesMatch(iter->type, mimetype)) if (WebIntentsTypesMatch(iter->type, type))
++iter; ++iter;
else else
iter = matching_services->erase(iter); iter = matching_services->erase(iter);
...@@ -151,9 +151,15 @@ bool IntentsAreEquivalent(const webkit_glue::WebIntentServiceData& lhs, ...@@ -151,9 +151,15 @@ bool IntentsAreEquivalent(const webkit_glue::WebIntentServiceData& lhs,
using webkit_glue::WebIntentServiceData; using webkit_glue::WebIntentServiceData;
// Internal object representing all data associated with a single query. // Internal object representing all data associated with a single query.
struct WebIntentsRegistry::IntentsQuery { struct WebIntentsRegistry::IntentsQuery : public WebDataServiceConsumer {
// Handle so we can call back into the WebIntentsRegistry when
// processing query results. The registry is guaranteed to be
// valid for the life of this object. We do not own this object.
WebIntentsRegistry* registry_;
// Underlying data query. // Underlying data query.
WebDataService::Handle pending_query_; WebDataService::Handle query_handle_;
// The callback for this particular query. // The callback for this particular query.
QueryCallback callback_; QueryCallback callback_;
...@@ -173,27 +179,49 @@ struct WebIntentsRegistry::IntentsQuery { ...@@ -173,27 +179,49 @@ struct WebIntentsRegistry::IntentsQuery {
GURL url_; GURL url_;
// Create a new IntentsQuery for services with the specified action/type. // Create a new IntentsQuery for services with the specified action/type.
IntentsQuery(const QueryCallback& callback, IntentsQuery(WebIntentsRegistry* registry,
const QueryCallback& callback,
const string16& action, const string16& type) const string16& action, const string16& type)
: callback_(callback), action_(action), type_(type) {} : registry_(registry), callback_(callback), action_(action),
type_(type) {}
// Create a new IntentsQuery for all intent services or for existence checks. // Create a new IntentsQuery for all intent services or for existence checks.
explicit IntentsQuery(const QueryCallback callback) IntentsQuery(WebIntentsRegistry* registry,
: callback_(callback), type_(ASCIIToUTF16("*")) {} const QueryCallback callback)
: registry_(registry), callback_(callback), type_(ASCIIToUTF16("*")) {}
// Create a new IntentsQuery for default services. // Create a new IntentsQuery for default services.
IntentsQuery(const DefaultQueryCallback& callback, IntentsQuery(WebIntentsRegistry* registry,
const DefaultQueryCallback& callback,
const string16& action, const string16& type, const GURL& url) const string16& action, const string16& type, const GURL& url)
: default_callback_(callback), action_(action), type_(type), url_(url) {} : registry_(registry), default_callback_(callback), action_(action),
type_(type), url_(url) {}
void OnWebDataServiceRequestDone(
WebDataService::Handle h,
const WDTypedResult* result) OVERRIDE {
// dispatch the request
if (result->GetType() == WEB_INTENTS_RESULT) {
registry_->OnWebIntentsResultReceived(this, result);
} else if (result->GetType() == WEB_INTENTS_DEFAULTS_RESULT) {
registry_->OnWebIntentsDefaultsResultReceived(this, result);
} else {
NOTREACHED();
}
}
}; };
WebIntentsRegistry::WebIntentsRegistry() {} WebIntentsRegistry::WebIntentsRegistry() {}
WebIntentsRegistry::~WebIntentsRegistry() { WebIntentsRegistry::~WebIntentsRegistry() {
// Cancel all pending queries, since we can't handle them any more. // Cancel all pending queries, since we can't handle them any more.
for (QueryMap::iterator it(queries_.begin()); it != queries_.end(); ++it) { for (QueryVector::iterator it = pending_queries_.begin();
wds_->CancelRequest(it->first); it != pending_queries_.end(); ++it) {
delete it->second; IntentsQuery* query = *it;
wds_->CancelRequest(query->query_handle_);
delete query;
} }
} }
...@@ -204,22 +232,14 @@ void WebIntentsRegistry::Initialize( ...@@ -204,22 +232,14 @@ void WebIntentsRegistry::Initialize(
extension_service_ = extension_service; extension_service_ = extension_service;
} }
void WebIntentsRegistry::OnWebDataServiceRequestDone( void WebIntentsRegistry::OnWebIntentsResultReceived(
WebDataService::Handle h, IntentsQuery* query,
const WDTypedResult* result) { const WDTypedResult* result) {
DCHECK(query);
DCHECK(result); DCHECK(result);
if (result->GetType() == WEB_INTENTS_DEFAULTS_RESULT) {
OnWebDataServiceDefaultsRequestDone(h, result);
return;
}
DCHECK(result->GetType() == WEB_INTENTS_RESULT); DCHECK(result->GetType() == WEB_INTENTS_RESULT);
QueryMap::iterator it = queries_.find(h); ReleaseQuery(query);
DCHECK(it != queries_.end());
IntentsQuery* query(it->second);
DCHECK(query);
queries_.erase(it);
IntentServiceList matching_services = static_cast< IntentServiceList matching_services = static_cast<
const WDResult<IntentServiceList>*>(result)->GetValue(); const WDResult<IntentServiceList>*>(result)->GetValue();
...@@ -238,7 +258,7 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone( ...@@ -238,7 +258,7 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone(
} }
// Filter out all services not matching the query type. // Filter out all services not matching the query type.
FilterServicesByMimetype(query->type_, &matching_services); FilterServicesByType(query->type_, &matching_services);
// Collapse intents that are equivalent for all but |type|. // Collapse intents that are equivalent for all but |type|.
CollapseIntents(&matching_services); CollapseIntents(&matching_services);
...@@ -247,27 +267,14 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone( ...@@ -247,27 +267,14 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone(
delete query; delete query;
} }
const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) { void WebIntentsRegistry::OnWebIntentsDefaultsResultReceived(
const ExtensionSet* extensions = extension_service_->extensions(); IntentsQuery* query,
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) { const WDTypedResult* result) {
QueryMap::iterator it = queries_.find(h);
DCHECK(it != queries_.end());
IntentsQuery* query(it->second);
DCHECK(query); DCHECK(query);
queries_.erase(it); DCHECK(result);
DCHECK(result->GetType() == WEB_INTENTS_DEFAULTS_RESULT);
ReleaseQuery(query);
std::vector<DefaultWebIntentService> services = static_cast< std::vector<DefaultWebIntentService> services = static_cast<
const WDResult<std::vector<DefaultWebIntentService> >*>(result)-> const WDResult<std::vector<DefaultWebIntentService> >*>(result)->
...@@ -325,14 +332,14 @@ void WebIntentsRegistry::OnWebDataServiceDefaultsRequestDone( ...@@ -325,14 +332,14 @@ void WebIntentsRegistry::OnWebDataServiceDefaultsRequestDone(
} }
void WebIntentsRegistry::GetIntentServices( void WebIntentsRegistry::GetIntentServices(
const string16& action, const string16& mimetype, const string16& action, const string16& type,
const QueryCallback& callback) { const QueryCallback& callback) {
DCHECK(wds_.get()); DCHECK(wds_.get());
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
IntentsQuery* query = new IntentsQuery(callback, action, mimetype); IntentsQuery* query = new IntentsQuery(this, callback, action, type);
query->pending_query_ = wds_->GetWebIntentServices(action, this); query->query_handle_ = wds_->GetWebIntentServices(action, query);
queries_[query->pending_query_] = query; TrackQuery(query);
} }
void WebIntentsRegistry::GetAllIntentServices( void WebIntentsRegistry::GetAllIntentServices(
...@@ -340,9 +347,9 @@ void WebIntentsRegistry::GetAllIntentServices( ...@@ -340,9 +347,9 @@ void WebIntentsRegistry::GetAllIntentServices(
DCHECK(wds_.get()); DCHECK(wds_.get());
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
IntentsQuery* query = new IntentsQuery(callback); IntentsQuery* query = new IntentsQuery(this, callback);
query->pending_query_ = wds_->GetAllWebIntentServices(this); query->query_handle_ = wds_->GetAllWebIntentServices(query);
queries_[query->pending_query_] = query; TrackQuery(query);
} }
void WebIntentsRegistry::IntentServiceExists( void WebIntentsRegistry::IntentServiceExists(
...@@ -351,22 +358,24 @@ void WebIntentsRegistry::IntentServiceExists( ...@@ -351,22 +358,24 @@ void WebIntentsRegistry::IntentServiceExists(
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
IntentsQuery* query = new IntentsQuery( IntentsQuery* query = new IntentsQuery(
base::Bind(&ExistenceCallback, service, callback)); this, base::Bind(&ExistenceCallback, service, callback));
query->pending_query_ = wds_->GetWebIntentServicesForURL( query->query_handle_ = wds_->GetWebIntentServicesForURL(
UTF8ToUTF16(service.service_url.spec()), this); UTF8ToUTF16(service.service_url.spec()), query);
queries_[query->pending_query_] = query; TrackQuery(query);
} }
void WebIntentsRegistry::GetIntentServicesForExtensionFilter( void WebIntentsRegistry::GetIntentServicesForExtensionFilter(
const string16& action, const string16& action,
const string16& mimetype, const string16& type,
const std::string& extension_id, const std::string& extension_id,
const QueryCallback& callback) { const QueryCallback& callback) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
// This isn't a WDS query, so we don't track it,
// or claim the query later.
scoped_ptr<IntentsQuery> query( scoped_ptr<IntentsQuery> query(
new IntentsQuery(callback, action, mimetype)); new IntentsQuery(this, callback, action, type));
content::BrowserThread::PostTask( content::BrowserThread::PostTask(
content::BrowserThread::UI, content::BrowserThread::UI,
FROM_HERE, FROM_HERE,
...@@ -386,7 +395,7 @@ void WebIntentsRegistry::DoGetIntentServicesForExtensionFilter( ...@@ -386,7 +395,7 @@ void WebIntentsRegistry::DoGetIntentServicesForExtensionFilter(
AddMatchingServicesForExtension(*extension, AddMatchingServicesForExtension(*extension,
query->action_, query->action_,
&matching_services); &matching_services);
FilterServicesByMimetype(query->type_, &matching_services); FilterServicesByType(query->type_, &matching_services);
} }
query->callback_.Run(matching_services); query->callback_.Run(matching_services);
...@@ -412,10 +421,10 @@ void WebIntentsRegistry::GetDefaultIntentService( ...@@ -412,10 +421,10 @@ void WebIntentsRegistry::GetDefaultIntentService(
DCHECK(!callback.is_null()); DCHECK(!callback.is_null());
IntentsQuery* query = IntentsQuery* query =
new IntentsQuery(callback, action, type, invoking_url); new IntentsQuery(this, callback, action, type, invoking_url);
query->pending_query_ = query->query_handle_ =
wds_->GetDefaultWebIntentServicesForAction(action, this); wds_->GetDefaultWebIntentServicesForAction(action, query);
queries_[query->pending_query_] = query; TrackQuery(query);
} }
void WebIntentsRegistry::RegisterIntentService( void WebIntentsRegistry::RegisterIntentService(
...@@ -460,3 +469,29 @@ void WebIntentsRegistry::CollapseIntents(IntentServiceList* services) { ...@@ -460,3 +469,29 @@ void WebIntentsRegistry::CollapseIntents(IntentServiceList* services) {
if (++write_iter != services->end()) if (++write_iter != services->end())
services->erase(write_iter, services->end()); services->erase(write_iter, services->end());
} }
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::TrackQuery(IntentsQuery* query) {
DCHECK(query);
pending_queries_.push_back(query);
}
void WebIntentsRegistry::ReleaseQuery(IntentsQuery* query) {
QueryVector::iterator it = std::find(
pending_queries_.begin(), pending_queries_.end(), query);
if (it != pending_queries_.end())
pending_queries_.erase(it);
else
NOTREACHED();
}
...@@ -21,9 +21,7 @@ class Extension; ...@@ -21,9 +21,7 @@ class Extension;
// Handles storing and retrieving of web intents services in the web database. // Handles storing and retrieving of web intents services in the web database.
// The registry provides filtering logic to retrieve specific types of services. // The registry provides filtering logic to retrieve specific types of services.
class WebIntentsRegistry class WebIntentsRegistry : public ProfileKeyedService {
: public WebDataServiceConsumer,
public ProfileKeyedService {
public: public:
typedef std::vector<webkit_glue::WebIntentServiceData> IntentServiceList; typedef std::vector<webkit_glue::WebIntentServiceData> IntentServiceList;
...@@ -47,11 +45,11 @@ class WebIntentsRegistry ...@@ -47,11 +45,11 @@ class WebIntentsRegistry
void UnregisterIntentService( void UnregisterIntentService(
const webkit_glue::WebIntentServiceData& service); const webkit_glue::WebIntentServiceData& service);
// Requests all services matching |action| and |mimetype|. // Requests all services matching |action| and |type|.
// |mimetype| can contain wildcards, i.e. "image/*" or "*". // |type| can contain wildcards, i.e. "image/*" or "*".
// |callback| must not be null. // |callback| must not be null.
void GetIntentServices(const string16& action, void GetIntentServices(const string16& action,
const string16& mimetype, const string16& type,
const QueryCallback& callback); const QueryCallback& callback);
// Requests all services. // Requests all services.
...@@ -66,14 +64,14 @@ class WebIntentsRegistry ...@@ -66,14 +64,14 @@ class WebIntentsRegistry
const webkit_glue::WebIntentServiceData& service, const webkit_glue::WebIntentServiceData& service,
const base::Callback<void(bool)>& callback); const base::Callback<void(bool)>& callback);
// Requests all extension services matching |action|, |mimetype| and // Requests all extension services matching |action|, |type| and
// |extension_id|. // |extension_id|.
// |mimetype| must conform to definition as outlined for GetIntentServices. // |type| must conform to definition as outlined for GetIntentServices.
// |callback| must not be null. // |callback| must not be null.
void GetIntentServicesForExtensionFilter(const string16& action, void GetIntentServicesForExtensionFilter(const string16& action,
const string16& mimetype, const string16& type,
const std::string& extension_id, const std::string& extension_id,
const QueryCallback& callback); const QueryCallback& callback);
// Record the given default service entry. // Record the given default service entry.
virtual void RegisterDefaultIntentService( virtual void RegisterDefaultIntentService(
...@@ -88,9 +86,9 @@ class WebIntentsRegistry ...@@ -88,9 +86,9 @@ class WebIntentsRegistry
// parameters. // parameters.
// |callback| must not be null. // |callback| must not be null.
void GetDefaultIntentService(const string16& action, void GetDefaultIntentService(const string16& action,
const string16& type, const string16& type,
const GURL& invoking_url, const GURL& invoking_url,
const DefaultQueryCallback& callback); const DefaultQueryCallback& callback);
protected: protected:
// Make sure that only WebIntentsRegistryFactory can create an instance of // Make sure that only WebIntentsRegistryFactory can create an instance of
...@@ -110,30 +108,34 @@ class WebIntentsRegistry ...@@ -110,30 +108,34 @@ class WebIntentsRegistry
void CollapseIntents(IntentServiceList* services); void CollapseIntents(IntentServiceList* services);
private: private:
const extensions::Extension* ExtensionForURL(const std::string& url); struct IntentsQuery;
typedef std::vector<IntentsQuery*> QueryVector;
struct IntentsQuery; // Handles services loaded
void OnWebIntentsResultReceived(
// Maps web data requests to intents queries. IntentsQuery* query,
// Allows OnWebDataServiceRequestDone to forward to appropriate consumer. const WDTypedResult* result);
typedef base::hash_map<WebDataService::Handle, IntentsQuery*> QueryMap;
// WebDataServiceConsumer implementation.
virtual void OnWebDataServiceRequestDone(
WebDataService::Handle h,
const WDTypedResult* result) OVERRIDE;
// Delegate for defaults requests from OnWebDataServiceRequestDone. // Handles default services loaded
virtual void OnWebDataServiceDefaultsRequestDone( void OnWebIntentsDefaultsResultReceived(
WebDataService::Handle h, IntentsQuery* query,
const WDTypedResult* result); const WDTypedResult* result);
// Implementation of GetIntentServicesForExtensionFilter. // Implementation of GetIntentServicesForExtensionFilter.
void DoGetIntentServicesForExtensionFilter(scoped_ptr<IntentsQuery> query, void DoGetIntentServicesForExtensionFilter(scoped_ptr<IntentsQuery> query,
const std::string& extension_id); const std::string& extension_id);
const extensions::Extension* ExtensionForURL(const std::string& url);
// Adds a query to the list of pending queries.
void TrackQuery(IntentsQuery* query);
// Takes ownership of a query. This removes a query from the list
// of pending queries.
void ReleaseQuery(IntentsQuery* query);
// Map for all in-flight web data requests/intent queries. // Map for all in-flight web data requests/intent queries.
QueryMap queries_; QueryVector pending_queries_;
// Local reference to Web Data Service. // Local reference to Web Data Service.
scoped_refptr<WebDataService> wds_; scoped_refptr<WebDataService> wds_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment