summaryrefslogtreecommitdiffstats
path: root/chrome/browser/intents
diff options
context:
space:
mode:
authorbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-20 21:23:43 +0000
committerbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-20 21:23:43 +0000
commit736c729be9be2117777969ba94711094eed4cd9a (patch)
tree343564a5b66c06079f70369838922b4d558f9454 /chrome/browser/intents
parentb9913e7a98457fc2a25f89328fd639e17ffdf427 (diff)
downloadchromium_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.cc87
-rw-r--r--chrome/browser/intents/web_intents_registry.h13
-rw-r--r--chrome/browser/intents/web_intents_registry_unittest.cc31
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");