0

Generic PrintWindowHierarchy for ChromeOS (ash and lacros)

Bug: None
Change-Id: I63ca70a232b647e7776bc8eaf2eae85a62a6eb40
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5237046
Reviewed-by: Yuta Hijikata <ythjkt@chromium.org>
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1252560}
This commit is contained in:
Mitsuru Oshima
2024-01-26 11:23:18 +00:00
committed by Chromium LUCI CQ
parent c545bbe234
commit b57af0bbc3
5 changed files with 155 additions and 58 deletions

@ -8,14 +8,12 @@
#include <string>
#include "ash/public/cpp/debug_utils.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/root_window_controller.h"
#include "ash/shell.h"
#include "ash/wm/window_properties.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_util.h"
#include "base/memory/raw_ptr.h"
#include "cc/debug/layer_tree_debug_state.h"
#include "chromeos/ui/wm/debug_util.h"
#include "ui/accessibility/aura/aura_window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/window_tree_host.h"
@ -69,63 +67,16 @@ void PrintViewHierarchy(std::ostringstream* out) {
views::PrintViewHierarchy(widget->GetRootView(), out);
}
void PrintWindowHierarchy(const aura::Window* active_window,
const aura::Window* focused_window,
const aura::Window* capture_window,
aura::Window* window,
int indent,
bool scrub_data,
std::vector<std::string>* out_window_titles,
std::ostringstream* out) {
*out << std::string(indent, ' ');
*out << " [window]";
window->GetDebugInfo(active_window, focused_window, capture_window, out);
if (window->GetProperty(kWindowStateKey))
*out << " state=" << WindowState::Get(window)->GetStateType();
std::u16string title(window->GetTitle());
if (!title.empty()) {
if (!scrub_data) {
*out << " title=\"" << title << "\"";
}
out_window_titles->push_back(base::UTF16ToUTF8(title));
}
std::string* tree_id = window->GetProperty(ui::kChildAXTreeID);
if (tree_id) {
*out << " ax_tree_id=" << *tree_id;
}
*out << std::endl;
views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
if (widget) {
*out << std::string(indent + 3, ' ');
*out << " [widget]";
views::PrintWidgetInformation(*widget, /*detailed*/ false, out);
}
std::vector<raw_ptr<aura::Window, VectorExperimental>> children =
instance ? instance->GetAdjustedWindowChildren(window)
: window->children();
for (aura::Window* child : children) {
PrintWindowHierarchy(active_window, focused_window, capture_window, child,
indent + 3, scrub_data, out_window_titles, out);
}
}
std::vector<std::string> PrintWindowHierarchy(std::ostringstream* out,
bool scrub_data) {
aura::Window* active_window = window_util::GetActiveWindow();
aura::Window* focused_window = window_util::GetFocusedWindow();
aura::Window* capture_window = window_util::GetCaptureWindow();
aura::Window::Windows roots = Shell::Get()->GetAllRootWindows();
std::vector<std::string> window_titles;
for (size_t i = 0; i < roots.size(); ++i) {
*out << "RootWindow " << i << ":\n";
PrintWindowHierarchy(active_window, focused_window, capture_window,
roots[i], 0, scrub_data, &window_titles, out);
}
return window_titles;
auto children_callback = base::BindRepeating(
[](aura::Window* window)
-> std::vector<raw_ptr<aura::Window, VectorExperimental>> {
return instance ? instance->GetAdjustedWindowChildren(window)
: window->children();
});
return chromeos::wm::PrintWindowHierarchy(Shell::Get()->GetAllRootWindows(),
scrub_data, out, children_callback);
}
void ToggleShowDebugBorders() {

@ -13,6 +13,8 @@ source_set("wm") {
sources = [
"constants.h",
"debug_util.cc",
"debug_util.h",
"desks/chromeos_desks_histogram_enums.h",
"desks/desks_helper.h",
"fullscreen/keep_fullscreen_for_url_checker.cc",
@ -29,8 +31,11 @@ source_set("wm") {
"//chromeos/ui/base",
"//components/prefs",
"//components/url_matcher",
"//ui/accessibility",
"//ui/aura",
"//ui/base",
"//ui/views",
"//ui/wm/public",
"//url",
]

@ -2,9 +2,11 @@ include_rules = [
"+components/prefs",
"+components/url_matcher",
"+ui/aura",
"+ui/accessibility",
"+ui/base",
"+ui/display",
"+ui/gfx",
"+ui/platform_window",
"+ui/views",
"+ui/wm/public",
]

@ -0,0 +1,101 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromeos/ui/wm/debug_util.h"
#include "chromeos/ui/base/window_properties.h"
#include "chromeos/ui/base/window_state_type.h"
#include "ui/accessibility/aura/aura_window_properties.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/capture_client.h"
#include "ui/aura/client/focus_client.h"
#include "ui/views/debug_utils.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/public/activation_client.h"
namespace chromeos::wm {
namespace {
void PrintWindowHierarchy(const aura::Window* active_window,
const aura::Window* focused_window,
const aura::Window* capture_window,
aura::Window* window,
int indent,
bool scrub_data,
GetChildrenCallback children_callback,
std::vector<std::string>* out_window_titles,
std::ostringstream* out) {
*out << std::string(indent, ' ');
*out << " [window]";
window->GetDebugInfo(active_window, focused_window, capture_window, out);
if (base::Contains(window->GetAllPropertyKeys(),
chromeos::kWindowStateTypeKey)) {
*out << " state=" << window->GetProperty(chromeos::kWindowStateTypeKey);
}
std::u16string title(window->GetTitle());
if (!title.empty()) {
if (!scrub_data) {
*out << " title=\"" << title << "\"";
}
out_window_titles->push_back(base::UTF16ToUTF8(title));
}
std::string* tree_id = window->GetProperty(ui::kChildAXTreeID);
if (tree_id) {
*out << " ax_tree_id=" << *tree_id;
}
*out << std::endl;
views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
if (widget) {
*out << std::string(indent + 3, ' ');
*out << " [widget]";
views::PrintWidgetInformation(*widget, /*detailed*/ false, out);
}
std::vector<raw_ptr<aura::Window, VectorExperimental>> children =
children_callback.is_null() ? window->children()
: children_callback.Run(window);
for (aura::Window* child : children) {
PrintWindowHierarchy(active_window, focused_window, capture_window, child,
indent + 3, scrub_data, children_callback,
out_window_titles, out);
}
}
} // namespace
std::vector<std::string> PrintWindowHierarchy(
aura::Window::Windows roots,
bool scrub_data,
std::ostringstream* out,
GetChildrenCallback children_callback) {
aura::Window* root0 = roots[0];
aura::Window* active_window =
::wm::GetActivationClient(root0)->GetActiveWindow();
aura::Window* focused_window =
aura::client::GetFocusClient(root0)->GetFocusedWindow();
aura::Window* capture_window =
aura::client::GetCaptureClient(root0)->GetCaptureWindow();
std::vector<std::string> window_titles;
for (size_t i = 0; i < roots.size(); ++i) {
*out << "RootWindow " << i << ":\n";
aura::Window* root = roots[i];
// These windows must be same across root windows, on both ash-chrome and
// lacros.
DCHECK_EQ(active_window,
::wm::GetActivationClient(root)->GetActiveWindow());
DCHECK_EQ(focused_window,
aura::client::GetFocusClient(root)->GetFocusedWindow());
DCHECK_EQ(capture_window,
aura::client::GetCaptureClient(root)->GetCaptureWindow());
PrintWindowHierarchy(active_window, focused_window, capture_window, root, 0,
scrub_data, children_callback, &window_titles, out);
}
return window_titles;
}
} // namespace chromeos::wm

@ -0,0 +1,38 @@
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_UI_WM_DEBUG_UTIL_H_
#define CHROMEOS_UI_WM_DEBUG_UTIL_H_
#include <memory>
#include <optional>
#include <sstream>
#include <string>
#include <vector>
#include "base/component_export.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "ui/aura/window.h"
namespace chromeos::wm {
using GetChildrenCallback = base::RepeatingCallback<
std::vector<raw_ptr<aura::Window, VectorExperimental>>(aura::Window*)>;
// Prints all windows hierarchy to `out`. If `scrub_data` is true, we
// may skip some data fields that are not very important for debugging. Returns
// a list of window titles. Window titles will be removed from `out` if
// `scrub_data` is true. `children_callback` can be provided to customize how
// child windows are structured under a window.
COMPONENT_EXPORT(CHROMEOS_UI_BASE)
std::vector<std::string> PrintWindowHierarchy(
aura::Window::Windows roots,
bool scrub_data,
std::ostringstream* out,
GetChildrenCallback children_callback = GetChildrenCallback());
} // namespace chromeos::wm
#endif // CHROMEOS_UI_WM_DEBUG_UTIL_H_