cros: Make WallpaperWindowStateManager work under Mash

Create mojo API and move the tests in 'wallpaper_private_api_unittest.cc'
to //ash, because:

1) They're only testing wallpaper_window_state_manager.

2) We want to remove //ash dependency in chrome wallpaper code.

(IIUC)|MultiUserWindowManagerChromeOS| under //chrome is responsible
for tracking the window ownership under multi-profile session. The
wallpaper_window_state_manager is only checking if the window is
visible. So if we move the tests to //ash, they only need to test that
the minimize/restore functions are no-op for invisible windows. Why
the windows are visible/invisible is beyond its scope.

Bug: 827062
Test: --enable-features=Mash
Change-Id: Ib7573e8911a6979f598f85cbb0b059be1c77b389
Reviewed-on: https://chromium-review.googlesource.com/967885
Commit-Queue: Wenzhao (Colin) Zang <wzang@chromium.org>
Reviewed-by: Oliver Chang <ochang@chromium.org>
Reviewed-by: Xiaoqian Dai <xdai@chromium.org>
Cr-Commit-Position: refs/heads/master@{#549811}
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index c8477cb..28702719 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1652,6 +1652,7 @@
     "wallpaper/wallpaper_controller_unittest.cc",
     "wallpaper/wallpaper_utils/wallpaper_color_calculator_unittest.cc",
     "wallpaper/wallpaper_utils/wallpaper_resizer_unittest.cc",
+    "wallpaper/wallpaper_window_state_manager_unittest.cc",
     "window_manager_common_unittests.cc",
     "window_user_data_unittest.cc",
     "wm/always_on_top_controller_unittest.cc",
diff --git a/ash/public/interfaces/wallpaper.mojom b/ash/public/interfaces/wallpaper.mojom
index dbfa041..d91a7c3 100644
--- a/ash/public/interfaces/wallpaper.mojom
+++ b/ash/public/interfaces/wallpaper.mojom
@@ -202,6 +202,15 @@
   // and it's allowed to change wallpaper per the user type and the login state.
   OpenWallpaperPickerIfAllowed();
 
+  // Minimizes all windows except the active window.
+  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
+  MinimizeInactiveWindows(string user_id_hash);
+
+  // Restores all minimized windows to their previous states. This should only
+  // be called after calling |MinimizeInactiveWindows|.
+  // |user_id_hash|: The hash value corresponding to |User::username_hash|.
+  RestoreMinimizedWindows(string user_id_hash);
+
   // Calling this method triggers an initial notification of the wallpaper
   // state. Observers are automatically removed as their connections are closed.
   AddObserver(associated WallpaperObserver observer);
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc
index cd43802..0816cca 100644
--- a/ash/wallpaper/wallpaper_controller.cc
+++ b/ash/wallpaper/wallpaper_controller.cc
@@ -25,6 +25,7 @@
 #include "ash/wallpaper/wallpaper_utils/wallpaper_resizer.h"
 #include "ash/wallpaper/wallpaper_view.h"
 #include "ash/wallpaper/wallpaper_widget_controller.h"
+#include "ash/wallpaper/wallpaper_window_state_manager.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/logging.h"
@@ -1336,6 +1337,24 @@
   }
 }
 
+void WallpaperController::MinimizeInactiveWindows(
+    const std::string& user_id_hash) {
+  if (!window_state_manager_)
+    window_state_manager_ = std::make_unique<WallpaperWindowStateManager>();
+
+  window_state_manager_->MinimizeInactiveWindows(user_id_hash);
+}
+
+void WallpaperController::RestoreMinimizedWindows(
+    const std::string& user_id_hash) {
+  if (!window_state_manager_) {
+    DCHECK(false) << "This should only be called after calling "
+                  << "MinimizeInactiveWindows.";
+    return;
+  }
+  window_state_manager_->RestoreMinimizedWindows(user_id_hash);
+}
+
 void WallpaperController::AddObserver(
     mojom::WallpaperObserverAssociatedPtrInfo observer) {
   mojom::WallpaperObserverAssociatedPtr observer_ptr;
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h
index bd13fcc..4e60955 100644
--- a/ash/wallpaper/wallpaper_controller.h
+++ b/ash/wallpaper/wallpaper_controller.h
@@ -41,6 +41,7 @@
 class WallpaperColorCalculator;
 class WallpaperControllerObserver;
 class WallpaperResizer;
+class WallpaperWindowStateManager;
 
 // The |CustomWallpaperElement| contains |first| the path of the image which
 // is currently being loaded and or in progress of being loaded and |second|
@@ -347,6 +348,8 @@
                              const std::string& wallpaper_files_id) override;
   void SetAnimationDuration(base::TimeDelta animation_duration) override;
   void OpenWallpaperPickerIfAllowed() override;
+  void MinimizeInactiveWindows(const std::string& user_id_hash) override;
+  void RestoreMinimizedWindows(const std::string& user_id_hash) override;
   void AddObserver(mojom::WallpaperObserverAssociatedPtrInfo observer) override;
   void GetWallpaperImage(GetWallpaperImageCallback callback) override;
   void GetWallpaperColors(GetWallpaperColorsCallback callback) override;
@@ -556,6 +559,10 @@
   // Asynchronous task to extract colors from the wallpaper.
   std::unique_ptr<WallpaperColorCalculator> color_calculator_;
 
+  // Manages the states of the other windows when the wallpaper app window is
+  // active.
+  std::unique_ptr<WallpaperWindowStateManager> window_state_manager_;
+
   // The prominent colors extracted from the current wallpaper.
   // kInvalidColor is used by default or if extracting colors fails.
   std::vector<SkColor> prominent_colors_;
diff --git a/ash/wallpaper/wallpaper_window_state_manager.cc b/ash/wallpaper/wallpaper_window_state_manager.cc
index dbc1716..9b32543 100644
--- a/ash/wallpaper/wallpaper_window_state_manager.cc
+++ b/ash/wallpaper/wallpaper_window_state_manager.cc
@@ -11,44 +11,13 @@
 #include "ui/aura/window.h"
 
 namespace ash {
-namespace {
-
-WallpaperWindowStateManager* g_window_state_manager = nullptr;
-
-}  // namespace
-
-// static
-void WallpaperWindowStateManager::MinimizeInactiveWindows(
-    const std::string& user_id_hash) {
-  if (!g_window_state_manager)
-    g_window_state_manager = new WallpaperWindowStateManager();
-  g_window_state_manager->BuildWindowListAndMinimizeInactiveForUser(
-      user_id_hash, wm::GetActiveWindow());
-}
-
-// static
-void WallpaperWindowStateManager::RestoreWindows(
-    const std::string& user_id_hash) {
-  if (!g_window_state_manager) {
-    DCHECK(false) << "This should only be called after calling "
-                  << "MinimizeInactiveWindows.";
-    return;
-  }
-
-  g_window_state_manager->RestoreMinimizedWindows(user_id_hash);
-  if (g_window_state_manager->user_id_hash_window_list_map_.empty()) {
-    delete g_window_state_manager;
-    g_window_state_manager = nullptr;
-  }
-}
 
 WallpaperWindowStateManager::WallpaperWindowStateManager() = default;
 
 WallpaperWindowStateManager::~WallpaperWindowStateManager() = default;
 
-void WallpaperWindowStateManager::BuildWindowListAndMinimizeInactiveForUser(
-    const std::string& user_id_hash,
-    aura::Window* active_window) {
+void WallpaperWindowStateManager::MinimizeInactiveWindows(
+    const std::string& user_id_hash) {
   if (user_id_hash_window_list_map_.find(user_id_hash) ==
       user_id_hash_window_list_map_.end()) {
     user_id_hash_window_list_map_[user_id_hash] = std::set<aura::Window*>();
@@ -56,6 +25,7 @@
   std::set<aura::Window*>* results =
       &user_id_hash_window_list_map_[user_id_hash];
 
+  aura::Window* active_window = wm::GetActiveWindow();
   aura::Window::Windows windows =
       Shell::Get()->mru_window_tracker()->BuildWindowListIgnoreModal();
 
diff --git a/ash/wallpaper/wallpaper_window_state_manager.h b/ash/wallpaper/wallpaper_window_state_manager.h
index b7e72afd..3da28019 100644
--- a/ash/wallpaper/wallpaper_window_state_manager.h
+++ b/ash/wallpaper/wallpaper_window_state_manager.h
@@ -26,29 +26,19 @@
   typedef std::map<std::string, std::set<aura::Window*>>
       UserIDHashWindowListMap;
 
-  // Minimizes all windows except the active window.
-  // TODO(mash): Expose this via a mojo API. http://crbug.com/557405
-  static void MinimizeInactiveWindows(const std::string& user_id_hash);
-
-  // Unminimizes all minimized windows restoring them to their previous state.
-  // This should only be called after calling MinimizeInactiveWindows.
-  // TODO(mash): Expose this via a mojo API. http://crbug.com/557405
-  static void RestoreWindows(const std::string& user_id_hash);
-
- private:
   WallpaperWindowStateManager();
 
   ~WallpaperWindowStateManager() override;
 
   // Store all unminimized windows except |active_window| and minimize them.
   // All the windows are saved in a map and the key value is |user_id_hash|.
-  void BuildWindowListAndMinimizeInactiveForUser(
-      const std::string& user_id_hash,
-      aura::Window* active_window);
+  void MinimizeInactiveWindows(const std::string& user_id_hash);
 
-  // Unminimize all the stored windows for |user_id_hash|.
+  // Unminimize all the stored windows for |user_id_hash|. This should only be
+  // called after calling MinimizeInactiveWindows.
   void RestoreMinimizedWindows(const std::string& user_id_hash);
 
+ private:
   // Remove the observer from |window| if |window| is no longer referenced in
   // user_id_hash_window_list_map_.
   void RemoveObserverIfUnreferenced(aura::Window* window);
diff --git a/ash/wallpaper/wallpaper_window_state_manager_unittest.cc b/ash/wallpaper/wallpaper_window_state_manager_unittest.cc
new file mode 100644
index 0000000..5bbfa59
--- /dev/null
+++ b/ash/wallpaper/wallpaper_window_state_manager_unittest.cc
@@ -0,0 +1,187 @@
+// Copyright 2018 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 "ash/wallpaper/wallpaper_window_state_manager.h"
+
+#include <memory>
+
+#include "ash/test/ash_test_base.h"
+#include "ash/wm/window_state.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "ui/aura/window.h"
+
+namespace ash {
+namespace {
+
+constexpr char kTestAccount[] = "user@test.com";
+
+std::string GetUserIdHash(const std::string& user_id) {
+  return user_id + "-hash";
+}
+
+class WallpaperWindowStateManagerTest : public AshTestBase {
+ public:
+  WallpaperWindowStateManagerTest()
+      : window_state_manager_(std::make_unique<WallpaperWindowStateManager>()) {
+  }
+
+  ~WallpaperWindowStateManagerTest() override = default;
+
+ protected:
+  std::unique_ptr<WallpaperWindowStateManager> window_state_manager_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(WallpaperWindowStateManagerTest);
+};
+
+TEST_F(WallpaperWindowStateManagerTest, HideAndRestoreWindows) {
+  SimulateUserLogin(kTestAccount);
+  std::unique_ptr<aura::Window> wallpaper_picker_window(
+      CreateTestWindowInShellWithId(0));
+  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
+  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
+  std::unique_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
+  std::unique_ptr<aura::Window> window4(CreateTestWindowInShellWithId(4));
+
+  wm::WindowState* wallpaper_picker_window_state =
+      wm::GetWindowState(wallpaper_picker_window.get());
+  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
+  wm::WindowState* window2_state = wm::GetWindowState(window2.get());
+  wm::WindowState* window3_state = wm::GetWindowState(window3.get());
+  wm::WindowState* window4_state = wm::GetWindowState(window4.get());
+
+  // Window 1 starts maximized and window 3 starts minimized.
+  window1_state->Maximize();
+  window3_state->Minimize();
+  EXPECT_FALSE(wallpaper_picker_window_state->IsMinimized());
+  EXPECT_FALSE(window1_state->IsMinimized());
+  EXPECT_FALSE(window2_state->IsMinimized());
+  EXPECT_TRUE(window3_state->IsMinimized());
+  EXPECT_FALSE(window4_state->IsMinimized());
+
+  // Activates the wallpaper picker window and call the minimize function.
+  wallpaper_picker_window_state->Activate();
+  EXPECT_TRUE(wallpaper_picker_window_state->IsActive());
+  window_state_manager_->MinimizeInactiveWindows(GetUserIdHash(kTestAccount));
+
+  // All windows except the wallpaper picker should be minimized.
+  EXPECT_FALSE(wallpaper_picker_window_state->IsMinimized());
+  EXPECT_TRUE(window1_state->IsMinimized());
+  EXPECT_TRUE(window2_state->IsMinimized());
+  EXPECT_TRUE(window3_state->IsMinimized());
+  EXPECT_TRUE(window4_state->IsMinimized());
+
+  // Activates window 4 and then minimizes it.
+  window4_state->Activate();
+  window4_state->Minimize();
+
+  // Destroy wallpaper picker window and call the restore function.
+  wallpaper_picker_window.reset();
+  window_state_manager_->RestoreMinimizedWindows(GetUserIdHash(kTestAccount));
+
+  // Window 1 should be restored to maximized.
+  EXPECT_TRUE(window1_state->IsMaximized());
+  // Window 2 should be restored and is no longer minimized.
+  EXPECT_FALSE(window2_state->IsMinimized());
+  // Window 3 should remain minimized because it was minimized before wallpaper
+  // picker was open.
+  EXPECT_TRUE(window3_state->IsMinimized());
+  // Window 4 should remain minimized since user interacted with it (i.e.
+  // explicitly minimized it) while wallpaper picker was open.
+  EXPECT_TRUE(window4_state->IsMinimized());
+}
+
+// Test for multiple calls to |MinimizeInactiveWindows| before calling
+// |RestoreMinimizedWindows|:
+// 1. If none of the windows changed their states, the following calls are
+//    no-op.
+// 2. If some windows are unminimized by user, the following call will minimize
+//    the unminimized windows again.
+TEST_F(WallpaperWindowStateManagerTest, HideAndManualUnminimizeWindows) {
+  SimulateUserLogin(kTestAccount);
+  std::unique_ptr<aura::Window> wallpaper_picker_window(
+      CreateTestWindowInShellWithId(0));
+  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
+
+  wm::WindowState* wallpaper_picker_window_state =
+      wm::GetWindowState(wallpaper_picker_window.get());
+  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
+
+  // Activates the wallpaper picker window and call the minimize function.
+  wallpaper_picker_window_state->Activate();
+  EXPECT_TRUE(wallpaper_picker_window_state->IsActive());
+  window_state_manager_->MinimizeInactiveWindows(GetUserIdHash(kTestAccount));
+
+  // All windows except the wallpaper picker should be minimized.
+  EXPECT_FALSE(wallpaper_picker_window_state->IsMinimized());
+  EXPECT_TRUE(window1_state->IsMinimized());
+
+  // Calling minimize function again should be an no-op if window state didn't
+  // change.
+  window_state_manager_->MinimizeInactiveWindows(GetUserIdHash(kTestAccount));
+  EXPECT_FALSE(wallpaper_picker_window_state->IsMinimized());
+  EXPECT_TRUE(window1_state->IsMinimized());
+
+  // Manually unminimize window 1.
+  window1_state->Unminimize();
+  EXPECT_FALSE(window1_state->IsMinimized());
+
+  // Call the minimize function and verify window 1 should be minimized again.
+  wallpaper_picker_window_state->Activate();
+  window_state_manager_->MinimizeInactiveWindows(GetUserIdHash(kTestAccount));
+  EXPECT_FALSE(wallpaper_picker_window_state->IsMinimized());
+  EXPECT_TRUE(window1_state->IsMinimized());
+
+  // Destroy wallpaper picker window and call the restore function.
+  wallpaper_picker_window.reset();
+  window_state_manager_->RestoreMinimizedWindows(GetUserIdHash(kTestAccount));
+
+  // Windows 1 should no longer be minimized.
+  EXPECT_FALSE(window1_state->IsMinimized());
+}
+
+// Test that invisible windows (e.g. those belonging to an inactive user) should
+// not be affected by |MinimizeInactiveWindows| or |RestoreMinimizedWindows|.
+TEST_F(WallpaperWindowStateManagerTest, IgnoreInvisibleWindows) {
+  SimulateUserLogin(kTestAccount);
+  std::unique_ptr<aura::Window> wallpaper_picker_window(
+      CreateTestWindowInShellWithId(0));
+  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
+  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
+
+  wm::WindowState* wallpaper_picker_window_state =
+      wm::GetWindowState(wallpaper_picker_window.get());
+  wm::WindowState* window1_state = wm::GetWindowState(window1.get());
+  wm::WindowState* window2_state = wm::GetWindowState(window2.get());
+
+  window2->Hide();
+  EXPECT_FALSE(window2->IsVisible());
+
+  // Activates the wallpaper picker window and call the minimize function.
+  wallpaper_picker_window_state->Activate();
+  EXPECT_TRUE(wallpaper_picker_window_state->IsActive());
+  window_state_manager_->MinimizeInactiveWindows(GetUserIdHash(kTestAccount));
+
+  // The wallpaper picker window should not be minimized, and window 1 should be
+  // minimized.
+  EXPECT_FALSE(wallpaper_picker_window_state->IsMinimized());
+  EXPECT_TRUE(window1_state->IsMinimized());
+  // Window 2 should stay unminimized and invisible.
+  EXPECT_FALSE(window2_state->IsMinimized());
+  EXPECT_FALSE(window2->IsVisible());
+
+  // Destroy wallpaper picker window and call the restore function.
+  wallpaper_picker_window.reset();
+  window_state_manager_->RestoreMinimizedWindows(GetUserIdHash(kTestAccount));
+
+  // Windows 1 should no longer be minimized.
+  EXPECT_FALSE(window1_state->IsMinimized());
+  // Window 2 should stay unminimized and invisible.
+  EXPECT_FALSE(window2_state->IsMinimized());
+  EXPECT_FALSE(window2->IsVisible());
+}
+
+}  // namespace
+}  // namespace ash
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
index 31ff18d..6a18350 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api.cc
@@ -11,9 +11,7 @@
 #include <utility>
 #include <vector>
 
-#include "ash/shell.h"
 #include "ash/wallpaper/wallpaper_controller.h"
-#include "ash/wallpaper/wallpaper_window_state_manager.h"
 #include "base/command_line.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -45,6 +43,7 @@
 #include "extensions/browser/event_router.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/webui/web_ui_util.h"
+#include "ui/display/screen.h"
 #include "ui/strings/grit/app_locale_settings.h"
 #include "url/gurl.h"
 
@@ -582,11 +581,8 @@
 
 ExtensionFunction::ResponseAction
 WallpaperPrivateMinimizeInactiveWindowsFunction::Run() {
-  // TODO(mash): Convert to mojo API. http://crbug.com/557405
-  if (!ash_util::IsRunningInMash()) {
-    ash::WallpaperWindowStateManager::MinimizeInactiveWindows(
-        user_manager::UserManager::Get()->GetActiveUser()->username_hash());
-  }
+  WallpaperControllerClient::Get()->MinimizeInactiveWindows(
+      user_manager::UserManager::Get()->GetActiveUser()->username_hash());
   return RespondNow(NoArguments());
 }
 
@@ -600,11 +596,8 @@
 
 ExtensionFunction::ResponseAction
 WallpaperPrivateRestoreMinimizedWindowsFunction::Run() {
-  // TODO(mash): Convert to mojo API. http://crbug.com/557405
-  if (!ash_util::IsRunningInMash()) {
-    ash::WallpaperWindowStateManager::RestoreWindows(
-        user_manager::UserManager::Get()->GetActiveUser()->username_hash());
-  }
+  WallpaperControllerClient::Get()->RestoreMinimizedWindows(
+      user_manager::UserManager::Get()->GetActiveUser()->username_hash());
   return RespondNow(NoArguments());
 }
 
diff --git a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
index ce8f2f8..133b7e1 100644
--- a/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
+++ b/chrome/browser/chromeos/extensions/wallpaper_private_api_unittest.cc
@@ -6,415 +6,73 @@
 
 #include <memory>
 
-#include "ash/test/ash_test_base.h"
-#include "ash/wm/window_state.h"
-#include "base/command_line.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
 #include "chrome/browser/chromeos/settings/device_settings_service.h"
-#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
-#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
 #include "chrome/browser/ui/ash/test_wallpaper_controller.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "chromeos/cryptohome/system_salt_getter.h"
 #include "components/signin/core/account_id/account_id.h"
 #include "components/user_manager/scoped_user_manager.h"
+#include "content/public/test/test_browser_thread_bundle.h"
 #include "extensions/browser/api_test_utils.h"
-#include "ui/aura/test/test_windows.h"
-#include "ui/aura/window.h"
-#include "ui/aura/window_event_dispatcher.h"
+#include "testing/gtest/include/gtest/gtest.h"
 
-namespace chromeos {
 namespace {
 
-const char kTestAccount1[] = "user1@test.com";
-const char kTestAccount2[] = "user2@test.com";
+constexpr char kTestAccount[] = "user@test.com";
 
-class WallpaperPrivateApiUnittest : public ash::AshTestBase {
+}  // namespace
+
+class WallpaperPrivateApiUnittest : public testing::Test {
  public:
   WallpaperPrivateApiUnittest()
-      : fake_user_manager_(new FakeChromeUserManager()),
+      : thread_bundle_(std::make_unique<content::TestBrowserThreadBundle>()),
+        fake_user_manager_(new chromeos::FakeChromeUserManager()),
         scoped_user_manager_(base::WrapUnique(fake_user_manager_)) {}
 
- protected:
-  FakeChromeUserManager* fake_user_manager() { return fake_user_manager_; }
+  ~WallpaperPrivateApiUnittest() override = default;
 
-  const AccountId test_account_id1_ = AccountId::FromUserEmail(kTestAccount1);
-  const AccountId test_account_id2_ = AccountId::FromUserEmail(kTestAccount2);
+  void SetUp() override {
+    // Required for WallpaperControllerClient.
+    chromeos::DeviceSettingsService::Initialize();
+    chromeos::CrosSettings::Initialize();
+    chromeos::SystemSaltGetter::Initialize();
+  }
+
+  void TearDown() override {
+    chromeos::CrosSettings::Shutdown();
+    chromeos::DeviceSettingsService::Shutdown();
+    chromeos::SystemSaltGetter::Shutdown();
+  }
+
+ protected:
+  chromeos::FakeChromeUserManager* fake_user_manager() {
+    return fake_user_manager_;
+  }
 
  private:
-  FakeChromeUserManager* fake_user_manager_;
+  std::unique_ptr<content::TestBrowserThreadBundle> thread_bundle_;
+
+  chromeos::FakeChromeUserManager* fake_user_manager_;
+
   user_manager::ScopedUserManager scoped_user_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateApiUnittest);
 };
 
-bool RunMinimizeFunction() {
-  scoped_refptr<WallpaperPrivateMinimizeInactiveWindowsFunction> function(
-      new WallpaperPrivateMinimizeInactiveWindowsFunction());
-  return extensions::api_test_utils::RunFunction(function.get(), "[]", nullptr);
-}
-
-bool RunRestoreFunction() {
-  scoped_refptr<WallpaperPrivateRestoreMinimizedWindowsFunction> function(
-      new WallpaperPrivateRestoreMinimizedWindowsFunction());
-  return extensions::api_test_utils::RunFunction(function.get(), "[]", nullptr);
-}
-
-}  // namespace
-
-TEST_F(WallpaperPrivateApiUnittest, HideAndRestoreWindows) {
-  fake_user_manager()->AddUser(test_account_id1_);
-  std::unique_ptr<aura::Window> window4(CreateTestWindowInShellWithId(4));
-  std::unique_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
-  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
-  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
-  std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
-
-  ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
-  ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
-  ash::wm::WindowState* window2_state = ash::wm::GetWindowState(window2.get());
-  ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
-  ash::wm::WindowState* window4_state = ash::wm::GetWindowState(window4.get());
-
-  window3_state->Minimize();
-  window1_state->Maximize();
-
-  // Window 3 starts minimized, window 1 starts maximized.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_FALSE(window1_state->IsMinimized());
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_TRUE(window3_state->IsMinimized());
-  EXPECT_FALSE(window4_state->IsMinimized());
-
-  // We then activate window 0 (i.e. wallpaper picker) and call the minimize
-  // function.
-  window0_state->Activate();
-  EXPECT_TRUE(window0_state->IsActive());
-  EXPECT_TRUE(RunMinimizeFunction());
-
-  // All windows except window 0 should be minimized.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-  EXPECT_TRUE(window2_state->IsMinimized());
-  EXPECT_TRUE(window3_state->IsMinimized());
-  EXPECT_TRUE(window4_state->IsMinimized());
-
-  // Activates window 4 and then minimizes it.
-  window4_state->Activate();
-  window4_state->Minimize();
-
-  // Then we destroy window 0 and call the restore function.
-  window0.reset();
-  EXPECT_TRUE(RunRestoreFunction());
-
-  // Windows 1 and 2 should no longer be minimized. Window 1 should again
-  // be maximized. Window 3 should still be minimized. Window 4 should remain
-  // minimized since user interacted with it while wallpaper picker was open.
-  EXPECT_TRUE(window1_state->IsMaximized());
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_TRUE(window3_state->IsMinimized());
-  EXPECT_TRUE(window4_state->IsMinimized());
-}
-
-// Test for multiple calls to |MinimizeInactiveWindows| before call
-// |RestoreWindows|:
-// 1. If all window hasn't change their states, the following calls are noops.
-// 2. If some windows are manually unminimized, the following call will minimize
-// all the unminimized windows.
-TEST_F(WallpaperPrivateApiUnittest, HideAndManualUnminimizeWindows) {
-  fake_user_manager()->AddUser(test_account_id1_);
-  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
-  std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
-
-  ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
-  ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
-
-  // We then activate window 0 (i.e. wallpaper picker) and call the minimize
-  // function.
-  window0_state->Activate();
-  EXPECT_TRUE(window0_state->IsActive());
-  EXPECT_TRUE(RunMinimizeFunction());
-
-  // All windows except window 0 should be minimized.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  // Calls minimize function again should be an noop if window state didn't
-  // change.
-  EXPECT_TRUE(RunMinimizeFunction());
-
-  // All windows except window 0 should be minimized.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  // Manually unminimize window 1.
-  window1_state->Unminimize();
-  EXPECT_FALSE(window1_state->IsMinimized());
-  window0_state->Activate();
-
-  EXPECT_TRUE(RunMinimizeFunction());
-
-  // Window 1 should be minimized again.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  // Then we destroy window 0 and call the restore function.
-  window0.reset();
-  EXPECT_TRUE(RunRestoreFunction());
-
-  // Windows 1 should no longer be minimized.
-  EXPECT_FALSE(window1_state->IsMinimized());
-}
-
-class WallpaperPrivateApiMultiUserUnittest
-    : public WallpaperPrivateApiUnittest {
- public:
-  WallpaperPrivateApiMultiUserUnittest(): multi_user_window_manager_(nullptr) {}
-
-  void SetUp() override;
-  void TearDown() override;
-
- protected:
-  void SetUpMultiUserWindowManager(const AccountId& active_account_id);
-
-  void SwitchActiveUser(const AccountId& active_account_id);
-
-  MultiUserWindowManagerChromeOS* multi_user_window_manager() {
-    return multi_user_window_manager_;
-  }
-
- private:
-  MultiUserWindowManagerChromeOS* multi_user_window_manager_;
-  std::unique_ptr<WallpaperControllerClient> wallpaper_controller_client_;
-  TestWallpaperController test_wallpaper_controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateApiMultiUserUnittest);
-};
-
-void WallpaperPrivateApiMultiUserUnittest::SetUp() {
-  AshTestBase::SetUp();
-  DeviceSettingsService::Initialize();
-  CrosSettings::Initialize();
-  wallpaper_controller_client_ = std::make_unique<WallpaperControllerClient>();
-  wallpaper_controller_client_->InitForTesting(
-      test_wallpaper_controller_.CreateInterfacePtr());
-  fake_user_manager()->AddUser(test_account_id1_);
-  fake_user_manager()->AddUser(test_account_id2_);
-}
-
-void WallpaperPrivateApiMultiUserUnittest::TearDown() {
-  MultiUserWindowManager::DeleteInstance();
-  AshTestBase::TearDown();
-  wallpaper_controller_client_.reset();
-  CrosSettings::Shutdown();
-  DeviceSettingsService::Shutdown();
-}
-
-void WallpaperPrivateApiMultiUserUnittest::SetUpMultiUserWindowManager(
-    const AccountId& active_account_id) {
-  multi_user_window_manager_ =
-      new MultiUserWindowManagerChromeOS(active_account_id);
-  multi_user_window_manager_->Init();
-  MultiUserWindowManager::SetInstanceForTest(multi_user_window_manager_);
-  // We do not want animations while the test is going on.
-  multi_user_window_manager_->SetAnimationSpeedForTest(
-      MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED);
-  EXPECT_TRUE(multi_user_window_manager_);
-}
-
-void WallpaperPrivateApiMultiUserUnittest::SwitchActiveUser(
-    const AccountId& active_account_id) {
-  fake_user_manager()->SwitchActiveUser(active_account_id);
-  multi_user_window_manager_->ActiveUserChanged(
-      fake_user_manager()->FindUser(active_account_id));
-}
-
-// In multi profile mode, user may open wallpaper picker in one profile and
-// then switch to a different profile and open another wallpaper picker
-// without closing the first one.
-TEST_F(WallpaperPrivateApiMultiUserUnittest, HideAndRestoreWindowsTwoUsers) {
-  SetUpMultiUserWindowManager(test_account_id1_);
-
-  std::unique_ptr<aura::Window> window4(CreateTestWindowInShellWithId(4));
-  std::unique_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
-  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
-  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
-  std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
-
-  ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
-  ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
-  ash::wm::WindowState* window2_state = ash::wm::GetWindowState(window2.get());
-  ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
-  ash::wm::WindowState* window4_state = ash::wm::GetWindowState(window4.get());
-
-  multi_user_window_manager()->SetWindowOwner(window0.get(), test_account_id1_);
-  multi_user_window_manager()->SetWindowOwner(window1.get(), test_account_id1_);
-
-  // Set some windows to an inactive owner.
-  multi_user_window_manager()->SetWindowOwner(window2.get(), test_account_id2_);
-  multi_user_window_manager()->SetWindowOwner(window3.get(), test_account_id2_);
-  multi_user_window_manager()->SetWindowOwner(window4.get(), test_account_id2_);
-
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_FALSE(window1_state->IsMinimized());
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_FALSE(window3_state->IsMinimized());
-  EXPECT_FALSE(window4_state->IsMinimized());
-
-  // We then activate window 0 (i.e. wallpaper picker) and call the minimize
-  // function.
-  window0_state->Activate();
-  EXPECT_TRUE(window0_state->IsActive());
-  EXPECT_TRUE(RunMinimizeFunction());
-
-  // All windows except window 0 should be minimized.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  // All windows that belong to inactive user should not be affected.
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_FALSE(window3_state->IsMinimized());
-  EXPECT_FALSE(window4_state->IsMinimized());
-
-  // Activate kTestAccount2. kTestAccount1 becomes inactive user.
-  SwitchActiveUser(test_account_id2_);
-
-  window2_state->Activate();
-  EXPECT_TRUE(window2_state->IsActive());
-  EXPECT_TRUE(RunMinimizeFunction());
-
-  // All windows except window 2 should be minimized.
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_TRUE(window3_state->IsMinimized());
-  EXPECT_TRUE(window4_state->IsMinimized());
-
-  // All windows that belong to inactive user should not be affected.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  // Destroy window 4. Nothing should happen to other windows.
-  window4_state->Unminimize();
-  window4.reset();
-
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_TRUE(window3_state->IsMinimized());
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  // Then we destroy window 2 and call the restore function.
-  window2.reset();
-  EXPECT_TRUE(RunRestoreFunction());
-
-  EXPECT_FALSE(window3_state->IsMinimized());
-
-  // All windows that belong to inactive user should not be affected.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  SwitchActiveUser(test_account_id1_);
-
-  // Then we destroy window 0 and call the restore function.
-  window0.reset();
-  EXPECT_TRUE(RunRestoreFunction());
-
-  EXPECT_FALSE(window1_state->IsMinimized());
-  EXPECT_FALSE(window3_state->IsMinimized());
-}
-
-// In multi profile mode, user may teleport windows. Teleported window should
-// also be minimized when open wallpaper picker.
-TEST_F(WallpaperPrivateApiMultiUserUnittest, HideTeleportedWindow) {
-  SetUpMultiUserWindowManager(AccountId::FromUserEmail(kTestAccount1));
-
-  std::unique_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
-  std::unique_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
-  std::unique_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
-  std::unique_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
-
-  ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
-  ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
-  ash::wm::WindowState* window2_state = ash::wm::GetWindowState(window2.get());
-  ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
-
-  multi_user_window_manager()->SetWindowOwner(window0.get(), test_account_id1_);
-  multi_user_window_manager()->SetWindowOwner(window1.get(), test_account_id1_);
-
-  // Set some windows to an inactive owner.
-  multi_user_window_manager()->SetWindowOwner(window2.get(), test_account_id2_);
-  multi_user_window_manager()->SetWindowOwner(window3.get(), test_account_id2_);
-
-  // Teleport window2 to kTestAccount1.
-  multi_user_window_manager()->ShowWindowForUser(window2.get(),
-                                                 test_account_id1_);
-
-  // Initial window state. All windows shouldn't be minimized.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_FALSE(window1_state->IsMinimized());
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_FALSE(window3_state->IsMinimized());
-
-  // We then activate window 0 (i.e. wallpaper picker) and call the minimize
-  // function.
-  window0_state->Activate();
-  EXPECT_TRUE(window0_state->IsActive());
-  EXPECT_TRUE(RunMinimizeFunction());
-
-  // All windows except window 0 should be minimized.
-  EXPECT_FALSE(window0_state->IsMinimized());
-  EXPECT_TRUE(window1_state->IsMinimized());
-
-  // Teleported window should also be minimized.
-  EXPECT_TRUE(window2_state->IsMinimized());
-  // Other window should remain the same.
-  EXPECT_FALSE(window3_state->IsMinimized());
-
-  // Then we destroy window 0 and call the restore function.
-  window0.reset();
-  EXPECT_TRUE(RunRestoreFunction());
-
-  EXPECT_FALSE(window1_state->IsMinimized());
-  EXPECT_FALSE(window2_state->IsMinimized());
-  EXPECT_FALSE(window3_state->IsMinimized());
-}
-
-class WallpaperPrivateApiResetWallpaperUnittest
-    : public WallpaperPrivateApiUnittest {
- public:
-  WallpaperPrivateApiResetWallpaperUnittest() = default;
-
-  void SetUp() override {
-    WallpaperPrivateApiUnittest::SetUp();
-
-    // Required for WallpaperControllerClient.
-    DeviceSettingsService::Initialize();
-    CrosSettings::Initialize();
-  }
-
-  void TearDown() override {
-    // Required for WallpaperControllerClient.
-    CrosSettings::Shutdown();
-    DeviceSettingsService::Shutdown();
-
-    WallpaperPrivateApiUnittest::TearDown();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateApiResetWallpaperUnittest);
-};
-
-// Test wallpaperPrivate.resetWallpaper() function.
-// Regression test for https://crbug.com/830157.
-TEST_F(WallpaperPrivateApiResetWallpaperUnittest, Basic) {
-  SystemSaltGetter::Get()->SetRawSaltForTesting(
-      SystemSaltGetter::RawSalt({1, 2, 3, 4, 5, 6, 7, 8}));
+// Test wallpaperPrivate.resetWallpaper() function. Regression test for
+// https://crbug.com/830157.
+TEST_F(WallpaperPrivateApiUnittest, ResetWallpaper) {
+  chromeos::SystemSaltGetter::Get()->SetRawSaltForTesting(
+      chromeos::SystemSaltGetter::RawSalt({1, 2, 3, 4, 5, 6, 7, 8}));
 
   WallpaperControllerClient client;
   TestWallpaperController test_controller;
   client.InitForTesting(test_controller.CreateInterfacePtr());
-  fake_user_manager()->AddUser(test_account_id1_);
+  fake_user_manager()->AddUser(AccountId::FromUserEmail(kTestAccount));
 
   {
     auto function =
@@ -428,4 +86,3 @@
   EXPECT_EQ(1, test_controller.set_default_wallpaper_count());
 }
 
-}  // namespace chromeos
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index c44fa01..fdb84fb 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -136,6 +136,16 @@
   NOTIMPLEMENTED();
 }
 
+void TestWallpaperController::MinimizeInactiveWindows(
+    const std::string& user_id_hash) {
+  NOTIMPLEMENTED();
+}
+
+void TestWallpaperController::RestoreMinimizedWindows(
+    const std::string& user_id_hash) {
+  NOTIMPLEMENTED();
+}
+
 void TestWallpaperController::AddObserver(
     ash::mojom::WallpaperObserverAssociatedPtrInfo observer) {
   ash::mojom::WallpaperObserverAssociatedPtr observer_ptr;
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index 60fd580..55a8ccb8 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -84,6 +84,8 @@
                              const std::string& wallpaper_files_id) override;
   void SetAnimationDuration(base::TimeDelta animation_duration) override;
   void OpenWallpaperPickerIfAllowed() override;
+  void MinimizeInactiveWindows(const std::string& user_id_hash) override;
+  void RestoreMinimizedWindows(const std::string& user_id_hash) override;
   void AddObserver(
       ash::mojom::WallpaperObserverAssociatedPtrInfo observer) override;
   void GetWallpaperImage(
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.cc b/chrome/browser/ui/ash/wallpaper_controller_client.cc
index f23df58..0b8ca53 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.cc
@@ -359,6 +359,16 @@
   wallpaper_controller_->OpenWallpaperPickerIfAllowed();
 }
 
+void WallpaperControllerClient::MinimizeInactiveWindows(
+    const std::string& user_id_hash) {
+  wallpaper_controller_->MinimizeInactiveWindows(user_id_hash);
+}
+
+void WallpaperControllerClient::RestoreMinimizedWindows(
+    const std::string& user_id_hash) {
+  wallpaper_controller_->RestoreMinimizedWindows(user_id_hash);
+}
+
 void WallpaperControllerClient::AddObserver(
     ash::mojom::WallpaperObserverAssociatedPtrInfo observer) {
   wallpaper_controller_->AddObserver(std::move(observer));
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.h b/chrome/browser/ui/ash/wallpaper_controller_client.h
index 97b3108..cfc1db5 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.h
@@ -65,6 +65,8 @@
   void RemovePolicyWallpaper(const AccountId& account_id);
   void SetAnimationDuration(const base::TimeDelta& animation_duration);
   void OpenWallpaperPickerIfAllowed();
+  void MinimizeInactiveWindows(const std::string& user_id_hash);
+  void RestoreMinimizedWindows(const std::string& user_id_hash);
   void AddObserver(ash::mojom::WallpaperObserverAssociatedPtrInfo observer);
   void GetWallpaperImage(
       ash::mojom::WallpaperController::GetWallpaperImageCallback callback);