| // Copyright 2013 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 "ash/accelerators/accelerator_commands.h" |
| |
| #include "ash/accelerators/accelerator_table.h" |
| #include "ash/ash_switches.h" |
| #include "ash/debug.h" |
| #include "ash/desktop_background/desktop_background_controller.h" |
| #include "ash/desktop_background/user_wallpaper_delegate.h" |
| #include "ash/display/display_manager.h" |
| #include "ash/host/ash_window_tree_host.h" |
| #include "ash/root_window_controller.h" |
| #include "ash/shell.h" |
| #include "ash/wm/window_util.h" |
| #include "base/command_line.h" |
| #include "third_party/skia/include/core/SkColor.h" |
| #include "third_party/skia/include/core/SkPaint.h" |
| #include "ui/aura/window.h" |
| #include "ui/aura/window_event_dispatcher.h" |
| #include "ui/compositor/debug_utils.h" |
| #include "ui/compositor/layer.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/views/debug_utils.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace ash { |
| namespace debug { |
| namespace { |
| |
| void HandlePrintLayerHierarchy() { |
| aura::Window::Windows root_windows = Shell::GetAllRootWindows(); |
| for (size_t i = 0; i < root_windows.size(); ++i) { |
| ui::PrintLayerHierarchy( |
| root_windows[i]->layer(), |
| root_windows[i]->GetHost()->dispatcher()->GetLastMouseLocationInRoot()); |
| } |
| } |
| |
| void HandlePrintViewHierarchy() { |
| aura::Window* active_window = ash::wm::GetActiveWindow(); |
| if (!active_window) |
| return; |
| views::Widget* browser_widget = |
| views::Widget::GetWidgetForNativeWindow(active_window); |
| if (!browser_widget) |
| return; |
| views::PrintViewHierarchy(browser_widget->GetRootView()); |
| } |
| |
| void PrintWindowHierarchy(aura::Window* window, |
| int indent, |
| std::ostringstream* out) { |
| std::string indent_str(indent, ' '); |
| std::string name(window->name()); |
| if (name.empty()) |
| name = "\"\""; |
| *out << indent_str << name << " (" << window << ")" |
| << " type=" << window->type() |
| << (wm::IsActiveWindow(window) ? " [active] " : " ") |
| << (window->IsVisible() ? " visible " : " ") |
| << window->bounds().ToString() |
| << '\n'; |
| |
| for (size_t i = 0; i < window->children().size(); ++i) |
| PrintWindowHierarchy(window->children()[i], indent + 3, out); |
| } |
| |
| void HandlePrintWindowHierarchy() { |
| Shell::RootWindowControllerList controllers = |
| Shell::GetAllRootWindowControllers(); |
| for (size_t i = 0; i < controllers.size(); ++i) { |
| std::ostringstream out; |
| out << "RootWindow " << i << ":\n"; |
| PrintWindowHierarchy(controllers[i]->GetRootWindow(), 0, &out); |
| // Error so logs can be collected from end-users. |
| LOG(ERROR) << out.str(); |
| } |
| } |
| |
| gfx::ImageSkia CreateWallpaperImage(SkColor fill, SkColor rect) { |
| // TODO(oshima): Consider adding a command line option to control |
| // wallpaper images for testing. |
| // The size is randomly picked. |
| gfx::Size image_size(1366, 768); |
| gfx::Canvas canvas(image_size, 1.0f, true); |
| canvas.DrawColor(fill); |
| SkPaint paint; |
| paint.setColor(rect); |
| paint.setStrokeWidth(10); |
| paint.setStyle(SkPaint::kStroke_Style); |
| paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); |
| canvas.DrawRoundRect(gfx::Rect(image_size), 100, paint); |
| return gfx::ImageSkia(canvas.ExtractImageRep()); |
| } |
| |
| void HandleToggleDesktopBackgroundMode() { |
| static int index = 0; |
| DesktopBackgroundController* desktop_background_controller = |
| Shell::GetInstance()->desktop_background_controller(); |
| switch (++index % 4) { |
| case 0: |
| ash::Shell::GetInstance()->user_wallpaper_delegate()-> |
| InitializeWallpaper(); |
| break; |
| case 1: |
| desktop_background_controller->SetWallpaperImage( |
| CreateWallpaperImage(SK_ColorRED, SK_ColorBLUE), |
| WALLPAPER_LAYOUT_STRETCH); |
| break; |
| case 2: |
| desktop_background_controller->SetWallpaperImage( |
| CreateWallpaperImage(SK_ColorBLUE, SK_ColorGREEN), |
| WALLPAPER_LAYOUT_CENTER); |
| break; |
| case 3: |
| desktop_background_controller->SetWallpaperImage( |
| CreateWallpaperImage(SK_ColorGREEN, SK_ColorRED), |
| WALLPAPER_LAYOUT_CENTER_CROPPED); |
| break; |
| } |
| } |
| |
| } // namespace |
| |
| void PrintUIHierarchies() { |
| // This is a separate command so the user only has to hit one key to generate |
| // all the logs. Developers use the individual dumps repeatedly, so keep |
| // those as separate commands to avoid spamming their logs. |
| HandlePrintLayerHierarchy(); |
| HandlePrintWindowHierarchy(); |
| HandlePrintViewHierarchy(); |
| } |
| |
| bool DebugAcceleratorsEnabled() { |
| return CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kAshDebugShortcuts); |
| } |
| |
| void PerformDebugAction(int action) { |
| if (!DebugAcceleratorsEnabled()) |
| return; |
| |
| switch (action) { |
| #if defined(OS_CHROMEOS) |
| case DEBUG_ADD_REMOVE_DISPLAY: |
| Shell::GetInstance()->display_manager()->AddRemoveDisplay(); |
| break; |
| #endif |
| case DEBUG_PRINT_LAYER_HIERARCHY: |
| HandlePrintLayerHierarchy(); |
| break; |
| case DEBUG_PRINT_VIEW_HIERARCHY: |
| HandlePrintViewHierarchy(); |
| break; |
| case DEBUG_PRINT_WINDOW_HIERARCHY: |
| HandlePrintWindowHierarchy(); |
| break; |
| case DEBUG_TOGGLE_DESKTOP_BACKGROUND_MODE: |
| HandleToggleDesktopBackgroundMode(); |
| break; |
| case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR: |
| Shell::GetInstance()->display_manager()->ToggleDisplayScaleFactor(); |
| break; |
| case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN: |
| Shell::GetPrimaryRootWindowController()->ash_host()->ToggleFullScreen(); |
| break; |
| case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: |
| ToggleShowDebugBorders(); |
| break; |
| case DEBUG_TOGGLE_SHOW_FPS_COUNTER: |
| ToggleShowFpsCounter(); |
| break; |
| case DEBUG_TOGGLE_SHOW_PAINT_RECTS: |
| ToggleShowPaintRects(); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| } // namespace debug |
| } // namespace ash |