crostini: Show a toast when a user tries to combine VK + Crostini

Instead of logging a console message, we now show a toast to the user
for 5 seconds the first time (per session) they focus a Crostini app
while in tablet mode.

./out/Default/unit_tests
for one and only one toast

Bug: chromium:962848
Test: autoninja -C out/Default chrome unit_tests &&
Test: Play around with tablet mode and Crostini on an Eve device, check
Change-Id: Ie70a847372f2a65d3f71fc39e29cb1165992ab3a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1743232
Auto-Submit: David Munro <davidmunro@google.com>
Reviewed-by: Nicholas Verne <nverne@chromium.org>
Commit-Queue: David Munro <davidmunro@google.com>
Cr-Commit-Position: refs/heads/master@{#685081}
diff --git a/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.cc b/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.cc
index 3b62513..b6a43f6b 100644
--- a/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.cc
+++ b/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.cc
@@ -8,9 +8,13 @@
 
 #include "ash/public/cpp/app_types.h"
 #include "ash/public/cpp/tablet_mode.h"
+#include "ash/public/cpp/toast_manager.h"
 #include "base/logging.h"
+#include "base/optional.h"
+#include "chrome/grit/generated_resources.h"
 #include "components/exo/wm_helper.h"
 #include "ui/aura/client/aura_constants.h"
+#include "ui/base/l10n/l10n_util.h"
 
 namespace crostini {
 
@@ -33,8 +37,13 @@
     ShowVirtualKeyboardUnsupportedNotifictionIfNeeded() {
   if (!virtual_keyboard_unsupported_message_shown_ &&
       delegate_->IsInTabletMode() && delegate_->IsFocusedWindowCrostini()) {
-    delegate_->ShowNotification(
-        nullptr);  // TODO(crbug/962848): actually show the notification
+    ash::ToastData data = {
+        /*id=*/"VKUnsupportedInCrostini",
+        /*text=*/
+        l10n_util::GetStringUTF16(IDS_CROSTINI_UNSUPPORTED_VIRTUAL_KEYBOARD),
+        /*timeout_ms=*/5000,
+        /*dismiss_text=*/base::Optional<base::string16>()};
+    delegate_->ShowToast(data);
     virtual_keyboard_unsupported_message_shown_ = true;
   }
 }
@@ -66,10 +75,9 @@
          static_cast<int>(ash::AppType::CROSTINI_APP);
 }
 
-void CrostiniUnsupportedActionNotifier::Delegate::ShowNotification(
-    message_center::Notification* notification) {
-  // TODO(crbug/962848): actually show the notification
-  LOG(WARNING) << "User tried to use tablet mode with a Crostini app";
+void CrostiniUnsupportedActionNotifier::Delegate::ShowToast(
+    const ash::ToastData& toast_data) {
+  ash::ToastManager::Get()->Show(toast_data);
 }
 
 void CrostiniUnsupportedActionNotifier::Delegate::AddFocusObserver(
diff --git a/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.h b/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.h
index 763780c..f7c28b6f 100644
--- a/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.h
+++ b/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier.h
@@ -8,8 +8,8 @@
 #include <memory>
 
 #include "ash/public/cpp/tablet_mode_observer.h"
+#include "ash/public/cpp/toast_data.h"
 #include "ui/aura/client/focus_change_observer.h"
-#include "ui/message_center/public/cpp/notification.h"
 
 namespace crostini {
 
@@ -34,9 +34,8 @@
     // doesn't count the terminal.
     virtual bool IsFocusedWindowCrostini();
 
-    // Shows a notification to the user, caller manages the lifecycle of the
-    // notification.
-    virtual void ShowNotification(message_center::Notification* notification);
+    // Shows a toast to the user
+    virtual void ShowToast(const ash::ToastData& toast_data);
 
     virtual void AddFocusObserver(aura::client::FocusChangeObserver* observer);
     virtual void RemoveFocusObserver(
@@ -50,11 +49,6 @@
       std::unique_ptr<Delegate> delegate);
   ~CrostiniUnsupportedActionNotifier() override;
 
-  // Checks if the user is trying to use a virtual keyboard with a crostini
-  // app and, if so and if they haven't already been notified that it's not
-  // supported, notify them.
-  void ShowVirtualKeyboardUnsupportedNotifictionIfNeeded();
-
   // ash::TabletModeObserver
   void OnTabletModeStarted() override;
 
@@ -65,6 +59,11 @@
   Delegate* get_delegate_for_testing() { return delegate_.get(); }
 
  private:
+  // Checks if the user is trying to use a virtual keyboard with a crostini
+  // app and, if so and if they haven't already been notified that it's not
+  // supported, notify them.
+  void ShowVirtualKeyboardUnsupportedNotifictionIfNeeded();
+
   std::unique_ptr<Delegate> delegate_;
   bool virtual_keyboard_unsupported_message_shown_ = false;
 
diff --git a/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier_unittest.cc b/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier_unittest.cc
index ff53ac4..162b791 100644
--- a/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier_unittest.cc
+++ b/chrome/browser/chromeos/crostini/crostini_unsupported_action_notifier_unittest.cc
@@ -23,10 +23,7 @@
  public:
   MOCK_METHOD(bool, IsInTabletMode, (), (override));
   MOCK_METHOD(bool, IsFocusedWindowCrostini, (), (override));
-  MOCK_METHOD(void,
-              ShowNotification,
-              (message_center::Notification * notification),
-              (override));
+  MOCK_METHOD(void, ShowToast, (const ash::ToastData& toast_data), (override));
   MOCK_METHOD(void,
               AddFocusObserver,
               (aura::client::FocusChangeObserver * observer),
@@ -67,12 +64,12 @@
 };
 
 TEST_P(CrostiniUnsupportedActionNotifierTest,
-       NotificationShownOnceOnlyWhenEnteringTabletModeWhileCrostiniAppFocused) {
+       ToastShownOnceOnlyWhenEnteringTabletModeWhileCrostiniAppFocused) {
   EXPECT_CALL(get_delegate(), IsInTabletMode)
       .WillRepeatedly(Return(is_tablet_mode()));
   EXPECT_CALL(get_delegate(), IsFocusedWindowCrostini)
       .WillRepeatedly(Return(is_crostini_focused()));
-  EXPECT_CALL(get_delegate(), ShowNotification(_))
+  EXPECT_CALL(get_delegate(), ShowToast(_))
       .Times((is_tablet_mode() && is_crostini_focused()) ? 1 : 0);
 
   notifier.OnTabletModeStarted();
@@ -81,12 +78,12 @@
 }
 
 TEST_P(CrostiniUnsupportedActionNotifierTest,
-       NotificationShownOnceOnlyWhenFocusingCrostiniWhileInTabletMode) {
+       ToastShownOnceOnlyWhenFocusingCrostiniWhileInTabletMode) {
   EXPECT_CALL(get_delegate(), IsInTabletMode)
       .WillRepeatedly(Return(is_tablet_mode()));
   EXPECT_CALL(get_delegate(), IsFocusedWindowCrostini)
       .WillRepeatedly(Return(is_crostini_focused()));
-  EXPECT_CALL(get_delegate(), ShowNotification(_))
+  EXPECT_CALL(get_delegate(), ShowToast(_))
       .Times((is_tablet_mode() && is_crostini_focused()) ? 1 : 0);
 
   notifier.OnWindowFocused(nullptr, nullptr);