summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/instant/instant_browsertest.cc71
-rw-r--r--chrome/browser/instant/instant_controller.cc4
-rw-r--r--chrome/browser/instant/instant_loader.cc16
-rw-r--r--chrome/browser/instant/instant_loader.h7
-rw-r--r--chrome/test/data/instant/download.zip1
-rw-r--r--chrome/test/data/instant/download.zip.mock-http-headers5
6 files changed, 102 insertions, 2 deletions
diff --git a/chrome/browser/instant/instant_browsertest.cc b/chrome/browser/instant/instant_browsertest.cc
index 26d4006..d0915d4 100644
--- a/chrome/browser/instant/instant_browsertest.cc
+++ b/chrome/browser/instant/instant_browsertest.cc
@@ -29,6 +29,45 @@
#define EXPECT_STR_EQ(ascii, utf16) \
EXPECT_EQ(ASCIIToWide(ascii), UTF16ToWide(utf16))
+namespace {
+
+// Wait for DOWNLOAD_INITIATED.
+class DownloadNotificationObserver : public NotificationObserver {
+ public:
+ DownloadNotificationObserver() : running_(false), fired_(false) {
+ registrar_.Add(this, NotificationType::DOWNLOAD_INITIATED,
+ NotificationService::AllSources());
+ }
+
+ void Run() {
+ if (fired_)
+ return;
+
+ running_ = true;
+ ui_test_utils::RunMessageLoop();
+ running_ = false;
+ }
+
+ bool fired() const { return fired_; }
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) OVERRIDE {
+ fired_ = true;
+ if (running_)
+ MessageLoopForUI::current()->Quit();
+ }
+
+ private:
+ bool running_;
+ bool fired_;
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(DownloadNotificationObserver);
+};
+
+} // namespace
+
class InstantTest : public InProcessBrowserTest {
public:
InstantTest()
@@ -740,3 +779,35 @@ IN_PROC_BROWSER_TEST_F(InstantTest, DontCrashOnBlockedJS) {
NotificationType::INSTANT_SUPPORT_DETERMINED);
// As long as we get the notification we're good (the renderer didn't crash).
}
+
+IN_PROC_BROWSER_TEST_F(InstantTest, DownloadOnEnter) {
+ ASSERT_TRUE(test_server()->Start());
+ EnableInstant();
+ ASSERT_NO_FATAL_FAILURE(SetupInstantProvider("search.html"));
+ ASSERT_NO_FATAL_FAILURE(FindLocationBar());
+ GURL url(test_server()->GetURL("files/instant/empty.html"));
+ location_bar_->location_entry()->SetUserText(UTF8ToUTF16(url.spec()));
+ ASSERT_NO_FATAL_FAILURE(WaitForPreviewToNavigate(true));
+ url = test_server()->GetURL("files/instant/download.zip");
+ location_bar_->location_entry()->SetUserText(UTF8ToUTF16(url.spec()));
+ // Wait for the load to fail (because instant disables downloads).
+ ui_test_utils::WaitForNotification(
+ NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR);
+
+ DownloadNotificationObserver download_observer;
+ ASSERT_NO_FATAL_FAILURE(SendKey(ui::VKEY_RETURN));
+ download_observer.Run();
+ // Pressing enter should initiate a download.
+ EXPECT_TRUE(download_observer.fired());
+
+ // And we should end up at about:blank.
+ TabContents* contents = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(contents);
+ EXPECT_EQ("about:blank",
+ contents->controller().GetLastCommittedEntry()->url().spec());
+ if (contents->controller().pending_entry()) {
+ // If there is a pending entry, the url should correspond to the download.
+ EXPECT_EQ(url.spec(),
+ contents->controller().pending_entry()->url().spec());
+ }
+}
diff --git a/chrome/browser/instant/instant_controller.cc b/chrome/browser/instant/instant_controller.cc
index 4949783..75686a0 100644
--- a/chrome/browser/instant/instant_controller.cc
+++ b/chrome/browser/instant/instant_controller.cc
@@ -228,7 +228,9 @@ void InstantController::DestroyPreviewContentsAndLeaveActive() {
bool InstantController::IsCurrent() {
return loader_manager_.get() && loader_manager_->active_loader() &&
- loader_manager_->active_loader()->ready() && !update_timer_.IsRunning();
+ loader_manager_->active_loader()->ready() &&
+ !loader_manager_->active_loader()->needs_reload() &&
+ !update_timer_.IsRunning();
}
void InstantController::CommitCurrentPreview(InstantCommitType type) {
diff --git a/chrome/browser/instant/instant_loader.cc b/chrome/browser/instant/instant_loader.cc
index 167a84f..6eda28f 100644
--- a/chrome/browser/instant/instant_loader.cc
+++ b/chrome/browser/instant/instant_loader.cc
@@ -27,6 +27,7 @@
#include "content/browser/renderer_host/render_widget_host_view.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/browser/tab_contents/navigation_entry.h"
+#include "content/browser/tab_contents/provisional_load_details.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/tab_contents/tab_contents_delegate.h"
#include "content/browser/tab_contents/tab_contents_view.h"
@@ -262,6 +263,8 @@ InstantLoader::TabContentsDelegateImpl::TabContentsDelegateImpl(
DCHECK(loader->preview_contents());
registrar_.Add(this, NotificationType::INTERSTITIAL_ATTACHED,
Source<TabContents>(loader->preview_contents()->tab_contents()));
+ registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
+ Source<NavigationController>(&loader->preview_contents()->controller()));
}
void InstantLoader::TabContentsDelegateImpl::PrepareForNewLoad() {
@@ -364,6 +367,14 @@ void InstantLoader::TabContentsDelegateImpl::Observe(
const NotificationSource& source,
const NotificationDetails& details) {
switch (type.value) {
+ case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR:
+ if (Details<ProvisionalLoadDetails>(details)->url() == loader_->url_) {
+ // This typically happens with downloads (which are disabled with
+ // instant active). To ensure the download happens when the user presses
+ // enter we set needs_reload_ to true, which triggers a reload.
+ loader_->needs_reload_ = true;
+ }
+ break;
case NotificationType::RENDER_WIDGET_HOST_DID_PAINT:
UnregisterForPaintNotifications();
PreviewPainted();
@@ -495,6 +506,7 @@ void InstantLoader::TabContentsDelegateImpl::DragEnded() {
}
bool InstantLoader::TabContentsDelegateImpl::CanDownload(int request_id) {
+ // Downloads are disabled.
return false;
}
@@ -580,7 +592,8 @@ InstantLoader::InstantLoader(InstantLoaderDelegate* delegate, TemplateURLID id)
template_url_id_(id),
ready_(false),
last_transition_type_(PageTransition::LINK),
- verbatim_(false) {
+ verbatim_(false),
+ needs_reload_(false) {
}
InstantLoader::~InstantLoader() {
@@ -632,6 +645,7 @@ void InstantLoader::Update(TabContentsWrapper* tab_contents,
user_text_ = new_user_text;
verbatim_ = verbatim;
last_suggestion_.clear();
+ needs_reload_ = false;
bool created_preview_contents = preview_contents_.get() == NULL;
if (created_preview_contents)
diff --git a/chrome/browser/instant/instant_loader.h b/chrome/browser/instant/instant_loader.h
index d6d9796..e0ea0fe 100644
--- a/chrome/browser/instant/instant_loader.h
+++ b/chrome/browser/instant/instant_loader.h
@@ -81,6 +81,10 @@ class InstantLoader : public NotificationObserver {
// Returns true if the preview TabContents is ready to be shown.
bool ready() const { return ready_; }
+ // Returns true if the url needs to be reloaded. This is set to true for
+ // downloads.
+ bool needs_reload() const { return needs_reload_; }
+
const GURL& url() const { return url_; }
bool verbatim() const { return verbatim_; }
@@ -190,6 +194,9 @@ class InstantLoader : public NotificationObserver {
// Last value of verbatim passed to |Update|.
bool verbatim_;
+ // True if the page needs to be reloaded.
+ bool needs_reload_;
+
DISALLOW_COPY_AND_ASSIGN(InstantLoader);
};
diff --git a/chrome/test/data/instant/download.zip b/chrome/test/data/instant/download.zip
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/chrome/test/data/instant/download.zip
@@ -0,0 +1 @@
+
diff --git a/chrome/test/data/instant/download.zip.mock-http-headers b/chrome/test/data/instant/download.zip.mock-http-headers
new file mode 100644
index 0000000..ef07401
--- /dev/null
+++ b/chrome/test/data/instant/download.zip.mock-http-headers
@@ -0,0 +1,5 @@
+HTTP/1.1 200 OK
+Content-Type: application/zip
+Content-Length: 0
+Date: Mon, 13 Nov 2006 21:38:09 GMT
+Expires: Tue, 14 Nov 2006 19:23:58 GMT