blob: 02f70453c164a917aa82418d580ea90a10eca4a9 [file] [log] [blame]
// Copyright 2020 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 <string>
#include <utility>
#include <vector>
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/grit/chromium_strings.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "chromeos/crosapi/mojom/bitmap.mojom.h"
#include "chromeos/crosapi/mojom/screen_manager.mojom.h"
#include "chromeos/lacros/lacros_chrome_service_impl.h"
#include "content/public/test/browser_test.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"
namespace {
const char* kLacrosPageTitle = "Title Of Lacros Browser Test";
const char* kLacrosPageTitleHTML =
"<html><head><title>Title Of Lacros Browser Test</title></head>"
"<body>This page has a title.</body></html>";
using ListWindowsCallback = base::RepeatingCallback<void(
std::vector<crosapi::mojom::SnapshotSourcePtr>*)>;
// Used to find the window corresponding to the test page.
bool FindTestWindow(ListWindowsCallback list_windows, uint64_t* window_id) {
base::RunLoop run_loop;
bool found_window = false;
auto look_for_window = base::BindRepeating(
[](ListWindowsCallback list_windows, base::RunLoop* run_loop,
bool* found_window, uint64_t* window_id) {
const base::string16 tab_title(base::ASCIIToUTF16(kLacrosPageTitle));
std::string expected_window_title = l10n_util::GetStringFUTF8(
IDS_BROWSER_WINDOW_TITLE_FORMAT, tab_title);
std::vector<crosapi::mojom::SnapshotSourcePtr> windows;
list_windows.Run(&windows);
for (auto& window : windows) {
if (window->title == expected_window_title) {
(*found_window) = true;
(*window_id) = window->id;
run_loop->Quit();
break;
}
}
},
std::move(list_windows), &run_loop, &found_window, window_id);
// When the browser test start, there is no guarantee that the window is
// open from ash's perspective.
base::RepeatingTimer timer;
timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(1),
std::move(look_for_window));
run_loop.Run();
return found_window;
}
} // namespace
class ScreenManagerLacrosBrowserTest : public InProcessBrowserTest {
protected:
ScreenManagerLacrosBrowserTest() = default;
ScreenManagerLacrosBrowserTest(const ScreenManagerLacrosBrowserTest&) =
delete;
ScreenManagerLacrosBrowserTest& operator=(
const ScreenManagerLacrosBrowserTest&) = delete;
~ScreenManagerLacrosBrowserTest() override = default;
void BindScreenManager() {
auto* lacros_chrome_service = chromeos::LacrosChromeServiceImpl::Get();
ASSERT_TRUE(lacros_chrome_service);
mojo::PendingRemote<crosapi::mojom::ScreenManager> pending_screen_manager;
lacros_chrome_service->BindScreenManagerReceiver(
pending_screen_manager.InitWithNewPipeAndPassReceiver());
screen_manager_.Bind(std::move(pending_screen_manager));
}
uint32_t QueryScreenManagerVersion() {
// Synchronously fetch the version of the ScreenManager interface. The
// version field will be available as |screen_manager_.version()|.
base::RunLoop run_loop(base::RunLoop::Type::kNestableTasksAllowed);
screen_manager_.QueryVersion(
base::BindOnce([](base::OnceClosure done_closure,
uint32_t version) { std::move(done_closure).Run(); },
run_loop.QuitClosure()));
run_loop.Run();
return screen_manager_.version();
}
mojo::Remote<crosapi::mojom::ScreenManager> screen_manager_;
};
// Tests that taking a screen snapshot via crosapi works.
IN_PROC_BROWSER_TEST_F(ScreenManagerLacrosBrowserTest,
DeprecatedTakeScreenSnapshot) {
BindScreenManager();
crosapi::Bitmap snapshot;
{
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
screen_manager_->DeprecatedTakeScreenSnapshot(&snapshot);
}
// Verify the snapshot is non-empty.
EXPECT_GT(snapshot.height, 0u);
EXPECT_GT(snapshot.width, 0u);
EXPECT_GT(snapshot.pixels.size(), 0u);
}
// Tests that taking a screen snapshot via crosapi works.
// This test makes the browser load a page with specific title, and then scans
// through a list of windows to look for the window with the expected title.
// This test cannot simply assert exactly 1 window is present because currently
// in lacros_chrome_browsertests, different browser tests share the same
// ash-chrome, so a window could come from any one of them.
IN_PROC_BROWSER_TEST_F(ScreenManagerLacrosBrowserTest,
DeprecatedTakeWindowSnapshot) {
GURL url(std::string("data:text/html,") + kLacrosPageTitleHTML);
ui_test_utils::NavigateToURL(browser(), url);
BindScreenManager();
auto list_windows = base::BindRepeating(
[](mojo::Remote<crosapi::mojom::ScreenManager>* screen_manager,
std::vector<crosapi::mojom::SnapshotSourcePtr>* windows) {
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
(*screen_manager)->DeprecatedListWindows(windows);
},
&screen_manager_);
uint64_t window_id;
bool found_window = FindTestWindow(std::move(list_windows), &window_id);
ASSERT_TRUE(found_window);
bool success = false;
crosapi::Bitmap snapshot;
{
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
screen_manager_->DeprecatedTakeWindowSnapshot(window_id, &success,
&snapshot);
}
ASSERT_TRUE(success);
// Verify the snapshot is non-empty.
EXPECT_GT(snapshot.height, 0u);
EXPECT_GT(snapshot.width, 0u);
EXPECT_GT(snapshot.pixels.size(), 0u);
}
// Tests that taking a screen snapshot via crosapi works.
IN_PROC_BROWSER_TEST_F(ScreenManagerLacrosBrowserTest, ScreenCapturer) {
BindScreenManager();
if (QueryScreenManagerVersion() < 1) {
LOG(WARNING) << "Ash version does not support required method.";
return;
}
mojo::Remote<crosapi::mojom::SnapshotCapturer> capturer;
screen_manager_->GetScreenCapturer(capturer.BindNewPipeAndPassReceiver());
std::vector<crosapi::mojom::SnapshotSourcePtr> screens;
{
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
capturer->ListSources(&screens);
}
ASSERT_LE(1u, screens.size());
bool success = false;
SkBitmap snapshot;
{
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
capturer->TakeSnapshot(screens[0]->id, &success, &snapshot);
}
EXPECT_TRUE(success);
// Verify the snapshot is non-empty.
EXPECT_GT(snapshot.height(), 0);
EXPECT_GT(snapshot.width(), 0);
}
// Tests that taking a window snapshot via crosapi works.
// This test makes the browser load a page with specific title, and then scans
// through a list of windows to look for the window with the expected title.
// This test cannot simply asserts exactly 1 window is present because currently
// in lacros_chrome_browsertests, different browser tests share the same
// ash-chrome, so a window could come from any one of them.
IN_PROC_BROWSER_TEST_F(ScreenManagerLacrosBrowserTest, WindowCapturer) {
BindScreenManager();
if (QueryScreenManagerVersion() < 1) {
LOG(WARNING) << "Ash version does not support required method.";
return;
}
GURL url(std::string("data:text/html,") + kLacrosPageTitleHTML);
ui_test_utils::NavigateToURL(browser(), url);
mojo::Remote<crosapi::mojom::SnapshotCapturer> capturer;
screen_manager_->GetWindowCapturer(capturer.BindNewPipeAndPassReceiver());
auto list_windows = base::BindRepeating(
[](mojo::Remote<crosapi::mojom::SnapshotCapturer>* capturer,
std::vector<crosapi::mojom::SnapshotSourcePtr>* windows) {
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
(*capturer)->ListSources(windows);
},
&capturer);
uint64_t window_id;
bool found_window = FindTestWindow(std::move(list_windows), &window_id);
ASSERT_TRUE(found_window);
bool success = false;
SkBitmap snapshot;
{
mojo::ScopedAllowSyncCallForTesting allow_sync_call;
capturer->TakeSnapshot(window_id, &success, &snapshot);
}
ASSERT_TRUE(success);
// Verify the snapshot is non-empty.
EXPECT_GT(snapshot.height(), 0);
EXPECT_GT(snapshot.width(), 0);
}