summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/automation/automation_provider_observers.cc36
-rw-r--r--chrome/browser/automation/automation_provider_observers.h13
-rw-r--r--chrome/browser/browser_encoding_browsertest.cc42
-rw-r--r--chrome/browser/download/save_page_browsertest.cc113
-rw-r--r--content/browser/download/download_manager_impl.cc6
-rw-r--r--content/browser/download/download_manager_impl.h3
-rw-r--r--content/browser/download/save_package.cc11
-rw-r--r--content/public/browser/download_manager.h4
-rw-r--r--content/public/browser/notification_types.h7
-rw-r--r--content/public/test/test_utils.cc19
-rw-r--r--content/public/test/test_utils.h9
11 files changed, 196 insertions, 67 deletions
diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc
index 051bf68..004398b 100644
--- a/chrome/browser/automation/automation_provider_observers.cc
+++ b/chrome/browser/automation/automation_provider_observers.cc
@@ -1707,31 +1707,31 @@ void OmniboxAcceptNotificationObserver::Observe(
}
SavePackageNotificationObserver::SavePackageNotificationObserver(
- DownloadManager* download_manager,
+ content::DownloadManager* download_manager,
AutomationProvider* automation,
IPC::Message* reply_message)
- : automation_(automation->AsWeakPtr()),
+ : download_manager_(download_manager),
+ automation_(automation->AsWeakPtr()),
reply_message_(reply_message) {
- content::Source<DownloadManager> source(download_manager);
- registrar_.Add(this, content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
- source);
+ download_manager_->AddObserver(this);
}
-SavePackageNotificationObserver::~SavePackageNotificationObserver() {}
+SavePackageNotificationObserver::~SavePackageNotificationObserver() {
+ download_manager_->RemoveObserver(this);
+}
-void SavePackageNotificationObserver::Observe(
- int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- if (type == content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED) {
- if (automation_) {
- AutomationJSONReply(automation_,
- reply_message_.release()).SendSuccess(NULL);
- }
- delete this;
- } else {
- NOTREACHED();
+void SavePackageNotificationObserver::OnSavePackageSuccessfullyFinished(
+ content::DownloadManager* manager, content::DownloadItem* item) {
+ if (automation_) {
+ AutomationJSONReply(automation_,
+ reply_message_.release()).SendSuccess(NULL);
}
+ delete this;
+}
+
+void SavePackageNotificationObserver::ManagerGoingDown(
+ content::DownloadManager* manager) {
+ delete this;
}
PageSnapshotTaker::PageSnapshotTaker(AutomationProvider* automation,
diff --git a/chrome/browser/automation/automation_provider_observers.h b/chrome/browser/automation/automation_provider_observers.h
index 6ba85ae..fec988a 100644
--- a/chrome/browser/automation/automation_provider_observers.h
+++ b/chrome/browser/automation/automation_provider_observers.h
@@ -1246,20 +1246,21 @@ class OmniboxAcceptNotificationObserver : public content::NotificationObserver {
};
// Allows the automation provider to wait for a save package notification.
-class SavePackageNotificationObserver : public content::NotificationObserver {
+class SavePackageNotificationObserver
+: public content::DownloadManager::Observer {
public:
SavePackageNotificationObserver(content::DownloadManager* download_manager,
AutomationProvider* automation,
IPC::Message* reply_message);
virtual ~SavePackageNotificationObserver();
- // Overridden from content::NotificationObserver:
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
+ // Overridden from content::DownloadManager::Observer:
+ virtual void OnSavePackageSuccessfullyFinished(
+ content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE;
+ virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE;
private:
- content::NotificationRegistrar registrar_;
+ content::DownloadManager* download_manager_;
base::WeakPtr<AutomationProvider> automation_;
scoped_ptr<IPC::Message> reply_message_;
diff --git a/chrome/browser/browser_encoding_browsertest.cc b/chrome/browser/browser_encoding_browsertest.cc
index 6b292bc..8c5fe94 100644
--- a/chrome/browser/browser_encoding_browsertest.cc
+++ b/chrome/browser/browser_encoding_browsertest.cc
@@ -16,6 +16,7 @@
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/download_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"
@@ -65,6 +66,37 @@ const EncodingTestData kEncodingTestDatas[] = {
{ "windows-1258.html", "windows-1258" }
};
+class SavePackageFinishedObserver : public content::DownloadManager::Observer {
+ public:
+ SavePackageFinishedObserver(content::DownloadManager* manager,
+ const base::Closure& callback)
+ : download_manager_(manager),
+ callback_(callback) {
+ download_manager_->AddObserver(this);
+ }
+
+ virtual ~SavePackageFinishedObserver() {
+ if (download_manager_)
+ download_manager_->RemoveObserver(this);
+ }
+
+ // DownloadManager::Observer:
+ virtual void OnSavePackageSuccessfullyFinished(
+ content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE {
+ callback_.Run();
+ }
+ virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE {
+ download_manager_->RemoveObserver(this);
+ download_manager_ = NULL;
+ }
+
+ private:
+ content::DownloadManager* download_manager_;
+ base::Closure callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(SavePackageFinishedObserver);
+};
+
} // namespace
using content::BrowserThread;
@@ -86,13 +118,15 @@ class BrowserEncodingTest
// We save the page as way of complete HTML file, which requires a directory
// name to save sub resources in it. Although this test file does not have
// sub resources, but the directory name is still required.
- content::WindowedNotificationObserver observer(
- content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
- content::NotificationService::AllSources());
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
chrome::GetActiveWebContents(browser())->SavePage(
full_file_name, temp_sub_resource_dir_,
content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML);
- observer.Wait();
+ loop_runner->Run();
FilePath expected_file_name = ui_test_utils::GetTestFilePath(
FilePath(kTestDir), expected);
diff --git a/chrome/browser/download/save_page_browsertest.cc b/chrome/browser/download/save_page_browsertest.cc
index 166a039..43c8781 100644
--- a/chrome/browser/download/save_page_browsertest.cc
+++ b/chrome/browser/download/save_page_browsertest.cc
@@ -53,6 +53,8 @@ using content::DownloadManager;
using content::URLRequestMockHTTPJob;
using content::WebContents;
+namespace {
+
// Waits for an item record in the downloads database to match |filter|. See
// DownloadStoredProperly() below for an example filter.
class DownloadPersistedObserver : public DownloadHistory::Observer {
@@ -240,6 +242,37 @@ class DownloadItemCreatedObserver : public DownloadManager::Observer {
DISALLOW_COPY_AND_ASSIGN(DownloadItemCreatedObserver);
};
+class SavePackageFinishedObserver : public content::DownloadManager::Observer {
+ public:
+ SavePackageFinishedObserver(content::DownloadManager* manager,
+ const base::Closure& callback)
+ : download_manager_(manager),
+ callback_(callback) {
+ download_manager_->AddObserver(this);
+ }
+
+ virtual ~SavePackageFinishedObserver() {
+ if (download_manager_)
+ download_manager_->RemoveObserver(this);
+ }
+
+ // DownloadManager::Observer:
+ virtual void OnSavePackageSuccessfullyFinished(
+ content::DownloadManager* manager, content::DownloadItem* item) OVERRIDE {
+ callback_.Run();
+ }
+ virtual void ManagerGoingDown(content::DownloadManager* manager) OVERRIDE {
+ download_manager_->RemoveObserver(this);
+ download_manager_ = NULL;
+ }
+
+ private:
+ content::DownloadManager* download_manager_;
+ base::Closure callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(SavePackageFinishedObserver);
+};
+
class SavePageBrowserTest : public InProcessBrowserTest {
public:
SavePageBrowserTest() {}
@@ -283,14 +316,9 @@ class SavePageBrowserTest : public InProcessBrowserTest {
// Returns true if and when there was a single download created, and its url
// is |expected_url|.
- bool WaitForSavePackageToFinish(
+ bool VerifySavePackageExpectations(
Browser* browser,
const GURL& expected_url) const {
- content::WindowedNotificationObserver observer(
- content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
- content::NotificationService::AllSources());
- observer.Wait();
-
// Generally, there should only be one download item created
// in all of these tests. If it's already here, grab it; if not,
// wait for it to show up.
@@ -307,9 +335,7 @@ class SavePageBrowserTest : public InProcessBrowserTest {
return false;
DownloadItem* download_item(items[0]);
- return ((expected_url == download_item->GetOriginalUrl()) &&
- (expected_url == content::Details<DownloadItem>(
- observer.details()).ptr()->GetOriginalUrl()));
+ return (expected_url == download_item->GetOriginalUrl());
}
// Note on synchronization:
@@ -358,9 +384,15 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveHTMLOnly) {
DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
&DownloadStoredProperly, url, full_file_name, 1,
DownloadItem::COMPLETE));
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- ASSERT_TRUE(WaitForSavePackageToFinish(browser(), url));
+ loop_runner->Run();
+ ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
persisted.WaitForPersisted();
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
EXPECT_TRUE(file_util::PathExists(full_file_name));
@@ -454,9 +486,15 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveViewSourceHTMLOnly) {
DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
&DownloadStoredProperly, actual_page_url, full_file_name, 1,
DownloadItem::COMPLETE));
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- ASSERT_TRUE(WaitForSavePackageToFinish(browser(), actual_page_url));
+ loop_runner->Run();
+ ASSERT_TRUE(VerifySavePackageExpectations(browser(), actual_page_url));
persisted.WaitForPersisted();
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
@@ -482,9 +520,15 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_SaveCompleteHTML) {
DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
&DownloadStoredProperly, url, full_file_name, 3,
DownloadItem::COMPLETE));
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
- ASSERT_TRUE(WaitForSavePackageToFinish(browser(), url));
+ loop_runner->Run();
+ ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
persisted.WaitForPersisted();
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
@@ -530,10 +574,16 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest,
// Save the page before completion.
FilePath full_file_name, dir;
GetDestinationPaths("b", &full_file_name, &dir);
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(incognito->profile()),
+ loop_runner->QuitClosure());
ASSERT_TRUE(GetCurrentTab(incognito)->SavePage(
full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
- ASSERT_TRUE(WaitForSavePackageToFinish(incognito, url));
+ loop_runner->Run();
+ ASSERT_TRUE(VerifySavePackageExpectations(incognito, url));
// Confirm download shelf is visible.
EXPECT_TRUE(incognito->window()->IsDownloadShelfVisible());
@@ -566,10 +616,16 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_FileNameFromPageTitle) {
DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
&DownloadStoredProperly, url, full_file_name, 3,
DownloadItem::COMPLETE));
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
ASSERT_TRUE(GetCurrentTab(browser())->SavePage(
full_file_name, dir, content::SAVE_PAGE_TYPE_AS_COMPLETE_HTML));
- ASSERT_TRUE(WaitForSavePackageToFinish(browser(), url));
+ loop_runner->Run();
+ ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
persisted.WaitForPersisted();
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
@@ -601,10 +657,16 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, MAYBE_RemoveFromList) {
DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
&DownloadStoredProperly, url, full_file_name, 1,
DownloadItem::COMPLETE));
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
ASSERT_TRUE(GetCurrentTab(browser())->SavePage(full_file_name, dir,
content::SAVE_PAGE_TYPE_AS_ONLY_HTML));
- ASSERT_TRUE(WaitForSavePackageToFinish(browser(), url));
+ loop_runner->Run();
+ ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
persisted.WaitForPersisted();
EXPECT_TRUE(browser()->window()->IsDownloadShelfVisible());
@@ -645,11 +707,13 @@ IN_PROC_BROWSER_TEST_F(SavePageBrowserTest, CleanFilenameFromPageTitle) {
ui_test_utils::NavigateToURL(browser(), url);
SavePackageFilePicker::SetShouldPromptUser(false);
- content::WindowedNotificationObserver observer(
- content::NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
- content::NotificationService::AllSources());
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
chrome::SavePage(browser());
- observer.Wait();
+ loop_runner->Run();
EXPECT_TRUE(file_util::PathExists(full_file_name));
@@ -688,8 +752,14 @@ IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest, SavePageAsMHTML) {
DownloadPersistedObserver persisted(browser()->profile(), base::Bind(
&DownloadStoredProperly, url, full_file_name, -1,
DownloadItem::COMPLETE));
+ scoped_refptr<content::MessageLoopRunner> loop_runner(
+ new content::MessageLoopRunner);
+ SavePackageFinishedObserver observer(
+ content::BrowserContext::GetDownloadManager(browser()->profile()),
+ loop_runner->QuitClosure());
chrome::SavePage(browser());
- ASSERT_TRUE(WaitForSavePackageToFinish(browser(), url));
+ loop_runner->Run();
+ ASSERT_TRUE(VerifySavePackageExpectations(browser(), url));
persisted.WaitForPersisted();
EXPECT_TRUE(file_util::PathExists(full_file_name));
@@ -697,3 +767,6 @@ IN_PROC_BROWSER_TEST_F(SavePageAsMHTMLBrowserTest, SavePageAsMHTML) {
EXPECT_TRUE(file_util::GetFileSize(full_file_name, &actual_file_size));
EXPECT_LE(kFileSizeMin, actual_file_size);
}
+
+} // namespace
+
diff --git a/content/browser/download/download_manager_impl.cc b/content/browser/download/download_manager_impl.cc
index 35b43cf..1d028c3 100644
--- a/content/browser/download/download_manager_impl.cc
+++ b/content/browser/download/download_manager_impl.cc
@@ -485,6 +485,12 @@ DownloadItemImpl* DownloadManagerImpl::CreateSavePackageDownloadItem(
return download_item;
}
+void DownloadManagerImpl::OnSavePackageSuccessfullyFinished(
+ DownloadItem* download_item) {
+ FOR_EACH_OBSERVER(Observer, observers_,
+ OnSavePackageSuccessfullyFinished(this, download_item));
+}
+
void DownloadManagerImpl::CancelDownload(int32 download_id) {
DownloadItem* download = GetDownload(download_id);
if (!download || !download->IsInProgress())
diff --git a/content/browser/download/download_manager_impl.h b/content/browser/download/download_manager_impl.h
index de7ad5d..a967c55 100644
--- a/content/browser/download/download_manager_impl.h
+++ b/content/browser/download/download_manager_impl.h
@@ -47,6 +47,9 @@ class CONTENT_EXPORT DownloadManagerImpl : public DownloadManager,
const std::string& mime_type,
DownloadItem::Observer* observer);
+ // Notifies DownloadManager about a successful completion of |download_item|.
+ void OnSavePackageSuccessfullyFinished(DownloadItem* download_item);
+
// DownloadManager functions.
virtual void SetDelegate(DownloadManagerDelegate* delegate) OVERRIDE;
virtual DownloadManagerDelegate* GetDelegate() const OVERRIDE;
diff --git a/content/browser/download/save_package.cc b/content/browser/download/save_package.cc
index 1be1da4..c074d1e 100644
--- a/content/browser/download/save_package.cc
+++ b/content/browser/download/save_package.cc
@@ -1392,16 +1392,7 @@ void SavePackage::FinalizeDownloadEntry() {
DCHECK(download_);
DCHECK(download_manager_);
- NotificationService::current()->Notify(
- NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
- // We use the DownloadManager as the source as that's a
- // central SavePackage related location that observers can
- // get to if they want to wait for notifications for a
- // particular BrowserContext. Alternatively, we could make
- // it come from the WebContents, which would be more specific
- // but less useful to (current) customers.
- Source<DownloadManager>(download_manager_),
- Details<DownloadItem>(download_));
+ download_manager_->OnSavePackageSuccessfullyFinished(download_);
StopObservation();
}
diff --git a/content/public/browser/download_manager.h b/content/public/browser/download_manager.h
index 14dfac4..e7b03de 100644
--- a/content/public/browser/download_manager.h
+++ b/content/public/browser/download_manager.h
@@ -84,6 +84,10 @@ class CONTENT_EXPORT DownloadManager
virtual void OnDownloadCreated(
DownloadManager* manager, DownloadItem* item) {}
+ // A SavePackage has successfully finished.
+ virtual void OnSavePackageSuccessfullyFinished(
+ DownloadManager* manager, DownloadItem* item) {}
+
// Called when the DownloadManager is being destroyed to prevent Observers
// from calling back to a stale pointer.
virtual void ManagerGoingDown(DownloadManager* manager) {}
diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h
index b70d05e..281a960 100644
--- a/content/public/browser/notification_types.h
+++ b/content/public/browser/notification_types.h
@@ -351,12 +351,7 @@ enum NotificationType {
// in a Details<ChildProcessData>.
NOTIFICATION_CHILD_INSTANCE_CREATED,
- // Saved Pages -------------------------------------------------------------
-
- // Sent when a SavePackage finishes successfully. The source is the
- // SavePackage, and Details are a GURL containing address of downloaded
- // page.
- NOTIFICATION_SAVE_PACKAGE_SUCCESSFULLY_FINISHED,
+ // Miscellaneous -------------------------------------------------------------
// Sent before the repost form warning is brought up.
// The source is a NavigationController.
diff --git a/content/public/test/test_utils.cc b/content/public/test/test_utils.cc
index 2e6b375..6d13f5a 100644
--- a/content/public/test/test_utils.cc
+++ b/content/public/test/test_utils.cc
@@ -94,13 +94,22 @@ base::Closure GetQuitTaskForRunLoop(base::RunLoop* run_loop) {
kNumQuitDeferrals);
}
-MessageLoopRunner::MessageLoopRunner() {
+MessageLoopRunner::MessageLoopRunner()
+ : loop_running_(false),
+ quit_closure_called_(false) {
}
MessageLoopRunner::~MessageLoopRunner() {
}
void MessageLoopRunner::Run() {
+ // Do not run the message loop if our quit closure has already been called.
+ // This helps in scenarios where the closure has a chance to run before
+ // we Run explicitly.
+ if (quit_closure_called_)
+ return;
+
+ loop_running_ = true;
RunThisRunLoop(&run_loop_);
}
@@ -109,7 +118,13 @@ base::Closure MessageLoopRunner::QuitClosure() {
}
void MessageLoopRunner::Quit() {
- GetQuitTaskForRunLoop(&run_loop_).Run();
+ quit_closure_called_ = true;
+
+ // Only run the quit task if we are running the message loop.
+ if (loop_running_) {
+ GetQuitTaskForRunLoop(&run_loop_).Run();
+ loop_running_ = false;
+ }
}
WindowedNotificationObserver::WindowedNotificationObserver(
diff --git a/content/public/test/test_utils.h b/content/public/test/test_utils.h
index f992b46..69325d2 100644
--- a/content/public/test/test_utils.h
+++ b/content/public/test/test_utils.h
@@ -48,7 +48,8 @@ class MessageLoopRunner : public base::RefCounted<MessageLoopRunner> {
public:
MessageLoopRunner();
- // Run the current MessageLoop.
+ // Run the current MessageLoop unless the quit closure
+ // has already been called.
void Run();
// Quit the matching call to Run (nested MessageLoops are unaffected).
@@ -65,6 +66,12 @@ class MessageLoopRunner : public base::RefCounted<MessageLoopRunner> {
friend class base::RefCounted<MessageLoopRunner>;
~MessageLoopRunner();
+ // True when the message loop is running.
+ bool loop_running_;
+
+ // True after closure returned by |QuitClosure| has been called.
+ bool quit_closure_called_;
+
base::RunLoop run_loop_;
DISALLOW_COPY_AND_ASSIGN(MessageLoopRunner);