Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/intents/web_intents_registry.h" | 5 #include "chrome/browser/intents/web_intents_registry.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | |
| 8 #include "base/bind_helpers.h" | |
| 7 #include "base/callback.h" | 9 #include "base/callback.h" |
| 8 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 9 #include "chrome/browser/intents/default_web_intent_service.h" | 11 #include "chrome/browser/intents/default_web_intent_service.h" |
| 10 #include "chrome/browser/webdata/web_data_service.h" | 12 #include "chrome/browser/webdata/web_data_service.h" |
| 13 #include "chrome/common/extensions/extension.h" | |
| 11 #include "chrome/common/extensions/extension_set.h" | 14 #include "chrome/common/extensions/extension_set.h" |
| 12 #include "googleurl/src/gurl.h" | 15 #include "googleurl/src/gurl.h" |
| 13 #include "net/base/mime_util.h" | 16 #include "net/base/mime_util.h" |
| 14 | 17 |
| 15 namespace { | 18 namespace { |
| 16 | 19 |
| 20 typedef WebIntentsRegistry::IntentServiceList IntentServiceList; | |
| 21 | |
| 17 // Compares two mime types for equality. Supports wild cards in both | 22 // Compares two mime types for equality. Supports wild cards in both |
| 18 // |type1| and |type2|. Wild cards are of the form '<type>/*' or '*'. | 23 // |type1| and |type2|. Wild cards are of the form '<type>/*' or '*'. |
| 19 bool MimeTypesAreEqual(const string16& type1, const string16& type2) { | 24 bool MimeTypesAreEqual(const string16& type1, const string16& type2) { |
| 20 // We don't have a MIME matcher that allows patterns on both sides | 25 // We don't have a MIME matcher that allows patterns on both sides |
| 21 // Instead, we do two comparisons, treating each type in turn as a | 26 // Instead, we do two comparisons, treating each type in turn as a |
| 22 // pattern. If either one matches, we consider this a MIME match. | 27 // pattern. If either one matches, we consider this a MIME match. |
| 23 if (net::MatchesMimeType(UTF16ToUTF8(type1), UTF16ToUTF8(type2))) | 28 if (net::MatchesMimeType(UTF16ToUTF8(type1), UTF16ToUTF8(type2))) |
| 24 return true; | 29 return true; |
| 25 return net::MatchesMimeType(UTF16ToUTF8(type2), UTF16ToUTF8(type1)); | 30 return net::MatchesMimeType(UTF16ToUTF8(type2), UTF16ToUTF8(type1)); |
| 26 } | 31 } |
| 27 | 32 |
| 33 void AddMatchingServicesForExtension(const Extension& extension, | |
|
James Hawkins
2012/03/15 01:05:20
Document method and params.
binji
2012/03/15 17:53:14
Done.
| |
| 34 const string16& action, | |
| 35 IntentServiceList* matching_services) { | |
| 36 const IntentServiceList& services(extension.intents_services()); | |
|
James Hawkins
2012/03/15 01:05:20
Use '=' here? It seems strange to use a copy cons
binji
2012/03/15 17:53:14
Done.
| |
| 37 for (IntentServiceList::const_iterator i = services.begin(); | |
| 38 i != services.end(); ++i) { | |
| 39 if (action.empty() || action == i->action) | |
| 40 matching_services->push_back(*i); | |
| 41 } | |
| 42 } | |
| 43 | |
| 44 void FilterServicesByMimetype(const string16& mimetype, | |
|
James Hawkins
2012/03/15 01:05:20
Document method and params.
binji
2012/03/15 17:53:14
Done.
| |
| 45 IntentServiceList* matching_services) { | |
| 46 // Filter out all services not matching the query type. | |
| 47 IntentServiceList::iterator iter(matching_services->begin()); | |
| 48 while (iter != matching_services->end()) { | |
| 49 if (MimeTypesAreEqual(iter->type, mimetype)) | |
| 50 ++iter; | |
| 51 else | |
| 52 iter = matching_services->erase(iter); | |
| 53 } | |
| 54 } | |
| 55 | |
| 28 } // namespace | 56 } // namespace |
| 29 | 57 |
| 30 using webkit_glue::WebIntentServiceData; | 58 using webkit_glue::WebIntentServiceData; |
| 31 | 59 |
| 32 // Internal object representing all data associated with a single query. | 60 // Internal object representing all data associated with a single query. |
| 33 struct WebIntentsRegistry::IntentsQuery { | 61 struct WebIntentsRegistry::IntentsQuery { |
| 34 // Unique query identifier. | 62 // Unique query identifier. |
| 35 QueryID query_id_; | 63 QueryID query_id_; |
| 36 | 64 |
| 37 // Underlying data query. | 65 // Underlying data query. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 IntentServiceList matching_services = static_cast< | 132 IntentServiceList matching_services = static_cast< |
| 105 const WDResult<IntentServiceList>*>(result)->GetValue(); | 133 const WDResult<IntentServiceList>*>(result)->GetValue(); |
| 106 | 134 |
| 107 // Loop over all services in all extensions, collect ones | 135 // Loop over all services in all extensions, collect ones |
| 108 // matching the query. | 136 // matching the query. |
| 109 if (extension_service_) { | 137 if (extension_service_) { |
| 110 const ExtensionSet* extensions = extension_service_->extensions(); | 138 const ExtensionSet* extensions = extension_service_->extensions(); |
| 111 if (extensions) { | 139 if (extensions) { |
| 112 for (ExtensionSet::const_iterator i(extensions->begin()); | 140 for (ExtensionSet::const_iterator i(extensions->begin()); |
| 113 i != extensions->end(); ++i) { | 141 i != extensions->end(); ++i) { |
| 114 const IntentServiceList& services((*i)->intents_services()); | 142 AddMatchingServicesForExtension(**i, |
| 115 for (IntentServiceList::const_iterator j(services.begin()); | 143 query->action_, |
| 116 j != services.end(); ++j) { | 144 &matching_services); |
| 117 if (query->action_.empty() || query->action_ == j->action) | |
| 118 matching_services.push_back(*j); | |
| 119 } | |
| 120 } | 145 } |
| 121 } | 146 } |
| 122 } | 147 } |
| 123 | 148 |
| 124 // Filter out all services not matching the query type. | 149 // Filter out all services not matching the query type. |
| 125 IntentServiceList::iterator iter(matching_services.begin()); | 150 FilterServicesByMimetype(query->type_, &matching_services); |
| 126 while (iter != matching_services.end()) { | |
| 127 if (MimeTypesAreEqual(iter->type, query->type_)) | |
| 128 ++iter; | |
| 129 else | |
| 130 iter = matching_services.erase(iter); | |
| 131 } | |
| 132 | 151 |
| 133 query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); | 152 query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); |
| 134 delete query; | 153 delete query; |
| 135 } | 154 } |
| 136 | 155 |
| 137 const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) { | 156 const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) { |
| 138 const ExtensionSet* extensions = extension_service_->extensions(); | 157 const ExtensionSet* extensions = extension_service_->extensions(); |
| 139 if (!extensions) | 158 if (!extensions) |
| 140 return NULL; | 159 return NULL; |
| 141 | 160 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 const base::Callback<void(bool)>& callback) { | 281 const base::Callback<void(bool)>& callback) { |
| 263 IntentsQuery* query = new IntentsQuery( | 282 IntentsQuery* query = new IntentsQuery( |
| 264 next_query_id_++, new ServiceCheckConsumer(service, callback)); | 283 next_query_id_++, new ServiceCheckConsumer(service, callback)); |
| 265 query->pending_query_ = wds_->GetWebIntentServicesForURL( | 284 query->pending_query_ = wds_->GetWebIntentServicesForURL( |
| 266 UTF8ToUTF16(service.service_url.spec()), this); | 285 UTF8ToUTF16(service.service_url.spec()), this); |
| 267 queries_[query->pending_query_] = query; | 286 queries_[query->pending_query_] = query; |
| 268 | 287 |
| 269 return query->query_id_; | 288 return query->query_id_; |
| 270 } | 289 } |
| 271 | 290 |
| 291 WebIntentsRegistry::QueryID | |
| 292 WebIntentsRegistry::GetIntentServicesWithExtensionId( | |
| 293 const string16& action, | |
| 294 const string16& mimetype, | |
| 295 const std::string& extension_id, | |
| 296 Consumer* consumer) { | |
|
James Hawkins
2012/03/15 01:05:20
DCHECK(consumer);
binji
2012/03/15 17:53:14
Done.
| |
| 297 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
| 298 | |
| 299 IntentsQuery* query = | |
|
James Hawkins
2012/03/15 01:05:20
Document ownership of |query|.
binji
2012/03/15 17:53:14
Done.
| |
| 300 new IntentsQuery(next_query_id_++, consumer, action, mimetype); | |
| 301 content::BrowserThread::PostTask( | |
| 302 content::BrowserThread::UI, | |
| 303 FROM_HERE, | |
| 304 base::Bind(&WebIntentsRegistry::DoGetIntentServicesWithExtensionId, | |
| 305 base::Unretained(this), | |
| 306 query, extension_id)); | |
| 307 | |
| 308 return query->query_id_; | |
| 309 } | |
| 310 | |
| 311 void WebIntentsRegistry::DoGetIntentServicesWithExtensionId( | |
| 312 IntentsQuery* query, | |
| 313 const std::string& extension_id) { | |
| 314 IntentServiceList matching_services; | |
| 315 | |
| 316 if (extension_service_) { | |
| 317 const Extension* extension = | |
| 318 extension_service_->GetExtensionById(extension_id, false); | |
| 319 AddMatchingServicesForExtension(*extension, query->action_, | |
|
James Hawkins
2012/03/15 01:05:20
nit: Start of parameter lines must align on the sa
binji
2012/03/15 17:53:14
Done.
| |
| 320 &matching_services); | |
| 321 FilterServicesByMimetype(query->type_, &matching_services); | |
| 322 } | |
| 323 | |
| 324 query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); | |
| 325 delete query; | |
|
James Hawkins
2012/03/15 01:05:20
Now I see the ownership. Seems dangerous; why not
binji
2012/03/15 17:53:14
Done.
| |
| 326 } | |
| 327 | |
| 272 void WebIntentsRegistry::RegisterDefaultIntentService( | 328 void WebIntentsRegistry::RegisterDefaultIntentService( |
| 273 const DefaultWebIntentService& default_service) { | 329 const DefaultWebIntentService& default_service) { |
| 274 DCHECK(wds_.get()); | 330 DCHECK(wds_.get()); |
| 275 wds_->AddDefaultWebIntentService(default_service); | 331 wds_->AddDefaultWebIntentService(default_service); |
| 276 } | 332 } |
| 277 | 333 |
| 278 void WebIntentsRegistry::UnregisterDefaultIntentService( | 334 void WebIntentsRegistry::UnregisterDefaultIntentService( |
| 279 const DefaultWebIntentService& default_service) { | 335 const DefaultWebIntentService& default_service) { |
| 280 DCHECK(wds_.get()); | 336 DCHECK(wds_.get()); |
| 281 wds_->RemoveDefaultWebIntentService(default_service); | 337 wds_->RemoveDefaultWebIntentService(default_service); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 299 const WebIntentServiceData& service) { | 355 const WebIntentServiceData& service) { |
| 300 DCHECK(wds_.get()); | 356 DCHECK(wds_.get()); |
| 301 wds_->AddWebIntentService(service); | 357 wds_->AddWebIntentService(service); |
| 302 } | 358 } |
| 303 | 359 |
| 304 void WebIntentsRegistry::UnregisterIntentService( | 360 void WebIntentsRegistry::UnregisterIntentService( |
| 305 const WebIntentServiceData& service) { | 361 const WebIntentServiceData& service) { |
| 306 DCHECK(wds_.get()); | 362 DCHECK(wds_.get()); |
| 307 wds_->RemoveWebIntentService(service); | 363 wds_->RemoveWebIntentService(service); |
| 308 } | 364 } |
| OLD | NEW |