blob: b7b388fb61d3e79b3829136708f904af4312cc68 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <iterator>
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/memory/scoped_ptr.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/favicon/favicon_service.h"
#include "chrome/browser/favicon/favicon_service_factory.h"
#include "chrome/browser/intents/default_web_intent_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/intents/web_intent_picker.h"
#include "chrome/browser/ui/intents/web_intent_picker_controller.h"
#include "chrome/browser/ui/intents/web_intent_picker_model.h"
#include "chrome/browser/ui/intents/web_intent_picker_model_observer.h"
#include "chrome/browser/ui/tab_contents/tab_contents.h"
#include "chrome/browser/webdata/web_data_service.h"
#include "chrome/browser/webdata/web_data_service_factory.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_intents_dispatcher.h"
#include "net/base/escape.h"
#include "net/base/mock_host_resolver.h"
#include "net/url_request/test_url_fetcher_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/gfx/image/image_unittest_util.h"
#include "ui/gfx/image/image_util.h"
#include "webkit/glue/web_intent_service_data.h"
namespace {
const string16 kAction1(ASCIIToUTF16("http://webintents.org/share"));
const string16 kAction2(ASCIIToUTF16("http://www.example.com/foobar"));
const string16 kType1(ASCIIToUTF16("image/png"));
const string16 kType2(ASCIIToUTF16("text/*"));
const GURL kServiceURL1("http://www.google.com");
const GURL kServiceURL2("http://www.chromium.org");
const char kDummyExtensionId[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
const char kCWSResponseEmpty[] =
"{\"kind\":\"chromewebstore#itemList\",\"total_items\":0,\"start_index\":0,"
"\"items\":[]}";
const char kCWSResponseResultFormat[] =
"{\"kind\":\"chromewebstore#itemList\","
"\"total_items\":1,"
"\"start_index\":0,"
"\"items\":[{"
"\"kind\":\"chromewebstore#item\","
"\"id\":\"%s\","
"\"type\":\"APPLICATION\","
"\"num_ratings\":0,"
"\"average_rating\":0.0,"
"\"manifest\": \"{\\n"
"\\\"name\\\": \\\"Dummy Share\\\",\\n"
"\\\"version\\\": \\\"1.0.0.0\\\",\\n"
"\\\"intents\\\": {\\n"
"\\\"%s\\\" : {\\n"
"\\\"type\\\" : [\\\"%s\\\"],\\n"
"\\\"path\\\" : \\\"share.html\\\",\\n"
"\\\"title\\\" : \\\"Dummy share!\\\",\\n"
"\\\"disposition\\\": \\\"inline\\\"\\n"
"}\\n"
"}\\n"
"}\\n\","
"\"family_safe\":true,"
"\"icon_url\": \"%s\"}]}";
const char kCWSFakeIconURLFormat[] = "http://example.com/%s/icon.png";
class DummyURLFetcherFactory : public net::URLFetcherFactory {
public:
DummyURLFetcherFactory() {}
virtual ~DummyURLFetcherFactory() {}
virtual net::URLFetcher* CreateURLFetcher(
int id,
const GURL& url,
net::URLFetcher::RequestType request_type,
net::URLFetcherDelegate* d) OVERRIDE {
return new net::TestURLFetcher(id, url, d);
}
};
} // namespace
class WebIntentPickerMock : public WebIntentPicker,
public WebIntentPickerModelObserver {
public:
WebIntentPickerMock()
: num_installed_services_(0),
num_icons_changed_(0),
num_extension_icons_changed_(0),
num_extensions_installed_(0),
message_loop_started_(false),
pending_async_completed_(false),
num_inline_disposition_(0),
delegate_(NULL) {
}
void MockClose() {
delegate_->OnClosing();
}
// WebIntentPicker implementation.
virtual void Close() OVERRIDE { StopWaiting(); }
virtual void SetActionString(const string16& action) OVERRIDE {}
virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE {
num_extensions_installed_++;
}
virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE {}
virtual void OnInlineDispositionAutoResize(const gfx::Size& size) OVERRIDE {}
virtual void OnPendingAsyncCompleted() OVERRIDE {
StopWaiting();
}
// WebIntentPickerModelObserver implementation.
virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE {
num_installed_services_ =
static_cast<int>(model->GetInstalledServiceCount());
}
virtual void OnFaviconChanged(
WebIntentPickerModel* model, size_t index) OVERRIDE {
num_icons_changed_++;
}
virtual void OnExtensionIconChanged(
WebIntentPickerModel* model, const string16& extension_id) OVERRIDE {
num_extension_icons_changed_++;
}
virtual void OnInlineDisposition(
const string16& title, const GURL& url) OVERRIDE {
num_inline_disposition_++;
}
void Wait() {
if (!pending_async_completed_) {
message_loop_started_ = true;
content::RunMessageLoop();
pending_async_completed_ = false;
}
}
void StopWaiting() {
pending_async_completed_ = true;
if (message_loop_started_) {
message_loop_started_ = false;
MessageLoop::current()->Quit();
}
}
int num_installed_services_;
int num_icons_changed_;
int num_extension_icons_changed_;
int num_extensions_installed_;
bool message_loop_started_;
bool pending_async_completed_;
int num_inline_disposition_;
WebIntentPickerDelegate* delegate_;
};
class IntentsDispatcherMock : public content::WebIntentsDispatcher {
public:
explicit IntentsDispatcherMock(const webkit_glue::WebIntentData& intent)
: intent_(intent),
dispatched_(false),
replied_(false) {}
virtual const webkit_glue::WebIntentData& GetIntent() OVERRIDE {
return intent_;
}
virtual void DispatchIntent(content::WebContents* web_contents) OVERRIDE {
dispatched_ = true;
}
virtual void ResetDispatch() OVERRIDE {
}
virtual void SendReplyMessage(webkit_glue::WebIntentReplyType reply_type,
const string16& data) OVERRIDE {
replied_ = true;
}
virtual void RegisterReplyNotification(
const base::Callback<void(webkit_glue::WebIntentReplyType)>&) OVERRIDE {
}
webkit_glue::WebIntentData intent_;
bool dispatched_;
bool replied_;
};
class WebIntentPickerControllerBrowserTest : public InProcessBrowserTest {
protected:
WebIntentPickerControllerBrowserTest() {}
virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
// We start the test server now instead of in
// SetUpInProcessBrowserTestFixture so that we can get its port number.
ASSERT_TRUE(test_server()->Start());
net::HostPortPair host_port = test_server()->host_port_pair();
command_line->AppendSwitchASCII(
switches::kAppsGalleryDownloadURL,
base::StringPrintf(
"http://www.example.com:%d/files/extensions/intents/%%s.crx",
host_port.port()));
command_line->AppendSwitchASCII(
switches::kAppsGalleryInstallAutoConfirmForTests, "accept");
}
virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
host_resolver()->AddRule("www.example.com", "127.0.0.1");
}
content::WebContents* GetWindowDispositionTarget(
WebIntentPickerController* controller) {
return controller->window_disposition_source_;
}
virtual void SetUpOnMainThread() OVERRIDE {
// The FakeURLFetcherFactory will return a NULL URLFetcher if a request is
// created for a URL it doesn't know and there is no default factory.
// Instead, use this dummy factory to infinitely delay the request.
default_url_fetcher_factory_.reset(new DummyURLFetcherFactory);
fake_url_fetcher_factory_.reset(
new net::FakeURLFetcherFactory(default_url_fetcher_factory_.get()));
web_data_service_ = WebDataServiceFactory::GetForProfile(
GetBrowser()->profile(), Profile::EXPLICIT_ACCESS);
favicon_service_ = FaviconServiceFactory::GetForProfile(
GetBrowser()->profile(), Profile::EXPLICIT_ACCESS);
controller_ = WebIntentPickerController::FromWebContents(
chrome::GetActiveWebContents(GetBrowser()));
SetupMockPicker();
controller_->set_model_observer(&picker_);
picker_.delegate_ = controller_;
CreateFakeIcon();
}
virtual void SetupMockPicker() {
controller_->set_picker(&picker_);
}
virtual Browser* GetBrowser() { return browser(); }
void AddWebIntentService(const string16& action, const GURL& service_url) {
webkit_glue::WebIntentServiceData service;
service.action = action;
service.type = kType1;
service.service_url = service_url;
web_data_service_->AddWebIntentService(service);
}
void AddCWSExtensionServiceEmpty(const string16& action) {
GURL cws_query_url = CWSIntentsRegistry::BuildQueryURL(action, kType1);
fake_url_fetcher_factory_->SetFakeResponse(cws_query_url.spec(),
kCWSResponseEmpty, true);
}
void AddCWSExtensionServiceWithResult(const std::string& extension_id,
const string16& action,
const string16& type) {
GURL cws_query_url = CWSIntentsRegistry::BuildQueryURL(action, type);
std::string icon_url;
std::string escaped_action = net::EscapePath(UTF16ToUTF8(action));
base::SStringPrintf(&icon_url, kCWSFakeIconURLFormat,
escaped_action.c_str());
std::string response;
base::SStringPrintf(&response, kCWSResponseResultFormat,
extension_id.c_str(),
UTF16ToUTF8(action).c_str(), UTF16ToUTF8(type).c_str(),
icon_url.c_str());
fake_url_fetcher_factory_->SetFakeResponse(cws_query_url.spec(), response,
true);
fake_url_fetcher_factory_->SetFakeResponse(icon_url, icon_response_,
true);
}
void SetDefaultService(const string16& action,
const std::string& url,
int64 service_hash) {
DefaultWebIntentService default_service;
default_service.action = action;
default_service.type = kType1;
default_service.user_date = 1000000;
default_service.suppression = service_hash;
default_service.service_url = url;
web_data_service_->AddDefaultWebIntentService(default_service);
}
int64 DigestServices() {
return controller_->DigestServices();
}
void OnSendReturnMessage(
webkit_glue::WebIntentReplyType reply_type) {
controller_->OnSendReturnMessage(reply_type);
}
void OnServiceChosen(
const GURL& url,
webkit_glue::WebIntentServiceData::Disposition disposition) {
controller_->OnServiceChosen(url, disposition);
}
void OnCancelled() {
controller_->OnUserCancelledPickerDialog();
}
void OnExtensionInstallRequested(const std::string& extension_id) {
controller_->OnExtensionInstallRequested(extension_id);
}
void CreateFakeIcon() {
gfx::Image image(gfx::test::CreateImage());
std::vector<unsigned char> image_data;
bool result = gfx::PNGEncodedDataFromImage(image, &image_data);
DCHECK(result);
std::copy(image_data.begin(), image_data.end(),
std::back_inserter(icon_response_));
}
WebIntentPickerMock picker_;
scoped_refptr<WebDataService> web_data_service_;
FaviconService* favicon_service_;
WebIntentPickerController* controller_;
scoped_ptr<DummyURLFetcherFactory> default_url_fetcher_factory_;
scoped_ptr<net::FakeURLFetcherFactory> fake_url_fetcher_factory_;
std::string icon_response_;
};
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest, ChooseService) {
AddWebIntentService(kAction1, kServiceURL1);
AddWebIntentService(kAction1, kServiceURL2);
AddCWSExtensionServiceEmpty(kAction1);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType1);
picker_.Wait();
EXPECT_EQ(2, picker_.num_installed_services_);
EXPECT_EQ(0, picker_.num_icons_changed_);
OnServiceChosen(kServiceURL2,
webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW);
ASSERT_EQ(2, browser()->tab_count());
EXPECT_EQ(GURL(kServiceURL2),
chrome::GetActiveWebContents(browser())->GetURL());
EXPECT_TRUE(GetWindowDispositionTarget(
WebIntentPickerController::FromWebContents(
chrome::GetActiveWebContents(browser()))));
EXPECT_TRUE(dispatcher.dispatched_);
OnSendReturnMessage(webkit_glue::WEB_INTENT_REPLY_SUCCESS);
ASSERT_EQ(1, browser()->tab_count());
}
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
FetchExtensionIcon) {
AddWebIntentService(kAction1, kServiceURL1);
AddWebIntentService(kAction1, kServiceURL2);
AddCWSExtensionServiceWithResult(kDummyExtensionId, kAction1, kType1);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType1);
picker_.Wait();
EXPECT_EQ(2, picker_.num_installed_services_);
EXPECT_EQ(0, picker_.num_icons_changed_);
EXPECT_EQ(1, picker_.num_extension_icons_changed_);
}
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest, OpenCancelOpen) {
AddWebIntentService(kAction1, kServiceURL1);
AddWebIntentService(kAction1, kServiceURL2);
AddCWSExtensionServiceEmpty(kAction1);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType1);
picker_.Wait();
OnCancelled();
controller_->ShowDialog(kAction1, kType1);
OnCancelled();
}
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
CloseTargetTabReturnToSource) {
AddWebIntentService(kAction1, kServiceURL1);
AddCWSExtensionServiceEmpty(kAction1);
GURL original = chrome::GetActiveWebContents(browser())->GetURL();
// Open a new page, but keep focus on original.
ui_test_utils::NavigateToURLWithDisposition(
browser(), GURL(chrome::kChromeUINewTabURL), NEW_BACKGROUND_TAB,
ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
ASSERT_EQ(2, browser()->tab_count());
EXPECT_EQ(original, chrome::GetActiveWebContents(browser())->GetURL());
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType1);
picker_.Wait();
EXPECT_EQ(1, picker_.num_installed_services_);
OnServiceChosen(kServiceURL1,
webkit_glue::WebIntentServiceData::DISPOSITION_WINDOW);
ASSERT_EQ(3, browser()->tab_count());
EXPECT_EQ(GURL(kServiceURL1),
chrome::GetActiveWebContents(browser())->GetURL());
EXPECT_TRUE(dispatcher.dispatched_);
OnSendReturnMessage(webkit_glue::WEB_INTENT_REPLY_SUCCESS);
ASSERT_EQ(2, browser()->tab_count());
EXPECT_EQ(original, chrome::GetActiveWebContents(browser())->GetURL());
}
class WebIntentPickerControllerIncognitoBrowserTest
: public WebIntentPickerControllerBrowserTest {
public:
WebIntentPickerControllerIncognitoBrowserTest() {}
virtual void SetUpOnMainThread() OVERRIDE {
incognito_browser_ = CreateIncognitoBrowser();
WebIntentPickerControllerBrowserTest::SetUpOnMainThread();
}
virtual Browser* GetBrowser() OVERRIDE { return incognito_browser_; }
int pending_async_count() { return controller_->pending_async_count_; }
private:
Browser* incognito_browser_;
};
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerIncognitoBrowserTest,
ShowDialogShouldntCrash) {
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType1);
// This should do nothing for now.
EXPECT_EQ(0, pending_async_count());
}
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
ExtensionInstallSuccess) {
const char extension_id[] = "ooodacpbmglpoagccnepcbfhfhpdgddn";
AddCWSExtensionServiceWithResult(extension_id, kAction1, kType2);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType2;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType2);
picker_.Wait();
ASSERT_EQ(1, browser()->tab_count());
OnExtensionInstallRequested(extension_id);
picker_.Wait();
EXPECT_EQ(1, picker_.num_extensions_installed_);
const extensions::Extension* extension = browser()->profile()->
GetExtensionService()->GetExtensionById(extension_id, false);
EXPECT_TRUE(extension);
// Installing an extension should also choose it. Since this extension uses
// window disposition, it will create a new tab.
EXPECT_EQ(2, browser()->tab_count());
EXPECT_EQ(0, picker_.num_inline_disposition_);
}
// Tests that inline install of an extension using inline disposition works
// and brings up content as inline content.
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
ExtensionInstallSuccessInline) {
const char extension_id[] = "nnhendkbgefomfgdlnmfhhmihihlljpi";
AddCWSExtensionServiceWithResult(extension_id, kAction1, kType2);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType2;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType2);
picker_.Wait();
OnExtensionInstallRequested(extension_id);
picker_.Wait();
EXPECT_EQ(1, picker_.num_extensions_installed_);
const extensions::Extension* extension = browser()->profile()->
GetExtensionService()->GetExtensionById(extension_id, false);
EXPECT_TRUE(extension);
// Installing an extension should also choose it. Since this extension uses
// inline disposition, it will create no tabs and invoke OnInlineDisposition.
EXPECT_EQ(1, browser()->tab_count());
EXPECT_EQ(1, picker_.num_inline_disposition_);
}
// Test that an explicit intent does not trigger loading intents from the
// registry (skips the picker), and creates the intent service handler
// immediately.
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
ExplicitIntentTest) {
// Install a target service for the explicit intent.
const char extension_id[] = "ooodacpbmglpoagccnepcbfhfhpdgddn";
AddCWSExtensionServiceWithResult(extension_id, kAction1, kType2);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType2;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType2);
picker_.Wait();
OnExtensionInstallRequested(extension_id);
picker_.Wait();
ASSERT_EQ(1, picker_.num_extensions_installed_);
// The intent launches a new tab.
ASSERT_EQ(2, browser()->tab_count());
// Make the controller think nothing is being shown.
picker_.MockClose();
SetupMockPicker();
// Now call the explicit intent.
webkit_glue::WebIntentData explicitIntent;
explicitIntent.action = kAction1;
explicitIntent.type = kType2;
explicitIntent.service = GURL(StringPrintf("%s://%s/%s",
chrome::kExtensionScheme,
extension_id,
"share.html"));
IntentsDispatcherMock dispatcher2(explicitIntent);
controller_->SetIntentsDispatcher(&dispatcher2);
controller_->ShowDialog(kAction1, kType2);
picker_.Wait();
EXPECT_EQ(3, browser()->tab_count());
EXPECT_EQ(0, picker_.num_inline_disposition_);
EXPECT_FALSE(dispatcher2.replied_);
// num_installed_services_ would be 2 if the intent wasn't explicit.
EXPECT_EQ(1, picker_.num_installed_services_);
}
// Test that an explicit intent for non-installed extension won't
// complete.
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
ExplicitIntentNoExtensionTest) {
AddWebIntentService(kAction1, kServiceURL1);
AddWebIntentService(kAction1, kServiceURL2);
AddCWSExtensionServiceWithResult(kDummyExtensionId, kAction1, kType1);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
intent.service = GURL(StringPrintf("%s://%s/%s",
chrome::kExtensionScheme,
kDummyExtensionId,
UTF16ToASCII(kAction1).c_str()));
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType1);
picker_.Wait();
EXPECT_EQ(1, browser()->tab_count());
EXPECT_EQ(0, picker_.num_inline_disposition_);
EXPECT_TRUE(dispatcher.replied_);
// num_installed_services_ would be 2 if the intent wasn't explicit.
EXPECT_EQ(0, picker_.num_installed_services_);
}
// Test that explicit intents won't load non-extensions.
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
ExplicitIntentNonExtensionTest) {
AddWebIntentService(kAction1, kServiceURL1);
AddWebIntentService(kAction1, kServiceURL2);
AddCWSExtensionServiceWithResult(kDummyExtensionId, kAction1, kType1);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
intent.service = GURL("http://www.google.com/");
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
controller_->ShowDialog(kAction1, kType1);
EXPECT_EQ(1, browser()->tab_count());
EXPECT_EQ(0, picker_.num_inline_disposition_);
// num_installed_services_ would be 2 if the intent wasn't explicit.
EXPECT_EQ(0, picker_.num_installed_services_);
EXPECT_TRUE(dispatcher.replied_);
}
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
DefaultsTest) {
AddWebIntentService(kAction1, kServiceURL1);
AddWebIntentService(kAction1, kServiceURL2);
AddCWSExtensionServiceEmpty(kAction1);
// Bring up the picker to get the test-installed services so we can create a
// default with the right defaulting fingerprint.
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
IntentsDispatcherMock dispatcher1(intent);
controller_->SetIntentsDispatcher(&dispatcher1);
controller_->ShowDialog(kAction1, kType1);
picker_.Wait();
int64 service_hash = DigestServices();
SetDefaultService(kAction1, kServiceURL1.spec(), service_hash);
// Reset the picker for the real dispatch.
picker_.MockClose();
SetupMockPicker();
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
ui_test_utils::WindowedTabAddedNotificationObserver new_tab_observer((
content::Source<content::WebContentsDelegate>(browser())));
controller_->ShowDialog(kAction1, kType1);
new_tab_observer.Wait();
EXPECT_EQ(2, picker_.num_installed_services_);
// The tab is shown immediately without needing to call OnServiceChosen.
ASSERT_EQ(2, browser()->tab_count());
EXPECT_EQ(GURL(kServiceURL1),
chrome::GetActiveWebContents(browser())->GetURL());
EXPECT_TRUE(dispatcher.dispatched_);
}
IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest,
DefaultsTestWithOldDefault) {
AddWebIntentService(kAction1, kServiceURL1);
AddWebIntentService(kAction1, kServiceURL2);
AddCWSExtensionServiceEmpty(kAction1);
webkit_glue::WebIntentData intent;
intent.action = kAction1;
intent.type = kType1;
IntentsDispatcherMock dispatcher(intent);
controller_->SetIntentsDispatcher(&dispatcher);
SetDefaultService(kAction1, kServiceURL1.spec(), 0);
controller_->ShowDialog(kAction1, kType1);
picker_.Wait();
EXPECT_EQ(2, picker_.num_installed_services_);
// The found default isn't used immediately because the defaulting
// context has changed.
ASSERT_EQ(1, browser()->tab_count());
EXPECT_FALSE(dispatcher.dispatched_);
}