diff --git a/DEPS b/DEPS
index 10a3b0c..04a6226 100644
--- a/DEPS
+++ b/DEPS
@@ -59,11 +59,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '4dbdc677affd61309f1da173096089fdd20219b3',
+  'skia_revision': 'a44b013a328d5d524e338dbed9accff507a2a4d0',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '32a6cc20a29b89674d5892ee75497d5977c887d2',
+  'v8_revision': '1facfc8241e32978a6c244bcc6f77b493a9bb455',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling swarming_client
   # and whatever else without interference from each other.
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 8efd1f2..72f45afa 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -1823,8 +1823,6 @@
     "login/users/affiliation_unittest.cc",
     "login/users/multi_profile_user_controller_unittest.cc",
     "login/users/user_manager_unittest.cc",
-    "login/users/wallpaper/wallpaper_manager_test_utils.cc",
-    "login/users/wallpaper/wallpaper_manager_test_utils.h",
     "login/users/wallpaper/wallpaper_manager_unittest.cc",
     "mobile/mobile_activator_unittest.cc",
     "mobile_config_unittest.cc",
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
index ab60b216a..d46a1206 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service.cc
@@ -233,8 +233,8 @@
   // ImageDecoder::ImageRequest.
   decode_request_.reset();
   const PrimaryAccount& account = GetPrimaryAccount();
-  chromeos::WallpaperManager::Get()->SetDefaultWallpaper(
-      account.id, account.is_active /* update_wallpaper */);
+  chromeos::WallpaperManager::Get()->SetDefaultWallpaper(account.id,
+                                                         account.is_active);
 }
 
 void ArcWallpaperService::GetWallpaper(GetWallpaperCallback callback) {
diff --git a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
index 4cdb0802..db0937a 100644
--- a/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/wallpaper/arc_wallpaper_service_unittest.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
 #include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h"
-#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_test_utils.h"
 #include "chrome/browser/image_decoder.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
@@ -132,8 +131,6 @@
 TEST_F(ArcWallpaperServiceTest, SetDefaultWallpaper) {
   service_->SetDefaultWallpaper();
   RunAllPendingInMessageLoop();
-  // Wait until wallpaper loading is done.
-  chromeos::wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   ASSERT_EQ(1u, wallpaper_instance_->changed_ids().size());
   EXPECT_EQ(-1, wallpaper_instance_->changed_ids()[0]);
 }
@@ -144,8 +141,7 @@
   std::vector<uint8_t> bytes;
   service_->SetWallpaper(bytes, 10 /* ID */);
   content::RunAllTasksUntilIdle();
-  // Wait until wallpaper loading is done.
-  chromeos::wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
+
   ASSERT_EQ(1u, wallpaper_instance_->changed_ids().size());
   EXPECT_EQ(10, wallpaper_instance_->changed_ids()[0]);
 
@@ -164,8 +160,6 @@
   std::vector<uint8_t> bytes;
   service_->SetWallpaper(bytes, 10 /* ID */);
   content::RunAllTasksUntilIdle();
-  // Wait until wallpaper loading is done.
-  chromeos::wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
 
   // For failure case, ArcWallpaperService reports that wallpaper is changed to
   // requested wallpaper (ID=10), then reports that the wallpaper is changed
diff --git a/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc b/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc
index 73e4c70..5820b41 100644
--- a/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc
+++ b/chrome/browser/chromeos/customization/customization_wallpaper_downloader_browsertest.cc
@@ -247,8 +247,7 @@
 IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest,
                        OEMWallpaperIsPresent) {
   CreateCmdlineWallpapers();
-  WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       ash::Shell::Get()->wallpaper_controller()->GetWallpaper(),
@@ -277,8 +276,7 @@
 IN_PROC_BROWSER_TEST_F(CustomizationWallpaperDownloaderBrowserTest,
                        OEMWallpaperRetryFetch) {
   CreateCmdlineWallpapers();
-  WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       ash::Shell::Get()->wallpaper_controller()->GetWallpaper(),
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index d663661..688258e 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -479,8 +479,7 @@
   if (wallpaper_manager->IsPolicyControlled(account_id))
     return false;
 
-  wallpaper_manager->SetDefaultWallpaper(account_id,
-                                         true /* update_wallpaper */);
+  wallpaper_manager->SetDefaultWallpaper(account_id, true);
 
   Profile* profile = Profile::FromBrowserContext(browser_context());
   // This API is only available to the component wallpaper picker. We do not
diff --git a/chrome/browser/chromeos/login/lock/views_screen_locker.cc b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
index 7465d59..fae53fb 100644
--- a/chrome/browser/chromeos/login/lock/views_screen_locker.cc
+++ b/chrome/browser/chromeos/login/lock/views_screen_locker.cc
@@ -188,7 +188,7 @@
     lock_screen_utils::SetUserInputMethod(account_id.GetUserEmail(),
                                           ime_state_.get());
     lock_screen_utils::SetKeyboardSettings(account_id);
-    WallpaperManager::Get()->SetUserWallpaper(account_id);
+    WallpaperManager::Get()->SetUserWallpaperDelayed(account_id);
 
     bool use_24hour_clock = false;
     if (user_manager::known_user::GetBooleanPref(
diff --git a/chrome/browser/chromeos/login/ui/user_adding_screen.cc b/chrome/browser/chromeos/login/ui/user_adding_screen.cc
index b6f2e89..75a545e 100644
--- a/chrome/browser/chromeos/login/ui/user_adding_screen.cc
+++ b/chrome/browser/chromeos/login/ui/user_adding_screen.cc
@@ -69,7 +69,7 @@
 
   // Reset wallpaper if cancel adding user from multiple user sign in page.
   if (user_manager::UserManager::Get()->IsUserLoggedIn()) {
-    WallpaperManager::Get()->SetUserWallpaper(
+    WallpaperManager::Get()->SetUserWallpaperDelayed(
         user_manager::UserManager::Get()->GetActiveUser()->GetAccountId());
   }
 }
diff --git a/chrome/browser/chromeos/login/ui/webui_login_display.cc b/chrome/browser/chromeos/login/ui/webui_login_display.cc
index e5afbdf..1d24b425 100644
--- a/chrome/browser/chromeos/login/ui/webui_login_display.cc
+++ b/chrome/browser/chromeos/login/ui/webui_login_display.cc
@@ -223,14 +223,14 @@
 }
 
 void WebUILoginDisplay::LoadWallpaper(const AccountId& account_id) {
-  WallpaperManager::Get()->SetUserWallpaper(account_id);
+  WallpaperManager::Get()->SetUserWallpaperDelayed(account_id);
 }
 
 void WebUILoginDisplay::LoadSigninWallpaper() {
   if (!WallpaperManager::Get()->SetDeviceWallpaperIfApplicable(
           user_manager::SignInAccountId())) {
-    WallpaperManager::Get()->SetDefaultWallpaper(
-        user_manager::SignInAccountId(), true /* update_wallpaper */);
+    WallpaperManager::Get()->SetDefaultWallpaperDelayed(
+        user_manager::SignInAccountId());
   }
 }
 
diff --git a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
index 8bae38218..379d559 100644
--- a/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
+++ b/chrome/browser/chromeos/login/users/chrome_user_manager_impl.cc
@@ -770,7 +770,7 @@
       user_manager::User::USER_IMAGE_INVALID, false);
 
   // Initializes wallpaper after active_user_ is set.
-  WallpaperManager::Get()->SetUserWallpaper(user_manager::GuestAccountId());
+  WallpaperManager::Get()->SetUserWallpaperNow(user_manager::GuestAccountId());
 }
 
 void ChromeUserManagerImpl::RegularUserLoggedIn(const AccountId& account_id) {
@@ -785,7 +785,7 @@
   }
 
   if (IsCurrentUserNew())
-    WallpaperManager::Get()->SetUserWallpaper(account_id);
+    WallpaperManager::Get()->SetUserWallpaperNow(account_id);
 
   GetUserImageManager(account_id)->UserLoggedIn(IsCurrentUserNew(), false);
 
@@ -801,7 +801,7 @@
   ChromeUserManager::RegularUserLoggedInAsEphemeral(account_id);
 
   GetUserImageManager(account_id)->UserLoggedIn(IsCurrentUserNew(), false);
-  WallpaperManager::Get()->SetUserWallpaper(account_id);
+  WallpaperManager::Get()->SetUserWallpaperNow(account_id);
 }
 
 void ChromeUserManagerImpl::SupervisedUserLoggedIn(
@@ -816,11 +816,11 @@
     SetIsCurrentUserNew(true);
     active_user_ = user_manager::User::CreateSupervisedUser(account_id);
     // Leaving OAuth token status at the default state = unknown.
-    WallpaperManager::Get()->SetUserWallpaper(account_id);
+    WallpaperManager::Get()->SetUserWallpaperNow(account_id);
   } else {
     if (supervised_user_manager_->CheckForFirstRun(account_id.GetUserEmail())) {
       SetIsCurrentUserNew(true);
-      WallpaperManager::Get()->SetUserWallpaper(account_id);
+      WallpaperManager::Get()->SetUserWallpaperNow(account_id);
     } else {
       SetIsCurrentUserNew(false);
     }
@@ -860,7 +860,7 @@
   // always fetched/cleared inside a user session), in the case the user-policy
   // controlled wallpaper was cached/cleared by not updated in the login screen,
   // so we need to update the wallpaper after the public user logged in.
-  WallpaperManager::Get()->SetUserWallpaper(user->GetAccountId());
+  WallpaperManager::Get()->SetUserWallpaperNow(user->GetAccountId());
   WallpaperManager::Get()->EnsureLoggedInUserWallpaperLoaded();
 
   SetPublicAccountDelegates();
@@ -877,7 +877,7 @@
       user_manager::User::USER_IMAGE_INVALID, false);
 
   const AccountId& kiosk_app_account_id = user->GetAccountId();
-  WallpaperManager::Get()->SetUserWallpaper(kiosk_app_account_id);
+  WallpaperManager::Get()->SetUserWallpaperNow(kiosk_app_account_id);
 
   // TODO(bartfab): Add KioskAppUsers to the users_ list and keep metadata like
   // the kiosk_app_id in these objects, removing the need to re-parse the
@@ -947,7 +947,7 @@
           *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
               IDR_LOGIN_DEFAULT_USER)),
       user_manager::User::USER_IMAGE_INVALID, false);
-  WallpaperManager::Get()->SetUserWallpaper(user_manager::DemoAccountId());
+  WallpaperManager::Get()->SetUserWallpaperNow(user_manager::DemoAccountId());
 
   base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
   command_line->AppendSwitch(::switches::kForceAppMode);
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
index 1f892fbc..7f32f5b 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.cc
@@ -361,45 +361,48 @@
 // Enqueued but not started request might be updated by subsequent load
 // request. Therefore it's created empty, and updated being enqueued.
 //
-// PendingWallpaper is owned by WallpaperManager.
-class WallpaperManager::PendingWallpaper {
+// PendingWallpaper is owned by WallpaperManager, but reference to this object
+// is passed to other threads by PostTask() calls, therefore it is
+// RefCountedThreadSafe.
+class WallpaperManager::PendingWallpaper
+    : public base::RefCountedThreadSafe<PendingWallpaper> {
  public:
-  PendingWallpaper(const base::TimeDelta delay) : weak_factory_(this) {
-    on_finish_ = std::make_unique<MovableOnDestroyCallback>(
-        base::Bind(&WallpaperManager::PendingWallpaper::OnWallpaperSet,
-                   weak_factory_.GetWeakPtr()));
-    timer.Start(FROM_HERE, delay,
-                base::Bind(&WallpaperManager::PendingWallpaper::ProcessRequest,
-                           weak_factory_.GetWeakPtr()));
+  // Do LoadWallpaper() - image not found in cache.
+  PendingWallpaper(const base::TimeDelta delay, const AccountId& account_id)
+      : account_id_(account_id),
+        default_(false),
+        on_finish_(new MovableOnDestroyCallback(
+            base::Bind(&WallpaperManager::PendingWallpaper::OnWallpaperSet,
+                       this))) {
+    timer.Start(
+        FROM_HERE, delay,
+        base::Bind(&WallpaperManager::PendingWallpaper::ProcessRequest, this));
   }
 
-  ~PendingWallpaper() { weak_factory_.InvalidateWeakPtrs(); }
-
-  // There are four cases:
+  // There are 4 cases in SetUserWallpaper:
   // 1) gfx::ImageSkia is found in cache.
-  void SetWallpaperFromImage(const AccountId& account_id,
-                             const gfx::ImageSkia& image,
-                             const wallpaper::WallpaperInfo& info) {
-    SetMode(account_id, image, info, base::FilePath(), false);
+  //    - Schedule task to (probably) resize it and install:
+  //    call SetWallpaper(user_wallpaper, layout);
+  // 2) WallpaperInfo is found in cache
+  //    - need to LoadWallpaper(), resize and install.
+  // 3) wallpaper path is not NULL, load image URL, then resize, etc...
+  // 4) SetDefaultWallpaper (either on some error, or when user is new).
+  void ResetSetWallpaperImage(const gfx::ImageSkia& image,
+                              const wallpaper::WallpaperInfo& info) {
+    SetMode(image, info, base::FilePath(), false);
   }
 
-  // 2) WallpaperInfo is found in cache.
-  void SetWallpaperFromInfo(const AccountId& account_id,
-                            const wallpaper::WallpaperInfo& info) {
-    SetMode(account_id, gfx::ImageSkia(), info, base::FilePath(), false);
+  void ResetLoadWallpaper(const wallpaper::WallpaperInfo& info) {
+    SetMode(gfx::ImageSkia(), info, base::FilePath(), false);
   }
 
-  // 3) Wallpaper path is not null.
-  void SetWallpaperFromPath(const AccountId& account_id,
-                            const wallpaper::WallpaperInfo& info,
-                            const base::FilePath& wallpaper_path) {
-    SetMode(account_id, gfx::ImageSkia(), info, wallpaper_path, false);
+  void ResetSetCustomWallpaper(const wallpaper::WallpaperInfo& info,
+                               const base::FilePath& wallpaper_path) {
+    SetMode(gfx::ImageSkia(), info, wallpaper_path, false);
   }
 
-  // 4) Set default wallpaper (either on some error, or when user is new).
-  void SetDefaultWallpaper(const AccountId& account_id) {
-    SetMode(account_id, gfx::ImageSkia(), WallpaperInfo(), base::FilePath(),
-            true);
+  void ResetSetDefaultWallpaper() {
+    SetMode(gfx::ImageSkia(), WallpaperInfo(), base::FilePath(), true);
   }
 
   uint32_t GetImageId() const {
@@ -407,13 +410,15 @@
   }
 
  private:
-  // All methods use SetMode() to set object to new state.
-  void SetMode(const AccountId& account_id,
-               const gfx::ImageSkia& image,
+  friend class base::RefCountedThreadSafe<PendingWallpaper>;
+
+  ~PendingWallpaper() {}
+
+  // All Reset*() methods use SetMode() to set object to new state.
+  void SetMode(const gfx::ImageSkia& image,
                const wallpaper::WallpaperInfo& info,
                const base::FilePath& wallpaper_path,
                const bool is_default) {
-    account_id_ = account_id;
     user_wallpaper_ = image;
     info_ = info;
     wallpaper_path_ = wallpaper_path;
@@ -422,13 +427,9 @@
 
   // This method is usually triggered by timer to actually load request.
   void ProcessRequest() {
-    // The only known case for this check to fail is global destruction during
-    // wallpaper load. It should never happen.
-    if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
-      return;
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-    // Erase reference to self.
-    timer.Stop();
+    timer.Stop();  // Erase reference to self.
 
     WallpaperManager* manager = WallpaperManager::Get();
     if (manager->pending_inactive_ == this)
@@ -437,14 +438,11 @@
     started_load_at_ = base::Time::Now();
 
     if (default_) {
-      // The most recent request is |SetDefaultWallpaper|.
       manager->DoSetDefaultWallpaper(account_id_, true /* update_wallpaper */,
                                      std::move(on_finish_));
     } else if (!user_wallpaper_.isNull()) {
-      // The most recent request is |SetWallpaperFromImage|.
       SetWallpaper(user_wallpaper_, info_);
     } else if (!wallpaper_path_.empty()) {
-      // The most recent request is |SetWallpaperFromPath|.
       manager->task_runner_->PostTask(
           FROM_HERE,
           base::BindOnce(&WallpaperManager::GetCustomWallpaperInternal,
@@ -454,13 +452,12 @@
                          base::Passed(std::move(on_finish_)),
                          manager->weak_factory_.GetWeakPtr()));
     } else if (!info_.location.empty()) {
-      // The most recent request is |SetWallpaperFromInfo|.
       manager->LoadWallpaper(account_id_, info_, true /* update_wallpaper */,
                              std::move(on_finish_));
     } else {
-      // PendingWallpaper was created but none of the four methods was called.
-      // This should never happen. Do not record time in this case.
+      // PendingWallpaper was created and never initialized?
       NOTREACHED();
+      // Error. Do not record time.
       started_load_at_ = base::Time();
     }
     on_finish_.reset();
@@ -468,13 +465,14 @@
 
   // This method is called by callback, when load request is finished.
   void OnWallpaperSet() {
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
     // The only known case for this check to fail is global destruction during
     // wallpaper load. It should never happen.
     if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
-      return;
+      return;  // We are in a process of global destruction.
 
-    // Erase reference to self.
-    timer.Stop();
+    timer.Stop();  // Erase reference to self.
 
     WallpaperManager* manager = WallpaperManager::Get();
     if (!started_load_at_.is_null()) {
@@ -506,8 +504,6 @@
   // Load start time to calculate duration.
   base::Time started_load_at_;
 
-  base::WeakPtrFactory<PendingWallpaper> weak_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(PendingWallpaper);
 };
 
@@ -618,9 +614,6 @@
   device_wallpaper_image_subscription_.reset();
   user_manager::UserManager::Get()->RemoveObserver(this);
   weak_factory_.InvalidateWeakPtrs();
-  // In case there's wallpaper load request being processed.
-  for (size_t i = 0; i < loading_.size(); ++i)
-    delete loading_[i];
 }
 
 // static
@@ -772,7 +765,7 @@
   // If decoded wallpaper is empty, we have probably failed to decode the file.
   // Use default wallpaper in this case.
   if (image.isNull()) {
-    GetPendingWallpaper()->SetDefaultWallpaper(account_id);
+    SetDefaultWallpaperDelayed(account_id);
     return;
   }
 
@@ -818,7 +811,7 @@
                         base::Time::Now().LocalMidnight()};
   SetUserWallpaperInfo(account_id, info, is_persistent);
   if (update_wallpaper) {
-    GetPendingWallpaper()->SetWallpaperFromImage(account_id, image, info);
+    GetPendingWallpaper(account_id, false)->ResetSetWallpaperImage(image, info);
   }
 
   wallpaper_cache_[account_id] = CustomWallpaperElement(wallpaper_path, image);
@@ -827,6 +820,7 @@
 void WallpaperManager::SetDefaultWallpaper(const AccountId& account_id,
                                            bool update_wallpaper) {
   RemoveUserWallpaperInfo(account_id);
+
   const wallpaper::WallpaperInfo info = {
       std::string(), wallpaper::WALLPAPER_LAYOUT_CENTER, wallpaper::DEFAULT,
       base::Time::Now().LocalMidnight()};
@@ -836,7 +830,23 @@
   SetUserWallpaperInfo(account_id, info, is_persistent);
 
   if (update_wallpaper)
-    GetPendingWallpaper()->SetDefaultWallpaper(account_id);
+    SetDefaultWallpaperNow(account_id);
+}
+
+void WallpaperManager::SetDefaultWallpaperNow(const AccountId& account_id) {
+  GetPendingWallpaper(account_id, false)->ResetSetDefaultWallpaper();
+}
+
+void WallpaperManager::SetDefaultWallpaperDelayed(const AccountId& account_id) {
+  GetPendingWallpaper(account_id, true)->ResetSetDefaultWallpaper();
+}
+
+void WallpaperManager::SetUserWallpaperNow(const AccountId& account_id) {
+  ScheduleSetUserWallpaper(account_id, false);
+}
+
+void WallpaperManager::SetUserWallpaperDelayed(const AccountId& account_id) {
+  ScheduleSetUserWallpaper(account_id, true);
 }
 
 void WallpaperManager::SetUserWallpaperInfo(const AccountId& account_id,
@@ -887,8 +897,10 @@
   wallpaper_cache_[account_id] =
       CustomWallpaperElement(base::FilePath(), image);
 
-  if (update_wallpaper)
-    GetPendingWallpaper()->SetWallpaperFromImage(account_id, image, info);
+  if (update_wallpaper) {
+    GetPendingWallpaper(last_selected_user_, false /* Not delayed */)
+        ->ResetSetWallpaperImage(image, info);
+  }
 }
 
 void WallpaperManager::InitializeWallpaper() {
@@ -924,13 +936,12 @@
 
   if (!user_manager->IsUserLoggedIn()) {
     if (!StartupUtils::IsDeviceRegistered())
-      GetPendingWallpaper()->SetDefaultWallpaper(
-          user_manager::SignInAccountId());
+      SetDefaultWallpaperDelayed(user_manager::SignInAccountId());
     else
       InitializeRegisteredDeviceWallpaper();
     return;
   }
-  SetUserWallpaper(user_manager->GetActiveUser()->GetAccountId());
+  SetUserWallpaperDelayed(user_manager->GetActiveUser()->GetAccountId());
 }
 
 void WallpaperManager::UpdateWallpaper(bool clear_cache) {
@@ -939,13 +950,13 @@
   // be set. It could result a black screen on external monitors.
   // See http://crbug.com/265689 for detail.
   if (last_selected_user_.empty())
-    GetPendingWallpaper()->SetDefaultWallpaper(user_manager::SignInAccountId());
+    SetDefaultWallpaperNow(user_manager::SignInAccountId());
 
   for (auto& observer : observers_)
     observer.OnUpdateWallpaperForTesting();
   if (clear_cache)
     wallpaper_cache_.clear();
-  SetUserWallpaper(last_selected_user_);
+  SetUserWallpaperNow(last_selected_user_);
 }
 
 bool WallpaperManager::IsPendingWallpaper(uint32_t image_id) {
@@ -1012,7 +1023,7 @@
     if (info == current_user_wallpaper_info_)
       return;
   }
-  SetUserWallpaper(
+  SetUserWallpaperNow(
       user_manager::UserManager::Get()->GetActiveUser()->GetAccountId());
 }
 
@@ -1108,7 +1119,7 @@
   // If we're at the login screen, do not change the wallpaper but defer it
   // until the user logs in to the system.
   if (user_manager::UserManager::Get()->IsUserLoggedIn())
-    GetPendingWallpaper()->SetDefaultWallpaper(account_id);
+    SetDefaultWallpaperNow(account_id);
 }
 
 void WallpaperManager::SetCustomizedDefaultWallpaper(
@@ -1209,7 +1220,7 @@
 }
 
 void WallpaperManager::OnChildStatusChanged(const user_manager::User& user) {
-  SetUserWallpaper(user.GetAccountId());
+  SetUserWallpaperNow(user.GetAccountId());
 }
 
 void WallpaperManager::OnWindowActivated(ActivationReason reason,
@@ -1571,8 +1582,7 @@
       !HasNonDeviceLocalAccounts(users)) {
     // Boot into sign in form, preload default wallpaper.
     if (!SetDeviceWallpaperIfApplicable(user_manager::SignInAccountId()))
-      GetPendingWallpaper()->SetDefaultWallpaper(
-          user_manager::SignInAccountId());
+      SetDefaultWallpaperDelayed(user_manager::SignInAccountId());
     return;
   }
 
@@ -1581,7 +1591,7 @@
     // Normal boot, load user wallpaper.
     // If normal boot animation is disabled wallpaper would be set
     // asynchronously once user pods are loaded.
-    SetUserWallpaper(users[index]->GetAccountId());
+    SetUserWallpaperDelayed(users[index]->GetAccountId());
   }
 }
 
@@ -1798,7 +1808,8 @@
     SetWallpaper(user_image->image(), info);
 }
 
-void WallpaperManager::SetUserWallpaper(const AccountId& account_id) {
+void WallpaperManager::ScheduleSetUserWallpaper(const AccountId& account_id,
+                                                bool delayed) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // Some unit tests come here without a UserManager or without a pref system.
   if (!user_manager::UserManager::IsInitialized() ||
@@ -1827,7 +1838,7 @@
        user->HasGaiaAccount()) ||
       user->GetType() == user_manager::USER_TYPE_GUEST) {
     InitInitialUserWallpaper(account_id, false);
-    GetPendingWallpaper()->SetDefaultWallpaper(account_id);
+    GetPendingWallpaper(account_id, delayed)->ResetSetDefaultWallpaper();
     if (base::SysInfo::IsRunningOnChromeOS()) {
       LOG(ERROR)
           << "User is ephemeral or guest! Fallback to default wallpaper.";
@@ -1847,13 +1858,13 @@
   gfx::ImageSkia user_wallpaper;
   current_user_wallpaper_info_ = info;
   if (GetWallpaperFromCache(account_id, &user_wallpaper)) {
-    GetPendingWallpaper()->SetWallpaperFromImage(account_id, user_wallpaper,
-                                                 info);
+    GetPendingWallpaper(account_id, delayed)
+        ->ResetSetWallpaperImage(user_wallpaper, info);
   } else {
     if (info.location.empty()) {
       // Uses default built-in wallpaper when file is empty. Eventually, we
       // will only ship one built-in wallpaper in ChromeOS image.
-      GetPendingWallpaper()->SetDefaultWallpaper(account_id);
+      GetPendingWallpaper(account_id, delayed)->ResetSetDefaultWallpaper();
       return;
     }
 
@@ -1886,14 +1897,13 @@
           CustomWallpaperElement(wallpaper_path, gfx::ImageSkia());
       loaded_wallpapers_for_test_++;
 
-      GetPendingWallpaper()->SetWallpaperFromPath(account_id, info,
-                                                  wallpaper_path);
+      GetPendingWallpaper(account_id, delayed)
+          ->ResetSetCustomWallpaper(info, wallpaper_path);
       return;
     }
 
-    // Load downloaded online or converted default wallpapers according to the
-    // WallpaperInfo.
-    GetPendingWallpaper()->SetWallpaperFromInfo(account_id, info);
+    // Load downloaded ONLINE or converted DEFAULT wallpapers.
+    GetPendingWallpaper(account_id, delayed)->ResetLoadWallpaper(info);
   }
 }
 
@@ -1997,22 +2007,22 @@
   if (last_load_times_.size() == 0) {
     delay = base::TimeDelta::FromMilliseconds(kLoadDefaultDelayMs);
   } else {
-    // Calculate the average loading time.
     delay = std::accumulate(last_load_times_.begin(), last_load_times_.end(),
                             base::TimeDelta(), std::plus<base::TimeDelta>()) /
             last_load_times_.size();
+  }
 
-    if (delay < base::TimeDelta::FromMilliseconds(kLoadMinDelayMs))
-      delay = base::TimeDelta::FromMilliseconds(kLoadMinDelayMs);
-    else if (delay > base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs))
-      delay = base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs);
+  if (delay < base::TimeDelta::FromMilliseconds(kLoadMinDelayMs))
+    delay = base::TimeDelta::FromMilliseconds(kLoadMinDelayMs);
+  else if (delay > base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs))
+    delay = base::TimeDelta::FromMilliseconds(kLoadMaxDelayMs);
 
-    // Reduce the delay by the time passed after the last wallpaper load.
-    DCHECK(!last_load_finished_at_.is_null());
+  // If we had ever loaded wallpaper, adjust wait delay by time since last load.
+  if (!last_load_finished_at_.is_null()) {
     const base::TimeDelta interval = base::Time::Now() - last_load_finished_at_;
     if (interval > delay)
       delay = base::TimeDelta::FromMilliseconds(0);
-    else
+    else if (interval > base::TimeDelta::FromMilliseconds(0))
       delay -= interval;
   }
   return delay;
@@ -2212,25 +2222,26 @@
   DoSetDefaultWallpaper(account_id, update_wallpaper, std::move(on_finish));
 }
 
-WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper() {
-  // If |pending_inactive_| already exists, return it directly. This allows the
-  // pending request (whose timer is still running) to be overriden by a
-  // subsequent request.
+WallpaperManager::PendingWallpaper* WallpaperManager::GetPendingWallpaper(
+    const AccountId& account_id,
+    bool delayed) {
   if (!pending_inactive_) {
-    loading_.push_back(
-        new WallpaperManager::PendingWallpaper(GetWallpaperLoadDelay()));
-    pending_inactive_ = loading_.back();
+    loading_.push_back(new WallpaperManager::PendingWallpaper(
+        (delayed ? GetWallpaperLoadDelay()
+                 : base::TimeDelta::FromMilliseconds(0)),
+        account_id));
+    pending_inactive_ = loading_.back().get();
   }
   return pending_inactive_;
 }
 
 void WallpaperManager::RemovePendingWallpaperFromList(
-    PendingWallpaper* finished_loading_request) {
+    PendingWallpaper* pending) {
   DCHECK(loading_.size() > 0);
-  for (size_t i = 0; i < loading_.size(); ++i) {
-    if (loading_[i] == finished_loading_request) {
-      loading_.erase(loading_.begin() + i);
-      delete loading_[i];
+  for (WallpaperManager::PendingList::iterator i = loading_.begin();
+       i != loading_.end(); ++i) {
+    if (i->get() == pending) {
+      loading_.erase(i);
       break;
     }
   }
@@ -2303,7 +2314,7 @@
   if (!success) {
     LOG(ERROR) << "Failed to download the device wallpaper. Fallback to "
                   "default wallpaper.";
-    GetPendingWallpaper()->SetDefaultWallpaper(account_id);
+    SetDefaultWallpaperDelayed(account_id);
     return;
   }
 
@@ -2335,7 +2346,7 @@
     } else {
       LOG(ERROR) << "The device wallpaper hash doesn't match with provided "
                     "hash value. Fallback to default wallpaper! ";
-      GetPendingWallpaper()->SetDefaultWallpaper(account_id);
+      SetDefaultWallpaperDelayed(account_id);
 
       // Reset the boolean variable so that it can retry to download when the
       // next device wallpaper request comes in.
@@ -2362,8 +2373,8 @@
                                     wallpaper::WALLPAPER_LAYOUT_CENTER_CROPPED,
                                     wallpaper::DEVICE,
                                     base::Time::Now().LocalMidnight()};
-    GetPendingWallpaper()->SetWallpaperFromImage(
-        account_id, user_image->image(), wallpaper_info);
+    GetPendingWallpaper(user_manager::SignInAccountId(), false)
+        ->ResetSetWallpaperImage(user_image->image(), wallpaper_info);
   }
 }
 
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h
index bf1dabc3..fd3d2b4 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h
@@ -257,21 +257,30 @@
                           const gfx::ImageSkia& image,
                           bool update_wallpaper);
 
-  // Sets default wallpaper. |update_wallpaper| indicates whether to actually
-  // change the wallpaper, or only update cache.
+  // Updates wallpaper info for |account_id| to default. If |update_wallpaper|
+  // is false, don't change wallpaper but only update cache.
   void SetDefaultWallpaper(const AccountId& account_id, bool update_wallpaper);
 
-  // Sets |account_id|'s wallpaper.
-  void SetUserWallpaper(const AccountId& account_id);
+  // Sets wallpaper to default wallpaper (asynchronously with zero delay).
+  void SetDefaultWallpaperNow(const AccountId& account_id);
 
-  // Sets wallpaper info for |account_id| and saves it to local state if
-  // |is_persistent| is true.
+  // Sets wallpaper to default wallpaper (asynchronously with default delay).
+  void SetDefaultWallpaperDelayed(const AccountId& account_id);
+
+  // Sets |account_id|'s wallpaper (asynchronously with zero delay).
+  void SetUserWallpaperNow(const AccountId& account_id);
+
+  // Sets |account_id|'s wallpaper (asynchronously with default delay).
+  void SetUserWallpaperDelayed(const AccountId& account_id);
+
+  // Sets selected wallpaper information for |account_id| and saves it to Local
+  // State if |is_persistent| is true.
   void SetUserWallpaperInfo(const AccountId& account_id,
                             const wallpaper::WallpaperInfo& info,
                             bool is_persistent);
 
-  // Sets wallpaper to |image|. If |update_wallpaper| is false, skip change
-  // wallpaper but only update cache.
+  // Sets wallpaper to |image| (asynchronously with zero delay). If
+  // |update_wallpaper| is false, skip change wallpaper but only update cache.
   void SetWallpaperFromImageSkia(const AccountId& account_id,
                                  const gfx::ImageSkia& image,
                                  wallpaper::WallpaperLayout layout,
@@ -283,7 +292,7 @@
   void InitializeWallpaper();
 
   // Updates current wallpaper. It may switch the size of wallpaper based on the
-  // current display's resolution.
+  // current display's resolution. (asynchronously with zero delay)
   void UpdateWallpaper(bool clear_cache);
 
   // Returns if the image is in the pending list. |image_id| can be obtained
@@ -506,6 +515,9 @@
                           MovableOnDestroyCallbackHolder on_finish,
                           std::unique_ptr<user_manager::UserImage> user_image);
 
+  // Creates new PendingWallpaper request (or updates currently pending).
+  void ScheduleSetUserWallpaper(const AccountId& account_id, bool delayed);
+
   // Sets wallpaper to default if |update_wallpaper| is true. Otherwise just
   // load defaut wallpaper to cache.
   void DoSetDefaultWallpaper(const AccountId& account_id,
@@ -526,9 +538,11 @@
   // Notify all registered observers.
   void NotifyAnimationFinished();
 
-  // Calculates delay for the next wallpaper load. In most cases it is zero. It
-  // starts with the average wallpaper load time, and is reduced by the time
-  // passed after the last wallpaper load.
+  // Calculate delay for next wallpaper load.
+  // It is usually average wallpaper load time.
+  // If last wallpaper load happened long ago, timeout should be reduced by
+  // the time passed after last wallpaper load. So usual user experience results
+  // in zero delay.
   base::TimeDelta GetWallpaperLoadDelay() const;
 
   // This is called after we check that supplied default wallpaper files exist.
@@ -592,13 +606,13 @@
                                      bool update_wallpaper,
                                      MovableOnDestroyCallbackHolder on_finish);
 
-  // Returns modifiable PendingWallpaper. (Either |pending_inactive_| or a new
-  // |PendingWallpaper| object.)
-  PendingWallpaper* GetPendingWallpaper();
+  // Returns modifiable PendingWallpaper.
+  // Returns pending_inactive_ or creates new PendingWallpaper if necessary.
+  PendingWallpaper* GetPendingWallpaper(const AccountId& account_id,
+                                        bool delayed);
 
   // This is called by PendingWallpaper when load is finished.
-  void RemovePendingWallpaperFromList(
-      PendingWallpaper* finished_loading_request);
+  void RemovePendingWallpaperFromList(PendingWallpaper* pending);
 
   // Set wallpaper to |user_image| controlled by policy.  (Takes a UserImage
   // because that's the callback interface provided by UserImageLoader.)
@@ -704,7 +718,7 @@
   // Owns PendingWallpaper.
   // PendingWallpaper deletes itself from here on load complete.
   // All pending will be finally deleted on destroy.
-  typedef std::vector<PendingWallpaper*> PendingList;
+  typedef std::vector<scoped_refptr<PendingWallpaper>> PendingList;
   PendingList loading_;
 
   content::NotificationRegistrar registrar_;
diff --git a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
index e91ef1c..5be5c10c 100644
--- a/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
+++ b/chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager_browsertest.cc
@@ -236,7 +236,7 @@
   wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true);
 
   // Set the wallpaper for |test_account_id1_|.
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   gfx::ImageSkia wallpaper = controller_->GetWallpaper();
 
@@ -285,16 +285,15 @@
   WallpaperManager* wallpaper_manager = WallpaperManager::Get();
   // New user log in, a default wallpaper is loaded.
   LogIn(test_account_id1_, kTestUser1Hash);
-  wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_EQ(1, LoadedWallpapers());
   // Loads the same wallpaper before the initial one finished. It should be
   // prevented.
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_EQ(1, LoadedWallpapers());
   // Loads the same wallpaper after the initial one finished. It should be
   // prevented.
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_EQ(1, LoadedWallpapers());
   ClearDisposableWallpaperCache();
@@ -315,15 +314,15 @@
                         base::Time::Now().LocalMidnight()};
   wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true);
 
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   WaitAsyncWallpaperLoadStarted();
   EXPECT_EQ(2, LoadedWallpapers());
   // Loads the same wallpaper before the initial one finished. It should be
   // prevented.
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   WaitAsyncWallpaperLoadStarted();
   EXPECT_EQ(2, LoadedWallpapers());
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_EQ(2, LoadedWallpapers());
 }
@@ -384,8 +383,8 @@
                        HotPlugInScreenAtGAIALoginScreen) {
   UpdateDisplay("800x600");
   // Set initial wallpaper to the default wallpaper.
-  WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(
+      user_manager::StubAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
 
   // Hook up a 2000x2000 display. The large resolution custom wallpaper should
@@ -483,7 +482,6 @@
 #endif
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTestCrashRestore,
                        MAYBE_RestoreWallpaper) {
-  wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_EQ(1, LoadedWallpapers());
 }
 
@@ -526,11 +524,11 @@
                         wallpaper::CUSTOMIZED,
                         base::Time::Now().LocalMidnight()};
   wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true);
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   std::unique_ptr<WallpaperManager::TestApi> test_api;
   test_api.reset(new WallpaperManager::TestApi(wallpaper_manager));
-  // Verify SetUserWallpaper updates wallpaper cache.
+  // Verify SetUserWallpaperNow updates wallpaper cache.
   gfx::ImageSkia cached_wallpaper;
   EXPECT_TRUE(
       test_api->GetWallpaperFromCache(test_account_id1_, &cached_wallpaper));
@@ -603,8 +601,7 @@
   EXPECT_TRUE(test_api->GetPathFromCache(test_account_id1_, &path));
   EXPECT_NE(original_path, path);
 
-  wallpaper_manager->SetDefaultWallpaper(test_account_id1_,
-                                         true /* update_wallpaper */);
+  wallpaper_manager->SetDefaultWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   // SetDefaultWallpaper should invalidate the user's wallpaper cache.
   EXPECT_FALSE(
@@ -734,8 +731,7 @@
 
   // At 800x600, the small wallpaper should be loaded.
   UpdateDisplay("800x600");
-  WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -745,8 +741,7 @@
 IN_PROC_BROWSER_TEST_F(WallpaperManagerBrowserTest, LargeDefaultWallpaper) {
   CreateCmdlineWallpapers();
   UpdateDisplay("1600x1200");
-  WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -758,8 +753,7 @@
   CreateCmdlineWallpapers();
 
   UpdateDisplay("1200x800/r");
-  WallpaperManager::Get()->SetDefaultWallpaper(EmptyAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -771,8 +765,7 @@
   SessionManager::Get()->CreateSession(user_manager::GuestAccountId(),
                                        user_manager::kGuestUserName);
   UpdateDisplay("800x600");
-  WallpaperManager::Get()->SetDefaultWallpaper(user_manager::GuestAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -784,8 +777,7 @@
   SessionManager::Get()->CreateSession(user_manager::GuestAccountId(),
                                        user_manager::kGuestUserName);
   UpdateDisplay("1600x1200");
-  WallpaperManager::Get()->SetDefaultWallpaper(user_manager::GuestAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -796,8 +788,7 @@
   CreateCmdlineWallpapers();
   LogInAsChild(test_account_id1_, kTestUser1Hash);
   UpdateDisplay("800x600");
-  WallpaperManager::Get()->SetDefaultWallpaper(test_account_id1_,
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -808,8 +799,7 @@
   CreateCmdlineWallpapers();
   LogInAsChild(test_account_id1_, kTestUser1Hash);
   UpdateDisplay("1600x1200");
-  WallpaperManager::Get()->SetDefaultWallpaper(test_account_id1_,
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -824,8 +814,7 @@
   SessionManager::Get()->CreateSession(user_manager::StubAccountId(),
                                        "test_hash");
 
-  WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
 
   // Custom wallpaper should be applied immediately, canceling the default
   // wallpaper load task.
@@ -841,8 +830,7 @@
       controller_->GetWallpaper(),
       wallpaper_manager_test_utils::kCustomWallpaperColor));
 
-  WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
 
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
@@ -857,8 +845,7 @@
   SessionManager::Get()->CreateSession(user_manager::StubAccountId(),
                                        "test_hash");
 
-  WallpaperManager::Get()->SetDefaultWallpaper(user_manager::StubAccountId(),
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(EmptyAccountId());
 
   gfx::ImageSkia image = wallpaper_manager_test_utils::CreateTestImage(
       640, 480, wallpaper_manager_test_utils::kCustomWallpaperColor);
@@ -906,7 +893,7 @@
                          wallpaper::CUSTOMIZED,
                          base::Time::Now().LocalMidnight()};
   wallpaper_manager->SetUserWallpaperInfo(test_account_id2_, info2, true);
-  wallpaper_manager->SetUserWallpaper(test_account_id2_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id2_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(wallpaper_manager_test_utils::ImageIsNearColor(
       controller_->GetWallpaper(),
@@ -960,7 +947,7 @@
                         wallpaper::CUSTOMIZED,
                         base::Time::Now().LocalMidnight()};
   wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true);
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(base::PathExists(small_wallpaper_path));
 
@@ -980,7 +967,7 @@
                          wallpaper::CUSTOMIZED,
                          base::Time::Now().LocalMidnight()};
   wallpaper_manager->SetUserWallpaperInfo(test_account_id2_, info2, true);
-  wallpaper_manager->SetUserWallpaper(test_account_id2_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id2_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(base::PathExists(small_wallpaper_path2));
 
@@ -1021,7 +1008,7 @@
                         wallpaper::CUSTOMIZED,
                         base::Time::Now().LocalMidnight()};
   wallpaper_manager->SetUserWallpaperInfo(test_account_id1_, info, true);
-  wallpaper_manager->SetUserWallpaper(test_account_id1_);
+  wallpaper_manager->SetUserWallpaperNow(test_account_id1_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
   EXPECT_TRUE(base::PathExists(small_wallpaper_path));
 
@@ -1032,8 +1019,7 @@
   WallpaperInfo info2 = {"", WALLPAPER_LAYOUT_CENTER_CROPPED,
                          wallpaper::DEFAULT, base::Time::Now().LocalMidnight()};
   wallpaper_manager->SetUserWallpaperInfo(test_account_id2_, info2, true);
-  WallpaperManager::Get()->SetDefaultWallpaper(test_account_id2_,
-                                               true /* update_wallpaper */);
+  WallpaperManager::Get()->SetDefaultWallpaperNow(test_account_id2_);
   wallpaper_manager_test_utils::WaitAsyncWallpaperLoadFinished();
 
   // Simulate the removal of |test_account_id2_|.
diff --git a/chrome/browser/ui/ash/lock_screen_client.cc b/chrome/browser/ui/ash/lock_screen_client.cc
index 7985267..2c68835 100644
--- a/chrome/browser/ui/ash/lock_screen_client.cc
+++ b/chrome/browser/ui/ash/lock_screen_client.cc
@@ -92,7 +92,7 @@
 }
 
 void LockScreenClient::LoadWallpaper(const AccountId& account_id) {
-  chromeos::WallpaperManager::Get()->SetUserWallpaper(account_id);
+  chromeos::WallpaperManager::Get()->SetUserWallpaperDelayed(account_id);
 }
 
 void LockScreenClient::SignOutUser() {
diff --git a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
index c49054d..0348314 100644
--- a/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
+++ b/chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.cc
@@ -189,7 +189,7 @@
     wallpaper_delegate->SetAnimationDurationOverride(
         std::max(duration, kMinimalAnimationTimeMS));
     if (screen_cover_ != NEW_USER_COVERS_SCREEN) {
-      chromeos::WallpaperManager::Get()->SetUserWallpaper(new_account_id_);
+      chromeos::WallpaperManager::Get()->SetUserWallpaperNow(new_account_id_);
       wallpaper_user_id_for_test_ =
           (NO_USER_COVERS_SCREEN == screen_cover_ ? "->" : "") +
           new_account_id_.Serialize();
@@ -198,7 +198,7 @@
     // Revert the wallpaper cross dissolve animation duration back to the
     // default.
     if (screen_cover_ == NEW_USER_COVERS_SCREEN)
-      chromeos::WallpaperManager::Get()->SetUserWallpaper(new_account_id_);
+      chromeos::WallpaperManager::Get()->SetUserWallpaperNow(new_account_id_);
 
     // Coming here the wallpaper user id is the final result. No matter how we
     // got here.
diff --git a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
index 92543e0..a6db11fe 100644
--- a/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/supervised_user_creation_screen_handler.cc
@@ -300,7 +300,7 @@
     const AccountId& manager_id) {
   if (!delegate_)
     return;
-  WallpaperManager::Get()->SetUserWallpaper(manager_id);
+  WallpaperManager::Get()->SetUserWallpaperNow(manager_id);
 }
 
 void SupervisedUserCreationScreenHandler::HandleImportUserSelected(
diff --git a/media/base/android/media_codec_util.cc b/media/base/android/media_codec_util.cc
index aea22f1..75008f4 100644
--- a/media/base/android/media_codec_util.cc
+++ b/media/base/android/media_codec_util.cc
@@ -184,6 +184,11 @@
       {"GT-N5110", SDK_VERSION_JELLY_BEAN_MR2},
       {"e-tab4", SDK_VERSION_JELLY_BEAN_MR2},
       {"GT-I8200Q", SDK_VERSION_JELLY_BEAN_MR2},
+
+      // crbug.com/693216
+      {"GT-I8552B", SDK_VERSION_JELLY_BEAN_MR2},
+      {"GT-I8262", SDK_VERSION_JELLY_BEAN_MR2},
+      {"GT-I8262B", SDK_VERSION_JELLY_BEAN_MR2},
   };
 
   const auto iter =
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index d5bffd3..0135d9c 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -69,7 +69,7 @@
 
 if (is_chromeos && use_v4lplugin) {
   action("libv4l2_generate_stubs") {
-    extra_header = "v4l2_stub_header.fragment"
+    extra_header = "v4l2/v4l2_stub_header.fragment"
 
     script = "../../tools/generate_stubs/generate_stubs.py"
     sources = [
diff --git a/media/gpu/v4l2_stub_header.fragment b/media/gpu/v4l2/v4l2_stub_header.fragment
similarity index 100%
rename from media/gpu/v4l2_stub_header.fragment
rename to media/gpu/v4l2/v4l2_stub_header.fragment
diff --git a/mojo/edk/system/ports/BUILD.gn b/mojo/edk/system/ports/BUILD.gn
index 556b4bc..42fd523 100644
--- a/mojo/edk/system/ports/BUILD.gn
+++ b/mojo/edk/system/ports/BUILD.gn
@@ -42,6 +42,7 @@
   testonly = true
 
   sources = [
+    "name_unittest.cc",
     "ports_unittest.cc",
   ]
 
diff --git a/mojo/edk/system/ports/name_unittest.cc b/mojo/edk/system/ports/name_unittest.cc
new file mode 100644
index 0000000..7e4d82b7
--- /dev/null
+++ b/mojo/edk/system/ports/name_unittest.cc
@@ -0,0 +1,75 @@
+// Copyright 2017 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 "mojo/edk/system/ports/name.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace mojo {
+namespace edk {
+namespace ports {
+namespace test {
+
+TEST(NameTest, Defaults) {
+  PortName default_port_name;
+  EXPECT_EQ(kInvalidPortName, default_port_name);
+
+  NodeName default_node_name;
+  EXPECT_EQ(kInvalidNodeName, default_node_name);
+}
+
+TEST(NameTest, PortNameChecks) {
+  PortName port_name_a(50, 100);
+  PortName port_name_b(50, 100);
+  PortName port_name_c(100, 50);
+
+  EXPECT_EQ(port_name_a, port_name_b);
+  EXPECT_NE(port_name_a, port_name_c);
+  EXPECT_NE(port_name_b, port_name_c);
+
+  EXPECT_LT(port_name_a, port_name_c);
+  EXPECT_LT(port_name_b, port_name_c);
+  EXPECT_FALSE(port_name_a < port_name_b);
+  EXPECT_FALSE(port_name_b < port_name_a);
+
+  std::hash<PortName> port_hash_fn;
+
+  size_t hash_a = port_hash_fn(port_name_a);
+  size_t hash_b = port_hash_fn(port_name_b);
+  size_t hash_c = port_hash_fn(port_name_c);
+
+  EXPECT_EQ(hash_a, hash_b);
+  EXPECT_NE(hash_a, hash_c);
+  EXPECT_NE(hash_b, hash_c);
+}
+
+TEST(NameTest, NodeNameChecks) {
+  NodeName node_name_a(50, 100);
+  NodeName node_name_b(50, 100);
+  NodeName node_name_c(100, 50);
+
+  EXPECT_EQ(node_name_a, node_name_b);
+  EXPECT_NE(node_name_a, node_name_c);
+  EXPECT_NE(node_name_b, node_name_c);
+
+  EXPECT_LT(node_name_a, node_name_c);
+  EXPECT_LT(node_name_b, node_name_c);
+  EXPECT_FALSE(node_name_a < node_name_b);
+  EXPECT_FALSE(node_name_b < node_name_a);
+
+  std::hash<NodeName> node_hash_fn;
+
+  size_t hash_a = node_hash_fn(node_name_a);
+  size_t hash_b = node_hash_fn(node_name_b);
+  size_t hash_c = node_hash_fn(node_name_c);
+
+  EXPECT_EQ(hash_a, hash_b);
+  EXPECT_NE(hash_a, hash_c);
+  EXPECT_NE(hash_b, hash_c);
+}
+
+}  // namespace test
+}  // namespace ports
+}  // namespace edk
+}  // namespace mojo
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js b/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
index 2bf85cc8..e57ef585 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/DOMStorageItemsView.js
@@ -40,9 +40,30 @@
       {id: 'value', title: Common.UIString('Value'), sortable: false, editable: true, longText: true, weight: 50}
     ]);
     this._dataGrid = new DataGrid.DataGrid(columns, this._editingCallback.bind(this), this._deleteCallback.bind(this));
+    this._dataGrid.addEventListener(
+        DataGrid.DataGrid.Events.SelectedNode,
+        event => this._previewEntry(/** @type {!DataGrid.DataGridNode} */ (event.data)));
+    this._dataGrid.addEventListener(DataGrid.DataGrid.Events.DeselectedNode, event => this._previewEntry(null));
     this._dataGrid.setStriped(true);
     this._dataGrid.setName('DOMStorageItemsView');
-    this._dataGrid.asWidget().show(this.element);
+
+    this._splitWidget = new UI.SplitWidget(false, false);
+    this._splitWidget.show(this.element);
+    this._splitWidget.setSecondIsSidebar(true);
+
+    this._previewPanel = new UI.VBox();
+    var resizer = this._previewPanel.element.createChild('div', 'preview-panel-resizer');
+    this._splitWidget.setMainWidget(this._dataGrid.asWidget());
+    this._splitWidget.setSidebarWidget(this._previewPanel);
+    this._splitWidget.installResizer(resizer);
+
+    /** @type {?UI.Widget} */
+    this._preview = null;
+    /** @type {?string} */
+    this._previewValue = null;
+
+    this._showPreview(null, null);
+
     this._eventListeners = [];
     this.setStorage(domStorage);
   }
@@ -107,8 +128,6 @@
     var rootNode = this._dataGrid.rootNode();
     var children = rootNode.children;
 
-    this.setCanDeleteSelected(true);
-
     for (var i = 0; i < children.length; ++i) {
       if (children[i].data.key === storageData.key)
         return;
@@ -126,27 +145,16 @@
       return;
 
     var storageData = event.data;
-    var rootNode = this._dataGrid.rootNode();
-    var children = rootNode.children;
+    var childNode = this._dataGrid.rootNode().children.find(child => child.data.key === storageData.key);
+    if (!childNode || childNode.data.value === storageData.value)
+      return;
 
-    var keyFound = false;
-    for (var i = 0; i < children.length; ++i) {
-      var childNode = children[i];
-      if (childNode.data.key === storageData.key) {
-        if (keyFound) {
-          rootNode.removeChild(childNode);
-          return;
-        }
-        keyFound = true;
-        if (childNode.data.value !== storageData.value) {
-          childNode.data.value = storageData.value;
-          childNode.refresh();
-          childNode.select();
-          childNode.reveal();
-        }
-        this.setCanDeleteSelected(true);
-      }
-    }
+    childNode.data.value = storageData.value;
+    childNode.refresh();
+    if (!childNode.selected)
+      return;
+    this._previewEntry(childNode);
+    this.setCanDeleteSelected(true);
   }
 
   /**
@@ -237,4 +245,40 @@
     if (this._domStorage)
       this._domStorage.removeItem(node.data.key);
   }
+
+  /**
+   * @param {?UI.Widget} preview
+   * @param {?string} value
+   */
+  _showPreview(preview, value) {
+    if (this._preview && this._previewValue === value)
+      return;
+    if (this._preview)
+      this._preview.detach();
+    if (!preview)
+      preview = new UI.EmptyWidget(Common.UIString('Select a value to preview'));
+    this._previewValue = value;
+    this._preview = preview;
+    preview.show(this._previewPanel.contentElement);
+  }
+
+  /**
+   * @param {?DataGrid.DataGridNode} entry
+   */
+  async _previewEntry(entry) {
+    var value = entry && entry.data && entry.data.value;
+    if (!value) {
+      this._showPreview(null, value);
+      return;
+    }
+    var protocol = this._domStorage.isLocalStorage ? 'localstorage' : 'sessionstorage';
+    var url = `${protocol}://${entry.key}`;
+    var provider =
+        Common.StaticContentProvider.fromString(url, Common.resourceTypes.XHR, /** @type {string} */ (value));
+    var preview = await SourceFrame.PreviewFactory.createPreview(provider, 'text/plain');
+    // Selection could've changed while the preview was loaded
+    if (!entry.selected)
+      return;
+    this._showPreview(preview, value);
+  }
 };
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 69cafc2..a950f86 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -11825,9 +11825,9 @@
   <int value="387" label="DeviceNativePrintersAccessMode"/>
   <int value="388" label="DeviceNativePrintersBlacklist"/>
   <int value="389" label="DeviceNativePrintersWhitelist"/>
-  <int value="390" label="DeviceTPMFirmwareUpdateSettings"/>
+  <int value="390" label="TPMFirmwareUpdateSettings"/>
   <int value="391" label="RunAllFlashInAllowMode"/>
-  <int value="392" label="AutoFillCreditCardEnabled"/>
+  <int value="392" label="AutofillCreditCardEnabled"/>
   <int value="393" label="NtlmV2Enabled"/>
   <int value="394" label="MinimumRequiredChromeVersion"/>
 </enum>