Revert "cros: Merge part of TabletModeClient with TabletMode"

This reverts commit 5d46f946229cd775e25ad46579315e628c09c943.

Reason for revert: Speculative revert: TopControlsSlideControllerTest fails frequently after this patch.

Original change's description:
> cros: Merge part of TabletModeClient with TabletMode
>
> - Make ash::TabletMode a concrete class that holds a bool of whether
>   tablet mode is enabled and notifies observers when its changed;
> - Make ash::TabletModeController an ash::TabletMode::Delegate to
>   provide real state and test support;
> - Move tablet mode observing part from TabletModeClient
>   into ash::TabletMode. This leaves TabletModeClient only
>   to track and enable mobile behavior for tabs.
>
> Bug: 974238
> Change-Id: Ifda13f72a5016d62439bf96087a5fae3be9df50d
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1665553
> Commit-Queue: Xiyuan Xia <xiyuan@chromium.org>
> Reviewed-by: Scott Violet <sky@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#671340}

TBR=xiyuan@chromium.org,sky@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 974238
Change-Id: I71d01fd8bc56c7d8e45baf8c0a974b93dcd6cb38
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1672855
Commit-Queue: Huanzhong Huang <huanzhong@chromium.org>
Reviewed-by: Huanzhong Huang <huanzhong@chromium.org>
Cr-Commit-Position: refs/heads/master@{#671635}
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index e6c7b7b..04b66a1 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -290,7 +290,6 @@
     "power_utils_unittest.cc",
     "rounded_corner_decorator_unittest.cc",
     "shelf_model_unittest.cc",
-    "tablet_mode_unittest.cc",
     "voice_interaction_controller_unittest.cc",
   ]
 
diff --git a/ash/public/cpp/tablet_mode.cc b/ash/public/cpp/tablet_mode.cc
index e9f6054..a0e5be2 100644
--- a/ash/public/cpp/tablet_mode.cc
+++ b/ash/public/cpp/tablet_mode.cc
@@ -4,62 +4,26 @@
 
 #include "ash/public/cpp/tablet_mode.h"
 
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "base/logging.h"
-#include "base/no_destructor.h"
 
 namespace ash {
 
 namespace {
-
-// Singleton delegate instance.
-TabletMode::Delegate* g_delegate = nullptr;
-
-}  // namespace
-
-TabletMode::Delegate::Delegate() {
-  DCHECK(!g_delegate);
-  g_delegate = this;
-}
-
-TabletMode::Delegate::~Delegate() {
-  DCHECK_EQ(g_delegate, this);
-  g_delegate = nullptr;
+TabletMode* g_instance = nullptr;
 }
 
 TabletMode* TabletMode::Get() {
-  static base::NoDestructor<TabletMode> instance;
-  return instance.get();
+  return g_instance;
 }
 
-TabletMode::TabletMode() = default;
-TabletMode::~TabletMode() = default;
-
-bool TabletMode::InTabletMode() const {
-  // |g_delegate| could be null in unit tests.
-  if (!g_delegate)
-    return false;
-
-  return g_delegate->InTabletMode();
+TabletMode::TabletMode() {
+  DCHECK_EQ(nullptr, g_instance);
+  g_instance = this;
 }
 
-void TabletMode::SetEnabledForTest(bool enabled) {
-  DCHECK(g_delegate);
-  g_delegate->SetEnabledForTest(enabled);
-}
-
-void TabletMode::AddObserver(TabletModeToggleObserver* observer) {
-  observers_.AddObserver(observer);
-}
-
-void TabletMode::RemoveObserver(TabletModeToggleObserver* observer) {
-  observers_.RemoveObserver(observer);
-}
-
-void TabletMode::NotifyTabletModeChanged() {
-  const bool in_tablet_mode = InTabletMode();
-  for (auto& observer : observers_)
-    observer.OnTabletModeToggled(in_tablet_mode);
+TabletMode::~TabletMode() {
+  DCHECK_EQ(this, g_instance);
+  g_instance = nullptr;
 }
 
 }  // namespace ash
diff --git a/ash/public/cpp/tablet_mode.h b/ash/public/cpp/tablet_mode.h
index c807214..9f71113c 100644
--- a/ash/public/cpp/tablet_mode.h
+++ b/ash/public/cpp/tablet_mode.h
@@ -6,63 +6,29 @@
 #define ASH_PUBLIC_CPP_TABLET_MODE_H_
 
 #include "ash/public/cpp/ash_public_export.h"
-#include "base/macros.h"
-#include "base/observer_list.h"
-
-namespace base {
-template <typename T>
-class NoDestructor;
-}  // namespace base
 
 namespace ash {
 
-class TabletModeController;
 class TabletModeToggleObserver;
-class TestTabletModeDelegate;
 
-// TabletMode info that is maintained by Ash and allows Chrome to be informed
-// when it changes.
-class ASH_PUBLIC_EXPORT TabletMode final {
+// An interface implemented by Ash that allows Chrome to be informed of changes
+// to tablet mode state.
+class ASH_PUBLIC_EXPORT TabletMode {
  public:
-  // Delegate interface to access tablet mode and change it.
-  class Delegate {
-   public:
-    // Invoked to get tablet mode. Returns true if the system is in tablet mode.
-    virtual bool InTabletMode() const = 0;
-
-    // Invoked to force tablet mode for test.
-    virtual void SetEnabledForTest(bool enabled) = 0;
-
-   protected:
-    Delegate();
-    virtual ~Delegate();
-  };
-
   // Returns the singleton instance.
   static TabletMode* Get();
 
+  virtual void SetTabletModeToggleObserver(
+      TabletModeToggleObserver* observer) = 0;
+
   // Returns true if the system is in tablet mode.
-  bool InTabletMode() const;
+  virtual bool InTabletMode() const = 0;
 
-  void SetEnabledForTest(bool enabled);
+  virtual void SetEnabledForTest(bool enabled) = 0;
 
-  void AddObserver(TabletModeToggleObserver* observer);
-  void RemoveObserver(TabletModeToggleObserver* observer);
-
- private:
-  friend class base::NoDestructor<TabletMode>;
-  friend class TabletModeController;
-  friend class TestTabletModeDelegate;
-
+ protected:
   TabletMode();
-  ~TabletMode();
-
-  // Invoked by TabletModeController to notify tablet mode is changed.
-  void NotifyTabletModeChanged();
-
-  base::ObserverList<TabletModeToggleObserver> observers_;
-
-  DISALLOW_COPY_AND_ASSIGN(TabletMode);
+  virtual ~TabletMode();
 };
 
 }  // namespace ash
diff --git a/ash/public/cpp/tablet_mode_toggle_observer.h b/ash/public/cpp/tablet_mode_toggle_observer.h
index 7166aae..4bd0d20 100644
--- a/ash/public/cpp/tablet_mode_toggle_observer.h
+++ b/ash/public/cpp/tablet_mode_toggle_observer.h
@@ -6,17 +6,18 @@
 #define ASH_PUBLIC_CPP_TABLET_MODE_TOGGLE_OBSERVER_H_
 
 #include "ash/public/cpp/ash_public_export.h"
-#include "base/observer_list_types.h"
 
 namespace ash {
 
 // A simplified observer which allows Ash to inform Chrome when tablet mode has
 // been enabled or disabled.
-class ASH_PUBLIC_EXPORT TabletModeToggleObserver
-    : public base::CheckedObserver {
+class ASH_PUBLIC_EXPORT TabletModeToggleObserver {
  public:
   // Fired after the tablet mode has been toggled.
   virtual void OnTabletModeToggled(bool enabled) = 0;
+
+ protected:
+  virtual ~TabletModeToggleObserver() = default;
 };
 
 }  // namespace ash
diff --git a/ash/public/cpp/tablet_mode_unittest.cc b/ash/public/cpp/tablet_mode_unittest.cc
deleted file mode 100644
index 093c089..0000000
--- a/ash/public/cpp/tablet_mode_unittest.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2019 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/public/cpp/tablet_mode.h"
-
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
-#include "base/macros.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace ash {
-
-class TestTabletModeClientObserver : public TabletModeToggleObserver {
- public:
-  TestTabletModeClientObserver() = default;
-  ~TestTabletModeClientObserver() override = default;
-
-  // TabletModeToggleObserver:
-  void OnTabletModeToggled(bool enabled) override {
-    ++toggle_count_;
-    last_toggle_ = enabled;
-  }
-
-  int toggle_count_ = 0;
-  bool last_toggle_ = false;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TestTabletModeClientObserver);
-};
-
-class TestTabletModeDelegate : public TabletMode::Delegate {
- public:
-  TestTabletModeDelegate() = default;
-  ~TestTabletModeDelegate() override = default;
-
-  // TabletMode::Delegate:
-  bool InTabletMode() const override { return in_tablet_mode_; }
-
-  void SetEnabledForTest(bool enabled) override {
-    in_tablet_mode_ = enabled;
-    TabletMode::Get()->NotifyTabletModeChanged();
-  }
-
- private:
-  bool in_tablet_mode_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(TestTabletModeDelegate);
-};
-
-using TabletModeTest = testing::Test;
-
-TEST_F(TabletModeTest, Observers) {
-  TestTabletModeDelegate delegate;
-
-  TestTabletModeClientObserver observer;
-  TabletMode::Get()->AddObserver(&observer);
-
-  // Observer is not notified with state when added.
-  EXPECT_EQ(0, observer.toggle_count_);
-
-  // Setting state notifies observer.
-  TabletMode::Get()->SetEnabledForTest(true);
-  EXPECT_EQ(1, observer.toggle_count_);
-  EXPECT_TRUE(observer.last_toggle_);
-
-  TabletMode::Get()->SetEnabledForTest(false);
-  EXPECT_EQ(2, observer.toggle_count_);
-  EXPECT_FALSE(observer.last_toggle_);
-
-  TabletMode::Get()->RemoveObserver(&observer);
-}
-
-}  // namespace ash
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.cc b/ash/wm/tablet_mode/tablet_mode_controller.cc
index 5c17a50..126f095 100644
--- a/ash/wm/tablet_mode/tablet_mode_controller.cc
+++ b/ash/wm/tablet_mode/tablet_mode_controller.cc
@@ -13,6 +13,7 @@
 #include "ash/public/cpp/fps_counter.h"
 #include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/tablet_mode.h"
+#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "ash/root_window_controller.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
@@ -331,6 +332,13 @@
     DeleteScreenshot();
 }
 
+void TabletModeController::SetTabletModeToggleObserver(
+    TabletModeToggleObserver* observer) {
+  DCHECK(observer);
+  DCHECK(!toggle_observer_);
+  toggle_observer_ = observer;
+}
+
 bool TabletModeController::InTabletMode() const {
   return !!tablet_mode_window_manager_;
 }
@@ -620,7 +628,8 @@
       observer.OnTabletModeEnded();
 
     state_ = State::kInClamshellMode;
-    TabletMode::Get()->NotifyTabletModeChanged();
+    if (toggle_observer_)  // Null at startup and in tests.
+      toggle_observer_->OnTabletModeToggled(false);
     VLOG(1) << "Exit tablet mode.";
   }
 
@@ -919,7 +928,8 @@
   }
 
   state_ = State::kInTabletMode;
-  TabletMode::Get()->NotifyTabletModeChanged();
+  if (toggle_observer_)  // Null at startup and in tests.
+    toggle_observer_->OnTabletModeToggled(true);
   VLOG(1) << "Enter tablet mode.";
 }
 
diff --git a/ash/wm/tablet_mode/tablet_mode_controller.h b/ash/wm/tablet_mode/tablet_mode_controller.h
index 1afe742..bc2ef66 100644
--- a/ash/wm/tablet_mode/tablet_mode_controller.h
+++ b/ash/wm/tablet_mode/tablet_mode_controller.h
@@ -67,7 +67,7 @@
 class ASH_EXPORT TabletModeController
     : public AccelerometerReader::Observer,
       public chromeos::PowerManagerClient::Observer,
-      public TabletMode::Delegate,
+      public TabletMode,
       public ShellObserver,
       public WindowTreeHostManager::Observer,
       public SessionObserver,
@@ -121,7 +121,8 @@
   // clamshell.
   void StopObservingAnimation(bool record_stats, bool delete_screenshot);
 
-  // TabletMode::Delegate:
+  // TabletMode:
+  void SetTabletModeToggleObserver(TabletModeToggleObserver* observer) override;
   bool InTabletMode() const override;
   void SetEnabledForTest(bool enabled) override;
 
@@ -359,6 +360,10 @@
   gfx::Vector3dF base_smoothed_;
   gfx::Vector3dF lid_smoothed_;
 
+  // A simplified observer that only gets notified of entering or exiting tablet
+  // mode.
+  TabletModeToggleObserver* toggle_observer_ = nullptr;
+
   // Tracks whether a flag is used to force ui mode.
   UiMode force_ui_mode_ = UiMode::kNone;
 
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index edac44a..ea14910 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -388,7 +388,6 @@
 #include "services/audio/public/mojom/constants.mojom.h"
 #include "services/video_capture/public/mojom/constants.mojom.h"
 #elif defined(OS_CHROMEOS)
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "chrome/browser/ash_service_registry.h"
 #include "chrome/browser/chromeos/arc/fileapi/arc_content_file_system_backend_delegate.h"
@@ -414,6 +413,7 @@
 #include "chrome/browser/chromeos/system/input_device_settings.h"
 #include "chrome/browser/speech/tts_chromeos.h"
 #include "chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/browser_dialogs.h"
 #include "chrome/services/cups_proxy/cups_proxy_service.h"
 #include "chrome/services/cups_proxy/public/mojom/constants.mojom.h"
@@ -1535,7 +1535,8 @@
 #if defined(OS_ANDROID)
   return true;
 #elif defined(OS_CHROMEOS)
-  return ash::TabletMode::Get()->InTabletMode();
+  return TabletModeClient::Get() &&
+         TabletModeClient::Get()->tablet_mode_enabled();
 #else
   return false;
 #endif  // defined(OS_ANDROID)
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
index 9ad5aab..0d16305 100644
--- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
+++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service.cc
@@ -9,8 +9,6 @@
 
 #include "ash/public/cpp/ash_pref_names.h"
 #include "ash/public/cpp/keyboard/keyboard_switches.h"
-#include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "base/bind.h"
 #include "base/logging.h"
 #include "base/memory/singleton.h"
@@ -22,6 +20,8 @@
 #include "chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_bridge_impl.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/common/pref_names.h"
 #include "components/arc/arc_browser_context_keyed_service_factory_base.h"
 #include "components/arc/common/ime_struct_traits.h"
@@ -194,13 +194,12 @@
 };
 
 class ArcInputMethodManagerService::TabletModeObserver
-    : public ash::TabletModeToggleObserver {
+    : public TabletModeClientObserver {
  public:
   explicit TabletModeObserver(ArcInputMethodManagerService* owner)
       : owner_(owner) {}
   ~TabletModeObserver() override = default;
 
-  // ash::TabletModeToggleObserver overrides:
   void OnTabletModeToggled(bool enabled) override {
     owner_->UpdateArcIMEAllowed();
     owner_->NotifyInputMethodManagerObservers(enabled);
@@ -254,7 +253,10 @@
       std::make_unique<InputMethodEngineObserver>(this),
       proxy_ime_extension_id_.c_str(), profile_);
 
-  ash::TabletMode::Get()->AddObserver(tablet_mode_observer_.get());
+  // TabletModeClient should be already created here because it's created in
+  // PreProfileInit() and this service is created in PostProfileInit().
+  DCHECK(TabletModeClient::Get());
+  TabletModeClient::Get()->AddObserver(tablet_mode_observer_.get());
 
   chromeos::AccessibilityManager* accessibility_manager =
       chromeos::AccessibilityManager::Get();
@@ -302,7 +304,8 @@
   if (ui::IMEBridge::Get())
     ui::IMEBridge::Get()->RemoveObserver(this);
 
-  ash::TabletMode::Get()->RemoveObserver(tablet_mode_observer_.get());
+  if (TabletModeClient::Get())
+    TabletModeClient::Get()->RemoveObserver(tablet_mode_observer_.get());
 
   auto* imm = chromeos::input_method::InputMethodManager::Get();
   imm->RemoveImeMenuObserver(this);
@@ -740,7 +743,7 @@
   const bool is_normal_vk_enabled =
       !profile_->GetPrefs()->GetBoolean(
           ash::prefs::kAccessibilityVirtualKeyboardEnabled) &&
-      ash::TabletMode::Get()->InTabletMode();
+      TabletModeClient::Get()->tablet_mode_enabled();
   return is_command_line_flag_enabled || is_normal_vk_enabled;
 }
 
diff --git a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
index f8bb8ad..c98e0f0 100644
--- a/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
+++ b/chrome/browser/chromeos/arc/input_method_manager/arc_input_method_manager_service_unittest.cc
@@ -11,8 +11,6 @@
 
 #include "ash/public/cpp/ash_pref_names.h"
 #include "ash/public/cpp/keyboard/keyboard_switches.h"
-#include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/cpp/test/shell_test_api.h"
 #include "base/macros.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/run_loop.h"
@@ -23,6 +21,7 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/chromeos/arc/input_method_manager/test_input_method_manager_bridge.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client_test_helper.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/chrome_ash_test_base.h"
 #include "chrome/test/base/testing_profile.h"
@@ -36,7 +35,6 @@
 #include "ui/base/ime/ime_bridge.h"
 #include "ui/base/ime/mock_ime_input_context_handler.h"
 #include "ui/base/ime/mock_input_method.h"
-#include "ui/views/widget/widget.h"
 
 namespace arc {
 namespace {
@@ -186,7 +184,7 @@
   TestingProfile* profile() { return profile_.get(); }
 
   void ToggleTabletMode(bool enabled) {
-    ash::ShellTestApi().SetTabletModeEnabledForTest(enabled);
+    tablet_mode_client_->OnTabletModeToggled(enabled);
   }
 
   void SetUp() override {
@@ -196,10 +194,7 @@
     chromeos::input_method::InputMethodManager::Initialize(
         input_method_manager_);
     profile_ = std::make_unique<TestingProfile>();
-
-    // Create a test widget so that enabling tablet mode does not show app list
-    // whose search box could mess with the tests.
-    widget_ = CreateTestWidget();
+    tablet_mode_client_ = std::make_unique<TabletModeClient>();
 
     chrome_keyboard_controller_client_test_helper_ =
         ChromeKeyboardControllerClientTestHelper::InitializeForAsh();
@@ -223,14 +218,17 @@
     // |chrome_keyboard_controller_client_test_helper_| observes the keyboard
     // destruction.
     chrome_keyboard_controller_client_test_helper_.reset();
+    // To match ChromeBrowserMainExtraPartsAsh, shut down the TabletModeClient
+    // after Shell.
+    tablet_mode_client_.reset();
   }
 
  private:
   std::unique_ptr<ArcServiceManager> arc_service_manager_;
   std::unique_ptr<TestingProfile> profile_;
+  std::unique_ptr<TabletModeClient> tablet_mode_client_;
   std::unique_ptr<ChromeKeyboardControllerClientTestHelper>
       chrome_keyboard_controller_client_test_helper_;
-  std::unique_ptr<views::Widget> widget_;
   TestInputMethodManager* input_method_manager_ = nullptr;
   TestInputMethodManagerBridge* test_bridge_ = nullptr;  // Owned by |service_|
   ArcInputMethodManagerService* service_ = nullptr;
diff --git a/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc b/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc
index 91dedc19..ae99152b 100644
--- a/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc
+++ b/chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/chromeos/chrome_content_browser_client_chromeos_part.h"
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/feature_list.h"
 #include "chrome/browser/browser_features.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/search/search.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -73,8 +73,10 @@
 void OverrideWebkitPrefsForTabletMode(content::WebContents* contents,
                                       content::WebPreferences* web_prefs) {
   // Enable some mobile-like behaviors when in tablet mode on Chrome OS.
-  if (!ash::TabletMode::Get()->InTabletMode())
+  if (!TabletModeClient::Get() ||
+      !TabletModeClient::Get()->tablet_mode_enabled()) {
     return;
+  }
 
   // Do this only for webcontents displayed in browsers and are not of hosted
   // apps.
diff --git a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
index e8328a58..5470d3ba 100644
--- a/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/chromeos/extensions/autotest_private/autotest_private_api.cc
@@ -51,6 +51,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/browser/ui/ash/launcher/shelf_spinner_controller.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/views/crostini/crostini_installer_view.h"
 #include "chrome/browser/ui/views/crostini/crostini_uninstaller_view.h"
 #include "chrome/common/chrome_features.h"
@@ -1554,8 +1555,8 @@
 AutotestPrivateIsTabletModeEnabledFunction::Run() {
   DVLOG(1) << "AutotestPrivateIsTabletModeEnabledFunction";
 
-  return RespondNow(OneArgument(
-      std::make_unique<base::Value>(ash::TabletMode::Get()->InTabletMode())));
+  return RespondNow(OneArgument(std::make_unique<base::Value>(
+      TabletModeClient::Get()->tablet_mode_enabled())));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/chromeos/first_run/first_run.cc b/chrome/browser/chromeos/first_run/first_run.cc
index 762eea9..8c880f20 100644
--- a/chrome/browser/chromeos/first_run/first_run.cc
+++ b/chrome/browser/chromeos/first_run/first_run.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/chromeos/first_run/first_run.h"
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/command_line.h"
 #include "base/macros.h"
 #include "base/metrics/histogram_macros.h"
@@ -20,6 +19,7 @@
 #include "chrome/browser/prefs/pref_service_syncable_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/common/chrome_switches.h"
@@ -77,7 +77,8 @@
     return;
   }
 
-  if (ash::TabletMode::Get()->InTabletMode())
+  // TabletModeClient does not exist in some tests.
+  if (TabletModeClient::Get() && TabletModeClient::Get()->tablet_mode_enabled())
     return;
 
   if (profile->GetProfilePolicyConnector()->IsManaged())
diff --git a/chrome/browser/chromeos/login/login_auth_recorder.cc b/chrome/browser/chromeos/login/login_auth_recorder.cc
index e0e37dc0..e95299e1 100644
--- a/chrome/browser/chromeos/login/login_auth_recorder.cc
+++ b/chrome/browser/chromeos/login/login_auth_recorder.cc
@@ -4,8 +4,8 @@
 
 #include "chrome/browser/chromeos/login/login_auth_recorder.h"
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/metrics/histogram_macros.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "components/session_manager/core/session_manager.h"
 
 namespace chromeos {
@@ -114,7 +114,7 @@
   }
 
   // Record usage of PIN / Password / Smartlock / Fingerprint in lock screen.
-  const bool is_tablet_mode = ash::TabletMode::Get()->InTabletMode();
+  const bool is_tablet_mode = TabletModeClient::Get()->tablet_mode_enabled();
   if (is_tablet_mode) {
     UMA_HISTOGRAM_ENUMERATION("Ash.Login.Lock.AuthMethod.Used.TabletMode",
                               method, AuthMethod::kMethodCount);
diff --git a/chrome/browser/chromeos/login/login_auth_recorder_browsertest.cc b/chrome/browser/chromeos/login/login_auth_recorder_browsertest.cc
index e665f248..4f9f960 100644
--- a/chrome/browser/chromeos/login/login_auth_recorder_browsertest.cc
+++ b/chrome/browser/chromeos/login/login_auth_recorder_browsertest.cc
@@ -4,9 +4,9 @@
 
 #include "chrome/browser/chromeos/login/login_auth_recorder.h"
 
-#include "ash/public/cpp/test/shell_test_api.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/ui/ash/login_screen_client.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "components/session_manager/core/session_manager.h"
 
@@ -40,7 +40,7 @@
   }
 
   void EnableTabletMode(bool enable) {
-    ash::ShellTestApi().SetTabletModeEnabledForTest(enable);
+    TabletModeClient::Get()->OnTabletModeToggled(enable);
   }
 
   LoginAuthRecorder* metrics_recorder() {
diff --git a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
index a275f3e..4094295 100644
--- a/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
+++ b/chrome/browser/chromeos/login/oobe_interactive_ui_test.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/cpp/test/shell_test_api.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/macros.h"
@@ -30,6 +29,7 @@
 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
 #include "chrome/browser/chromeos/login/wizard_controller.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/assistant_optin_flow_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
@@ -47,7 +47,6 @@
 #include "net/dns/mock_host_resolver.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
-#include "ui/display/display_switches.h"
 
 using net::test_server::BasicHttpResponse;
 using net::test_server::HttpRequest;
@@ -378,13 +377,8 @@
   }
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
-    if (params_.is_tablet) {
-      // Makes the device capable to entering tablet mode.
+    if (params_.is_tablet)
       command_line->AppendSwitch(ash::switches::kAshEnableTabletMode);
-      // Having an active internal display so that tablet mode does not end
-      // on display config change.
-      command_line->AppendSwitch(::switches::kUseFirstDisplayAsInternal);
-    }
 
     if (params_.arc_state != ArcState::kNotAvailable) {
       arc::SetArcAvailableCommandLineForTesting(command_line);
@@ -412,7 +406,7 @@
 
   void SetUpOnMainThread() override {
     if (params_.is_tablet)
-      ash::ShellTestApi().SetTabletModeEnabledForTest(true);
+      TabletModeClient::Get()->OnTabletModeToggled(true);
 
     if (params_.arc_state != ArcState::kNotAvailable) {
       // Init ArcSessionManager for testing.
diff --git a/chrome/browser/chromeos/login/screens/discover_screen.cc b/chrome/browser/chromeos/login/screens/discover_screen.cc
index fd788654..590f2f48 100644
--- a/chrome/browser/chromeos/login/screens/discover_screen.cc
+++ b/chrome/browser/chromeos/login/screens/discover_screen.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/chromeos/login/screens/discover_screen.h"
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/logging.h"
 #include "chrome/browser/chromeos/login/quick_unlock/quick_unlock_utils.h"
 #include "chrome/browser/chromeos/login/users/chrome_user_manager_util.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/webui/chromeos/login/discover_screen_handler.h"
 #include "components/prefs/pref_service.h"
 
@@ -34,7 +34,7 @@
 void DiscoverScreen::Show() {
   PrefService* prefs = ProfileManager::GetActiveUserProfile()->GetPrefs();
   if (chrome_user_manager_util::IsPublicSessionOrEphemeralLogin() ||
-      !ash::TabletMode::Get()->InTabletMode() ||
+      !TabletModeClient::Get()->tablet_mode_enabled() ||
       !chromeos::quick_unlock::IsPinEnabled(prefs) ||
       chromeos::quick_unlock::IsPinDisabledByPolicy(prefs)) {
     exit_callback_.Run();
diff --git a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
index 15414697..475910f 100644
--- a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
+++ b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.cc
@@ -11,13 +11,13 @@
 #include "ash/public/cpp/login_screen.h"
 #include "ash/public/cpp/login_screen_model.h"
 #include "ash/public/cpp/shell_window_ids.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "chrome/browser/chromeos/login/ui/login_display_host_mojo.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/ash/login_screen_client.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/gaia_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
@@ -209,7 +209,7 @@
     : controller_(controller),
       size_(gfx::Size(kGaiaDialogWidth, kGaiaDialogHeight)) {
   display_observer_.Add(display::Screen::GetScreen());
-  tablet_mode_observer_.Add(ash::TabletMode::Get());
+  tablet_mode_observer_.Add(TabletModeClient::Get());
   keyboard_observer_.Add(ChromeKeyboardControllerClient::Get());
 
   accel_map_[ui::Accelerator(
diff --git a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h
index 423dd22..edac1eb 100644
--- a/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h
+++ b/chrome/browser/chromeos/login/ui/oobe_ui_dialog_delegate.h
@@ -8,21 +8,19 @@
 #include <string>
 
 #include "ash/public/cpp/login_types.h"
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observer.h"
 #include "base/strings/string16.h"
 #include "chrome/browser/chromeos/login/screens/error_screen.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
 #include "components/web_modal/web_contents_modal_dialog_host.h"
 #include "ui/display/display_observer.h"
 #include "ui/web_dialogs/web_dialog_delegate.h"
 
-namespace ash {
-class TabletMode;
-}
+class TabletModeClient;
 
 namespace content {
 class WebContents;
@@ -56,7 +54,7 @@
 //         V
 //   clientView---->Widget's view hierarchy
 class OobeUIDialogDelegate : public display::DisplayObserver,
-                             public ash::TabletModeToggleObserver,
+                             public TabletModeClientObserver,
                              public ui::WebDialogDelegate,
                              public ChromeKeyboardControllerClient::Observer,
                              public CaptivePortalWindowProxy::Observer {
@@ -95,7 +93,7 @@
   // display::DisplayObserver:
   void OnDisplayMetricsChanged(const display::Display& display,
                                uint32_t changed_metrics) override;
-  // ash::TabletModeToggleObserver:
+  // TabletModeClientObserver:
   void OnTabletModeToggled(bool enabled) override;
 
   // ui::WebDialogDelegate:
@@ -137,7 +135,7 @@
 
   ScopedObserver<display::Screen, display::DisplayObserver> display_observer_{
       this};
-  ScopedObserver<ash::TabletMode, ash::TabletModeToggleObserver>
+  ScopedObserver<TabletModeClient, TabletModeClientObserver>
       tablet_mode_observer_{this};
   ScopedObserver<ChromeKeyboardControllerClient,
                  ChromeKeyboardControllerClient::Observer>
diff --git a/chrome/browser/chromeos/login/wizard_controller.cc b/chrome/browser/chromeos/login/wizard_controller.cc
index b3ca37ab..c13d757 100644
--- a/chrome/browser/chromeos/login/wizard_controller.cc
+++ b/chrome/browser/chromeos/login/wizard_controller.cc
@@ -14,7 +14,6 @@
 
 #include "ash/public/cpp/ash_switches.h"
 #include "ash/public/cpp/login_screen.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
@@ -90,6 +89,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/login_screen_client.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/webui/chromeos/login/app_downloading_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/app_launch_splash_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/arc_kiosk_splash_screen_handler.h"
@@ -191,7 +191,7 @@
 // Checks if device is in tablet mode, and that HID-detection screen is not
 // disabled by flag.
 bool CanShowHIDDetectionScreen() {
-  return !ash::TabletMode::Get()->InTabletMode() &&
+  return !TabletModeClient::Get()->tablet_mode_enabled() &&
          !base::CommandLine::ForCurrentProcess()->HasSwitch(
              chromeos::switches::kDisableHIDDetectionOnOOBE) &&
          !base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
index 3e3bf31..a14bfc5 100644
--- a/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
+++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos.cc
@@ -7,13 +7,13 @@
 #include <stdint.h>
 #include <cmath>
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "ash/public/interfaces/cros_display_config.mojom.h"
 #include "base/bind.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "content/public/browser/system_connector.h"
 #include "extensions/common/api/system_display.h"
 #include "services/service_manager/public/cpp/connector.h"
@@ -604,13 +604,17 @@
 void DisplayInfoProviderChromeOS::StartObserving() {
   DisplayInfoProvider::StartObserving();
 
-  ash::TabletMode::Get()->AddObserver(this);
+  TabletModeClient* client = TabletModeClient::Get();
+  if (client)
+    client->AddObserver(this);
 }
 
 void DisplayInfoProviderChromeOS::StopObserving() {
   DisplayInfoProvider::StopObserving();
 
-  ash::TabletMode::Get()->RemoveObserver(this);
+  TabletModeClient* client = TabletModeClient::Get();
+  if (client)
+    client->RemoveObserver(this);
 }
 
 void DisplayInfoProviderChromeOS::OnTabletModeToggled(bool enabled) {
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos.h b/chrome/browser/extensions/system_display/display_info_provider_chromeos.h
index 0b01a9c6..8742e39 100644
--- a/chrome/browser/extensions/system_display/display_info_provider_chromeos.h
+++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos.h
@@ -8,10 +8,10 @@
 #include <map>
 #include <memory>
 
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "ash/public/interfaces/cros_display_config.mojom.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "extensions/browser/api/system_display/display_info_provider.h"
 
 namespace service_manager {
@@ -21,7 +21,7 @@
 namespace extensions {
 
 class DisplayInfoProviderChromeOS : public DisplayInfoProvider,
-                                    public ash::TabletModeToggleObserver {
+                                    public TabletModeClientObserver {
  public:
   explicit DisplayInfoProviderChromeOS(service_manager::Connector* connector);
   ~DisplayInfoProviderChromeOS() override;
@@ -57,7 +57,7 @@
   void StartObserving() override;
   void StopObserving() override;
 
-  // ash::TabletModeToggleObserver implementation.
+  // TabletModeClientObserver implementation.
   void OnTabletModeToggled(bool enabled) override;
 
  private:
diff --git a/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc b/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc
index 82459eb..6795758 100644
--- a/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc
+++ b/chrome/browser/extensions/system_display/display_info_provider_chromeos_unittest.cc
@@ -10,16 +10,16 @@
 #include "ash/display/screen_orientation_controller.h"
 #include "ash/display/screen_orientation_controller_test_api.h"
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/cpp/test/shell_test_api.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "ash/shell.h"
+#include "ash/wm/tablet_mode/tablet_mode_controller.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/browser/extensions/system_display/display_info_provider_chromeos.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/test/base/chrome_ash_test_base.h"
 #include "content/public/test/test_service_manager_context.h"
 #include "extensions/common/api/system_display.h"
@@ -79,10 +79,20 @@
     DisplayInfoProvider::InitializeForTesting(
         new DisplayInfoProviderChromeOS(connector_.get()));
 
+    tablet_mode_client_ = std::make_unique<TabletModeClient>();
+    tablet_mode_client_->Init();
+
     // Wait for TabletModeController to take its initial state from the power
     // manager.
     base::RunLoop().RunUntilIdle();
-    EXPECT_FALSE(ash::TabletMode::Get()->InTabletMode());
+    EXPECT_FALSE(ash::Shell::Get()->tablet_mode_controller()->InTabletMode());
+  }
+
+  void TearDown() override {
+    ChromeAshTestBase::TearDown();
+    // To match ChromeBrowserMainExtraPartsAsh, shut down the TabletModeClient
+    // after Shell.
+    tablet_mode_client_.reset();
   }
 
   void AddCrosDisplayConfigControllerBinding(
@@ -115,7 +125,9 @@
   }
 
   void EnableTabletMode(bool enable) {
-    ash::ShellTestApi().SetTabletModeEnabledForTest(enable);
+    ash::TabletModeController* controller =
+        ash::Shell::Get()->tablet_mode_controller();
+    controller->SetEnabledForTest(enable);
   }
 
   display::DisplayManager* GetDisplayManager() const {
@@ -193,6 +205,7 @@
   content::TestServiceManagerContext service_manager_context_;
   std::unique_ptr<service_manager::Connector> connector_;
   std::unique_ptr<ash::CrosDisplayConfig> cros_display_config_;
+  std::unique_ptr<TabletModeClient> tablet_mode_client_;
 
   DISALLOW_COPY_AND_ASSIGN(DisplayInfoProviderChromeosTest);
 };
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index ec2dc97..917dedb 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1525,6 +1525,7 @@
       "ash/tab_scrubber.h",
       "ash/tablet_mode_client.cc",
       "ash/tablet_mode_client.h",
+      "ash/tablet_mode_client_observer.h",
       "ash/test_ime_controller.cc",
       "ash/test_ime_controller.h",
       "ash/vpn_list_forwarder.cc",
@@ -3922,6 +3923,8 @@
     sources += [
       "ash/ash_test_util.cc",
       "ash/ash_test_util.h",
+      "ash/fake_tablet_mode_controller.cc",
+      "ash/fake_tablet_mode_controller.h",
       "ash/test_login_screen.cc",
       "ash/test_login_screen.h",
       "ash/test_login_screen_model.cc",
diff --git a/chrome/browser/ui/app_list/app_list_client_impl.cc b/chrome/browser/ui/app_list/app_list_client_impl.cc
index 5e88af3..e85a86e2 100644
--- a/chrome/browser/ui/app_list/app_list_client_impl.cc
+++ b/chrome/browser/ui/app_list/app_list_client_impl.cc
@@ -10,7 +10,6 @@
 #include <vector>
 
 #include "ash/public/cpp/app_list/app_list_controller.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
@@ -31,6 +30,7 @@
 #include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller.h"
 #include "chrome/browser/ui/ash/launcher/chrome_launcher_controller_util.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/browser_navigator.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
@@ -47,7 +47,8 @@
 AppListClientImpl* g_app_list_client_instance = nullptr;
 
 bool IsTabletMode() {
-  return ash::TabletMode::Get()->InTabletMode();
+  return TabletModeClient::Get() &&
+         TabletModeClient::Get()->tablet_mode_enabled();
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/app_list/arc/arc_app_context_menu.cc b/chrome/browser/ui/app_list/arc/arc_app_context_menu.cc
index d5d9c73..1c87187e 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_context_menu.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_context_menu.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/bind.h"
 #include "base/feature_list.h"
 #include "chrome/browser/chromeos/arc/app_shortcuts/arc_app_shortcuts_menu_builder.h"
@@ -17,6 +16,7 @@
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/chrome_pages.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
@@ -139,7 +139,8 @@
   if (arc::ShowPackageInfo(app_info->package_name,
                            arc::mojom::ShowPackageInfoPage::MAIN,
                            controller()->GetAppListDisplayId()) &&
-      !ash::TabletMode::Get()->InTabletMode()) {
+      !(TabletModeClient::Get() &&
+        TabletModeClient::Get()->tablet_mode_enabled())) {
     controller()->DismissView();
   }
 }
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.cc b/chrome/browser/ui/app_list/chrome_app_list_item.cc
index bf86806f..25708f2 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.cc
@@ -6,11 +6,11 @@
 
 #include <utility>
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_list_client_impl.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
 #include "chrome/browser/ui/app_list/chrome_app_list_model_updater.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "extensions/browser/app_sorting.h"
 #include "extensions/browser/extension_system.h"
 #include "ui/gfx/color_utils.h"
@@ -125,7 +125,8 @@
 void ChromeAppListItem::MaybeDismissAppList() {
   // Launching apps can take some time. It looks nicer to dismiss the app list.
   // Do not close app list for home launcher.
-  if (!ash::TabletMode::Get()->InTabletMode()) {
+  if (!TabletModeClient::Get() ||
+      !TabletModeClient::Get()->tablet_mode_enabled()) {
     GetController()->DismissView();
   }
 }
diff --git a/chrome/browser/ui/app_list/search/search_controller.cc b/chrome/browser/ui/app_list/search/search_controller.cc
index 7bdb8faa..faf3c0e 100644
--- a/chrome/browser/ui/app_list/search/search_controller.cc
+++ b/chrome/browser/ui/app_list/search/search_controller.cc
@@ -11,7 +11,6 @@
 
 #include "ash/public/cpp/app_list/app_list_config.h"
 #include "ash/public/cpp/app_list/app_list_features.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_util.h"
@@ -27,6 +26,7 @@
 #include "chrome/browser/ui/app_list/search/search_result_ranker/ranking_item_util.h"
 #include "chrome/browser/ui/app_list/search/search_result_ranker/recurrence_ranker.h"
 #include "chrome/browser/ui/app_list/search/search_result_ranker/search_result_ranker.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "third_party/metrics_proto/chrome_os_app_list_launch_event.pb.h"
 
 using metrics::ChromeOSAppListLaunchEventProto;
@@ -114,8 +114,10 @@
 
   // Launching apps can take some time. It looks nicer to dismiss the app list.
   // Do not close app list for home launcher.
-  if (!ash::TabletMode::Get()->InTabletMode())
+  if (!TabletModeClient::Get() ||
+      !TabletModeClient::Get()->tablet_mode_enabled()) {
     list_controller_->DismissView();
+  }
 }
 
 void SearchController::InvokeResultAction(ChromeSearchResult* result,
diff --git a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
index 2b70e3b0..ca32cb3 100644
--- a/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
+++ b/chrome/browser/ui/ash/chrome_browser_main_extra_parts_ash.cc
@@ -107,7 +107,12 @@
 ChromeBrowserMainExtraPartsAsh::ChromeBrowserMainExtraPartsAsh()
     : notification_observer_(std::make_unique<NotificationObserver>()) {}
 
-ChromeBrowserMainExtraPartsAsh::~ChromeBrowserMainExtraPartsAsh() = default;
+ChromeBrowserMainExtraPartsAsh::~ChromeBrowserMainExtraPartsAsh() {
+  // Views code observes TabletModeClient and may not be destroyed until
+  // ash::Shell is, so destroy |tablet_mode_client_| after ash::Shell.
+  // Also extensions need to remove observers after PostMainMessageLoopRun().
+  tablet_mode_client_.reset();
+}
 
 void ChromeBrowserMainExtraPartsAsh::PreProfileInit() {
   // NetworkConnect handles the network connection state machine for the UI.
@@ -140,7 +145,11 @@
   session_controller_client_->Init();
 
   system_tray_client_ = std::make_unique<SystemTrayClient>();
+
+  // Makes mojo request to TabletModeController in ash.
   tablet_mode_client_ = std::make_unique<TabletModeClient>();
+  tablet_mode_client_->Init();
+
   vpn_list_forwarder_ = std::make_unique<VpnListForwarder>();
 
   wallpaper_controller_client_ = std::make_unique<WallpaperControllerClient>();
diff --git a/chrome/browser/ui/ash/fake_tablet_mode_controller.cc b/chrome/browser/ui/ash/fake_tablet_mode_controller.cc
new file mode 100644
index 0000000..61a34145
--- /dev/null
+++ b/chrome/browser/ui/ash/fake_tablet_mode_controller.cc
@@ -0,0 +1,24 @@
+// 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 "chrome/browser/ui/ash/fake_tablet_mode_controller.h"
+
+#include <utility>
+
+FakeTabletModeController::FakeTabletModeController() = default;
+
+FakeTabletModeController::~FakeTabletModeController() = default;
+
+void FakeTabletModeController::SetTabletModeToggleObserver(
+    ash::TabletModeToggleObserver* observer) {
+  observer_ = observer;
+}
+
+bool FakeTabletModeController::InTabletMode() const {
+  return enabled_;
+}
+
+void FakeTabletModeController::SetEnabledForTest(bool enabled) {
+  enabled_ = enabled;
+}
diff --git a/chrome/browser/ui/ash/fake_tablet_mode_controller.h b/chrome/browser/ui/ash/fake_tablet_mode_controller.h
new file mode 100644
index 0000000..99c4ae9
--- /dev/null
+++ b/chrome/browser/ui/ash/fake_tablet_mode_controller.h
@@ -0,0 +1,33 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_ASH_FAKE_TABLET_MODE_CONTROLLER_H_
+#define CHROME_BROWSER_UI_ASH_FAKE_TABLET_MODE_CONTROLLER_H_
+
+#include "ash/public/cpp/tablet_mode.h"
+#include "base/macros.h"
+
+// Simulates the TabletModeController in ash.
+class FakeTabletModeController : public ash::TabletMode {
+ public:
+  FakeTabletModeController();
+
+  ~FakeTabletModeController() override;
+
+  bool has_observer() const { return !!observer_; }
+
+  // ash::mojom::TabletModeController:
+  void SetTabletModeToggleObserver(
+      ash::TabletModeToggleObserver* observer) override;
+  bool InTabletMode() const override;
+  void SetEnabledForTest(bool enabled) override;
+
+ private:
+  bool enabled_ = false;
+  ash::TabletModeToggleObserver* observer_ = nullptr;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeTabletModeController);
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_FAKE_TABLET_MODE_CONTROLLER_H_
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
index e412d6b..44d146c 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller.cc
@@ -14,7 +14,6 @@
 #include "ash/public/cpp/shelf_item.h"
 #include "ash/public/cpp/shelf_model.h"
 #include "ash/public/cpp/shelf_prefs.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/window_animation_types.h"
 #include "base/bind.h"
 #include "base/bind_helpers.h"
@@ -57,6 +56,7 @@
 #include "chrome/browser/ui/ash/multi_user/multi_user_util.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h"
 #include "chrome/browser/ui/ash/session_controller_client_impl.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
@@ -537,7 +537,8 @@
     return ash::SHELF_ACTION_WINDOW_MINIMIZED;
   }
 
-  if (ash::TabletMode::Get()->InTabletMode()) {
+  if (TabletModeClient::Get() &&
+      TabletModeClient::Get()->tablet_mode_enabled()) {
     // Run slide down animation to show the window.
     wm::SetWindowVisibilityAnimationType(
         native_window, ash::wm::WINDOW_VISIBILITY_ANIMATION_TYPE_SLIDE_DOWN);
diff --git a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
index 613b14c..5441814 100644
--- a/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
+++ b/chrome/browser/ui/ash/launcher/launcher_context_menu.cc
@@ -8,7 +8,6 @@
 #include <string>
 
 #include "ash/public/cpp/shelf_model.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/metrics/user_metrics.h"
 #include "chrome/browser/chromeos/crostini/crostini_registry_service.h"
 #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
@@ -21,6 +20,7 @@
 #include "chrome/browser/ui/ash/launcher/crostini_shelf_context_menu.h"
 #include "chrome/browser/ui/ash/launcher/extension_launcher_context_menu.h"
 #include "chrome/browser/ui/ash/launcher/internal_app_shelf_context_menu.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/display/types/display_constants.h"
 #include "ui/gfx/paint_vector_icon.h"
@@ -107,7 +107,7 @@
         controller_->Close(item_.id);
       }
       base::RecordAction(base::UserMetricsAction("CloseFromContextMenu"));
-      if (ash::TabletMode::Get()->InTabletMode()) {
+      if (TabletModeClient::Get()->tablet_mode_enabled()) {
         base::RecordAction(
             base::UserMetricsAction("Tablet_WindowCloseFromContextMenu"));
       }
diff --git a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
index b28e45dc..48d404ef 100644
--- a/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
+++ b/chrome/browser/ui/ash/screen_orientation_delegate_chromeos.cc
@@ -5,8 +5,8 @@
 #include "chrome/browser/ui/ash/screen_orientation_delegate_chromeos.h"
 
 #include "ash/display/screen_orientation_controller.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/shell.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "content/public/browser/web_contents.h"
 
 namespace {
@@ -59,7 +59,8 @@
 }
 
 bool ScreenOrientationDelegateChromeos::ScreenOrientationProviderSupported() {
-  return ash::TabletMode::Get()->InTabletMode();
+  return TabletModeClient::Get() &&
+         TabletModeClient::Get()->tablet_mode_enabled();
 }
 
 void ScreenOrientationDelegateChromeos::Unlock(
diff --git a/chrome/browser/ui/ash/tablet_mode_client.cc b/chrome/browser/ui/ash/tablet_mode_client.cc
index 8eb8592..e9fbe73 100644
--- a/chrome/browser/ui/ash/tablet_mode_client.cc
+++ b/chrome/browser/ui/ash/tablet_mode_client.cc
@@ -9,6 +9,7 @@
 #include "ash/public/cpp/tablet_mode.h"
 #include "base/bind.h"
 #include "chrome/browser/chromeos/arc/arc_web_contents_data.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_tab_strip_tracker.h"
@@ -20,22 +21,57 @@
 #include "services/service_manager/public/cpp/connector.h"
 #include "ui/base/material_design/material_design_controller.h"
 
+namespace {
+
+TabletModeClient* g_tablet_mode_client_instance = nullptr;
+
+}  // namespace
+
 TabletModeClient::TabletModeClient() {
-  ash::TabletMode::Get()->AddObserver(this);
-  OnTabletModeToggled(ash::TabletMode::Get()->InTabletMode());
+  DCHECK(!g_tablet_mode_client_instance);
+  g_tablet_mode_client_instance = this;
 }
 
 TabletModeClient::~TabletModeClient() {
-  ash::TabletMode::Get()->RemoveObserver(this);
+  DCHECK_EQ(this, g_tablet_mode_client_instance);
+  g_tablet_mode_client_instance = nullptr;
+  // The Ash Shell and TabletMode instance should have been destroyed by now.
+  DCHECK(!ash::TabletMode::Get());
+}
+
+void TabletModeClient::Init() {
+  ash::TabletMode::Get()->SetTabletModeToggleObserver(this);
+  OnTabletModeToggled(ash::TabletMode::Get()->InTabletMode());
+}
+
+// static
+TabletModeClient* TabletModeClient::Get() {
+  return g_tablet_mode_client_instance;
+}
+
+void TabletModeClient::AddObserver(TabletModeClientObserver* observer) {
+  observers_.AddObserver(observer);
+}
+
+void TabletModeClient::RemoveObserver(TabletModeClientObserver* observer) {
+  observers_.RemoveObserver(observer);
 }
 
 void TabletModeClient::OnTabletModeToggled(bool enabled) {
+  if (tablet_mode_enabled_ == enabled)
+    return;
+
+  tablet_mode_enabled_ = enabled;
+
   SetMobileLikeBehaviorEnabled(enabled);
+
   ui::MaterialDesignController::OnTabletModeToggled(enabled);
+  for (auto& observer : observers_)
+    observer.OnTabletModeToggled(enabled);
 }
 
 bool TabletModeClient::ShouldTrackBrowser(Browser* browser) {
-  return ash::TabletMode::Get()->InTabletMode();
+  return tablet_mode_enabled_;
 }
 
 void TabletModeClient::OnTabStripModelChanged(
diff --git a/chrome/browser/ui/ash/tablet_mode_client.h b/chrome/browser/ui/ash/tablet_mode_client.h
index d226911..309f364a 100644
--- a/chrome/browser/ui/ash/tablet_mode_client.h
+++ b/chrome/browser/ui/ash/tablet_mode_client.h
@@ -9,10 +9,12 @@
 
 #include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "base/macros.h"
+#include "base/observer_list.h"
 #include "chrome/browser/ui/browser_tab_strip_tracker_delegate.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 
 class BrowserTabStripTracker;
+class TabletModeClientObserver;
 
 // Holds tablet mode state in chrome. Observes ash for changes, then
 // synchronously fires all its observers. This allows all tablet mode code in
@@ -24,6 +26,18 @@
   TabletModeClient();
   ~TabletModeClient() override;
 
+  // Initializes and connects to ash.
+  void Init();
+
+  static TabletModeClient* Get();
+
+  bool tablet_mode_enabled() const { return tablet_mode_enabled_; }
+
+  // Adds the observer and immediately triggers it with the initial state.
+  void AddObserver(TabletModeClientObserver* observer);
+
+  void RemoveObserver(TabletModeClientObserver* observer);
+
   // ash::TabletModeToggleObserver:
   void OnTabletModeToggled(bool enabled) override;
 
@@ -41,6 +55,8 @@
   // well as starts observing new browser pages if |enabled| is true.
   void SetMobileLikeBehaviorEnabled(bool enabled);
 
+  bool tablet_mode_enabled_ = false;
+
   // We only override the WebKit preferences of webcontents that belong to
   // tabstrips in browsers. When a webcontents is newly created, its WebKit
   // preferences are refreshed *before* it's added to any tabstrip, hence
@@ -50,6 +66,9 @@
   // a refresh of its WebKit prefs.
   std::unique_ptr<BrowserTabStripTracker> tab_strip_tracker_;
 
+  base::ObserverList<TabletModeClientObserver,
+                     true /* check_empty */>::Unchecked observers_;
+
   DISALLOW_COPY_AND_ASSIGN(TabletModeClient);
 };
 
diff --git a/chrome/browser/ui/ash/tablet_mode_client_observer.h b/chrome/browser/ui/ash/tablet_mode_client_observer.h
new file mode 100644
index 0000000..65af83a
--- /dev/null
+++ b/chrome/browser/ui/ash/tablet_mode_client_observer.h
@@ -0,0 +1,18 @@
+// 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.
+
+#ifndef CHROME_BROWSER_UI_ASH_TABLET_MODE_CLIENT_OBSERVER_H_
+#define CHROME_BROWSER_UI_ASH_TABLET_MODE_CLIENT_OBSERVER_H_
+
+// Observer for tablet mode changes inside chrome.
+class TabletModeClientObserver {
+ public:
+  // Fired after the tablet mode has been toggled.
+  virtual void OnTabletModeToggled(bool enabled) = 0;
+
+ protected:
+  virtual ~TabletModeClientObserver() {}
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_TABLET_MODE_CLIENT_OBSERVER_H_
diff --git a/chrome/browser/ui/ash/tablet_mode_client_unittest.cc b/chrome/browser/ui/ash/tablet_mode_client_unittest.cc
new file mode 100644
index 0000000..ebf0bb6
--- /dev/null
+++ b/chrome/browser/ui/ash/tablet_mode_client_unittest.cc
@@ -0,0 +1,73 @@
+// 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 "chrome/browser/ui/ash/tablet_mode_client.h"
+
+#include "base/macros.h"
+#include "chrome/browser/ui/ash/fake_tablet_mode_controller.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+class TestTabletModeClientObserver : public TabletModeClientObserver {
+ public:
+  TestTabletModeClientObserver() = default;
+  ~TestTabletModeClientObserver() override = default;
+
+  void OnTabletModeToggled(bool enabled) override {
+    ++toggle_count_;
+    last_toggle_ = enabled;
+  }
+
+  int toggle_count_ = 0;
+  bool last_toggle_ = false;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestTabletModeClientObserver);
+};
+
+using TabletModeClientTest = testing::Test;
+
+TEST_F(TabletModeClientTest, Construction) {
+  // In production, TabletModeController is constructed before TabletModeClient
+  // and destroyed before it too. Match that here.
+  auto controller = std::make_unique<FakeTabletModeController>();
+  TabletModeClient client;
+  client.Init();
+
+  // Singleton was initialized.
+  EXPECT_EQ(&client, TabletModeClient::Get());
+
+  // Object was set as client.
+  EXPECT_TRUE(controller->has_observer());
+
+  controller = nullptr;
+}
+
+TEST_F(TabletModeClientTest, Observers) {
+  auto controller = std::make_unique<FakeTabletModeController>();
+  TestTabletModeClientObserver observer;
+  TabletModeClient client;
+  client.Init();
+  client.AddObserver(&observer);
+
+  // Observer is not notified with state when added.
+  EXPECT_EQ(0, observer.toggle_count_);
+
+  // Setting state notifies observer.
+  client.OnTabletModeToggled(true);
+  EXPECT_EQ(1, observer.toggle_count_);
+  EXPECT_TRUE(observer.last_toggle_);
+
+  client.OnTabletModeToggled(false);
+  EXPECT_EQ(2, observer.toggle_count_);
+  EXPECT_FALSE(observer.last_toggle_);
+
+  client.RemoveObserver(&observer);
+
+  controller = nullptr;
+}
+
+}  // namespace
diff --git a/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc b/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc
index 5146dfed..bc7e4456 100644
--- a/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc
+++ b/chrome/browser/ui/ash/tablet_mode_page_behavior_browsertest.cc
@@ -3,11 +3,10 @@
 // found in the LICENSE file.
 
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/cpp/test/shell_test_api.h"
 #include "base/command_line.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/browser_features.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
@@ -40,11 +39,13 @@
   }
 
   void ToggleTabletMode() {
-    ash::ShellTestApi().SetTabletModeEnabledForTest(!GetTabletModeEnabled());
+    auto* tablet_mode_client = TabletModeClient::Get();
+    tablet_mode_client->OnTabletModeToggled(
+        !tablet_mode_client->tablet_mode_enabled());
   }
 
   bool GetTabletModeEnabled() const {
-    return ash::TabletMode::Get()->InTabletMode();
+    return TabletModeClient::Get()->tablet_mode_enabled();
   }
 
   content::WebContents* GetActiveWebContents(Browser* browser) const {
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 36b19f6..a111149a 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -79,7 +79,7 @@
 #endif
 
 #if defined(OS_CHROMEOS)
-#include "ash/public/cpp/tablet_mode.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chromeos/constants/chromeos_switches.h"
 #endif
 
@@ -785,7 +785,8 @@
   // Always show this option if we're in tablet mode on Chrome OS.
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           chromeos::switches::kEnableRequestTabletSite) ||
-      ash::TabletMode::Get()->InTabletMode()) {
+      (TabletModeClient::Get() &&
+       TabletModeClient::Get()->tablet_mode_enabled())) {
     AddCheckItemWithStringId(IDC_TOGGLE_REQUEST_TABLET_SITE,
                              IDS_TOGGLE_REQUEST_TABLET_SITE);
   }
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
index 0368b61..467a359 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.cc
@@ -14,7 +14,6 @@
 #include "ash/public/cpp/immersive/immersive_fullscreen_controller.h"
 #include "ash/public/cpp/shelf_types.h"
 #include "ash/public/cpp/shell_window_ids.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/public/cpp/window_state_type.h"
 #include "ash/public/interfaces/constants.mojom.h"
@@ -27,6 +26,7 @@
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/ash/kiosk_next_shell_client.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_context_menu.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/exclusive_access/exclusive_access_manager.h"
 #include "chrome/browser/ui/views/exclusive_access_bubble_views.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -75,11 +75,13 @@
 ChromeNativeAppWindowViewsAuraAsh::ChromeNativeAppWindowViewsAuraAsh()
     : exclusive_access_manager_(
           std::make_unique<ExclusiveAccessManager>(this)) {
-  ash::TabletMode::Get()->AddObserver(this);
+  if (TabletModeClient::Get())
+    TabletModeClient::Get()->AddObserver(this);
 }
 
 ChromeNativeAppWindowViewsAuraAsh::~ChromeNativeAppWindowViewsAuraAsh() {
-  ash::TabletMode::Get()->RemoveObserver(this);
+  if (TabletModeClient::Get())
+    TabletModeClient::Get()->RemoveObserver(this);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -517,6 +519,7 @@
   if (app_window()->IsOsFullscreen())
     return true;
 
+  TabletModeClient* client = TabletModeClient::Get();
   // Windows in tablet mode which are resizable have their title bars
   // hidden in ash for more size, so enable immersive mode so users
   // have access to window controls. Non resizable windows do not gain
@@ -524,7 +527,7 @@
   // is no need for immersive mode.
   // TODO(crbug.com/801619): This adds a little extra animation
   // when minimizing or unminimizing window.
-  return ash::TabletMode::Get()->InTabletMode() && CanResize() &&
+  return client && client->tablet_mode_enabled() && CanResize() &&
          !IsMinimized();
 }
 
diff --git a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
index ed085bb..d729967c 100644
--- a/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
+++ b/chrome/browser/ui/views/apps/chrome_native_app_window_views_aura_ash.h
@@ -8,10 +8,10 @@
 #include <memory>
 #include <vector>
 
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "ash/wm/window_state_observer.h"
 #include "base/gtest_prod_util.h"
 #include "base/scoped_observer.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/browser/ui/exclusive_access/exclusive_access_context.h"
 #include "chrome/browser/ui/views/apps/chrome_native_app_window_views_aura.h"
 #include "chrome/browser/ui/views/exclusive_access_bubble_views_context.h"
@@ -35,7 +35,7 @@
 class ChromeNativeAppWindowViewsAuraAsh
     : public ChromeNativeAppWindowViewsAura,
       public views::ContextMenuController,
-      public ash::TabletModeToggleObserver,
+      public TabletModeClientObserver,
       public ui::AcceleratorProvider,
       public ExclusiveAccessContext,
       public ExclusiveAccessBubbleViewsContext,
@@ -78,7 +78,7 @@
   void SetFullscreen(int fullscreen_types) override;
   void SetActivateOnPointer(bool activate_on_pointer) override;
 
-  // ash::TabletModeToggleObserver:
+  // ash:TabletModeObserver:
   void OnTabletModeToggled(bool enabled) override;
 
   // ui::AcceleratorProvider:
diff --git a/chrome/browser/ui/views/extensions/extension_dialog.cc b/chrome/browser/ui/views/extensions/extension_dialog.cc
index dcf609b..87c17b85 100644
--- a/chrome/browser/ui/views/extensions/extension_dialog.cc
+++ b/chrome/browser/ui/views/extensions/extension_dialog.cc
@@ -29,7 +29,7 @@
 #include "url/gurl.h"
 
 #if defined(OS_CHROMEOS)
-#include "ash/public/cpp/tablet_mode.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #endif
 
 using content::BrowserContext;
@@ -175,7 +175,8 @@
 bool ExtensionDialog::CanResize() const {
 #if defined(OS_CHROMEOS)
   // Prevent dialog resize mouse cursor in tablet mode, crbug.com/453634.
-  if (ash::TabletMode::Get()->InTabletMode())
+  const auto* client = TabletModeClient::Get();
+  if (client && client->tablet_mode_enabled())
     return false;
 #endif
   // Can resize only if minimum contents size set.
diff --git a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
index 63bc131..94c9c7f 100644
--- a/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_frame_header_ash.cc
@@ -7,9 +7,9 @@
 #include "ash/public/cpp/ash_constants.h"
 #include "ash/public/cpp/caption_buttons/frame_caption_button_container_view.h"
 #include "ash/public/cpp/frame_utils.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/vector_icons/vector_icons.h"
 #include "base/logging.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "third_party/skia/include/core/SkCanvas.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "third_party/skia/include/core/SkPaint.h"
@@ -153,7 +153,8 @@
 views::CaptionButtonLayoutSize BrowserFrameHeaderAsh::GetButtonLayoutSize()
     const {
   return target_widget()->IsMaximized() || target_widget()->IsFullscreen() ||
-                 ash::TabletMode::Get()->InTabletMode()
+                 (TabletModeClient::Get() &&
+                  TabletModeClient::Get()->tablet_mode_enabled())
              ? views::CaptionButtonLayoutSize::kBrowserCaptionMaximized
              : views::CaptionButtonLayoutSize::kBrowserCaptionRestored;
 }
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
index 31af247..27c3d4a 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.cc
@@ -13,7 +13,6 @@
 #include "ash/public/cpp/caption_buttons/frame_caption_button_container_view.h"
 #include "ash/public/cpp/default_frame_header.h"
 #include "ash/public/cpp/frame_utils.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/touch_uma.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/public/cpp/window_state_type.h"
@@ -28,6 +27,7 @@
 #include "chrome/browser/themes/theme_properties.h"
 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h"
 #include "chrome/browser/ui/ash/session_util.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
@@ -123,7 +123,9 @@
   browser_view()->browser()->command_controller()->RemoveCommandObserver(
       IDC_BACK, this);
 
-  ash::TabletMode::Get()->RemoveObserver(this);
+  if (TabletModeClient::Get())
+    TabletModeClient::Get()->RemoveObserver(this);
+
   ash::SplitViewNotifier::Get()->RemoveObserver(this);
 
   ImmersiveModeController* immersive_controller =
@@ -162,7 +164,9 @@
   if (browser->profile()->IsOffTheRecord())
     window->SetProperty(ash::kBlockedForAssistantSnapshotKey, true);
 
-  ash::TabletMode::Get()->AddObserver(this);
+  // TabletModeClient may not be initialized during unit tests.
+  if (TabletModeClient::Get())
+    TabletModeClient::Get()->AddObserver(this);
 
   if (browser->is_app() && IsV1AppBackButtonEnabled()) {
     browser->command_controller()->AddCommandObserver(IDC_BACK, this);
@@ -460,7 +464,7 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// ash::TabletModeToggleObserver:
+// ash::mojom::TabletModeClient:
 
 void BrowserNonClientFrameViewAsh::OnTabletModeToggled(bool enabled) {
   if (!enabled && browser_view()->immersive_mode_controller()->IsRevealed()) {
@@ -616,8 +620,8 @@
   // minimize all windows when pressing the Launcher button on the shelf.
   const bool hide_caption_buttons_in_tablet_mode =
       !UsePackagedAppHeaderStyle(browser_view()->browser());
-  if (hide_caption_buttons_in_tablet_mode &&
-      ash::TabletMode::Get()->InTabletMode()) {
+  if (hide_caption_buttons_in_tablet_mode && TabletModeClient::Get() &&
+      TabletModeClient::Get()->tablet_mode_enabled()) {
     return false;
   }
 
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
index fbc21df..0c0130ed 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view_ash.h
@@ -8,12 +8,12 @@
 #include <memory>
 
 #include "ash/public/cpp/split_view.h"
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "base/gtest_prod_util.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "base/scoped_observer.h"
 #include "chrome/browser/command_observer.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/browser/ui/views/frame/browser_frame_header_ash.h"
 #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
 #include "chrome/browser/ui/views/frame/immersive_mode_controller.h"
@@ -40,7 +40,7 @@
 class BrowserNonClientFrameViewAsh
     : public BrowserNonClientFrameView,
       public BrowserFrameHeaderAsh::AppearanceProvider,
-      public ash::TabletModeToggleObserver,
+      public TabletModeClientObserver,
       public TabIconViewModel,
       public CommandObserver,
       public ash::SplitViewObserver,
@@ -90,7 +90,7 @@
   int GetFrameHeaderImageYInset() override;
   gfx::ImageSkia GetFrameHeaderOverlayImage(bool active) override;
 
-  // ash::TabletModeToggleObserver:
+  // TabletModeClientObserver:
   void OnTabletModeToggled(bool enabled) override;
 
   // TabIconViewModel:
diff --git a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
index 1210253..8abc833e 100644
--- a/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
+++ b/chrome/browser/ui/views/frame/immersive_mode_controller_ash.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/views/frame/immersive_mode_controller_ash.h"
 
 #include "ash/public/cpp/immersive/immersive_revealed_lock.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/window_properties.h"
 #include "base/macros.h"
 #include "chrome/browser/chrome_notification_types.h"
@@ -130,7 +129,7 @@
 
 bool ImmersiveModeControllerAsh::ShouldStayImmersiveAfterExitingFullscreen() {
   return !browser_view_->IsBrowserTypeNormal() &&
-         ash::TabletMode::Get()->InTabletMode();
+         TabletModeClient::Get()->tablet_mode_enabled();
 }
 
 void ImmersiveModeControllerAsh::OnWidgetActivationChanged(
@@ -139,7 +138,7 @@
   if (browser_view_->IsBrowserTypeNormal())
     return;
 
-  if (!ash::TabletMode::Get()->InTabletMode())
+  if (!TabletModeClient::Get()->tablet_mode_enabled())
     return;
 
   // Don't use immersive mode as long as we are in the locked fullscreen mode
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
index 61e3a07..401ec7a 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.cc
@@ -4,11 +4,11 @@
 
 #include "chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h"
 
-#include "ash/public/cpp/tablet_mode.h"
 #include "base/bind.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/ssl/security_state_tab_helper.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/top_container_view.h"
 #include "chrome/common/chrome_render_frame.mojom.h"
@@ -35,7 +35,8 @@
 namespace {
 
 bool IsTabletModeEnabled() {
-  return ash::TabletMode::Get()->InTabletMode();
+  return TabletModeClient::Get() &&
+         TabletModeClient::Get()->tablet_mode_enabled();
 }
 
 bool IsSpokenFeedbackEnabled() {
@@ -303,7 +304,9 @@
   registrar_.Add(this, content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE,
                  content::NotificationService::AllSources());
 
-  ash::TabletMode::Get()->AddObserver(this);
+  if (TabletModeClient::Get())
+    TabletModeClient::Get()->AddObserver(this);
+
   browser_view_->browser()->tab_strip_model()->AddObserver(this);
 
   chromeos::AccessibilityManager* accessibility_manager =
@@ -322,7 +325,9 @@
   OnEnabledStateChanged(false);
 
   browser_view_->browser()->tab_strip_model()->RemoveObserver(this);
-  ash::TabletMode::Get()->RemoveObserver(this);
+
+  if (TabletModeClient::Get())
+    TabletModeClient::Get()->RemoveObserver(this);
 }
 
 bool TopControlsSlideControllerChromeOS::IsEnabled() const {
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h
index 21a24d3..f2a23afd 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos.h
@@ -7,11 +7,11 @@
 
 #include <memory>
 
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "base/containers/flat_map.h"
 #include "base/macros.h"
 #include "base/optional.h"
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
 #include "chrome/browser/ui/views/frame/top_controls_slide_controller.h"
 #include "content/public/browser/notification_observer.h"
@@ -38,7 +38,7 @@
 // - Page security level changes.
 class TopControlsSlideControllerChromeOS
     : public TopControlsSlideController,
-      public ash::TabletModeToggleObserver,
+      public TabletModeClientObserver,
       public TabStripModelObserver,
       public content::NotificationObserver {
  public:
@@ -55,7 +55,7 @@
   void SetTopControlsGestureScrollInProgress(bool in_progress) override;
   bool IsTopControlsGestureScrollInProgress() const override;
 
-  // ash::TabletModeToggleObserver:
+  // TabletModeClientObserver:
   void OnTabletModeToggled(bool tablet_mode_enabled) override;
 
   // TabStripModelObserver:
diff --git a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
index baabe16..8b05a88 100644
--- a/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
+++ b/chrome/browser/ui/views/frame/top_controls_slide_controller_chromeos_browsertest.cc
@@ -9,8 +9,6 @@
 #include <vector>
 
 #include "ash/public/cpp/ash_switches.h"
-#include "ash/public/cpp/tablet_mode.h"
-#include "ash/public/cpp/test/shell_test_api.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "ash/public/interfaces/cros_display_config.mojom-test-utils.h"
 #include "ash/public/interfaces/cros_display_config.mojom.h"
@@ -23,6 +21,7 @@
 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
 #include "chrome/browser/permissions/permission_request_impl.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/browser_commands.h"
 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
@@ -38,7 +37,6 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/display/display.h"
-#include "ui/display/display_switches.h"
 #include "ui/events/test/event_generator.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/views/controls/native/native_view_host.h"
@@ -260,12 +258,7 @@
   void SetUpDefaultCommandLine(base::CommandLine* command_line) override {
     InProcessBrowserTest::SetUpDefaultCommandLine(command_line);
 
-    // Mark the device is capable of entering tablet mode.
     command_line->AppendSwitch(ash::switches::kAshEnableTabletMode);
-
-    // Use first display as internal display. Otherwise, tablet mode is ended
-    // on display change.
-    command_line->AppendSwitch(switches::kUseFirstDisplayAsInternal);
   }
 
   void SetUpOnMainThread() override {
@@ -295,11 +288,13 @@
   }
 
   void ToggleTabletMode() {
-    ash::ShellTestApi().SetTabletModeEnabledForTest(!GetTabletModeEnabled());
+    auto* tablet_mode_client = TabletModeClient::Get();
+    tablet_mode_client->OnTabletModeToggled(
+        !tablet_mode_client->tablet_mode_enabled());
   }
 
   bool GetTabletModeEnabled() const {
-    return ash::TabletMode::Get()->InTabletMode();
+    return TabletModeClient::Get()->tablet_mode_enabled();
   }
 
   void CheckBrowserLayout(BrowserView* browser_view,
diff --git a/chrome/browser/ui/views/tabs/tab_drag_controller.cc b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
index 8f207c0..82a6874 100644
--- a/chrome/browser/ui/views/tabs/tab_drag_controller.cc
+++ b/chrome/browser/ui/views/tabs/tab_drag_controller.cc
@@ -48,9 +48,9 @@
 
 #if defined(OS_CHROMEOS)
 #include "ash/public/cpp/ash_features.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/window_properties.h"               // nogncheck
 #include "ash/public/cpp/window_state_type.h"               // nogncheck
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "ui/wm/core/coordinate_conversion.h"
 #endif
 
@@ -117,7 +117,7 @@
 void StoreCurrentDraggedBrowserBoundsInTabletMode(
     aura::Window* window,
     const gfx::Rect& bounds_in_screen) {
-  if (ash::TabletMode::Get()->InTabletMode()) {
+  if (TabletModeClient::Get()->tablet_mode_enabled()) {
     // The bounds that is stored in ash::kRestoreBoundsOverrideKey will be used
     // by DragDetails to calculate the window bounds during dragging in tablet
     // mode.
@@ -1842,7 +1842,7 @@
   }
 
 #if defined(OS_CHROMEOS)
-  if (ash::TabletMode::Get()->InTabletMode()) {
+  if (TabletModeClient::Get()->tablet_mode_enabled()) {
     new_bounds = GetDraggedBrowserBoundsInTabletMode(
         source->AsView()->GetWidget()->GetNativeWindow());
   }
@@ -1882,7 +1882,7 @@
     const gfx::Point& point_in_screen) {
   gfx::Rect bounds = widget->GetWindowBoundsInScreen();
 #if defined(OS_CHROMEOS)
-  if (ash::TabletMode::Get()->InTabletMode())
+  if (TabletModeClient::Get()->tablet_mode_enabled())
     bounds = GetDraggedBrowserBoundsInTabletMode(widget->GetNativeWindow());
 #endif
 
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
index a2576ee..cd1d375 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -8,7 +8,6 @@
 
 #include "ash/public/cpp/ash_features.h"
 #include "ash/public/cpp/event_rewriter_controller.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "ash/shell.h"
 #include "base/bind.h"
@@ -34,6 +33,7 @@
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/ash/ash_util.h"
 #include "chrome/browser/ui/ash/keyboard/chrome_keyboard_controller_client.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/webui/chromeos/login/demo_setup_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/eula_screen_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
@@ -99,7 +99,8 @@
       base::Bind(&CoreOobeHandler::OnAccessibilityStatusChanged,
                  base::Unretained(this)));
 
-  ash::TabletMode::Get()->AddObserver(this);
+  TabletModeClient* tablet_mode_client = TabletModeClient::Get();
+  tablet_mode_client->AddObserver(this);
 
   // |connector| may be null in tests.
   auto* connector = content::GetSystemConnector();
@@ -112,7 +113,7 @@
 
 CoreOobeHandler::~CoreOobeHandler() {
   OobeConfiguration::Get()->RemoveObserver(this);
-  ash::TabletMode::Get()->RemoveObserver(this);
+  TabletModeClient::Get()->RemoveObserver(this);
 }
 
 void CoreOobeHandler::DeclareLocalizedValues(
@@ -178,7 +179,7 @@
 
 void CoreOobeHandler::GetAdditionalParameters(base::DictionaryValue* dict) {
   dict->SetKey("isInTabletMode",
-               base::Value(ash::TabletMode::Get()->InTabletMode()));
+               base::Value(TabletModeClient::Get()->tablet_mode_enabled()));
   dict->SetKey("isDemoModeEnabled",
                base::Value(DemoSetupController::IsDemoModeAllowed()));
   dict->SetKey("showTechnologyBadge",
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
index 3e6ca78..41232f4 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
@@ -9,7 +9,6 @@
 #include <string>
 #include <vector>
 
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "ash/public/interfaces/cros_display_config.mojom.h"
 #include "base/callback.h"
 #include "base/macros.h"
@@ -20,6 +19,7 @@
 #include "chrome/browser/chromeos/login/help_app_launcher.h"
 #include "chrome/browser/chromeos/login/oobe_configuration.h"
 #include "chrome/browser/chromeos/login/version_info_updater.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
 #include "ui/events/event_source.h"
 
@@ -70,7 +70,7 @@
                         public VersionInfoUpdater::Delegate,
                         public CoreOobeView,
                         public ui::EventSource,
-                        public ash::TabletModeToggleObserver,
+                        public TabletModeClientObserver,
                         public OobeConfiguration::Observer {
  public:
   explicit CoreOobeHandler(JSCallsContainer* js_calls_container);
@@ -144,7 +144,7 @@
   void StopDemoModeDetection() override;
   void UpdateKeyboardState() override;
 
-  // ash::TabletModeToggleObserver:
+  // TabletModeClientObserver:
   void OnTabletModeToggled(bool enabled) override;
 
   // OobeConfiguration::Observer:
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index c13ec8c..54b787d4 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "ash/public/cpp/login_constants.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/cpp/wallpaper_types.h"
 #include "ash/public/interfaces/tray_action.mojom.h"
 #include "base/bind.h"
@@ -65,6 +64,7 @@
 #include "chrome/browser/profiles/profile_metrics.h"
 #include "chrome/browser/ui/ash/ime_controller_client.h"
 #include "chrome/browser/ui/ash/session_controller_client_impl.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "chrome/browser/ui/webui/chromeos/internet_detail_dialog.h"
 #include "chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h"
@@ -266,9 +266,9 @@
           base::Bind(&SigninScreenHandler::OnAllowedInputMethodsChanged,
                      base::Unretained(this)));
 
-  ash::TabletMode* tablet_mode = ash::TabletMode::Get();
-  tablet_mode->AddObserver(this);
-  OnTabletModeToggled(tablet_mode->InTabletMode());
+  TabletModeClient* tablet_mode_client = TabletModeClient::Get();
+  tablet_mode_client->AddObserver(this);
+  OnTabletModeToggled(tablet_mode_client->tablet_mode_enabled());
 
   WallpaperControllerClient::Get()->AddObserver(this);
 }
@@ -276,7 +276,7 @@
 SigninScreenHandler::~SigninScreenHandler() {
   if (auto* wallpaper_controller_client = WallpaperControllerClient::Get())
     wallpaper_controller_client->RemoveObserver(this);
-  ash::TabletMode::Get()->RemoveObserver(this);
+  TabletModeClient::Get()->RemoveObserver(this);
   OobeUI* oobe_ui = GetOobeUI();
   if (oobe_ui && oobe_ui_observer_added_)
     oobe_ui->RemoveObserver(this);
@@ -1359,7 +1359,7 @@
 
 void SigninScreenHandler::HandleGetTabletModeState() {
   CallJS("login.AccountPickerScreen.setTabletModeState",
-         ash::TabletMode::Get()->InTabletMode());
+         TabletModeClient::Get()->tablet_mode_enabled());
 }
 
 void SigninScreenHandler::HandleGetDemoModeState() {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index 1ac05ab..48988d3 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -10,7 +10,6 @@
 #include <set>
 #include <string>
 
-#include "ash/public/cpp/tablet_mode_toggle_observer.h"
 #include "ash/public/cpp/wallpaper_controller_observer.h"
 #include "base/callback.h"
 #include "base/compiler_specific.h"
@@ -22,6 +21,7 @@
 #include "chrome/browser/chromeos/login/signin_specifics.h"
 #include "chrome/browser/chromeos/login/ui/login_display.h"
 #include "chrome/browser/chromeos/settings/cros_settings.h"
+#include "chrome/browser/ui/ash/tablet_mode_client_observer.h"
 #include "chrome/browser/ui/webui/chromeos/login/base_webui_handler.h"
 #include "chrome/browser/ui/webui/chromeos/login/network_state_informer.h"
 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
@@ -183,7 +183,7 @@
       public NetworkStateInformer::NetworkStateInformerObserver,
       public PowerManagerClient::Observer,
       public input_method::ImeKeyboard::Observer,
-      public ash::TabletModeToggleObserver,
+      public TabletModeClientObserver,
       public OobeUI::Observer,
       public ash::WallpaperControllerObserver {
  public:
@@ -302,7 +302,7 @@
   // PowerManagerClient::Observer implementation:
   void SuspendDone(const base::TimeDelta& sleep_duration) override;
 
-  // ash::TabletModeToggleObserver:
+  // TabletModeClientObserver:
   void OnTabletModeToggled(bool enabled) override;
 
   // Restore input focus to current user pod.
diff --git a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
index ef68e3e..7dc7653 100644
--- a/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.cc
@@ -5,11 +5,11 @@
 #include "chrome/browser/ui/webui/settings/chromeos/device_keyboard_handler.h"
 
 #include "ash/public/cpp/keyboard_shortcut_viewer.h"
-#include "ash/public/cpp/tablet_mode.h"
 #include "ash/public/interfaces/constants.mojom.h"
 #include "base/bind.h"
 #include "base/command_line.h"
 #include "base/values.h"
+#include "chrome/browser/ui/ash/tablet_mode_client.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "chromeos/services/assistant/public/features.h"
 #include "content/public/browser/web_ui.h"
@@ -115,7 +115,8 @@
 void KeyboardHandler::UpdateKeyboards() {
   bool physical_keyboard = false;
   // In tablet mode, physical keybards are disabled / ignored.
-  if (!ash::TabletMode::Get()->InTabletMode()) {
+  if (!TabletModeClient::Get() ||
+      !TabletModeClient::Get()->tablet_mode_enabled()) {
     physical_keyboard = true;
   }
   if (!physical_keyboard) {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index f3e2a09a6..e42c12e 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3918,6 +3918,7 @@
       "../browser/ui/ash/network/network_state_notifier_unittest.cc",
       "../browser/ui/ash/network/tether_notification_presenter_unittest.cc",
       "../browser/ui/ash/session_controller_client_impl_unittest.cc",
+      "../browser/ui/ash/tablet_mode_client_unittest.cc",
       "../browser/ui/ash/wallpaper_controller_client_unittest.cc",
       "../browser/ui/window_sizer/window_sizer_ash_unittest.cc",
     ]