diff options
author | binji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-20 21:23:43 +0000 |
---|---|---|
committer | binji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-20 21:23:43 +0000 |
commit | 736c729be9be2117777969ba94711094eed4cd9a (patch) | |
tree | 343564a5b66c06079f70369838922b4d558f9454 /chrome/browser/intents | |
parent | b9913e7a98457fc2a25f89328fd639e17ffdf427 (diff) | |
download | chromium_src-736c729be9be2117777969ba94711094eed4cd9a.zip chromium_src-736c729be9be2117777969ba94711094eed4cd9a.tar.gz chromium_src-736c729be9be2117777969ba94711094eed4cd9a.tar.bz2 |
[Web Intents] Inline installation of extensions in web intents picker.
Retry of http://codereview.chromium.org/9595031/
BUG=113476
TEST=WebIntentsRegistryTest.GetIntentServicesForExtensionFilter, WebIntentPickerControllerBrowserTest.ExtensionInstallSuccess
TBR=rsesek@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9763001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@127789 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/intents')
-rw-r--r-- | chrome/browser/intents/web_intents_registry.cc | 87 | ||||
-rw-r--r-- | chrome/browser/intents/web_intents_registry.h | 13 | ||||
-rw-r--r-- | chrome/browser/intents/web_intents_registry_unittest.cc | 31 |
3 files changed, 118 insertions, 13 deletions
diff --git a/chrome/browser/intents/web_intents_registry.cc b/chrome/browser/intents/web_intents_registry.cc index 87a0985..d58c1af 100644 --- a/chrome/browser/intents/web_intents_registry.cc +++ b/chrome/browser/intents/web_intents_registry.cc @@ -4,16 +4,21 @@ #include "chrome/browser/intents/web_intents_registry.h" +#include "base/bind.h" +#include "base/bind_helpers.h" #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.h" #include "chrome/common/extensions/extension_set.h" #include "googleurl/src/gurl.h" #include "net/base/mime_util.h" namespace { +typedef WebIntentsRegistry::IntentServiceList IntentServiceList; + // Compares two mime types for equality. Supports wild cards in both // |type1| and |type2|. Wild cards are of the form '<type>/*' or '*'. bool MimeTypesAreEqual(const string16& type1, const string16& type2) { @@ -25,6 +30,33 @@ bool MimeTypesAreEqual(const string16& type1, const string16& type2) { return net::MatchesMimeType(UTF16ToUTF8(type2), UTF16ToUTF8(type1)); } +// Adds any intent services of |extension| that match |action| to +// |matching_services|. +void AddMatchingServicesForExtension(const Extension& extension, + const string16& action, + IntentServiceList* matching_services) { + const IntentServiceList& services = extension.intents_services(); + for (IntentServiceList::const_iterator i = services.begin(); + i != services.end(); ++i) { + if (action.empty() || action == i->action) + matching_services->push_back(*i); + } +} + +// Removes all services from |matching_services| that do not match |mimetype|. +// Wildcards are supported, of the form '<type>/*' or '*'. +void FilterServicesByMimetype(const string16& mimetype, + IntentServiceList* matching_services) { + // Filter out all services not matching the query type. + IntentServiceList::iterator iter(matching_services->begin()); + while (iter != matching_services->end()) { + if (MimeTypesAreEqual(iter->type, mimetype)) + ++iter; + else + iter = matching_services->erase(iter); + } +} + } // namespace using webkit_glue::WebIntentServiceData; @@ -111,24 +143,14 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone( if (extensions) { for (ExtensionSet::const_iterator i(extensions->begin()); i != extensions->end(); ++i) { - const IntentServiceList& services((*i)->intents_services()); - for (IntentServiceList::const_iterator j(services.begin()); - j != services.end(); ++j) { - if (query->action_.empty() || query->action_ == j->action) - matching_services.push_back(*j); - } + AddMatchingServicesForExtension(**i, query->action_, + &matching_services); } } } // Filter out all services not matching the query type. - IntentServiceList::iterator iter(matching_services.begin()); - while (iter != matching_services.end()) { - if (MimeTypesAreEqual(iter->type, query->type_)) - ++iter; - else - iter = matching_services.erase(iter); - } + FilterServicesByMimetype(query->type_, &matching_services); query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); delete query; @@ -269,6 +291,45 @@ WebIntentsRegistry::QueryID WebIntentsRegistry::IntentServiceExists( return query->query_id_; } +WebIntentsRegistry::QueryID + WebIntentsRegistry::GetIntentServicesForExtensionFilter( + const string16& action, + const string16& mimetype, + const std::string& extension_id, + Consumer* consumer) { + DCHECK(consumer); + DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); + + scoped_ptr<IntentsQuery> query( + new IntentsQuery(next_query_id_++, consumer, action, mimetype)); + int query_id = query->query_id_; + content::BrowserThread::PostTask( + content::BrowserThread::UI, + FROM_HERE, + base::Bind(&WebIntentsRegistry::DoGetIntentServicesForExtensionFilter, + base::Unretained(this), + base::Passed(&query), extension_id)); + + return query_id; +} + +void WebIntentsRegistry::DoGetIntentServicesForExtensionFilter( + scoped_ptr<IntentsQuery> query, + const std::string& extension_id) { + IntentServiceList matching_services; + + if (extension_service_) { + const Extension* extension = + extension_service_->GetExtensionById(extension_id, false); + AddMatchingServicesForExtension(*extension, + query->action_, + &matching_services); + FilterServicesByMimetype(query->type_, &matching_services); + } + + query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); +} + void WebIntentsRegistry::RegisterDefaultIntentService( const DefaultWebIntentService& default_service) { DCHECK(wds_.get()); diff --git a/chrome/browser/intents/web_intents_registry.h b/chrome/browser/intents/web_intents_registry.h index 473175a..dbb2e08 100644 --- a/chrome/browser/intents/web_intents_registry.h +++ b/chrome/browser/intents/web_intents_registry.h @@ -77,6 +77,15 @@ class WebIntentsRegistry const webkit_glue::WebIntentServiceData& service, const base::Callback<void(bool)>& callback); + // Requests all extension services matching |action|, |mimetype| and + // |extension_id|. + // |mimetype| must conform to definition as outlined for GetIntentServices. + // |consumer| must not be NULL. + QueryID GetIntentServicesForExtensionFilter(const string16& action, + const string16& mimetype, + const std::string& extension_id, + Consumer* consumer); + // Record the given default service entry. virtual void RegisterDefaultIntentService( const DefaultWebIntentService& default_service); @@ -122,6 +131,10 @@ class WebIntentsRegistry WebDataService::Handle h, const WDTypedResult* result); + // Implementation of GetIntentServicesForExtensionFilter. + void DoGetIntentServicesForExtensionFilter(scoped_ptr<IntentsQuery> query, + const std::string& extension_id); + // Map for all in-flight web data requests/intent queries. QueryMap queries_; diff --git a/chrome/browser/intents/web_intents_registry_unittest.cc b/chrome/browser/intents/web_intents_registry_unittest.cc index ef1a1e1..82077fd 100644 --- a/chrome/browser/intents/web_intents_registry_unittest.cc +++ b/chrome/browser/intents/web_intents_registry_unittest.cc @@ -25,6 +25,8 @@ class MockExtensionService: public TestExtensionService { public: virtual ~MockExtensionService() {} MOCK_CONST_METHOD0(extensions, const ExtensionSet*()); + MOCK_CONST_METHOD2(GetExtensionById, + const Extension*(const std::string&, bool)); }; namespace { @@ -93,6 +95,9 @@ class WebIntentsRegistryTest : public testing::Test { registry_.Initialize(wds_, &extension_service_); EXPECT_CALL(extension_service_, extensions()). WillRepeatedly(testing::Return(&extensions_)); + EXPECT_CALL(extension_service_, GetExtensionById(testing::_, testing::_)). + WillRepeatedly( + testing::Invoke(this, &WebIntentsRegistryTest::GetExtensionById)); } virtual void TearDown() { @@ -104,6 +109,17 @@ class WebIntentsRegistryTest : public testing::Test { MessageLoop::current()->Run(); } + const Extension* GetExtensionById(const std::string& extension_id, + testing::Unused) { + for (ExtensionSet::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + if ((*iter)->id() == extension_id) + return &**iter; + } + + return NULL; + } + MessageLoopForUI message_loop_; content::TestBrowserThread ui_thread_; content::TestBrowserThread db_thread_; @@ -194,6 +210,21 @@ TEST_F(WebIntentsRegistryTest, BasicTests) { EXPECT_EQ(1U, consumer.services_.size()); } +TEST_F(WebIntentsRegistryTest, GetIntentServicesForExtensionFilter) { + extensions_.Insert(LoadAndExpectSuccess("intent_valid.json")); + extensions_.Insert(LoadAndExpectSuccess("intent_valid_2.json")); + ASSERT_EQ(2U, extensions_.size()); + + TestConsumer consumer; + consumer.expected_id_ = registry_.GetIntentServicesForExtensionFilter( + ASCIIToUTF16("http://webintents.org/edit"), + ASCIIToUTF16("image/*"), + (*extensions_.begin())->id(), + &consumer); + consumer.WaitForData(); + ASSERT_EQ(1U, consumer.services_.size()); +} + TEST_F(WebIntentsRegistryTest, GetAllIntents) { webkit_glue::WebIntentServiceData service; service.service_url = GURL("http://google.com"); |