Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: chrome/browser/intents/web_intents_registry.cc

Issue 9430027: Add default query method to WebIntentsRegistry. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix forward decl Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 #include "chrome/common/extensions/extension_set.h"
12 #include "googleurl/src/gurl.h"
10 #include "net/base/mime_util.h" 13 #include "net/base/mime_util.h"
11 14
12 namespace { 15 namespace {
13 16
14 // Compares two mime types for equality. Supports wild cards in both 17 // Compares two mime types for equality. Supports wild cards in both
15 // |type1| and |type2|. Wild cards are of the form '<type>/*' or '*'. 18 // |type1| and |type2|. Wild cards are of the form '<type>/*' or '*'.
16 bool MimeTypesAreEqual(const string16& type1, const string16& type2) { 19 bool MimeTypesAreEqual(const string16& type1, const string16& type2) {
17 // We don't have a MIME matcher that allows patterns on both sides 20 // 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 21 // Instead, we do two comparisons, treating each type in turn as a
19 // pattern. If either one matches, we consider this a MIME match. 22 // pattern. If either one matches, we consider this a MIME match.
(...skipping 17 matching lines...) Expand all
37 // The consumer for this particular query. 40 // The consumer for this particular query.
38 Consumer* consumer_; 41 Consumer* consumer_;
39 42
40 // The particular action to filter for while searching through extensions. 43 // The particular action to filter for while searching through extensions.
41 // If |action_| is empty, return all extension-provided services. 44 // If |action_| is empty, return all extension-provided services.
42 string16 action_; 45 string16 action_;
43 46
44 // The MIME type that was requested for this service query. 47 // The MIME type that was requested for this service query.
45 // Suppports wild cards. 48 // Suppports wild cards.
46 string16 type_; 49 string16 type_;
50
51 // The url of the invoking page.
52 GURL url_;
53
54 // Create a new IntentsQuery for services with the specified action/type.
55 IntentsQuery(QueryID id, Consumer* consumer,
56 const string16& action, const string16& type)
57 : query_id_(id), consumer_(consumer), action_(action), type_(type) {}
58
59 // Create a new IntentsQuery for all intent services or for existence checks.
60 IntentsQuery(QueryID id, Consumer* consumer)
61 : query_id_(id), consumer_(consumer), type_(ASCIIToUTF16("*")) {}
62
63 // Create a new IntentsQuery for default services.
64 IntentsQuery(QueryID id, Consumer* consumer,
65 const string16& action, const string16& type, const GURL& url)
66 : query_id_(id), consumer_(consumer),
67 action_(action), type_(type), url_(url) {}
47 }; 68 };
48 69
49 WebIntentsRegistry::WebIntentsRegistry() : next_query_id_(0) {} 70 WebIntentsRegistry::WebIntentsRegistry() : next_query_id_(0) {}
50 71
51 WebIntentsRegistry::~WebIntentsRegistry() { 72 WebIntentsRegistry::~WebIntentsRegistry() {
52 // Cancel all pending queries, since we can't handle them any more. 73 // Cancel all pending queries, since we can't handle them any more.
53 for (QueryMap::iterator it(queries_.begin()); it != queries_.end(); ++it) { 74 for (QueryMap::iterator it(queries_.begin()); it != queries_.end(); ++it) {
54 wds_->CancelRequest(it->first); 75 wds_->CancelRequest(it->first);
55 delete it->second; 76 delete it->second;
56 } 77 }
57 } 78 }
58 79
59 void WebIntentsRegistry::Initialize( 80 void WebIntentsRegistry::Initialize(
60 scoped_refptr<WebDataService> wds, 81 scoped_refptr<WebDataService> wds,
61 ExtensionServiceInterface* extension_service) { 82 ExtensionServiceInterface* extension_service) {
62 wds_ = wds; 83 wds_ = wds;
63 extension_service_ = extension_service; 84 extension_service_ = extension_service;
64 } 85 }
65 86
66 void WebIntentsRegistry::OnWebDataServiceRequestDone( 87 void WebIntentsRegistry::OnWebDataServiceRequestDone(
67 WebDataService::Handle h, 88 WebDataService::Handle h,
68 const WDTypedResult* result) { 89 const WDTypedResult* result) {
69 DCHECK(result); 90 DCHECK(result);
91 if (result->GetType() == WEB_INTENTS_DEFAULTS_RESULT) {
92 OnWebDataServiceDefaultsRequestDone(h, result);
93 return;
94 }
70 DCHECK(result->GetType() == WEB_INTENTS_RESULT); 95 DCHECK(result->GetType() == WEB_INTENTS_RESULT);
71 96
72 QueryMap::iterator it = queries_.find(h); 97 QueryMap::iterator it = queries_.find(h);
73 DCHECK(it != queries_.end()); 98 DCHECK(it != queries_.end());
74 99
75 IntentsQuery* query(it->second); 100 IntentsQuery* query(it->second);
76 DCHECK(query); 101 DCHECK(query);
77 queries_.erase(it); 102 queries_.erase(it);
78 103
79 IntentServiceList matching_services = static_cast< 104 IntentServiceList matching_services = static_cast<
(...skipping 22 matching lines...) Expand all
102 if (MimeTypesAreEqual(iter->type, query->type_)) 127 if (MimeTypesAreEqual(iter->type, query->type_))
103 ++iter; 128 ++iter;
104 else 129 else
105 iter = matching_services.erase(iter); 130 iter = matching_services.erase(iter);
106 } 131 }
107 132
108 query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services); 133 query->consumer_->OnIntentsQueryDone(query->query_id_, matching_services);
109 delete query; 134 delete query;
110 } 135 }
111 136
137 const Extension* WebIntentsRegistry::ExtensionForURL(const std::string& url) {
138 const ExtensionSet* extensions = extension_service_->extensions();
139 if (!extensions)
140 return NULL;
141
142 // Use the unsafe ExtensionURLInfo constructor: we don't care if the extension
143 // is running or not.
144 GURL gurl(url);
145 ExtensionURLInfo info(gurl);
146 return extensions->GetExtensionOrAppByURL(info);
147 }
148
149 void WebIntentsRegistry::OnWebDataServiceDefaultsRequestDone(
150 WebDataService::Handle h,
151 const WDTypedResult* result) {
152 QueryMap::iterator it = queries_.find(h);
153 DCHECK(it != queries_.end());
154
155 IntentsQuery* query(it->second);
156 DCHECK(query);
157 queries_.erase(it);
158
159 std::vector<DefaultWebIntentService> services = static_cast<
160 const WDResult<std::vector<DefaultWebIntentService> >*>(result)->
161 GetValue();
162
163 DefaultWebIntentService default_service;
164 std::vector<DefaultWebIntentService>::iterator iter(services.begin());
165 for (; iter != services.end(); ++iter) {
166 if (!MimeTypesAreEqual(iter->type, query->type_)) {
167 continue;
168 }
169 if (!iter->url_pattern.MatchesURL(query->url_)) {
170 continue;
171 }
172 const Extension* extension = ExtensionForURL(iter->service_url);
173 if (extension != NULL &&
174 !extension_service_->IsExtensionEnabled(extension->id())) {
175 continue;
176 }
177
178 // Found a match. If it is better than default_service, use it.
179 // Currently the metric is that if the new value is user-set,
180 // prefer it. If the present value is suppressed, prefer it.
181 // If the new value has a more specific pattern, prefer it.
182 if (default_service.user_date <= 0 && iter->user_date >= 0)
183 default_service = *iter;
184 else if (default_service.suppression > 0 && iter->suppression <= 0)
185 default_service = *iter;
186 else if (default_service.url_pattern.match_all_urls() &&
187 !iter->url_pattern.match_all_urls())
188 default_service = *iter;
189 else if (iter->url_pattern < default_service.url_pattern)
190 default_service = *iter;
191 }
192
193 query->consumer_->OnIntentsDefaultsQueryDone(query->query_id_,
194 default_service);
195 delete query;
196 }
197
112 WebIntentsRegistry::QueryID WebIntentsRegistry::GetIntentServices( 198 WebIntentsRegistry::QueryID WebIntentsRegistry::GetIntentServices(
113 const string16& action, const string16& mimetype, Consumer* consumer) { 199 const string16& action, const string16& mimetype, Consumer* consumer) {
114 DCHECK(consumer); 200 DCHECK(consumer);
115 DCHECK(wds_.get()); 201 DCHECK(wds_.get());
116 202
117 IntentsQuery* query = new IntentsQuery; 203 IntentsQuery* query =
118 query->query_id_ = next_query_id_++; 204 new IntentsQuery(next_query_id_++, consumer, action, mimetype);
119 query->consumer_ = consumer;
120 query->action_ = action;
121 query->type_ = mimetype;
122 query->pending_query_ = wds_->GetWebIntentServices(action, this); 205 query->pending_query_ = wds_->GetWebIntentServices(action, this);
123 queries_[query->pending_query_] = query; 206 queries_[query->pending_query_] = query;
124 207
125 return query->query_id_; 208 return query->query_id_;
126 } 209 }
127 210
128 WebIntentsRegistry::QueryID WebIntentsRegistry::GetAllIntentServices( 211 WebIntentsRegistry::QueryID WebIntentsRegistry::GetAllIntentServices(
129 Consumer* consumer) { 212 Consumer* consumer) {
130 DCHECK(consumer); 213 DCHECK(consumer);
131 DCHECK(wds_.get()); 214 DCHECK(wds_.get());
132 215
133 IntentsQuery* query = new IntentsQuery; 216 IntentsQuery* query = new IntentsQuery(next_query_id_++, consumer);
134 query->query_id_ = next_query_id_++;
135 query->consumer_ = consumer;
136 query->type_ = ASCIIToUTF16("*");
137 query->pending_query_ = wds_->GetAllWebIntentServices(this); 217 query->pending_query_ = wds_->GetAllWebIntentServices(this);
138 queries_[query->pending_query_] = query; 218 queries_[query->pending_query_] = query;
139 219
140 return query->query_id_; 220 return query->query_id_;
141 } 221 }
142 222
143 // Trampoline consumer for calls to IntentServiceExists. Forwards existence 223 // Trampoline consumer for calls to IntentServiceExists. Forwards existence
144 // of the provided |service| to the provided |callback|. 224 // of the provided |service| to the provided |callback|.
145 class ServiceCheckConsumer : public WebIntentsRegistry::Consumer { 225 class ServiceCheckConsumer : public WebIntentsRegistry::Consumer {
146 public: 226 public:
(...skipping 14 matching lines...) Expand all
161 i != list.end(); ++i) { 241 i != list.end(); ++i) {
162 if (*i == service_) { 242 if (*i == service_) {
163 callback_.Run(true); 243 callback_.Run(true);
164 return; 244 return;
165 } 245 }
166 } 246 }
167 247
168 callback_.Run(false); 248 callback_.Run(false);
169 } 249 }
170 250
251 virtual void OnIntentsDefaultsQueryDone(
252 WebIntentsRegistry::QueryID query_id,
253 const DefaultWebIntentService& default_service) {}
254
171 private: 255 private:
172 base::Callback<void(bool)> callback_; 256 base::Callback<void(bool)> callback_;
173 WebIntentServiceData service_; 257 WebIntentServiceData service_;
174 }; 258 };
175 259
176 WebIntentsRegistry::QueryID WebIntentsRegistry::IntentServiceExists( 260 WebIntentsRegistry::QueryID WebIntentsRegistry::IntentServiceExists(
177 const WebIntentServiceData& service, 261 const WebIntentServiceData& service,
178 const base::Callback<void(bool)>& callback) { 262 const base::Callback<void(bool)>& callback) {
179 IntentsQuery* query = new IntentsQuery; 263 IntentsQuery* query = new IntentsQuery(
180 query->query_id_ = next_query_id_++; 264 next_query_id_++, new ServiceCheckConsumer(service, callback));
181 query->type_ = ASCIIToUTF16("*");
182 query->consumer_ = new ServiceCheckConsumer(service, callback);
183 query->pending_query_ = wds_->GetWebIntentServicesForURL( 265 query->pending_query_ = wds_->GetWebIntentServicesForURL(
184 UTF8ToUTF16(service.service_url.spec()), this); 266 UTF8ToUTF16(service.service_url.spec()), this);
185 queries_[query->pending_query_] = query; 267 queries_[query->pending_query_] = query;
186 268
187 return query->query_id_; 269 return query->query_id_;
188 } 270 }
189 271
272 void WebIntentsRegistry::RegisterDefaultIntentService(
273 const DefaultWebIntentService& default_service) {
274 DCHECK(wds_.get());
275 wds_->AddDefaultWebIntentService(default_service);
276 }
277
278 void WebIntentsRegistry::UnregisterDefaultIntentService(
279 const DefaultWebIntentService& default_service) {
280 DCHECK(wds_.get());
281 wds_->RemoveDefaultWebIntentService(default_service);
282 }
283
284 WebIntentsRegistry::QueryID WebIntentsRegistry::GetDefaultIntentService(
285 const string16& action,
286 const string16& type,
287 const GURL& invoking_url,
288 Consumer* consumer) {
289 IntentsQuery* query =
290 new IntentsQuery(next_query_id_++, consumer, action, type, invoking_url);
291 query->pending_query_ =
292 wds_->GetDefaultWebIntentServicesForAction(action, this);
293 queries_[query->pending_query_] = query;
294
295 return query->query_id_;
296 }
297
190 void WebIntentsRegistry::RegisterIntentService( 298 void WebIntentsRegistry::RegisterIntentService(
191 const WebIntentServiceData& service) { 299 const WebIntentServiceData& service) {
192 DCHECK(wds_.get()); 300 DCHECK(wds_.get());
193 wds_->AddWebIntentService(service); 301 wds_->AddWebIntentService(service);
194 } 302 }
195 303
196 void WebIntentsRegistry::UnregisterIntentService( 304 void WebIntentsRegistry::UnregisterIntentService(
197 const WebIntentServiceData& service) { 305 const WebIntentServiceData& service) {
198 DCHECK(wds_.get()); 306 DCHECK(wds_.get());
199 wds_->RemoveWebIntentService(service); 307 wds_->RemoveWebIntentService(service);
200 } 308 }
OLDNEW
« no previous file with comments | « chrome/browser/intents/web_intents_registry.h ('k') | chrome/browser/intents/web_intents_registry_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698