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 <algorithm> | 5 #include <algorithm> |
6 #include <iterator> | 6 #include <iterator> |
7 | 7 |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
12 #include "base/string_util.h" | |
12 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/favicon/favicon_service.h" | 14 #include "chrome/browser/favicon/favicon_service.h" |
14 #include "chrome/browser/intents/web_intents_registry.h" | 15 #include "chrome/browser/intents/web_intents_registry.h" |
15 #include "chrome/browser/intents/web_intents_registry_factory.h" | 16 #include "chrome/browser/intents/web_intents_registry_factory.h" |
16 #include "chrome/browser/profiles/profile.h" | 17 #include "chrome/browser/profiles/profile.h" |
17 #include "chrome/browser/ui/browser.h" | 18 #include "chrome/browser/ui/browser.h" |
18 #include "chrome/browser/ui/intents/web_intent_picker.h" | 19 #include "chrome/browser/ui/intents/web_intent_picker.h" |
19 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" | 20 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" |
20 #include "chrome/browser/ui/intents/web_intent_picker_model.h" | 21 #include "chrome/browser/ui/intents/web_intent_picker_model.h" |
21 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h" | 22 #include "chrome/browser/ui/intents/web_intent_picker_model_observer.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
87 content::URLFetcherDelegate* d) OVERRIDE { | 88 content::URLFetcherDelegate* d) OVERRIDE { |
88 return new TestURLFetcher(id, url, d); | 89 return new TestURLFetcher(id, url, d); |
89 } | 90 } |
90 }; | 91 }; |
91 | 92 |
92 } // namespace | 93 } // namespace |
93 | 94 |
94 class WebIntentPickerMock : public WebIntentPicker, | 95 class WebIntentPickerMock : public WebIntentPicker, |
95 public WebIntentPickerModelObserver { | 96 public WebIntentPickerModelObserver { |
96 public: | 97 public: |
97 WebIntentPickerMock() | 98 WebIntentPickerMock() { |
98 : num_installed_services_(0), | 99 reset(); |
99 num_icons_changed_(0), | 100 } |
100 num_extension_icons_changed_(0), | 101 |
101 num_extensions_installed_(0), | 102 void reset() { |
groby-ooo-7-16
2012/04/24 21:36:51
Why separate this out? Nobody calls reset?
Greg Billock
2012/04/25 16:04:32
I was using this but found a better way and forgot
| |
102 message_loop_started_(false), | 103 num_installed_services_ = 0; |
103 pending_async_completed_(false) { | 104 num_icons_changed_ = 0; |
105 num_extension_icons_changed_ = 0; | |
106 num_extensions_installed_ = 0; | |
107 message_loop_started_ = false; | |
108 pending_async_completed_ = false; | |
109 num_inline_disposition_ = 0; | |
110 delegate_ = NULL; | |
111 } | |
112 | |
113 void MockClose() { | |
114 delegate_->OnClosing(); | |
104 } | 115 } |
105 | 116 |
106 // WebIntentPicker implementation. | 117 // WebIntentPicker implementation. |
107 virtual void Close() OVERRIDE {} | 118 virtual void Close() OVERRIDE {} |
108 virtual void SetActionString(const string16& action) OVERRIDE {} | 119 virtual void SetActionString(const string16& action) OVERRIDE {} |
109 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE { | 120 virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE { |
110 num_extensions_installed_++; | 121 num_extensions_installed_++; |
111 } | 122 } |
112 virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE {} | 123 virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE {} |
113 virtual void OnPendingAsyncCompleted() OVERRIDE { | 124 virtual void OnPendingAsyncCompleted() OVERRIDE { |
114 StopWaiting(); | 125 StopWaiting(); |
115 } | 126 } |
116 | 127 |
117 // WebIntentPickerModelObserver implementation. | 128 // WebIntentPickerModelObserver implementation. |
118 virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE { | 129 virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE { |
119 num_installed_services_ = | 130 num_installed_services_ = |
120 static_cast<int>(model->GetInstalledServiceCount()); | 131 static_cast<int>(model->GetInstalledServiceCount()); |
121 } | 132 } |
122 virtual void OnFaviconChanged( | 133 virtual void OnFaviconChanged( |
123 WebIntentPickerModel* model, size_t index) OVERRIDE { | 134 WebIntentPickerModel* model, size_t index) OVERRIDE { |
124 num_icons_changed_++; | 135 num_icons_changed_++; |
125 } | 136 } |
126 virtual void OnExtensionIconChanged( | 137 virtual void OnExtensionIconChanged( |
127 WebIntentPickerModel* model, const string16& extension_id) OVERRIDE { | 138 WebIntentPickerModel* model, const string16& extension_id) OVERRIDE { |
128 num_extension_icons_changed_++; | 139 num_extension_icons_changed_++; |
129 } | 140 } |
130 virtual void OnInlineDisposition( | 141 virtual void OnInlineDisposition( |
131 WebIntentPickerModel* model, const GURL& url) OVERRIDE {} | 142 WebIntentPickerModel* model, const GURL& url) OVERRIDE { |
143 num_inline_disposition_++; | |
144 } | |
132 | 145 |
133 void Wait() { | 146 void Wait() { |
134 if (!pending_async_completed_) { | 147 if (!pending_async_completed_) { |
135 message_loop_started_ = true; | 148 message_loop_started_ = true; |
136 ui_test_utils::RunMessageLoop(); | 149 ui_test_utils::RunMessageLoop(); |
137 pending_async_completed_ = false; | 150 pending_async_completed_ = false; |
138 } | 151 } |
139 } | 152 } |
140 | 153 |
141 void StopWaiting() { | 154 void StopWaiting() { |
142 pending_async_completed_ = true; | 155 pending_async_completed_ = true; |
143 if (message_loop_started_) | 156 if (message_loop_started_) |
144 MessageLoop::current()->Quit(); | 157 MessageLoop::current()->Quit(); |
145 } | 158 } |
146 | 159 |
147 int num_installed_services_; | 160 int num_installed_services_; |
148 int num_icons_changed_; | 161 int num_icons_changed_; |
149 int num_extension_icons_changed_; | 162 int num_extension_icons_changed_; |
150 int num_extensions_installed_; | 163 int num_extensions_installed_; |
151 bool message_loop_started_; | 164 bool message_loop_started_; |
152 bool pending_async_completed_; | 165 bool pending_async_completed_; |
166 int num_inline_disposition_; | |
167 WebIntentPickerDelegate* delegate_; | |
153 }; | 168 }; |
154 | 169 |
155 class IntentsDispatcherMock : public content::WebIntentsDispatcher { | 170 class IntentsDispatcherMock : public content::WebIntentsDispatcher { |
156 public: | 171 public: |
157 explicit IntentsDispatcherMock(const webkit_glue::WebIntentData& intent) | 172 explicit IntentsDispatcherMock(const webkit_glue::WebIntentData& intent) |
158 : intent_(intent), | 173 : intent_(intent), |
159 dispatched_(false) {} | 174 dispatched_(false), |
175 replied_(false) {} | |
160 | 176 |
161 virtual const webkit_glue::WebIntentData& GetIntent() OVERRIDE { | 177 virtual const webkit_glue::WebIntentData& GetIntent() OVERRIDE { |
162 return intent_; | 178 return intent_; |
163 } | 179 } |
164 | 180 |
165 virtual void DispatchIntent(content::WebContents* web_contents) OVERRIDE { | 181 virtual void DispatchIntent(content::WebContents* web_contents) OVERRIDE { |
166 dispatched_ = true; | 182 dispatched_ = true; |
167 } | 183 } |
168 | 184 |
169 virtual void SendReplyMessage(webkit_glue::WebIntentReplyType reply_type, | 185 virtual void SendReplyMessage(webkit_glue::WebIntentReplyType reply_type, |
170 const string16& data) OVERRIDE { | 186 const string16& data) OVERRIDE { |
187 replied_ = true; | |
188 LOG(INFO) << "Intent Reply: " << UTF16ToASCII(data); | |
171 } | 189 } |
172 | 190 |
173 virtual void RegisterReplyNotification( | 191 virtual void RegisterReplyNotification( |
174 const base::Callback<void(webkit_glue::WebIntentReplyType)>&) OVERRIDE { | 192 const base::Callback<void(webkit_glue::WebIntentReplyType)>&) OVERRIDE { |
175 } | 193 } |
176 | 194 |
177 webkit_glue::WebIntentData intent_; | 195 webkit_glue::WebIntentData intent_; |
178 bool dispatched_; | 196 bool dispatched_; |
197 bool replied_; | |
179 }; | 198 }; |
180 | 199 |
181 class WebIntentPickerControllerBrowserTest : public InProcessBrowserTest { | 200 class WebIntentPickerControllerBrowserTest : public InProcessBrowserTest { |
182 protected: | 201 protected: |
183 typedef WebIntentPickerModel::Disposition Disposition; | 202 typedef WebIntentPickerModel::Disposition Disposition; |
184 | 203 |
185 WebIntentPickerControllerBrowserTest() {} | 204 WebIntentPickerControllerBrowserTest() {} |
186 | 205 |
187 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | 206 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
188 // We start the test server now instead of in | 207 // We start the test server now instead of in |
(...skipping 24 matching lines...) Expand all Loading... | |
213 fake_url_fetcher_factory_.reset( | 232 fake_url_fetcher_factory_.reset( |
214 new FakeURLFetcherFactory(default_url_fetcher_factory_.get())); | 233 new FakeURLFetcherFactory(default_url_fetcher_factory_.get())); |
215 | 234 |
216 web_data_service_ = | 235 web_data_service_ = |
217 GetBrowser()->profile()->GetWebDataService(Profile::EXPLICIT_ACCESS); | 236 GetBrowser()->profile()->GetWebDataService(Profile::EXPLICIT_ACCESS); |
218 favicon_service_ = | 237 favicon_service_ = |
219 GetBrowser()->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); | 238 GetBrowser()->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); |
220 controller_ = GetBrowser()-> | 239 controller_ = GetBrowser()-> |
221 GetSelectedTabContentsWrapper()->web_intent_picker_controller(); | 240 GetSelectedTabContentsWrapper()->web_intent_picker_controller(); |
222 | 241 |
223 controller_->set_picker(&picker_); | 242 SetupMockPicker(); |
224 controller_->set_model_observer(&picker_); | 243 controller_->set_model_observer(&picker_); |
244 picker_.delegate_ = controller_; | |
225 | 245 |
226 CreateFakeIcon(); | 246 CreateFakeIcon(); |
227 } | 247 } |
228 | 248 |
249 virtual void SetupMockPicker() { | |
250 controller_->set_picker(&picker_); | |
251 } | |
252 | |
229 virtual Browser* GetBrowser() { return browser(); } | 253 virtual Browser* GetBrowser() { return browser(); } |
230 | 254 |
231 void AddWebIntentService(const string16& action, const GURL& service_url) { | 255 void AddWebIntentService(const string16& action, const GURL& service_url) { |
232 webkit_glue::WebIntentServiceData service; | 256 webkit_glue::WebIntentServiceData service; |
233 service.action = action; | 257 service.action = action; |
234 service.type = kType1; | 258 service.type = kType1; |
235 service.service_url = service_url; | 259 service.service_url = service_url; |
236 web_data_service_->AddWebIntentService(service); | 260 web_data_service_->AddWebIntentService(service); |
237 } | 261 } |
238 | 262 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
431 picker_.Wait(); | 455 picker_.Wait(); |
432 EXPECT_EQ(1, picker_.num_extensions_installed_); | 456 EXPECT_EQ(1, picker_.num_extensions_installed_); |
433 const Extension* extension = browser()->profile()->GetExtensionService()-> | 457 const Extension* extension = browser()->profile()->GetExtensionService()-> |
434 GetExtensionById(extension_id, false); | 458 GetExtensionById(extension_id, false); |
435 EXPECT_TRUE(extension); | 459 EXPECT_TRUE(extension); |
436 | 460 |
437 // Installing an extension should also choose it. Since this extension uses | 461 // Installing an extension should also choose it. Since this extension uses |
438 // window disposition, it will create a new tab. | 462 // window disposition, it will create a new tab. |
439 ASSERT_EQ(2, browser()->tab_count()); | 463 ASSERT_EQ(2, browser()->tab_count()); |
440 } | 464 } |
465 | |
466 // Test that an explicit intent does not trigger loading intents from the | |
467 // registry (skips the picker), and creates the intent service handler | |
468 // immediately. | |
469 IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest, | |
470 ExplicitIntentTest) { | |
471 // Install a target service for the explicit intent. | |
472 const char extension_id[] = "ooodacpbmglpoagccnepcbfhfhpdgddn"; | |
473 AddCWSExtensionServiceWithResult(extension_id, kAction1, kType2); | |
474 controller_->ShowDialog(browser(), kAction1, kType2); | |
475 picker_.Wait(); | |
476 | |
477 webkit_glue::WebIntentData intent; | |
478 intent.action = kAction1; | |
479 intent.type = kType2; | |
480 IntentsDispatcherMock dispatcher(intent); | |
481 controller_->SetIntentsDispatcher(&dispatcher); | |
groby-ooo-7-16
2012/04/24 21:36:51
Why do we set up a dispatcher when we install a ta
Greg Billock
2012/04/25 16:04:32
Needed for smooth operation of the controller. I l
| |
482 | |
483 OnExtensionInstallRequested(extension_id); | |
484 picker_.Wait(); | |
485 ASSERT_EQ(1, picker_.num_extensions_installed_); | |
486 // The intent launches a new tab. | |
487 ASSERT_EQ(2, browser()->tab_count()); | |
488 | |
489 // Make the controller think nothing is being shown. | |
490 picker_.MockClose(); | |
491 SetupMockPicker(); | |
492 | |
493 // Now call the explicit intent. | |
494 webkit_glue::WebIntentData explicitIntent; | |
495 explicitIntent.action = kAction1; | |
496 explicitIntent.type = kType2; | |
497 explicitIntent.service = GURL(StringPrintf("%s://%s/%s", | |
498 chrome::kExtensionScheme, | |
499 extension_id, | |
500 "share.html")); | |
501 LOG(INFO) << "Calling " << explicitIntent.service.spec(); | |
502 IntentsDispatcherMock dispatcher2(explicitIntent); | |
503 controller_->SetIntentsDispatcher(&dispatcher2); | |
504 controller_->ShowDialog(browser(), kAction1, kType2); | |
505 | |
506 EXPECT_EQ(2, browser()->tab_count()); | |
507 EXPECT_EQ(0, picker_.num_inline_disposition_); | |
508 EXPECT_FALSE(dispatcher2.replied_); | |
509 | |
510 // num_installed_services_ would be 2 if the intent wasn't explicit. | |
511 EXPECT_EQ(0, picker_.num_installed_services_); | |
512 } | |
513 | |
514 // Test that an explicit intent for non-installed extension won't | |
515 // complete. | |
516 IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest, | |
517 ExplicitIntentNoExtensionTest) { | |
518 AddWebIntentService(kAction1, kServiceURL1); | |
519 AddWebIntentService(kAction1, kServiceURL2); | |
520 AddCWSExtensionServiceWithResult(kDummyExtensionId, kAction1, kType1); | |
521 | |
522 webkit_glue::WebIntentData intent; | |
523 intent.action = kAction1; | |
524 intent.type = kType1; | |
525 intent.service = GURL(StringPrintf("%s://%s/%s", | |
526 chrome::kExtensionScheme, | |
527 kDummyExtensionId, | |
528 UTF16ToASCII(kAction1).c_str())); | |
529 LOG(INFO) << "Calling " << intent.service.spec(); | |
530 IntentsDispatcherMock dispatcher(intent); | |
531 controller_->SetIntentsDispatcher(&dispatcher); | |
532 controller_->ShowDialog(browser(), kAction1, kType1); | |
533 picker_.Wait(); | |
534 | |
535 EXPECT_EQ(1, browser()->tab_count()); | |
536 EXPECT_EQ(0, picker_.num_inline_disposition_); | |
537 EXPECT_TRUE(dispatcher.replied_); | |
538 | |
539 // num_installed_services_ would be 2 if the intent wasn't explicit. | |
540 EXPECT_EQ(0, picker_.num_installed_services_); | |
541 } | |
542 | |
543 // Test that explicit intents won't load non-extensions. | |
544 IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest, | |
545 ExplicitIntentNonExtensionTest) { | |
546 AddWebIntentService(kAction1, kServiceURL1); | |
547 AddWebIntentService(kAction1, kServiceURL2); | |
548 AddCWSExtensionServiceWithResult(kDummyExtensionId, kAction1, kType1); | |
549 | |
550 webkit_glue::WebIntentData intent; | |
551 intent.action = kAction1; | |
552 intent.type = kType1; | |
553 intent.service = GURL("http://www.google.com/"); | |
554 IntentsDispatcherMock dispatcher(intent); | |
555 controller_->SetIntentsDispatcher(&dispatcher); | |
556 controller_->ShowDialog(browser(), kAction1, kType1); | |
557 | |
558 EXPECT_EQ(1, browser()->tab_count()); | |
559 EXPECT_EQ(0, picker_.num_inline_disposition_); | |
560 | |
561 // num_installed_services_ would be 2 if the intent wasn't explicit. | |
562 EXPECT_EQ(0, picker_.num_installed_services_); | |
563 EXPECT_TRUE(dispatcher.replied_); | |
564 } | |
OLD | NEW |