diff options
-rw-r--r-- | ash/accelerators/accelerator_controller.cc | 28 | ||||
-rw-r--r-- | ash/accelerators/debug_commands.cc | 66 | ||||
-rw-r--r-- | ash/accelerators/debug_commands.h | 22 | ||||
-rw-r--r-- | ash/ash.gyp | 2 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_controller.cc | 64 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_controller.h | 13 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_controller_unittest.cc | 82 | ||||
-rw-r--r-- | ash/desktop_background/desktop_background_view.cc | 40 |
8 files changed, 245 insertions, 72 deletions
diff --git a/ash/accelerators/accelerator_controller.cc b/ash/accelerators/accelerator_controller.cc index aa4786d..135e0f7 100644 --- a/ash/accelerators/accelerator_controller.cc +++ b/ash/accelerators/accelerator_controller.cc @@ -11,11 +11,10 @@ #include "ash/accelerators/accelerator_commands.h" #include "ash/accelerators/accelerator_table.h" +#include "ash/accelerators/debug_commands.h" #include "ash/ash_switches.h" #include "ash/caps_lock_delegate.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_controller.h" #include "ash/display/display_manager.h" #include "ash/focus_cycler.h" @@ -270,29 +269,6 @@ bool HandleRotateScreen() { return true; } -bool HandleToggleDesktopBackgroundMode() { - static int index = 0; - static const SkColor kColorOptions[] = { - SK_ColorBLACK, SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN - }; - DesktopBackgroundController* desktop_background_controller = - Shell::GetInstance()->desktop_background_controller(); - SkColor color = kColorOptions[++index % arraysize(kColorOptions)]; - if (color == SK_ColorBLACK) { - ash::Shell::GetInstance()->user_wallpaper_delegate()-> - InitializeWallpaper(); - } else { - SkBitmap bitmap; - bitmap.setConfig(SkBitmap::kARGB_8888_Config, 10, 10, 0); - bitmap.allocPixels(); - bitmap.eraseColor(color); - desktop_background_controller->SetCustomWallpaper( - gfx::ImageSkia::CreateFrom1xBitmap(bitmap), WALLPAPER_LAYOUT_STRETCH); - - } - return true; -} - bool HandleToggleRootWindowFullScreen() { Shell::GetPrimaryRootWindow()->ToggleFullScreen(); return true; @@ -882,7 +858,7 @@ bool AcceleratorController::PerformAction(int action, case ROTATE_SCREEN: return HandleRotateScreen(); case TOGGLE_DESKTOP_BACKGROUND_MODE: - return HandleToggleDesktopBackgroundMode(); + return debug::CycleDesktopBackgroundMode(); case TOGGLE_ROOT_WINDOW_FULL_SCREEN: return HandleToggleRootWindowFullScreen(); case DEBUG_TOGGLE_DEVICE_SCALE_FACTOR: diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc new file mode 100644 index 0000000..4ca1720 --- /dev/null +++ b/ash/accelerators/debug_commands.cc @@ -0,0 +1,66 @@ +// 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/desktop_background/desktop_background_controller.h" +#include "ash/desktop_background/user_wallpaper_delegate.h" +#include "ash/shell.h" +#include "third_party/skia/include/core/SkColor.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/image/image_skia.h" + +namespace ash { +namespace debug { +namespace { + +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()); +} + +} // namespace + +bool CycleDesktopBackgroundMode() { + 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->SetCustomWallpaper( + CreateWallpaperImage(SK_ColorRED, SK_ColorBLUE), + WALLPAPER_LAYOUT_STRETCH); + break; + case 2: + desktop_background_controller->SetCustomWallpaper( + CreateWallpaperImage(SK_ColorBLUE, SK_ColorGREEN), + WALLPAPER_LAYOUT_CENTER); + break; + case 3: + desktop_background_controller->SetCustomWallpaper( + CreateWallpaperImage(SK_ColorGREEN, SK_ColorRED), + WALLPAPER_LAYOUT_CENTER_CROPPED); + break; + } + return true; +} + +} // namespace debug +} // namespace ash diff --git a/ash/accelerators/debug_commands.h b/ash/accelerators/debug_commands.h new file mode 100644 index 0000000..a064d4f --- /dev/null +++ b/ash/accelerators/debug_commands.h @@ -0,0 +1,22 @@ +// 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. + +#ifndef ASH_ACCELERATORS_DEBUG_COMMANDS_H_ +#define ASH_ACCELERATORS_DEBUG_COMMANDS_H_ + +#include "ash/ash_export.h" + +// This file contains implementations of commands that are used only +// when running on desktop for debugging. +namespace ash { +namespace debug { + +// Cycle through different wallpaper modes. This is used when running +// on desktop for testing. +ASH_EXPORT bool CycleDesktopBackgroundMode(); + +} // namespace debug +} // namespace ash + +#endif // ASH_ACCELERATORS_DEBUG_COMMANDS_H_ diff --git a/ash/ash.gyp b/ash/ash.gyp index 6e89c95..3b0604f 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -57,6 +57,8 @@ 'accelerators/accelerator_filter.h', 'accelerators/accelerator_table.cc', 'accelerators/accelerator_table.h', + 'accelerators/debug_commands.cc', + 'accelerators/debug_commands.h', 'accelerators/exit_warning_handler.cc', 'accelerators/exit_warning_handler.h', 'accelerators/focus_manager_factory.cc', diff --git a/ash/desktop_background/desktop_background_controller.cc b/ash/desktop_background/desktop_background_controller.cc index d91f383..b8fef38 100644 --- a/ash/desktop_background/desktop_background_controller.cc +++ b/ash/desktop_background/desktop_background_controller.cc @@ -10,6 +10,8 @@ #include "ash/desktop_background/desktop_background_widget_controller.h" #include "ash/desktop_background/user_wallpaper_delegate.h" #include "ash/desktop_background/wallpaper_resizer.h" +#include "ash/display/display_info.h" +#include "ash/display/display_manager.h" #include "ash/root_window_controller.h" #include "ash/shell.h" #include "ash/shell_factory.h" @@ -45,22 +47,6 @@ internal::RootWindowLayoutManager* GetRootWindowLayoutManager( root_window->layout_manager()); } -// Returns the maximum width and height of all root windows. -gfx::Size GetRootWindowsSize() { - int width = 0; - int height = 0; - Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); - for (Shell::RootWindowList::iterator iter = root_windows.begin(); - iter != root_windows.end(); ++iter) { - gfx::Size root_window_size = (*iter)->GetHostSize(); - if (root_window_size.width() > width) - width = root_window_size.width(); - if (root_window_size.height() > height) - height = root_window_size.height(); - } - return gfx::Size(width, height); -} - } // namespace const int kSmallWallpaperMaxWidth = 1366; @@ -139,10 +125,10 @@ class DesktopBackgroundController::WallpaperLoader if (file_bitmap_) { gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(*file_bitmap_); wallpaper_resizer_.reset(new WallpaperResizer( - image, GetRootWindowsSize(), file_layout_)); + image, GetMaxDisplaySizeInNative(), file_layout_)); } else { wallpaper_resizer_.reset(new WallpaperResizer( - resource_id_, GetRootWindowsSize(), resource_layout_)); + resource_id_, GetMaxDisplaySizeInNative(), resource_layout_)); } } @@ -275,7 +261,7 @@ void DesktopBackgroundController::SetCustomWallpaper( return; current_wallpaper_.reset(new WallpaperResizer( - image, GetRootWindowsSize(), layout)); + image, GetMaxDisplaySizeInNative(), layout)); current_wallpaper_->StartResize(); current_default_wallpaper_path_ = base::FilePath(); @@ -302,19 +288,10 @@ void DesktopBackgroundController::CreateEmptyWallpaper() { WallpaperResolution DesktopBackgroundController::GetAppropriateResolution() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - Shell::RootWindowList root_windows = Shell::GetAllRootWindows(); - for (Shell::RootWindowList::iterator iter = root_windows.begin(); - iter != root_windows.end(); ++iter) { - // Compare to host size as constants are defined in terms of - // physical pixel size. - // TODO(oshima): This may not be ideal for fractional scaling - // scenario. Revisit and fix if necessary. - gfx::Size host_window_size = (*iter)->GetHostSize(); - if (host_window_size.width() > kSmallWallpaperMaxWidth || - host_window_size.height() > kSmallWallpaperMaxHeight) - return WALLPAPER_RESOLUTION_LARGE; - } - return WALLPAPER_RESOLUTION_SMALL; + gfx::Size size = GetMaxDisplaySizeInNative(); + return (size.width() > kSmallWallpaperMaxWidth || + size.height() > kSmallWallpaperMaxHeight) ? + WALLPAPER_RESOLUTION_LARGE : WALLPAPER_RESOLUTION_SMALL; } bool DesktopBackgroundController::MoveDesktopToLockedContainer() { @@ -443,4 +420,27 @@ int DesktopBackgroundController::GetBackgroundContainerId(bool locked) { internal::kShellWindowId_DesktopBackgroundContainer; } +// static +gfx::Size DesktopBackgroundController::GetMaxDisplaySizeInNative() { + int width = 0; + int height = 0; + std::vector<gfx::Display> displays = Shell::GetScreen()->GetAllDisplays(); + internal::DisplayManager* display_manager = + Shell::GetInstance()->display_manager(); + + for (std::vector<gfx::Display>::iterator iter = displays.begin(); + iter != displays.end(); ++iter) { + // Don't use size_in_pixel because we want to use the native pixel size. + gfx::Size size_in_pixel = + display_manager->GetDisplayInfo(iter->id()).bounds_in_native().size(); + if (iter->rotation() == gfx::Display::ROTATE_90 || + iter->rotation() == gfx::Display::ROTATE_270) { + size_in_pixel = gfx::Size(size_in_pixel.height(), size_in_pixel.width()); + } + width = std::max(size_in_pixel.width(), width); + height = std::max(size_in_pixel.height(), height); + } + return gfx::Size(width, height); +} + } // namespace ash diff --git a/ash/desktop_background/desktop_background_controller.h b/ash/desktop_background/desktop_background_controller.h index 24399c9..4955d20 100644 --- a/ash/desktop_background/desktop_background_controller.h +++ b/ash/desktop_background/desktop_background_controller.h @@ -8,6 +8,7 @@ #include "ash/ash_export.h" #include "base/basictypes.h" #include "base/files/file_path.h" +#include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/observer_list.h" @@ -24,9 +25,6 @@ class RootWindow; } namespace ash { -namespace internal { -class DesktopBackgroundControllerTest; -} // namespace internal enum WallpaperLayout { // Center the wallpaper on the desktop without scaling it. The wallpaper @@ -131,7 +129,8 @@ class ASH_EXPORT DesktopBackgroundController { bool MoveDesktopToUnlockedContainer(); private: - friend class internal::DesktopBackgroundControllerTest; + friend class DesktopBackgroundControllerTest; + FRIEND_TEST_ALL_PREFIXES(DesktopBackgroundControllerTest, GetMaxDisplaySize); // An operation to asynchronously loads wallpaper. class WallpaperLoader; @@ -171,6 +170,12 @@ class ASH_EXPORT DesktopBackgroundController { // Send notification that background animation finished. void NotifyAnimationFinished(); + // Returns the maximum size of all displays combined in native + // resolutions. Note that this isn't the bounds of the display who + // has maximum resolutions. Instead, this returns the size of the + // maximum width of all displays, and the maximum height of all displays. + static gfx::Size GetMaxDisplaySizeInNative(); + // If non-NULL, used in place of the real command line. CommandLine* command_line_for_testing_; diff --git a/ash/desktop_background/desktop_background_controller_unittest.cc b/ash/desktop_background/desktop_background_controller_unittest.cc index fa13434..c29c96d 100644 --- a/ash/desktop_background/desktop_background_controller_unittest.cc +++ b/ash/desktop_background/desktop_background_controller_unittest.cc @@ -34,8 +34,6 @@ using aura::RootWindow; using aura::Window; namespace ash { -namespace internal { - namespace { // Containers IDs used for tests. @@ -109,7 +107,7 @@ class DesktopBackgroundControllerTest : public test::AshTestBase { test::AshTestBase::SetUp(); // Ash shell initialization creates wallpaper. Reset it so we can manually // control wallpaper creation and animation in our tests. - RootWindowController* root_window_controller = + internal::RootWindowController* root_window_controller = Shell::GetPrimaryRootWindowController(); root_window_controller->SetWallpaperController(NULL); root_window_controller->SetAnimatingWallpaperController(NULL); @@ -132,7 +130,7 @@ class DesktopBackgroundControllerTest : public test::AshTestBase { // Runs kAnimatingDesktopController's animation to completion. // TODO(bshe): Don't require tests to run animations; it's slow. void RunDesktopControllerAnimation() { - DesktopBackgroundWidgetController* controller = + internal::DesktopBackgroundWidgetController* controller = Shell::GetPrimaryRootWindowController()-> animating_wallpaper_controller()->GetController(false); ASSERT_NO_FATAL_FAILURE(RunAnimationForWidget(controller->widget())); @@ -300,7 +298,7 @@ TEST_F(DesktopBackgroundControllerTest, ControllerOwnership) { // The new wallpaper is ready to start animating. kAnimatingDesktopController // holds the widget controller instance. kDesktopController will get it later. - RootWindowController* root_window_controller = + internal::RootWindowController* root_window_controller = Shell::GetPrimaryRootWindowController(); EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()-> GetController(false)); @@ -342,7 +340,7 @@ TEST_F(DesktopBackgroundControllerTest, BackgroundMovementDuringUnlock) { // In this state we have two desktop background views stored in different // properties. Both are in the lock screen background container. - RootWindowController* root_window_controller = + internal::RootWindowController* root_window_controller = Shell::GetPrimaryRootWindowController(); EXPECT_TRUE(root_window_controller->animating_wallpaper_controller()-> GetController(false)); @@ -384,9 +382,9 @@ TEST_F(DesktopBackgroundControllerTest, ChangeWallpaperQuick) { // Change to a new wallpaper. controller->CreateEmptyWallpaper(); - RootWindowController* root_window_controller = + internal::RootWindowController* root_window_controller = Shell::GetPrimaryRootWindowController(); - DesktopBackgroundWidgetController* animating_controller = + internal::DesktopBackgroundWidgetController* animating_controller = root_window_controller->animating_wallpaper_controller()-> GetController(false); EXPECT_TRUE(animating_controller); @@ -452,6 +450,17 @@ TEST_F(DesktopBackgroundControllerTest, GetAppropriateResolution) { display_manager_test_api.UpdateDisplay("2560x1700"); EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE, controller_->GetAppropriateResolution()); + + // Rotated smaller screen may use larger image. + display_manager_test_api.UpdateDisplay("800x600/r"); + EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL, + controller_->GetAppropriateResolution()); + display_manager_test_api.UpdateDisplay("800x600/r,800x600"); + EXPECT_EQ(WALLPAPER_RESOLUTION_SMALL, + controller_->GetAppropriateResolution()); + display_manager_test_api.UpdateDisplay("1366x800/r"); + EXPECT_EQ(WALLPAPER_RESOLUTION_LARGE, + controller_->GetAppropriateResolution()); } // Test that DesktopBackgroundController loads the appropriate wallpaper @@ -494,6 +503,21 @@ TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaper) { kLargeWallpaperColor)); } +TEST_F(DesktopBackgroundControllerTest, LargeDefaultWallpaperWhenRotated) { + if (!SupportsMultipleDisplays()) + return; + WriteWallpapersAndSetFlags(); + TestObserver observer(controller_); + test::DisplayManagerTestApi display_manager_test_api( + Shell::GetInstance()->display_manager()); + + display_manager_test_api.UpdateDisplay("1200x800/r"); + ASSERT_TRUE(controller_->SetDefaultWallpaper(false)); + observer.WaitForWallpaperDataChanged(); + EXPECT_TRUE(ImageIsNearColor(controller_->GetWallpaper(), + kLargeWallpaperColor)); +} + TEST_F(DesktopBackgroundControllerTest, SmallGuestWallpaper) { if (!SupportsMultipleDisplays()) return; @@ -524,5 +548,45 @@ TEST_F(DesktopBackgroundControllerTest, LargeGuestWallpaper) { kLargeGuestWallpaperColor)); } -} // namespace internal +TEST_F(DesktopBackgroundControllerTest, GetMaxDisplaySize) { + // Device scale factor shouldn't affect the native size. + UpdateDisplay("1000x300*2"); + EXPECT_EQ( + "1000x300", + DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); + + // Rotated display should return the rotated size. + UpdateDisplay("1000x300*2/r"); + EXPECT_EQ( + "300x1000", + DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); + + // UI Scaling shouldn't affect the native size. + UpdateDisplay("1000x300*2@1.5"); + EXPECT_EQ( + "1000x300", + DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); + + if (!SupportsMultipleDisplays()) + return; + + // First display has maximum size. + UpdateDisplay("400x300,100x100"); + EXPECT_EQ( + "400x300", + DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); + + // Second display has maximum size. + UpdateDisplay("400x300,500x600"); + EXPECT_EQ( + "500x600", + DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); + + // Maximum width and height belongs to different displays. + UpdateDisplay("400x300,100x500"); + EXPECT_EQ( + "400x500", + DesktopBackgroundController::GetMaxDisplaySizeInNative().ToString()); +} + } // namespace ash diff --git a/ash/desktop_background/desktop_background_view.cc b/ash/desktop_background/desktop_background_view.cc index b46109f..db1b27d 100644 --- a/ash/desktop_background/desktop_background_view.cc +++ b/ash/desktop_background/desktop_background_view.cc @@ -23,6 +23,8 @@ #include "ui/compositor/layer.h" #include "ui/gfx/canvas.h" #include "ui/gfx/image/image.h" +#include "ui/gfx/size_conversions.h" +#include "ui/gfx/transform.h" #include "ui/views/widget/widget.h" namespace ash { @@ -34,6 +36,41 @@ int RoundPositive(double x) { return static_cast<int>(floor(x + 0.5)); } +// A view that controls the child view's layer so that the layer +// always has the same size as the display's original, un-scaled size +// in DIP. The layer then transformed to fit to the virtual screen +// size when laid-out. +// This is to avoid scaling the image at painting time, then scaling +// it back to the screen size in the compositor. +class LayerControlView : public views::View { + public: + explicit LayerControlView(views::View* view) { + AddChildView(view); + view->SetPaintToLayer(true); + } + + // Overrides views::View. + virtual void Layout() OVERRIDE { + gfx::Display display = Shell::GetScreen()->GetDisplayNearestWindow( + GetWidget()->GetNativeView()); + DisplayManager* display_manager = Shell::GetInstance()->display_manager(); + DisplayInfo info = display_manager->GetDisplayInfo(display.id()); + + gfx::SizeF pixel_size = display.size(); + pixel_size.Scale(1.0f / info.ui_scale()); + gfx::Size rounded_size = gfx::ToCeiledSize(pixel_size); + DCHECK_EQ(1, child_count()); + views::View* child = child_at(0); + child->SetBounds(0, 0, rounded_size.width(), rounded_size.height()); + gfx::Transform transform; + transform.Scale(info.ui_scale(), info.ui_scale()); + child->SetTransform(transform); + } + + private: + DISALLOW_COPY_AND_ASSIGN(LayerControlView); +}; + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -151,7 +188,8 @@ views::Widget* CreateDesktopBackground(aura::RootWindow* root_window, params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; params.parent = root_window->GetChildById(container_id); desktop_widget->Init(params); - desktop_widget->SetContentsView(new DesktopBackgroundView()); + desktop_widget->SetContentsView( + new LayerControlView(new DesktopBackgroundView())); int animation_type = wallpaper_delegate->GetAnimationType(); views::corewm::SetWindowVisibilityAnimationType( desktop_widget->GetNativeView(), animation_type); |