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/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/utf_string_conversions.h" | 8 #include "base/utf_string_conversions.h" |
| 9 #include "chrome/browser/intents/default_web_intent_service.h" | |
| 9 #include "chrome/browser/webdata/web_data_service.h" | 10 #include "chrome/browser/webdata/web_data_service.h" |
| 10 #include "net/base/mime_util.h" | 11 #include "net/base/mime_util.h" |
| 11 | 12 |
| 12 namespace { | 13 namespace { |
| 13 | 14 |
| 14 // Compares two mime types for equality. Supports wild cards in both | 15 // Compares two mime types for equality. Supports wild cards in both |
| 15 // |type1| and |type2|. Wild cards are of the form '<type>/*' or '*'. | 16 // |type1| and |type2|. Wild cards are of the form '<type>/*' or '*'. |
| 16 bool MimeTypesAreEqual(const string16& type1, const string16& type2) { | 17 bool MimeTypesAreEqual(const string16& type1, const string16& type2) { |
| 17 // We don't have a MIME matcher that allows patterns on both sides | 18 // We don't have a MIME matcher that allows patterns on both sides |
| 18 // Instead, we do two comparisons, treating each type in turn as a | 19 // Instead, we do two comparisons, treating each type in turn as a |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 37 // The consumer for this particular query. | 38 // The consumer for this particular query. |
| 38 Consumer* consumer_; | 39 Consumer* consumer_; |
| 39 | 40 |
| 40 // The particular action to filter for while searching through extensions. | 41 // The particular action to filter for while searching through extensions. |
| 41 // If |action_| is empty, return all extension-provided services. | 42 // If |action_| is empty, return all extension-provided services. |
| 42 string16 action_; | 43 string16 action_; |
| 43 | 44 |
| 44 // The MIME type that was requested for this service query. | 45 // The MIME type that was requested for this service query. |
| 45 // Suppports wild cards. | 46 // Suppports wild cards. |
| 46 string16 type_; | 47 string16 type_; |
| 48 | |
| 49 // The url of the invoking page. | |
| 50 GURL url_; | |
|
groby-ooo-7-16
2012/02/22 01:40:18
IWYU: #include "googleurl/src/gurl.h"
Greg Billock
2012/02/23 23:39:00
Done.
| |
| 47 }; | 51 }; |
| 48 | 52 |
| 49 WebIntentsRegistry::WebIntentsRegistry() : next_query_id_(0) {} | 53 WebIntentsRegistry::WebIntentsRegistry() : next_query_id_(0) {} |
| 50 | 54 |
| 51 WebIntentsRegistry::~WebIntentsRegistry() { | 55 WebIntentsRegistry::~WebIntentsRegistry() { |
| 52 // Cancel all pending queries, since we can't handle them any more. | 56 // Cancel all pending queries, since we can't handle them any more. |
| 53 for (QueryMap::iterator it(queries_.begin()); it != queries_.end(); ++it) { | 57 for (QueryMap::iterator it(queries_.begin()); it != queries_.end(); ++it) { |
| 54 wds_->CancelRequest(it->first); | 58 wds_->CancelRequest(it->first); |
| 55 delete it->second; | 59 delete it->second; |
| 56 } | 60 } |
| 57 } | 61 } |
| 58 | 62 |
| 59 void WebIntentsRegistry::Initialize( | 63 void WebIntentsRegistry::Initialize( |
| 60 scoped_refptr<WebDataService> wds, | 64 scoped_refptr<WebDataService> wds, |
| 61 ExtensionServiceInterface* extension_service) { | 65 ExtensionServiceInterface* extension_service) { |
| 62 wds_ = wds; | 66 wds_ = wds; |
| 63 extension_service_ = extension_service; | 67 extension_service_ = extension_service; |
| 64 } | 68 } |
| 65 | 69 |
| 66 void WebIntentsRegistry::OnWebDataServiceRequestDone( | 70 void WebIntentsRegistry::OnWebDataServiceRequestDone( |
| 67 WebDataService::Handle h, | 71 WebDataService::Handle h, |
| 68 const WDTypedResult* result) { | 72 const WDTypedResult* result) { |
| 69 DCHECK(result); | 73 DCHECK(result); |
| 74 if (result->GetType() == WEB_INTENTS_DEFAULTS_RESULT) { | |
| 75 OnWebDataServiceDefaultsRequestDone(h, result); | |
| 76 return; | |
| 77 } | |
| 70 DCHECK(result->GetType() == WEB_INTENTS_RESULT); | 78 DCHECK(result->GetType() == WEB_INTENTS_RESULT); |
| 71 | 79 |
| 72 QueryMap::iterator it = queries_.find(h); | 80 QueryMap::iterator it = queries_.find(h); |
| 73 DCHECK(it != queries_.end()); | 81 DCHECK(it != queries_.end()); |
| 74 | 82 |
| 75 IntentsQuery* query(it->second); | 83 IntentsQuery* query(it->second); |
| 76 DCHECK(query); | 84 DCHECK(query); |
| 77 queries_.erase(it); | 85 queries_.erase(it); |
| 78 | 86 |
| 79 IntentServiceList matching_services = static_cast< | 87 IntentServiceList matching_services = static_cast< |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 102 if (MimeTypesAreEqual(iter->type, query->type_)) | 110 if (MimeTypesAreEqual(iter->type, query->type_)) |
| 103 ++iter; | 111 ++iter; |
| 104 else | 112 else |
| 105 iter = matching_services.erase(iter); | 113 iter = matching_services.erase(iter); |
| 106 } | 114 } |
| 107 | 115 |
| 108 query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); | 116 query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); |
| 109 delete query; | 117 delete query; |
| 110 } | 118 } |
| 111 | 119 |
| 120 void WebIntentsRegistry::OnWebDataServiceDefaultsRequestDone( | |
| 121 WebDataService::Handle h, | |
| 122 const WDTypedResult* result) { | |
| 123 QueryMap::iterator it = queries_.find(h); | |
| 124 DCHECK(it != queries_.end()); | |
| 125 | |
| 126 IntentsQuery* query(it->second); | |
| 127 DCHECK(query); | |
| 128 queries_.erase(it); | |
| 129 | |
| 130 std::vector<DefaultWebIntentService> services = static_cast< | |
| 131 const WDResult<std::vector<DefaultWebIntentService> >*>(result)-> | |
| 132 GetValue(); | |
| 133 | |
| 134 DefaultWebIntentService default_service; | |
| 135 std::vector<DefaultWebIntentService>::iterator iter(services.begin()); | |
| 136 for (; iter != services.end(); ++iter) { | |
| 137 if (!MimeTypesAreEqual(iter->type, query->type_)) { | |
| 138 continue; | |
| 139 } | |
| 140 if (!iter->url_pattern.MatchesURL(query->url_)) { | |
| 141 continue; | |
| 142 } | |
| 143 | |
| 144 // Found a match. If it is better than default_service, use it. | |
| 145 // Currently the metric is that if the new value is user-set, | |
| 146 // prefer it. If the present value is suppressed, prefer it. | |
| 147 // If the new value has a more specific pattern, prefer it. | |
| 148 if (default_service.user_date <= 0 && iter->user_date >= 0) | |
|
groby-ooo-7-16
2012/02/22 01:40:18
We should probably check if the default service is
Greg Billock
2012/02/23 23:39:00
Done.
| |
| 149 default_service = *iter; | |
| 150 else if (default_service.suppression > 0 && iter->suppression <= 0) | |
| 151 default_service = *iter; | |
| 152 else if (default_service.url_pattern.match_all_urls() && | |
| 153 !iter->url_pattern.match_all_urls()) | |
| 154 default_service = *iter; | |
| 155 else if (iter->url_pattern < default_service.url_pattern) | |
| 156 default_service = *iter; | |
| 157 } | |
| 158 | |
| 159 query->consumer_->OnIntentsDefaultsQueryDone(query->query_id_, | |
| 160 default_service); | |
| 161 delete query; | |
| 162 } | |
| 163 | |
| 112 WebIntentsRegistry::QueryID WebIntentsRegistry::GetIntentServices( | 164 WebIntentsRegistry::QueryID WebIntentsRegistry::GetIntentServices( |
| 113 const string16& action, const string16& mimetype, Consumer* consumer) { | 165 const string16& action, const string16& mimetype, Consumer* consumer) { |
| 114 DCHECK(consumer); | 166 DCHECK(consumer); |
| 115 DCHECK(wds_.get()); | 167 DCHECK(wds_.get()); |
| 116 | 168 |
| 117 IntentsQuery* query = new IntentsQuery; | 169 IntentsQuery* query = new IntentsQuery; |
| 118 query->query_id_ = next_query_id_++; | 170 query->query_id_ = next_query_id_++; |
| 119 query->consumer_ = consumer; | 171 query->consumer_ = consumer; |
| 120 query->action_ = action; | 172 query->action_ = action; |
| 121 query->type_ = mimetype; | 173 query->type_ = mimetype; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 161 i != list.end(); ++i) { | 213 i != list.end(); ++i) { |
| 162 if (*i == service_) { | 214 if (*i == service_) { |
| 163 callback_.Run(true); | 215 callback_.Run(true); |
| 164 return; | 216 return; |
| 165 } | 217 } |
| 166 } | 218 } |
| 167 | 219 |
| 168 callback_.Run(false); | 220 callback_.Run(false); |
| 169 } | 221 } |
| 170 | 222 |
| 223 virtual void OnIntentsDefaultsQueryDone( | |
| 224 WebIntentsRegistry::QueryID query_id, | |
| 225 const DefaultWebIntentService& default_service) {} | |
| 226 | |
| 171 private: | 227 private: |
| 172 base::Callback<void(bool)> callback_; | 228 base::Callback<void(bool)> callback_; |
| 173 WebIntentServiceData service_; | 229 WebIntentServiceData service_; |
| 174 }; | 230 }; |
| 175 | 231 |
| 176 WebIntentsRegistry::QueryID WebIntentsRegistry::IntentServiceExists( | 232 WebIntentsRegistry::QueryID WebIntentsRegistry::IntentServiceExists( |
| 177 const WebIntentServiceData& service, | 233 const WebIntentServiceData& service, |
| 178 const base::Callback<void(bool)>& callback) { | 234 const base::Callback<void(bool)>& callback) { |
| 179 IntentsQuery* query = new IntentsQuery; | 235 IntentsQuery* query = new IntentsQuery; |
| 180 query->query_id_ = next_query_id_++; | 236 query->query_id_ = next_query_id_++; |
| 181 query->type_ = ASCIIToUTF16("*"); | 237 query->type_ = ASCIIToUTF16("*"); |
| 182 query->consumer_ = new ServiceCheckConsumer(service, callback); | 238 query->consumer_ = new ServiceCheckConsumer(service, callback); |
| 183 query->pending_query_ = wds_->GetWebIntentServicesForURL( | 239 query->pending_query_ = wds_->GetWebIntentServicesForURL( |
| 184 UTF8ToUTF16(service.service_url.spec()), this); | 240 UTF8ToUTF16(service.service_url.spec()), this); |
| 185 queries_[query->pending_query_] = query; | 241 queries_[query->pending_query_] = query; |
| 186 | 242 |
| 187 return query->query_id_; | 243 return query->query_id_; |
| 188 } | 244 } |
| 189 | 245 |
| 246 void WebIntentsRegistry::RegisterDefaultIntentService( | |
| 247 const DefaultWebIntentService& default_service) { | |
| 248 DCHECK(wds_.get()); | |
| 249 wds_->AddDefaultWebIntentService(default_service); | |
| 250 } | |
| 251 | |
| 252 void WebIntentsRegistry::UnregisterDefaultIntentService( | |
| 253 const DefaultWebIntentService& default_service) { | |
| 254 DCHECK(wds_.get()); | |
| 255 wds_->RemoveDefaultWebIntentService(default_service); | |
| 256 } | |
| 257 | |
| 258 WebIntentsRegistry::QueryID WebIntentsRegistry::GetDefaultIntentService( | |
| 259 const string16& action, | |
| 260 const string16& type, | |
| 261 const GURL& invoking_url, | |
| 262 Consumer* consumer) { | |
| 263 IntentsQuery* query = new IntentsQuery; | |
| 264 query->query_id_ = next_query_id_++; | |
|
groby-ooo-7-16
2012/02/22 01:40:18
Since we now have three places that build a query,
Greg Billock
2012/02/23 23:39:00
Created some constructors. That condenses things a
| |
| 265 query->action_ = action; | |
| 266 query->type_ = type; | |
| 267 query->url_ = invoking_url; | |
| 268 query->consumer_ = consumer; | |
| 269 query->pending_query_ = | |
| 270 wds_->GetDefaultWebIntentServicesForAction(action, this); | |
| 271 queries_[query->pending_query_] = query; | |
|
groby-ooo-7-16
2012/02/22 01:40:18
And similarly, a RegisterQuery() for the previous
Greg Billock
2012/02/23 23:39:00
I don't think that'd buy that much. This looks cle
| |
| 272 | |
| 273 return query->query_id_; | |
| 274 } | |
| 275 | |
| 190 void WebIntentsRegistry::RegisterIntentService( | 276 void WebIntentsRegistry::RegisterIntentService( |
| 191 const WebIntentServiceData& service) { | 277 const WebIntentServiceData& service) { |
| 192 DCHECK(wds_.get()); | 278 DCHECK(wds_.get()); |
| 193 wds_->AddWebIntentService(service); | 279 wds_->AddWebIntentService(service); |
| 194 } | 280 } |
| 195 | 281 |
| 196 void WebIntentsRegistry::UnregisterIntentService( | 282 void WebIntentsRegistry::UnregisterIntentService( |
| 197 const WebIntentServiceData& service) { | 283 const WebIntentServiceData& service) { |
| 198 DCHECK(wds_.get()); | 284 DCHECK(wds_.get()); |
| 199 wds_->RemoveWebIntentService(service); | 285 wds_->RemoveWebIntentService(service); |
| 200 } | 286 } |
| OLD | NEW |