| // 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/debug_commands.h" |
| |
| #include <string> |
| #include <utility> |
| |
| #include "ash/accelerators/accelerator_commands.h" |
| #include "ash/constants/ash_features.h" |
| #include "ash/constants/ash_switches.h" |
| #include "ash/hud_display/hud_display.h" |
| #include "ash/public/cpp/accelerators.h" |
| #include "ash/public/cpp/debug_utils.h" |
| #include "ash/public/cpp/system/toast_catalog.h" |
| #include "ash/public/cpp/system/toast_data.h" |
| #include "ash/shell.h" |
| #include "ash/system/toast/toast_manager_impl.h" |
| #include "ash/touch/touch_devices_controller.h" |
| #include "ash/wallpaper/wallpaper_controller_impl.h" |
| #include "ash/wm/tablet_mode/tablet_mode_controller.h" |
| #include "base/command_line.h" |
| #include "base/metrics/user_metrics.h" |
| #include "base/metrics/user_metrics_action.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "ui/accessibility/ax_tree_id.h" |
| #include "ui/aura/client/aura_constants.h" |
| #include "ui/display/manager/display_manager.h" |
| #include "ui/gfx/canvas.h" |
| #include "ui/gfx/geometry/skia_conversions.h" |
| #include "ui/gfx/image/image_skia.h" |
| #include "ui/gfx/image/image_skia_rep.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace ash { |
| namespace debug { |
| namespace { |
| |
| void HandlePrintLayerHierarchy() { |
| std::ostringstream out; |
| PrintLayerHierarchy(&out); |
| LOG(ERROR) << out.str(); |
| } |
| |
| void HandlePrintViewHierarchy() { |
| std::ostringstream out; |
| PrintViewHierarchy(&out); |
| LOG(ERROR) << out.str(); |
| } |
| |
| void HandlePrintWindowHierarchy() { |
| std::ostringstream out; |
| PrintWindowHierarchy(&out, /*scrub_data=*/false); |
| 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); |
| SkBitmap bitmap; |
| bitmap.allocN32Pixels(image_size.width(), image_size.height(), true); |
| SkCanvas canvas(bitmap); |
| canvas.drawColor(fill); |
| SkPaint paint; |
| paint.setColor(rect); |
| paint.setStrokeWidth(10); |
| paint.setStyle(SkPaint::kStroke_Style); |
| paint.setBlendMode(SkBlendMode::kSrcOver); |
| canvas.drawRoundRect(gfx::RectToSkRect(gfx::Rect(image_size)), 100.f, 100.f, |
| paint); |
| return gfx::ImageSkia::CreateFromBitmap(std::move(bitmap), 1.f); |
| } |
| |
| void HandleToggleWallpaperMode() { |
| static int index = 0; |
| auto* wallpaper_controller = Shell::Get()->wallpaper_controller(); |
| WallpaperInfo info("", WALLPAPER_LAYOUT_STRETCH, WallpaperType::kDefault, |
| base::Time::Now().LocalMidnight()); |
| switch (++index % 4) { |
| case 0: |
| wallpaper_controller->ShowDefaultWallpaperForTesting(); |
| break; |
| case 1: |
| wallpaper_controller->ShowWallpaperImage( |
| CreateWallpaperImage(SK_ColorRED, SK_ColorBLUE), info, |
| /*preview_mode=*/false, /*always_on_top=*/false); |
| break; |
| case 2: |
| info.layout = WALLPAPER_LAYOUT_CENTER; |
| wallpaper_controller->ShowWallpaperImage( |
| CreateWallpaperImage(SK_ColorBLUE, SK_ColorGREEN), info, |
| /*preview_mode=*/false, /*always_on_top=*/false); |
| break; |
| case 3: |
| info.layout = WALLPAPER_LAYOUT_CENTER_CROPPED; |
| wallpaper_controller->ShowWallpaperImage( |
| CreateWallpaperImage(SK_ColorGREEN, SK_ColorRED), info, |
| /*preview_mode=*/false, /*always_on_top=*/false); |
| break; |
| } |
| } |
| |
| void HandleDumpCalendarModel() { |
| accelerators::DumpCalendarModel(); |
| } |
| |
| void HandleToggleKeyboardBacklight() { |
| if (ash::features::IsKeyboardBacklightToggleEnabled()) { |
| base::RecordAction(base::UserMetricsAction("Accel_Keyboard_Backlight")); |
| accelerators::ToggleKeyboardBacklight(); |
| } |
| } |
| |
| void HandleToggleMicrophoneMute() { |
| base::RecordAction(base::UserMetricsAction("Accel_Microphone_Mute")); |
| accelerators::MicrophoneMuteToggle(); |
| } |
| |
| void HandleToggleTouchpad() { |
| base::RecordAction(base::UserMetricsAction("Accel_Toggle_Touchpad")); |
| Shell::Get()->touch_devices_controller()->ToggleTouchpad(); |
| } |
| |
| void HandleToggleTouchscreen() { |
| base::RecordAction(base::UserMetricsAction("Accel_Toggle_Touchscreen")); |
| TouchDevicesController* controller = Shell::Get()->touch_devices_controller(); |
| controller->SetTouchscreenEnabled( |
| !controller->GetTouchscreenEnabled(TouchDeviceEnabledSource::USER_PREF), |
| TouchDeviceEnabledSource::USER_PREF); |
| } |
| |
| void HandleToggleTabletMode() { |
| TabletModeController* controller = Shell::Get()->tablet_mode_controller(); |
| controller->SetEnabledForDev(!controller->InTabletMode()); |
| } |
| |
| void HandleTriggerCrash() { |
| LOG(FATAL) << "Intentional crash via debug accelerator."; |
| } |
| |
| void HandleTriggerHUDDisplay() { |
| hud_display::HUDDisplayView::Toggle(); |
| } |
| |
| } // 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 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kAshDebugShortcuts); |
| } |
| |
| bool DeveloperAcceleratorsEnabled() { |
| return base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kAshDeveloperShortcuts); |
| } |
| |
| void PerformDebugActionIfEnabled(AcceleratorAction action) { |
| if (!DebugAcceleratorsEnabled()) |
| return; |
| |
| switch (action) { |
| case DEBUG_DUMP_CALENDAR_MODEL: |
| HandleDumpCalendarModel(); |
| break; |
| case DEBUG_KEYBOARD_BACKLIGHT_TOGGLE: |
| HandleToggleKeyboardBacklight(); |
| break; |
| case DEBUG_MICROPHONE_MUTE_TOGGLE: |
| HandleToggleMicrophoneMute(); |
| break; |
| case DEBUG_PRINT_LAYER_HIERARCHY: |
| HandlePrintLayerHierarchy(); |
| break; |
| case DEBUG_PRINT_VIEW_HIERARCHY: |
| HandlePrintViewHierarchy(); |
| break; |
| case DEBUG_PRINT_WINDOW_HIERARCHY: |
| HandlePrintWindowHierarchy(); |
| break; |
| case DEBUG_SHOW_TOAST: |
| Shell::Get()->toast_manager()->Show(ToastData( |
| /*id=*/"id", ToastCatalogName::kDebugCommand, /*text=*/u"Toast", |
| ToastData::kDefaultToastDuration, |
| /*visible_on_lock_screen=*/false, /*has_dismiss_button=*/true, |
| /*custom_dismiss_text=*/u"Dismiss")); |
| break; |
| case DEBUG_TOGGLE_TOUCH_PAD: |
| HandleToggleTouchpad(); |
| break; |
| case DEBUG_TOGGLE_TOUCH_SCREEN: |
| HandleToggleTouchscreen(); |
| break; |
| case DEBUG_TOGGLE_TABLET_MODE: |
| HandleToggleTabletMode(); |
| break; |
| case DEBUG_TOGGLE_WALLPAPER_MODE: |
| HandleToggleWallpaperMode(); |
| break; |
| case DEBUG_TRIGGER_CRASH: |
| HandleTriggerCrash(); |
| break; |
| case DEBUG_TOGGLE_HUD_DISPLAY: |
| HandleTriggerHUDDisplay(); |
| break; |
| default: |
| break; |
| } |
| } |
| |
| } // namespace debug |
| } // namespace ash |