diff options
author | groby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-26 18:42:07 +0000 |
---|---|---|
committer | groby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-26 18:42:07 +0000 |
commit | 1b59118a8d97672d41bf37fac17e57a2be9da284 (patch) | |
tree | 7cbcd7474e60b90e7e62bedeffb053a44ed57437 | |
parent | 73b3ac867d8131aa5affcd8b74e083062fc3057e (diff) | |
download | chromium_src-1b59118a8d97672d41bf37fac17e57a2be9da284.zip chromium_src-1b59118a8d97672d41bf37fac17e57a2be9da284.tar.gz chromium_src-1b59118a8d97672d41bf37fac17e57a2be9da284.tar.bz2 |
Support MIME types for intent selection.
BUG=101414
TEST=WebIntentsRegistryTest.GetIntentsWithMimeMatching
Review URL: http://codereview.chromium.org/8390027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@107399 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/intents/web_intents_registry.cc | 38 | ||||
-rw-r--r-- | chrome/browser/intents/web_intents_registry.h | 7 | ||||
-rw-r--r-- | chrome/browser/intents/web_intents_registry_unittest.cc | 84 | ||||
-rw-r--r-- | chrome/browser/ui/intents/web_intent_picker_controller.cc | 2 | ||||
-rw-r--r-- | webkit/glue/web_intent_service_data.cc | 11 | ||||
-rw-r--r-- | webkit/glue/web_intent_service_data.h | 4 |
6 files changed, 135 insertions, 11 deletions
diff --git a/chrome/browser/intents/web_intents_registry.cc b/chrome/browser/intents/web_intents_registry.cc index 4771be5..6e7c7ab 100644 --- a/chrome/browser/intents/web_intents_registry.cc +++ b/chrome/browser/intents/web_intents_registry.cc @@ -3,7 +3,25 @@ // found in the LICENSE file. #include "chrome/browser/intents/web_intents_registry.h" + +#include "base/utf_string_conversions.h" #include "chrome/browser/webdata/web_data_service.h" +#include "net/base/mime_util.h" + +namespace { + +// 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) { + // We don't have a MIME matcher that allows patterns on both sides + // Instead, we do two comparison, treating each type in turn as a + // pattern. If either one matches, we consider this a MIME match. + if (net::MatchesMimeType(UTF16ToUTF8(type1), UTF16ToUTF8(type2))) + return true; + return net::MatchesMimeType(UTF16ToUTF8(type2), UTF16ToUTF8(type1)); +} + +} // namespace // Internal object representing all data associated with a single query. struct WebIntentsRegistry::IntentsQuery { @@ -20,8 +38,9 @@ struct WebIntentsRegistry::IntentsQuery { // If |action_| is empty, return all extension-provided intents. string16 action_; - // TODO(groby): Additional filter data will go here - filtering is handled - // per query. + // The MIME type that was requested for this intent query. + // Suppports wild cards. + string16 type_; }; WebIntentsRegistry::WebIntentsRegistry() : next_query_id_(0) {} @@ -54,7 +73,6 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone( DCHECK(query); queries_.erase(it); - // TODO(groby): Filtering goes here. IntentList matching_intents = static_cast< const WDResult<IntentList>*>(result)->GetValue(); @@ -74,13 +92,21 @@ void WebIntentsRegistry::OnWebDataServiceRequestDone( } } + // Filter out all intents not matching the query type. + IntentList::iterator iter(matching_intents.begin()); + while (iter != matching_intents.end()) { + if (MimeTypesAreEqual(iter->type, query->type_)) + ++iter; + else + iter = matching_intents.erase(iter); + } + query->consumer_->OnIntentsQueryDone(query->query_id_, matching_intents); delete query; } WebIntentsRegistry::QueryID WebIntentsRegistry::GetIntentProviders( - const string16& action, - Consumer* consumer) { + const string16& action, const string16& mimetype, Consumer* consumer) { DCHECK(consumer); DCHECK(wds_.get()); @@ -88,6 +114,7 @@ WebIntentsRegistry::QueryID WebIntentsRegistry::GetIntentProviders( query->query_id_ = next_query_id_++; query->consumer_ = consumer; query->action_ = action; + query->type_ = mimetype; query->pending_query_ = wds_->GetWebIntents(action, this); queries_[query->pending_query_] = query; @@ -102,6 +129,7 @@ WebIntentsRegistry::QueryID WebIntentsRegistry::GetAllIntentProviders( IntentsQuery* query = new IntentsQuery; query->query_id_ = next_query_id_++; query->consumer_ = consumer; + query->type_ = ASCIIToUTF16("*"); query->pending_query_ = wds_->GetAllWebIntents(this); queries_[query->pending_query_] = query; diff --git a/chrome/browser/intents/web_intents_registry.h b/chrome/browser/intents/web_intents_registry.h index 7a712a3..b0bf943 100644 --- a/chrome/browser/intents/web_intents_registry.h +++ b/chrome/browser/intents/web_intents_registry.h @@ -47,9 +47,12 @@ class WebIntentsRegistry // Removes a web intent provider from the registry. void UnregisterIntentProvider(const WebIntentServiceData& intent); - // Requests all intent providers matching |action|. + // Requests all intent providers matching |action| and |mimetype|. + // |mimetype| can contain wildcards, i.e. "image/*" or "*". // |consumer| must not be NULL. - QueryID GetIntentProviders(const string16& action, Consumer* consumer); + QueryID GetIntentProviders(const string16& action, + const string16& mimetype, + Consumer* consumer); // Requests all intent providers. |consumer| must not be NULL QueryID GetAllIntentProviders(Consumer* consumer); diff --git a/chrome/browser/intents/web_intents_registry_unittest.cc b/chrome/browser/intents/web_intents_registry_unittest.cc index f59f5c5..b2d0e05 100644 --- a/chrome/browser/intents/web_intents_registry_unittest.cc +++ b/chrome/browser/intents/web_intents_registry_unittest.cc @@ -182,11 +182,13 @@ TEST_F(WebIntentsRegistryTest, BasicTests) { TestConsumer consumer; consumer.expected_id_ = registry_.GetIntentProviders(ASCIIToUTF16("share"), + ASCIIToUTF16("*"), &consumer); consumer.WaitForData(); EXPECT_EQ(2U, consumer.services_.size()); consumer.expected_id_ = registry_.GetIntentProviders(ASCIIToUTF16("search"), + ASCIIToUTF16("*"), &consumer); consumer.WaitForData(); EXPECT_EQ(1U, consumer.services_.size()); @@ -196,6 +198,7 @@ TEST_F(WebIntentsRegistryTest, BasicTests) { registry_.UnregisterIntentProvider(service); consumer.expected_id_ = registry_.GetIntentProviders(ASCIIToUTF16("share"), + ASCIIToUTF16("*"), &consumer); consumer.WaitForData(); EXPECT_EQ(1U, consumer.services_.size()); @@ -243,7 +246,8 @@ TEST_F(WebIntentsRegistryTest, GetSomeExtensionIntents) { TestConsumer consumer; consumer.expected_id_ = registry_.GetIntentProviders( - ASCIIToUTF16("http://webintents.org/edit"),&consumer); + ASCIIToUTF16("http://webintents.org/edit"), ASCIIToUTF16("*"), + &consumer); consumer.WaitForData(); ASSERT_EQ(1U, consumer.services_.size()); } @@ -261,12 +265,86 @@ TEST_F(WebIntentsRegistryTest, GetIntentsFromMixedSources) { TestConsumer consumer; consumer.expected_id_ = registry_.GetIntentProviders( - ASCIIToUTF16("http://webintents.org/edit"),&consumer); + ASCIIToUTF16("http://webintents.org/edit"), ASCIIToUTF16("*"), + &consumer); consumer.WaitForData(); ASSERT_EQ(2U, consumer.services_.size()); consumer.expected_id_ = registry_.GetIntentProviders( - ASCIIToUTF16("http://webintents.org/share"),&consumer); + ASCIIToUTF16("http://webintents.org/share"), ASCIIToUTF16("*"), + &consumer); consumer.WaitForData(); ASSERT_EQ(1U, consumer.services_.size()); } + +TEST_F(WebIntentsRegistryTest, GetIntentsWithMimeMatching) { + WebIntentServiceData services[] = { + WebIntentServiceData(GURL("http://somewhere.com/intent/share.html"), + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("image/*"), + ASCIIToUTF16("Image Sharing Service")), + WebIntentServiceData(GURL("http://elsewhere.com/intent/share.html"), + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("image/jpeg"), + ASCIIToUTF16("Specific Image Editing Service")), + WebIntentServiceData(GURL("http://somewhere.com/intent/share.html"), + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("text/uri-list"), + ASCIIToUTF16("Link Sharing Service")), + WebIntentServiceData(GURL("http://elsewhere.com/intent/share.html"), + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("text/plain"), + ASCIIToUTF16("Text Sharing Service")) + }; + registry_.RegisterIntentProvider(services[0]); + registry_.RegisterIntentProvider(services[1]); + registry_.RegisterIntentProvider(services[2]); + registry_.RegisterIntentProvider(services[3]); + + TestConsumer consumer; + + // Test specific match on both sides. + consumer.expected_id_ = registry_.GetIntentProviders( + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("text/uri-list"), &consumer); + consumer.WaitForData(); + ASSERT_EQ(1U, consumer.services_.size()); + EXPECT_EQ(services[2], consumer.services_[0]); + + // Test specific query, wildcard registration. + consumer.expected_id_ = registry_.GetIntentProviders( + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("image/png"), &consumer); + consumer.WaitForData(); + ASSERT_EQ(1U, consumer.services_.size()); + EXPECT_EQ(services[0], consumer.services_[0]); + + // Test wildcard query, specific registration. + consumer.expected_id_ = registry_.GetIntentProviders( + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("text/*"), &consumer); + consumer.WaitForData(); + ASSERT_EQ(2U, consumer.services_.size()); + EXPECT_EQ(services[2], consumer.services_[0]); + EXPECT_EQ(services[3], consumer.services_[1]); + + // Test wildcard query, wildcard registration. + consumer.expected_id_ = registry_.GetIntentProviders( + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("image/*"), &consumer); + consumer.WaitForData(); + ASSERT_EQ(2U, consumer.services_.size()); + EXPECT_EQ(services[0], consumer.services_[0]); + EXPECT_EQ(services[1], consumer.services_[1]); + + // Test "catch-all" query. + consumer.expected_id_ = registry_.GetIntentProviders( + ASCIIToUTF16("http://webintents.org/share"), + ASCIIToUTF16("*"), &consumer); + consumer.WaitForData(); + ASSERT_EQ(4U, consumer.services_.size()); + EXPECT_EQ(services[0], consumer.services_[0]); + EXPECT_EQ(services[1], consumer.services_[1]); + EXPECT_EQ(services[2], consumer.services_[2]); + EXPECT_EQ(services[3], consumer.services_[3]); +} diff --git a/chrome/browser/ui/intents/web_intent_picker_controller.cc b/chrome/browser/ui/intents/web_intent_picker_controller.cc index 88e1225..3d29e23 100644 --- a/chrome/browser/ui/intents/web_intent_picker_controller.cc +++ b/chrome/browser/ui/intents/web_intent_picker_controller.cc @@ -276,7 +276,7 @@ void WebIntentPickerController::WebIntentDataFetcher::Fetch( const string16& type) { DCHECK(query_id_ == -1) << "Fetch already in process."; controller_->pending_async_count_++; - query_id_ = web_intents_registry_->GetIntentProviders(action, this); + query_id_ = web_intents_registry_->GetIntentProviders(action, type, this); } void WebIntentPickerController::WebIntentDataFetcher::OnIntentsQueryDone( diff --git a/webkit/glue/web_intent_service_data.cc b/webkit/glue/web_intent_service_data.cc index 67849db..09933c5 100644 --- a/webkit/glue/web_intent_service_data.cc +++ b/webkit/glue/web_intent_service_data.cc @@ -11,6 +11,17 @@ WebIntentServiceData::WebIntentServiceData() : disposition(WebIntentServiceData::DISPOSITION_WINDOW) { } +WebIntentServiceData::WebIntentServiceData(const GURL& svc_url, + const string16& svc_action, + const string16& svc_type, + const string16& svc_title) + : service_url(svc_url), + action(svc_action), + type(svc_type), + title(svc_title), + disposition(WebIntentServiceData::DISPOSITION_WINDOW) { +} + WebIntentServiceData::~WebIntentServiceData() {} bool WebIntentServiceData::operator==(const WebIntentServiceData& other) const { diff --git a/webkit/glue/web_intent_service_data.h b/webkit/glue/web_intent_service_data.h index aa42256..532aa03 100644 --- a/webkit/glue/web_intent_service_data.h +++ b/webkit/glue/web_intent_service_data.h @@ -19,6 +19,10 @@ struct WebIntentServiceData { }; WebIntentServiceData(); + WebIntentServiceData(const GURL& service_url, + const string16& action, + const string16& type, + const string16& title); ~WebIntentServiceData(); bool operator==(const WebIntentServiceData& other) const; |