summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgroby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 18:42:07 +0000
committergroby@chromium.org <groby@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-26 18:42:07 +0000
commit1b59118a8d97672d41bf37fac17e57a2be9da284 (patch)
tree7cbcd7474e60b90e7e62bedeffb053a44ed57437
parent73b3ac867d8131aa5affcd8b74e083062fc3057e (diff)
downloadchromium_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.cc38
-rw-r--r--chrome/browser/intents/web_intents_registry.h7
-rw-r--r--chrome/browser/intents/web_intents_registry_unittest.cc84
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_controller.cc2
-rw-r--r--webkit/glue/web_intent_service_data.cc11
-rw-r--r--webkit/glue/web_intent_service_data.h4
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;