| // 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 "ash/metrics/wm_feature_metrics_recorder.h" |
| |
| #include <array> |
| |
| #include "ash/session/session_controller_impl.h" |
| #include "ash/shell.h" |
| #include "ash/wm/mru_window_tracker.h" |
| #include "ash/wm/window_state.h" |
| #include "ash/wm/window_util.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "base/strings/strcat.h" |
| #include "chromeos/ui/base/app_types.h" |
| #include "chromeos/ui/base/window_properties.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| // The Metrics prefix for WM features. |
| constexpr char kWMFeatureMetricPrefix[] = "Ash.Wm."; |
| |
| // Pre-defined Window size ranges. |
| constexpr std::array<int, 4> kWidthRange = {0, 800, 1024, 1400}; |
| constexpr std::array<int, 4> kHeightRange = {0, 600, 728, 900}; |
| |
| WMFeatureMetricsRecorder::WindowSizeRange GetWindowSizeRange( |
| const gfx::Size& window_size) { |
| const int width = window_size.width(); |
| const int height = window_size.height(); |
| |
| int width_index = 0; |
| for (size_t i = 0; i < sizeof(kWidthRange) / sizeof(int) - 1; ++i) { |
| if (width > kWidthRange[i] && width <= kWidthRange[i + 1]) { |
| width_index = i; |
| break; |
| } |
| if (width > kWidthRange[i + 1]) { |
| width_index = i + 1; |
| } |
| } |
| |
| int height_index = 0; |
| for (size_t j = 0; j < sizeof(kHeightRange) / sizeof(int) - 1; ++j) { |
| if (height > kHeightRange[j] && height <= kHeightRange[j + 1]) { |
| height_index = j; |
| break; |
| } |
| if (height > kHeightRange[j + 1]) { |
| height_index = j + 1; |
| } |
| } |
| |
| return static_cast<WMFeatureMetricsRecorder::WindowSizeRange>( |
| width_index * (sizeof(kHeightRange) / sizeof(int)) + height_index); |
| } |
| |
| // Records the window state and layout related metrics for all windows and the |
| // current active window. |
| void RecordWindowLayoutAndStatePeriodically() { |
| // Get all windows and their placement configuration. |
| auto windows = |
| Shell::Get()->mru_window_tracker()->BuildMruWindowList(kAllDesks); |
| |
| const std::string metrics_prefix = |
| WMFeatureMetricsRecorder::GetFeatureMetricsPrefix( |
| WMFeatureMetricsRecorder::WMFeatureType::kWindowLayoutState); |
| // Report the number of the opened windows. |
| base::UmaHistogramCounts100(metrics_prefix + "WindowNumbers", windows.size()); |
| |
| aura::Window* active_window = window_util::GetActiveWindow(); |
| for (aura::Window* window : windows) { |
| const bool is_active_window = window == active_window; |
| std::vector<std::string> metrics_suffixes; |
| |
| // Report the window state types for all opened windows and the active |
| // window. |
| auto state_type = WindowState::Get(window)->GetStateType(); |
| metrics_suffixes.push_back("AllWindowStates"); |
| if (is_active_window) { |
| metrics_suffixes.push_back("ActiveWindowState"); |
| } |
| for (const std::string& metrics_suffix : metrics_suffixes) { |
| base::UmaHistogramEnumeration(metrics_prefix + metrics_suffix, |
| state_type); |
| } |
| |
| // Report the app types for all opened windows and the active window. |
| metrics_suffixes.clear(); |
| metrics_suffixes.push_back("AllAppTypes"); |
| if (is_active_window) { |
| metrics_suffixes.push_back("ActiveWindowAppType"); |
| } |
| for (const std::string& metrics_suffix : metrics_suffixes) { |
| base::UmaHistogramEnumeration(metrics_prefix + metrics_suffix, |
| window->GetProperty(chromeos::kAppTypeKey)); |
| } |
| |
| // Report the sizes for all windows and the active window. |
| metrics_suffixes.clear(); |
| metrics_suffixes.push_back("AllWindowSizes"); |
| if (chromeos::IsNormalWindowStateType(state_type)) { |
| metrics_suffixes.push_back("FreeformedWindowSizes"); |
| } |
| if (is_active_window) { |
| metrics_suffixes.push_back("ActiveWindowSize"); |
| } |
| const WMFeatureMetricsRecorder::WindowSizeRange size_range = |
| GetWindowSizeRange(window->bounds().size()); |
| for (const std::string& metrics_suffix : metrics_suffixes) { |
| base::UmaHistogramEnumeration(metrics_prefix + metrics_suffix, |
| size_range); |
| } |
| } |
| } |
| |
| } // namespace |
| |
| WMFeatureMetricsRecorder::WMFeatureMetricsRecorder() = default; |
| |
| WMFeatureMetricsRecorder::~WMFeatureMetricsRecorder() = default; |
| |
| // static |
| std::string WMFeatureMetricsRecorder::GetFeatureMetricsPrefix( |
| const WMFeatureType& wm_feature_type) { |
| switch (wm_feature_type) { |
| case WMFeatureType::kWindowLayoutState: |
| return base::StrCat({kWMFeatureMetricPrefix, "WindowLayoutState."}); |
| } |
| } |
| |
| void WMFeatureMetricsRecorder::RecordPeriodicalWMMetrics() { |
| RecordWindowLayoutAndStatePeriodically(); |
| } |
| |
| } // namespace ash |