Commit f1998c7f authored by smckay@chromium.org's avatar smckay@chromium.org

Refactor WebIntentsRegistry internals to use closures as WebDataService results handlers.

BUG=137907


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

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