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 9fb85f070862b795ebd0f67e99cffea5bb0c1f4e..f78aa9ed8fde01f4e82a2967e2207f9bf97b452c 100644 |
--- a/chrome/browser/intents/web_intents_registry.cc |
+++ b/chrome/browser/intents/web_intents_registry.cc |
@@ -40,6 +40,7 @@ const char* kQuickOfficeViewerMimeType[] = { |
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" |
}; |
+typedef base::Callback<void(const WDTypedResult* result)> ResultsHandler; |
typedef WebIntentsRegistry::IntentServiceList IntentServiceList; |
// Compares two mime types for equality. Supports wild cards in both |
@@ -102,7 +103,11 @@ void FilterServicesByType(const string16& type, |
// into a callback that returns true if the list contains a specific service. |
void ExistenceCallback(const webkit_glue::WebIntentServiceData& service, |
const base::Callback<void(bool)>& callback, |
- const WebIntentsRegistry::IntentServiceList& list) { |
+ const WDTypedResult* result) { |
+ |
+ WebIntentsRegistry::IntentServiceList list = static_cast< |
+ const WDResult<IntentServiceList>*>(result)->GetValue(); |
+ |
for (WebIntentsRegistry::IntentServiceList::const_iterator i = list.begin(); |
i != list.end(); ++i) { |
if (*i == service) { |
@@ -150,22 +155,9 @@ bool IntentsAreEquivalent(const webkit_glue::WebIntentServiceData& lhs, |
using webkit_glue::WebIntentServiceData; |
-// Internal object representing all data associated with a single query. |
-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. |
- WebDataService::Handle query_handle_; |
- |
- // The callback for this particular query. |
- QueryCallback callback_; |
- |
- // Callback for a query for defaults. |
- DefaultQueryCallback default_callback_; |
+// Internal object containing arguments to be used in post processing |
+// WDS results. |
+struct WebIntentsRegistry::QueryParams { |
// The particular action to filter for while searching through extensions. |
// If |action_| is empty, return all extension-provided services. |
@@ -178,38 +170,47 @@ struct WebIntentsRegistry::IntentsQuery : public WebDataServiceConsumer { |
// The url of the invoking page. |
GURL url_; |
- // Create a new IntentsQuery for services with the specified action/type. |
- IntentsQuery(WebIntentsRegistry* registry, |
- const QueryCallback& callback, |
- const string16& action, const string16& type) |
- : registry_(registry), callback_(callback), action_(action), |
- type_(type) {} |
- |
- // Create a new IntentsQuery for all intent services or for existence checks. |
- IntentsQuery(WebIntentsRegistry* registry, |
- const QueryCallback callback) |
- : registry_(registry), callback_(callback), type_(ASCIIToUTF16("*")) {} |
- |
- // Create a new IntentsQuery for default services. |
- IntentsQuery(WebIntentsRegistry* registry, |
- const DefaultQueryCallback& callback, |
- const string16& action, const string16& type, const GURL& url) |
- : registry_(registry), default_callback_(callback), action_(action), |
- type_(type), url_(url) {} |
+ // Create a new QueryParams for all intent services or for existence checks. |
+ QueryParams() : type_(ASCIIToUTF16("*")) {} |
+ |
+ QueryParams(const string16& action, const string16& type) |
+ : action_(action), type_(type) {} |
+ |
+ // Create a new QueryParams for default services. |
+ QueryParams(const string16& action, const string16& type, const GURL& url) |
+ : action_(action), type_(type), url_(url) {} |
+}; |
+ |
+// Internal object adapting the WDS consumer interface to base::Bind |
+// callback way of doing business. |
+class WebIntentsRegistry::QueryAdapter : public WebDataServiceConsumer { |
+ |
+ public: |
+ // Underlying data query. |
+ WebDataService::Handle query_handle_; |
+ |
+ // Create a new QueryAdapter that delegates results to |handler|. |
+ QueryAdapter(WebIntentsRegistry* registry, const ResultsHandler& handler) |
+ : registry_(registry), handler_(handler) { |
+ registry_->TrackQuery(this); |
+ } |
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(); |
- } |
+ handler_.Run(result); |
+ registry_->ReleaseQuery(this); |
} |
+ |
+ private: |
+ // 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_; |
+ |
+ // The callback for this particular query. |
+ ResultsHandler handler_; |
}; |
WebIntentsRegistry::WebIntentsRegistry() {} |
@@ -219,7 +220,7 @@ WebIntentsRegistry::~WebIntentsRegistry() { |
// Cancel all pending queries, since we can't handle them any more. |
for (QueryVector::iterator it = pending_queries_.begin(); |
it != pending_queries_.end(); ++it) { |
- IntentsQuery* query = *it; |
+ QueryAdapter* query = *it; |
wds_->CancelRequest(query->query_handle_); |
delete query; |
} |
@@ -233,14 +234,12 @@ void WebIntentsRegistry::Initialize( |
} |
void WebIntentsRegistry::OnWebIntentsResultReceived( |
- IntentsQuery* query, |
+ const QueryParams& params, |
+ const QueryCallback& callback, |
const WDTypedResult* result) { |
- DCHECK(query); |
DCHECK(result); |
DCHECK(result->GetType() == WEB_INTENTS_RESULT); |
- ReleaseQuery(query); |
- |
IntentServiceList matching_services = static_cast< |
const WDResult<IntentServiceList>*>(result)->GetValue(); |
@@ -251,31 +250,28 @@ void WebIntentsRegistry::OnWebIntentsResultReceived( |
if (extensions) { |
for (ExtensionSet::const_iterator i(extensions->begin()); |
i != extensions->end(); ++i) { |
- AddMatchingServicesForExtension(**i, query->action_, |
+ AddMatchingServicesForExtension(**i, params.action_, |
&matching_services); |
} |
} |
} |
// Filter out all services not matching the query type. |
- FilterServicesByType(query->type_, &matching_services); |
+ FilterServicesByType(params.type_, &matching_services); |
// Collapse intents that are equivalent for all but |type|. |
CollapseIntents(&matching_services); |
- query->callback_.Run(matching_services); |
- delete query; |
+ callback.Run(matching_services); |
} |
void WebIntentsRegistry::OnWebIntentsDefaultsResultReceived( |
- IntentsQuery* query, |
+ const QueryParams& params, |
+ const DefaultQueryCallback& callback, |
const WDTypedResult* result) { |
- DCHECK(query); |
DCHECK(result); |
DCHECK(result->GetType() == WEB_INTENTS_DEFAULTS_RESULT); |
- ReleaseQuery(query); |
- |
std::vector<DefaultWebIntentService> services = static_cast< |
const WDResult<std::vector<DefaultWebIntentService> >*>(result)-> |
GetValue(); |
@@ -283,10 +279,10 @@ void WebIntentsRegistry::OnWebIntentsDefaultsResultReceived( |
DefaultWebIntentService default_service; |
std::vector<DefaultWebIntentService>::iterator iter(services.begin()); |
for (; iter != services.end(); ++iter) { |
- if (!WebIntentsTypesMatch(iter->type, query->type_)) { |
+ if (!WebIntentsTypesMatch(iter->type, params.type_)) { |
continue; |
} |
- if (!iter->url_pattern.MatchesURL(query->url_)) { |
+ if (!iter->url_pattern.MatchesURL(params.url_)) { |
continue; |
} |
const Extension* extension = ExtensionForURL(iter->service_url); |
@@ -320,15 +316,14 @@ void WebIntentsRegistry::OnWebIntentsDefaultsResultReceived( |
qoviewer_service.action = ASCIIToUTF16(kViewActionURL); |
qoviewer_service.type = ASCIIToUTF16(kQuickOfficeViewerMimeType[i]); |
qoviewer_service.service_url = kQuickOfficeViewerServiceURL; |
- if (WebIntentsTypesMatch(qoviewer_service.type, query->type_)) { |
+ if (WebIntentsTypesMatch(qoviewer_service.type, params.type_)) { |
default_service = qoviewer_service; |
break; |
} |
} |
} |
- query->default_callback_.Run(default_service); |
- delete query; |
+ callback.Run(default_service); |
} |
void WebIntentsRegistry::GetIntentServices( |
@@ -337,9 +332,15 @@ void WebIntentsRegistry::GetIntentServices( |
DCHECK(wds_.get()); |
DCHECK(!callback.is_null()); |
- IntentsQuery* query = new IntentsQuery(this, callback, action, type); |
+ const QueryParams params(action, type); |
+ const ResultsHandler handler = base::Bind( |
+ &WebIntentsRegistry::OnWebIntentsResultReceived, |
+ base::Unretained(this), |
+ params, |
+ callback); |
+ |
+ QueryAdapter* query = new QueryAdapter(this, handler); |
query->query_handle_ = wds_->GetWebIntentServices(action, query); |
- TrackQuery(query); |
} |
void WebIntentsRegistry::GetAllIntentServices( |
@@ -347,9 +348,15 @@ void WebIntentsRegistry::GetAllIntentServices( |
DCHECK(wds_.get()); |
DCHECK(!callback.is_null()); |
- IntentsQuery* query = new IntentsQuery(this, callback); |
+ const QueryParams params; |
+ const ResultsHandler handler = base::Bind( |
+ &WebIntentsRegistry::OnWebIntentsResultReceived, |
+ base::Unretained(this), |
+ params, |
+ callback); |
+ |
+ QueryAdapter* query = new QueryAdapter(this, handler); |
query->query_handle_ = wds_->GetAllWebIntentServices(query); |
- TrackQuery(query); |
} |
void WebIntentsRegistry::IntentServiceExists( |
@@ -357,11 +364,14 @@ void WebIntentsRegistry::IntentServiceExists( |
const base::Callback<void(bool)>& callback) { |
DCHECK(!callback.is_null()); |
- IntentsQuery* query = new IntentsQuery( |
- this, base::Bind(&ExistenceCallback, service, callback)); |
+ ResultsHandler handler = base::Bind( |
+ &ExistenceCallback, |
+ service, |
+ callback); |
+ |
+ QueryAdapter* query = new QueryAdapter(this, handler); |
query->query_handle_ = wds_->GetWebIntentServicesForURL( |
UTF8ToUTF16(service.service_url.spec()), query); |
- TrackQuery(query); |
} |
void WebIntentsRegistry::GetIntentServicesForExtensionFilter( |
@@ -372,33 +382,34 @@ void WebIntentsRegistry::GetIntentServicesForExtensionFilter( |
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
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( |
- new IntentsQuery(this, callback, action, type)); |
+ const QueryParams params(action, type); |
content::BrowserThread::PostTask( |
content::BrowserThread::UI, |
FROM_HERE, |
- base::Bind(&WebIntentsRegistry::DoGetIntentServicesForExtensionFilter, |
- base::Unretained(this), |
- base::Passed(&query), extension_id)); |
+ base::Bind( |
+ &WebIntentsRegistry::DoGetIntentServicesForExtensionFilter, |
+ base::Unretained(this), |
+ params, |
+ extension_id, |
+ callback)); |
} |
void WebIntentsRegistry::DoGetIntentServicesForExtensionFilter( |
- scoped_ptr<IntentsQuery> query, |
- const std::string& extension_id) { |
+ const QueryParams& params, |
+ const std::string& extension_id, |
+ const QueryCallback& callback) { |
IntentServiceList matching_services; |
if (extension_service_) { |
const Extension* extension = |
extension_service_->GetExtensionById(extension_id, false); |
AddMatchingServicesForExtension(*extension, |
- query->action_, |
+ params.action_, |
&matching_services); |
- FilterServicesByType(query->type_, &matching_services); |
+ FilterServicesByType(params.type_, &matching_services); |
} |
- query->callback_.Run(matching_services); |
+ callback.Run(matching_services); |
} |
void WebIntentsRegistry::RegisterDefaultIntentService( |
@@ -420,11 +431,17 @@ void WebIntentsRegistry::GetDefaultIntentService( |
const DefaultQueryCallback& callback) { |
DCHECK(!callback.is_null()); |
- IntentsQuery* query = |
- new IntentsQuery(this, callback, action, type, invoking_url); |
+ const QueryParams params(action, type); |
+ |
+ ResultsHandler handler = base::Bind( |
+ &WebIntentsRegistry::OnWebIntentsDefaultsResultReceived, |
+ base::Unretained(this), |
+ params, |
+ callback); |
+ |
+ QueryAdapter* query = new QueryAdapter(this, handler); |
query->query_handle_ = |
wds_->GetDefaultWebIntentServicesForAction(action, query); |
- TrackQuery(query); |
} |
void WebIntentsRegistry::RegisterIntentService( |
@@ -482,16 +499,18 @@ const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) { |
return extensions->GetExtensionOrAppByURL(info); |
} |
-void WebIntentsRegistry::TrackQuery(IntentsQuery* query) { |
+void WebIntentsRegistry::TrackQuery(QueryAdapter* query) { |
DCHECK(query); |
pending_queries_.push_back(query); |
} |
-void WebIntentsRegistry::ReleaseQuery(IntentsQuery* query) { |
+void WebIntentsRegistry::ReleaseQuery(QueryAdapter* query) { |
QueryVector::iterator it = std::find( |
pending_queries_.begin(), pending_queries_.end(), query); |
- if (it != pending_queries_.end()) |
+ if (it != pending_queries_.end()) { |
pending_queries_.erase(it); |
- else |
+ delete query; |
+ } else { |
NOTREACHED(); |
+ } |
} |