update_engine: Migrate time-based glib main loop calls to MessageLoop.

This patch replaces most calls to g_idle_add* and g_timeout_add* with
the equivalent MessageLoop::Post*Task(). To maintain compatibility with
unittests running the main loop and doing I/O we instantiate a
GlibMessageLoop for those tests.

BUG=chromium:499886
TEST=unittests still pass.

Change-Id: Ic87ba69bc47391ac3c36d1bfc3ca28d069666af1
Reviewed-on: https://chromium-review.googlesource.com/281197
Reviewed-by: Alex Vakulenko <[email protected]>
Tested-by: Alex Deymo <[email protected]>
Commit-Queue: Alex Deymo <[email protected]>
Trybot-Ready: Alex Deymo <[email protected]>
diff --git a/update_attempter_unittest.cc b/update_attempter_unittest.cc
index 6ef1d7a..41a8232 100644
--- a/update_attempter_unittest.cc
+++ b/update_attempter_unittest.cc
@@ -9,7 +9,11 @@
 #include <memory>
 
 #include <base/files/file_util.h>
+#include <chromeos/bind_lambda.h>
 #include <chromeos/dbus/service_constants.h>
+#include <chromeos/message_loops/glib_message_loop.h>
+#include <chromeos/message_loops/message_loop.h>
+#include <chromeos/message_loops/message_loop_utils.h>
 #include <gtest/gtest.h>
 #include <policy/libpolicy.h>
 #include <policy/mock_device_policy.h>
@@ -33,6 +37,7 @@
 
 using base::Time;
 using base::TimeDelta;
+using chromeos::MessageLoop;
 using std::string;
 using std::unique_ptr;
 using testing::A;
@@ -84,7 +89,7 @@
   bool schedule_updates_called() const { return schedule_updates_called_; }
 
   // Need to expose forced_omaha_url_ so we can test it.
-  const std::string& forced_omaha_url() const { return forced_omaha_url_; }
+  const string& forced_omaha_url() const { return forced_omaha_url_; }
 
  private:
   bool schedule_updates_called_ = false;
@@ -96,12 +101,12 @@
   UpdateAttempterTest()
       : attempter_(&fake_system_state_, &dbus_),
         mock_connection_manager(&fake_system_state_),
-        loop_(nullptr),
         fake_dbus_system_bus_(reinterpret_cast<DBusGConnection*>(1)),
         fake_dbus_debugd_proxy_(reinterpret_cast<DBusGProxy*>(2)) {
     // Override system state members.
     fake_system_state_.set_connection_manager(&mock_connection_manager);
     fake_system_state_.set_update_attempter(&attempter_);
+    loop_.SetAsCurrent();
 
     // Finish initializing the attempter.
     attempter_.Init();
@@ -120,7 +125,7 @@
     EXPECT_NE(nullptr, attempter_.system_state_);
     EXPECT_EQ(0, attempter_.http_response_code_);
     EXPECT_EQ(utils::kCpuSharesNormal, attempter_.shares_);
-    EXPECT_EQ(nullptr, attempter_.manage_shares_source_);
+    EXPECT_EQ(MessageLoop::kTaskIdNull, attempter_.manage_shares_id_);
     EXPECT_FALSE(attempter_.download_active_);
     EXPECT_EQ(UPDATE_STATUS_IDLE, attempter_.status_);
     EXPECT_EQ(0.0, attempter_.download_progress_);
@@ -160,52 +165,26 @@
 
   void TearDown() override {
     test_utils::RecursiveUnlinkDir(test_dir_);
+    EXPECT_EQ(0, MessageLoopRunMaxIterations(&loop_, 1));
   }
 
-  void QuitMainLoop();
-  static gboolean StaticQuitMainLoop(gpointer data);
+ public:
+  void ScheduleQuitMainLoop();
 
+  // Callbacks to run the different tests from the main loop.
   void UpdateTestStart();
   void UpdateTestVerify();
-  void RollbackTestStart(bool enterprise_rollback,
-                         bool valid_slot);
+  void RollbackTestStart(bool enterprise_rollback, bool valid_slot);
   void RollbackTestVerify();
-  static gboolean StaticUpdateTestStart(gpointer data);
-  static gboolean StaticUpdateTestVerify(gpointer data);
-  static gboolean StaticRollbackTestStart(gpointer data);
-  static gboolean StaticInvalidSlotRollbackTestStart(gpointer data);
-  static gboolean StaticEnterpriseRollbackTestStart(gpointer data);
-  static gboolean StaticRollbackTestVerify(gpointer data);
-
   void PingOmahaTestStart();
-  static gboolean StaticPingOmahaTestStart(gpointer data);
-
   void ReadScatterFactorFromPolicyTestStart();
-  static gboolean StaticReadScatterFactorFromPolicyTestStart(
-      gpointer data);
-
   void DecrementUpdateCheckCountTestStart();
-  static gboolean StaticDecrementUpdateCheckCountTestStart(
-      gpointer data);
-
   void NoScatteringDoneDuringManualUpdateTestStart();
-  static gboolean StaticNoScatteringDoneDuringManualUpdateTestStart(
-      gpointer data);
-
   void P2PNotEnabledStart();
-  static gboolean StaticP2PNotEnabled(gpointer data);
-
   void P2PEnabledStart();
-  static gboolean StaticP2PEnabled(gpointer data);
-
   void P2PEnabledInteractiveStart();
-  static gboolean StaticP2PEnabledInteractive(gpointer data);
-
   void P2PEnabledStartingFailsStart();
-  static gboolean StaticP2PEnabledStartingFails(gpointer data);
-
   void P2PEnabledHousekeepingFailsStart();
-  static gboolean StaticP2PEnabledHousekeepingFails(gpointer data);
 
   bool actual_using_p2p_for_downloading() {
     return actual_using_p2p_for_downloading_;
@@ -214,13 +193,16 @@
     return actual_using_p2p_for_sharing_;
   }
 
+  // TODO(deymo): Replace this with a FakeMessageLoop. Some of these tests use a
+  // real LibcurlHttpFetcher, which still requires a GlibMessageLoop.
+  chromeos::GlibMessageLoop loop_;
+
   FakeSystemState fake_system_state_;
   NiceMock<MockDBusWrapper> dbus_;
   UpdateAttempterUnderTest attempter_;
   NiceMock<MockActionProcessor>* processor_;
   NiceMock<MockPrefs>* prefs_;  // Shortcut to fake_system_state_->mock_prefs().
   NiceMock<MockConnectionManager> mock_connection_manager;
-  GMainLoop* loop_;
   // fake_dbus_xxx pointers will be non-null for comparison purposes, but won't
   // be valid objects so don't try to use them.
   DBusGConnection* fake_dbus_system_bus_;
@@ -232,6 +214,10 @@
   bool actual_using_p2p_for_sharing_;
 };
 
+void UpdateAttempterTest::ScheduleQuitMainLoop() {
+  loop_.PostTask(FROM_HERE, base::Bind([this] { this->loop_.BreakLoop(); }));
+}
+
 TEST_F(UpdateAttempterTest, ActionCompletedDownloadTest) {
   unique_ptr<MockHttpFetcher> fetcher(new MockHttpFetcher("", 0, nullptr));
   fetcher->FailTransfer(503);  // Sets the HTTP response code.
@@ -385,75 +371,6 @@
   EXPECT_EQ(UPDATE_STATUS_REPORTING_ERROR_EVENT, attempter_.status());
 }
 
-void UpdateAttempterTest::QuitMainLoop() {
-  g_main_loop_quit(loop_);
-}
-
-gboolean UpdateAttempterTest::StaticQuitMainLoop(gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->QuitMainLoop();
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticUpdateTestStart(gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->UpdateTestStart();
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticUpdateTestVerify(gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->UpdateTestVerify();
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticRollbackTestStart(gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->RollbackTestStart(
-      false, true);
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticInvalidSlotRollbackTestStart(
-    gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->RollbackTestStart(
-      false, false);
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticEnterpriseRollbackTestStart(gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->RollbackTestStart(
-      true, true);
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticRollbackTestVerify(gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->RollbackTestVerify();
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticPingOmahaTestStart(gpointer data) {
-  reinterpret_cast<UpdateAttempterTest*>(data)->PingOmahaTestStart();
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticReadScatterFactorFromPolicyTestStart(
-    gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->ReadScatterFactorFromPolicyTestStart();
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticDecrementUpdateCheckCountTestStart(
-    gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->DecrementUpdateCheckCountTestStart();
-  return FALSE;
-}
-
-gboolean UpdateAttempterTest::StaticNoScatteringDoneDuringManualUpdateTestStart(
-    gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->NoScatteringDoneDuringManualUpdateTestStart();
-  return FALSE;
-}
-
 namespace {
 // Actions that will be built as part of an update check.
 const string kUpdateActionTypes[] = {  // NOLINT(runtime/string)
@@ -499,7 +416,9 @@
   }
 
   attempter_.Update("", "", "", "", false, false);
-  g_idle_add(&StaticUpdateTestVerify, this);
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::UpdateTestVerify,
+                            base::Unretained(this)));
 }
 
 void UpdateAttempterTest::UpdateTestVerify() {
@@ -516,7 +435,7 @@
   ASSERT_NE(nullptr, download_action);
   EXPECT_EQ(&attempter_, download_action->delegate());
   EXPECT_EQ(UPDATE_STATUS_CHECKING_FOR_UPDATE, attempter_.status());
-  g_main_loop_quit(loop_);
+  loop_.BreakLoop();
 }
 
 void UpdateAttempterTest::RollbackTestStart(
@@ -566,10 +485,12 @@
     EXPECT_CALL(*processor_, StartProcessing());
 
     EXPECT_TRUE(attempter_.Rollback(true));
-    g_idle_add(&StaticRollbackTestVerify, this);
+    loop_.PostTask(FROM_HERE,
+                   base::Bind(&UpdateAttempterTest::RollbackTestVerify,
+                              base::Unretained(this)));
   } else {
     EXPECT_FALSE(attempter_.Rollback(true));
-    g_main_loop_quit(loop_);
+    loop_.BreakLoop();
   }
 }
 
@@ -589,39 +510,38 @@
   EXPECT_EQ(install_plan->install_path, string("/dev/sdz3"));
   EXPECT_EQ(install_plan->kernel_install_path, string("/dev/sdz2"));
   EXPECT_EQ(install_plan->powerwash_required, true);
-  g_main_loop_quit(loop_);
+  loop_.BreakLoop();
 }
 
 TEST_F(UpdateAttempterTest, UpdateTest) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticUpdateTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::UpdateTestStart,
+                            base::Unretained(this)));
+  loop_.Run();
 }
 
 TEST_F(UpdateAttempterTest, RollbackTest) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticRollbackTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::RollbackTestStart,
+                            base::Unretained(this),
+                            false, true));
+  loop_.Run();
 }
 
 TEST_F(UpdateAttempterTest, InvalidSlotRollbackTest) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticInvalidSlotRollbackTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::RollbackTestStart,
+                            base::Unretained(this),
+                            false, false));
+  loop_.Run();
 }
 
 TEST_F(UpdateAttempterTest, EnterpriseRollbackTest) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticEnterpriseRollbackTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::RollbackTestStart,
+                            base::Unretained(this),
+                            true, true));
+  loop_.Run();
 }
 
 void UpdateAttempterTest::PingOmahaTestStart() {
@@ -630,7 +550,7 @@
                                      OmahaRequestAction::StaticType())));
   EXPECT_CALL(*processor_, StartProcessing());
   attempter_.PingOmaha();
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, PingOmahaTest) {
@@ -639,11 +559,10 @@
   // Disable scheduling of subsequnet checks; we're using the DefaultPolicy in
   // testing, which is more permissive than we want to handle here.
   attempter_.DisableScheduleUpdates();
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticPingOmahaTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::PingOmahaTestStart,
+                            base::Unretained(this)));
+  chromeos::MessageLoopRunMaxIterations(&loop_, 100);
   EXPECT_EQ(UPDATE_STATUS_UPDATED_NEED_REBOOT, attempter_.status());
   EXPECT_TRUE(attempter_.schedule_updates_called());
 }
@@ -706,17 +625,12 @@
 }
 
 TEST_F(UpdateAttempterTest, P2PNotEnabled) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticP2PNotEnabled, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::P2PNotEnabledStart,
+                            base::Unretained(this)));
+  loop_.Run();
 }
-gboolean UpdateAttempterTest::StaticP2PNotEnabled(gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->P2PNotEnabledStart();
-  return FALSE;
-}
+
 void UpdateAttempterTest::P2PNotEnabledStart() {
   // If P2P is not enabled, check that we do not attempt housekeeping
   // and do not convey that p2p is to be used.
@@ -725,24 +639,18 @@
   mock_p2p_manager.fake().SetP2PEnabled(false);
   EXPECT_CALL(mock_p2p_manager, PerformHousekeeping()).Times(0);
   attempter_.Update("", "", "", "", false, false);
-  EXPECT_FALSE(actual_using_p2p_for_downloading());
+  EXPECT_FALSE(actual_using_p2p_for_downloading_);
   EXPECT_FALSE(actual_using_p2p_for_sharing());
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, P2PEnabledStartingFails) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticP2PEnabledStartingFails, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::P2PEnabledStartingFailsStart,
+                            base::Unretained(this)));
+  loop_.Run();
 }
-gboolean UpdateAttempterTest::StaticP2PEnabledStartingFails(
-    gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->P2PEnabledStartingFailsStart();
-  return FALSE;
-}
+
 void UpdateAttempterTest::P2PEnabledStartingFailsStart() {
   // If p2p is enabled, but starting it fails ensure we don't do
   // any housekeeping and do not convey that p2p should be used.
@@ -755,22 +663,17 @@
   attempter_.Update("", "", "", "", false, false);
   EXPECT_FALSE(actual_using_p2p_for_downloading());
   EXPECT_FALSE(actual_using_p2p_for_sharing());
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, P2PEnabledHousekeepingFails) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticP2PEnabledHousekeepingFails, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(
+      FROM_HERE,
+      base::Bind(&UpdateAttempterTest::P2PEnabledHousekeepingFailsStart,
+                 base::Unretained(this)));
+  loop_.Run();
 }
-gboolean UpdateAttempterTest::StaticP2PEnabledHousekeepingFails(
-    gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->P2PEnabledHousekeepingFailsStart();
-  return FALSE;
-}
+
 void UpdateAttempterTest::P2PEnabledHousekeepingFailsStart() {
   // If p2p is enabled, starting it works but housekeeping fails, ensure
   // we do not convey p2p is to be used.
@@ -783,21 +686,16 @@
   attempter_.Update("", "", "", "", false, false);
   EXPECT_FALSE(actual_using_p2p_for_downloading());
   EXPECT_FALSE(actual_using_p2p_for_sharing());
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, P2PEnabled) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticP2PEnabled, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::P2PEnabledStart,
+                            base::Unretained(this)));
+  loop_.Run();
 }
-gboolean UpdateAttempterTest::StaticP2PEnabled(gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->P2PEnabledStart();
-  return FALSE;
-}
+
 void UpdateAttempterTest::P2PEnabledStart() {
   MockP2PManager mock_p2p_manager;
   fake_system_state_.set_p2p_manager(&mock_p2p_manager);
@@ -810,21 +708,16 @@
   attempter_.Update("", "", "", "", false, false);
   EXPECT_TRUE(actual_using_p2p_for_downloading());
   EXPECT_TRUE(actual_using_p2p_for_sharing());
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, P2PEnabledInteractive) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticP2PEnabledInteractive, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE,
+                 base::Bind(&UpdateAttempterTest::P2PEnabledInteractiveStart,
+                            base::Unretained(this)));
+  loop_.Run();
 }
-gboolean UpdateAttempterTest::StaticP2PEnabledInteractive(gpointer data) {
-  UpdateAttempterTest* ua_test = reinterpret_cast<UpdateAttempterTest*>(data);
-  ua_test->P2PEnabledInteractiveStart();
-  return FALSE;
-}
+
 void UpdateAttempterTest::P2PEnabledInteractiveStart() {
   MockP2PManager mock_p2p_manager;
   fake_system_state_.set_p2p_manager(&mock_p2p_manager);
@@ -838,15 +731,15 @@
   attempter_.Update("", "", "", "", false, true /* interactive */);
   EXPECT_FALSE(actual_using_p2p_for_downloading());
   EXPECT_TRUE(actual_using_p2p_for_sharing());
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, ReadScatterFactorFromPolicy) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticReadScatterFactorFromPolicyTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(
+      FROM_HERE,
+      base::Bind(&UpdateAttempterTest::ReadScatterFactorFromPolicyTestStart,
+                 base::Unretained(this)));
+  loop_.Run();
 }
 
 // Tests that the scatter_factor_in_seconds value is properly fetched
@@ -868,15 +761,15 @@
   attempter_.Update("", "", "", "", false, false);
   EXPECT_EQ(scatter_factor_in_seconds, attempter_.scatter_factor_.InSeconds());
 
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, DecrementUpdateCheckCountTest) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticDecrementUpdateCheckCountTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(
+      FROM_HERE,
+      base::Bind(&UpdateAttempterTest::DecrementUpdateCheckCountTestStart,
+                 base::Unretained(this)));
+  loop_.Run();
 }
 
 void UpdateAttempterTest::DecrementUpdateCheckCountTestStart() {
@@ -924,15 +817,14 @@
   EXPECT_TRUE(fake_prefs.GetInt64(kPrefsUpdateCheckCount, &new_value));
   EXPECT_EQ(initial_value, new_value);
 
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 TEST_F(UpdateAttempterTest, NoScatteringDoneDuringManualUpdateTestStart) {
-  loop_ = g_main_loop_new(g_main_context_default(), FALSE);
-  g_idle_add(&StaticNoScatteringDoneDuringManualUpdateTestStart, this);
-  g_main_loop_run(loop_);
-  g_main_loop_unref(loop_);
-  loop_ = nullptr;
+  loop_.PostTask(FROM_HERE, base::Bind(
+      &UpdateAttempterTest::NoScatteringDoneDuringManualUpdateTestStart,
+      base::Unretained(this)));
+  loop_.Run();
 }
 
 void UpdateAttempterTest::NoScatteringDoneDuringManualUpdateTestStart() {
@@ -977,7 +869,7 @@
       attempter_.omaha_request_params_->update_check_count_wait_enabled());
   EXPECT_FALSE(fake_prefs.Exists(kPrefsUpdateCheckCount));
 
-  g_idle_add(&StaticQuitMainLoop, this);
+  ScheduleQuitMainLoop();
 }
 
 // Checks that we only report daily metrics at most every 24 hours.