chromium/chrome/browser/lacros/app_mode/kiosk_accelerator_browsertest.cc

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/check_deref.h"
#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/test/test_future.h"
#include "chrome/browser/app_mode/test/accelerator_helpers.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/test/test_browser_closed_waiter.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/crosapi/mojom/crosapi.mojom-shared.h"
#include "chromeos/startup/browser_init_params.h"
#include "content/public/test/browser_test.h"
#include "ui/display/screen.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
#include "ui/gfx/geometry/rect.h"

using crosapi::mojom::BrowserInitParams;
using crosapi::mojom::BrowserInitParamsPtr;
using crosapi::mojom::CreationResult;
using crosapi::mojom::SessionType;

namespace {

const char kWebAppUrl[] = "https://www.example.com/";

[[nodiscard]] bool WaitUntilBrowserClosed(Browser* browser) {
  TestBrowserClosedWaiter waiter(browser);
  return waiter.WaitUntilClosed();
}

void CreateKioskWindow() {
  Browser::CreateParams params = web_app::CreateParamsForApp(
      kWebAppUrl,
      /*is_popup=*/true, /*trusted_source=*/true, /*window_bounds=*/gfx::Rect(),
      /*profile=*/ProfileManager::GetPrimaryUserProfile(),
      /*user_gesture*/ true);
  web_app::CreateWebAppWindowMaybeWithHomeTab(kWebAppUrl, params);
}

void SetBrowserInitParamsForWebKiosk() {
  BrowserInitParamsPtr init_params =
      chromeos::BrowserInitParams::GetForTests()->Clone();
  init_params->session_type = SessionType::kWebKioskSession;
  init_params->device_settings = crosapi::mojom::DeviceSettings::New();
  chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
}

}  // namespace

// Tests browser view accelerators work normally in non kiosk session.
using NonKioskAcceleratorTest = InProcessBrowserTest;

// Tests browser view accelerators do not work in kiosk session.
class WebKioskAcceleratorTest : public InProcessBrowserTest {
 protected:
  WebKioskAcceleratorTest() = default;
  ~WebKioskAcceleratorTest() override = default;

  void SetUp() override {
    SetBrowserInitParamsForWebKiosk();
    InProcessBrowserTest::SetUp();
  }

  void SetUpOnMainThread() override {
    InProcessBrowserTest::SetUpOnMainThread();
    SetKioskSessionType();
    CreateKioskWindow();
    WaitForNonKioskWindowToClose();
    SelectFirstBrowser();
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    InProcessBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitch(switches::kForceAppMode);
  }

  void TearDownOnMainThread() override {
    InProcessBrowserTest::TearDownOnMainThread();
  }

 private:
  void SetKioskSessionType() {
    BrowserInitParamsPtr init_params =
        chromeos::BrowserInitParams::GetForTests()->Clone();
    init_params->session_type = SessionType::kWebKioskSession;
    chromeos::BrowserInitParams::SetInitParamsForTests(std::move(init_params));
  }

  void WaitForNonKioskWindowToClose() {
    // The test framework automatically spawns a separate, non-kiosk browser
    // window.
    // This browser will automatically be closed by the code, but that happens
    // asynchronous so wait here until that's done.
    ASSERT_EQ(BrowserList::GetInstance()->size(), 2u);

    for (Browser* browser : *BrowserList::GetInstance()) {
      // The non kiosk window will be automatically closed, but we have to wait
      // for the closing to finish.
      if (browser->IsAttemptingToCloseBrowser() ||
          browser->IsBrowserClosing()) {
        ASSERT_TRUE(WaitUntilBrowserClosed(browser));
        // do not continue looping since the browser list is now invalidated.
        break;
      }
    }

    ASSERT_EQ(BrowserList::GetInstance()->size(), 1u);
  }
};

IN_PROC_BROWSER_TEST_F(NonKioskAcceleratorTest, CloseTabWorks) {
  ASSERT_EQ(BrowserList::GetInstance()->size(), 1u);
  ASSERT_TRUE(PressCloseTabAccelerator(browser()));
  ASSERT_TRUE(WaitUntilBrowserClosed(browser()));
  ASSERT_EQ(BrowserList::GetInstance()->size(), 0u);
}

IN_PROC_BROWSER_TEST_F(NonKioskAcceleratorTest, CloseWindowWorks) {
  ASSERT_EQ(BrowserList::GetInstance()->size(), 1u);
  ASSERT_TRUE(PressCloseWindowAccelerator(browser()));
  ASSERT_TRUE(WaitUntilBrowserClosed(browser()));
  ASSERT_EQ(BrowserList::GetInstance()->size(), 0u);
}

IN_PROC_BROWSER_TEST_F(WebKioskAcceleratorTest, CloseTabAndWindowDontWork) {
  ASSERT_EQ(BrowserList::GetInstance()->size(), 1u);
  ASSERT_FALSE(PressCloseTabAccelerator(browser()));
  ASSERT_FALSE(PressCloseWindowAccelerator(browser()));
  base::RunLoop loop;
  loop.RunUntilIdle();
  ASSERT_EQ(BrowserList::GetInstance()->size(), 1u);
}