Commit a071cc59 authored by Sammie Quon's avatar Sammie Quon Committed by Commit Bot

tablet: Take a screenshot and place under top window when enter tablet.

This will make sure everything underneath is completely occluded, so
nothing gets drawn.

Test: manual
Bug: 961549
Change-Id: I5124f8ffcee607964b8460f7214d962092a2e697
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1642370Reviewed-by: default avatarMitsuru Oshima <oshima@chromium.org>
Commit-Queue: Sammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#668467}
parent 860d21fe
...@@ -182,6 +182,7 @@ bool ShellTestApi::IsSystemModalWindowOpen() { ...@@ -182,6 +182,7 @@ bool ShellTestApi::IsSystemModalWindowOpen() {
void ShellTestApi::EnableTabletModeWindowManager(bool enable) { void ShellTestApi::EnableTabletModeWindowManager(bool enable) {
AccelerometerReader::GetInstance()->DisableForTest(); AccelerometerReader::GetInstance()->DisableForTest();
TabletModeController::SetForceNoScreenshotForTest();
shell_->tablet_mode_controller()->EnableTabletModeWindowManager(enable); shell_->tablet_mode_controller()->EnableTabletModeWindowManager(enable);
} }
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "ash/test_shell_delegate.h" #include "ash/test_shell_delegate.h"
#include "ash/wallpaper/wallpaper_controller_impl.h" #include "ash/wallpaper/wallpaper_controller_impl.h"
#include "ash/wm/overview/overview_controller.h" #include "ash/wm/overview/overview_controller.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
...@@ -186,6 +187,8 @@ void AshTestHelper::SetUp(bool start_session, bool provide_local_state) { ...@@ -186,6 +187,8 @@ void AshTestHelper::SetUp(bool start_session, bool provide_local_state) {
// Ensure tests have a wallpaper as placeholder. // Ensure tests have a wallpaper as placeholder.
shell->wallpaper_controller()->CreateEmptyWallpaperForTesting(); shell->wallpaper_controller()->CreateEmptyWallpaperForTesting();
TabletModeController::SetForceNoScreenshotForTest();
} }
void AshTestHelper::TearDown() { void AshTestHelper::TearDown() {
......
...@@ -50,6 +50,10 @@ namespace views { ...@@ -50,6 +50,10 @@ namespace views {
class Widget; class Widget;
} }
namespace viz {
class CopyOutputResult;
}
namespace ash { namespace ash {
class InternalInputDevicesEventBlocker; class InternalInputDevicesEventBlocker;
...@@ -87,6 +91,10 @@ class ASH_EXPORT TabletModeController ...@@ -87,6 +91,10 @@ class ASH_EXPORT TabletModeController
TabletModeController(); TabletModeController();
~TabletModeController() override; ~TabletModeController() override;
// Disables taking screenshots for testing as it makes the initialization flow
// async.
static void SetForceNoScreenshotForTest();
// TODO(jonross): Merge this with AttemptEnterTabletMode. Currently these are // TODO(jonross): Merge this with AttemptEnterTabletMode. Currently these are
// separate for several reasons: there is no internal display when running // separate for several reasons: there is no internal display when running
// unittests; the event blocker prevents keyboard input when running ChromeOS // unittests; the event blocker prevents keyboard input when running ChromeOS
...@@ -121,15 +129,15 @@ class ASH_EXPORT TabletModeController ...@@ -121,15 +129,15 @@ class ASH_EXPORT TabletModeController
// Starts observing |window| for animation changes. // Starts observing |window| for animation changes.
void MaybeObserveBoundsAnimation(aura::Window* window); void MaybeObserveBoundsAnimation(aura::Window* window);
// Stops observing the window which is being animated from tablet <->
// clamshell.
void StopObservingAnimation(bool record_stats, bool delete_screenshot);
// TabletMode: // TabletMode:
void SetTabletModeToggleObserver(TabletModeToggleObserver* observer) override; void SetTabletModeToggleObserver(TabletModeToggleObserver* observer) override;
bool IsEnabled() const override; bool IsEnabled() const override;
void SetEnabledForTest(bool enabled) override; void SetEnabledForTest(bool enabled) override;
// Stops observing the window which is being animated from tablet <->
// clamshell.
void StopObservingAnimation(bool record_stats);
// ShellObserver: // ShellObserver:
void OnShellInitialized() override; void OnShellInitialized() override;
...@@ -271,6 +279,24 @@ class ASH_EXPORT TabletModeController ...@@ -271,6 +279,24 @@ class ASH_EXPORT TabletModeController
// Resets |occlusion_tracker_pauser_|. // Resets |occlusion_tracker_pauser_|.
void ResetPauser(); void ResetPauser();
// Deletes the enter tablet mode screenshot and associated callbacks.
void DeleteScreenshot();
// Finishes initializing for tablet mode. May be called async if a screenshot
// was requested while starting initializing.
void FinishInitTabletMode();
// Takes a screenshot of everything in the rotation container, except for
// |top_window|.
void TakeScreenshot(aura::Window* top_window,
base::OnceClosure on_screenshot_taken);
// Called when a screenshot is taken. Creates |screenshot_widget_| which holds
// the screenshot results and stacks it under |top_window|.
void OnScreenshotTaken(aura::Window* top_window,
base::OnceClosure on_screenshot_taken,
std::unique_ptr<viz::CopyOutputResult> copy_result);
// The maximized window manager (if enabled). // The maximized window manager (if enabled).
std::unique_ptr<TabletModeWindowManager> tablet_mode_window_manager_; std::unique_ptr<TabletModeWindowManager> tablet_mode_window_manager_;
...@@ -373,6 +399,17 @@ class ASH_EXPORT TabletModeController ...@@ -373,6 +399,17 @@ class ASH_EXPORT TabletModeController
std::unique_ptr<TabletModeTransitionFpsCounter> fps_counter_; std::unique_ptr<TabletModeTransitionFpsCounter> fps_counter_;
base::CancelableOnceCallback<void(std::unique_ptr<viz::CopyOutputResult>)>
screenshot_taken_callback_;
base::CancelableOnceClosure screenshot_set_callback_;
// A layer that is created before an enter tablet mode animations is started,
// and destroyed when the animation is ended. It contains a screenshot of
// everything in the screen rotation container except the top window. It helps
// with animation performance because it fully occludes all windows except the
// animating window for the duration of the animation.
std::unique_ptr<ui::Layer> screenshot_layer_;
base::ObserverList<TabletModeObserver>::Unchecked tablet_mode_observers_; base::ObserverList<TabletModeObserver>::Unchecked tablet_mode_observers_;
base::WeakPtrFactory<TabletModeController> weak_factory_{this}; base::WeakPtrFactory<TabletModeController> weak_factory_{this};
......
...@@ -106,7 +106,7 @@ class ScopedObserveWindowAnimation { ...@@ -106,7 +106,7 @@ class ScopedObserveWindowAnimation {
return; return;
Shell::Get()->tablet_mode_controller()->StopObservingAnimation( Shell::Get()->tablet_mode_controller()->StopObservingAnimation(
/*record_stats=*/false); /*record_stats=*/false, /*delete_screenshot=*/true);
} }
private: private:
...@@ -117,6 +117,14 @@ class ScopedObserveWindowAnimation { ...@@ -117,6 +117,14 @@ class ScopedObserveWindowAnimation {
TabletModeWindowManager::~TabletModeWindowManager() = default; TabletModeWindowManager::~TabletModeWindowManager() = default;
// static
aura::Window* TabletModeWindowManager::GetTopWindow() {
MruWindowTracker::WindowList windows =
Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kActiveDesk);
return windows.empty() ? nullptr : windows[0];
}
void TabletModeWindowManager::Init() { void TabletModeWindowManager::Init() {
// The overview mode needs to be ended before the tablet mode is started. To // The overview mode needs to be ended before the tablet mode is started. To
// guarantee the proper order, it will be turned off from here. // guarantee the proper order, it will be turned off from here.
...@@ -187,13 +195,6 @@ void TabletModeWindowManager::WindowStateDestroyed(aura::Window* window) { ...@@ -187,13 +195,6 @@ void TabletModeWindowManager::WindowStateDestroyed(aura::Window* window) {
window_state_map_.erase(it); window_state_map_.erase(it);
} }
aura::Window* TabletModeWindowManager::GetTopWindow() {
MruWindowTracker::WindowList windows =
Shell::Get()->mru_window_tracker()->BuildWindowForCycleList(kActiveDesk);
return windows.empty() ? nullptr : windows[0];
}
void TabletModeWindowManager::OnOverviewModeEndingAnimationComplete( void TabletModeWindowManager::OnOverviewModeEndingAnimationComplete(
bool canceled) { bool canceled) {
if (canceled) if (canceled)
......
...@@ -50,6 +50,8 @@ class ASH_EXPORT TabletModeWindowManager : public aura::WindowObserver, ...@@ -50,6 +50,8 @@ class ASH_EXPORT TabletModeWindowManager : public aura::WindowObserver,
// This should only be deleted by the creator (TabletModeController). // This should only be deleted by the creator (TabletModeController).
~TabletModeWindowManager() override; ~TabletModeWindowManager() override;
static aura::Window* GetTopWindow();
void Init(); void Init();
// Stops tracking windows and returns them to their clamshell mode state. Work // Stops tracking windows and returns them to their clamshell mode state. Work
...@@ -72,8 +74,6 @@ class ASH_EXPORT TabletModeWindowManager : public aura::WindowObserver, ...@@ -72,8 +74,6 @@ class ASH_EXPORT TabletModeWindowManager : public aura::WindowObserver,
// Called from a window state object when it gets destroyed. // Called from a window state object when it gets destroyed.
void WindowStateDestroyed(aura::Window* window); void WindowStateDestroyed(aura::Window* window);
aura::Window* GetTopWindow();
// OverviewObserver: // OverviewObserver:
void OnOverviewModeEndingAnimationComplete(bool canceled) override; void OnOverviewModeEndingAnimationComplete(bool canceled) override;
......
...@@ -153,6 +153,12 @@ bool IsTabDraggingSourceWindow(aura::Window* window) { ...@@ -153,6 +153,12 @@ bool IsTabDraggingSourceWindow(aura::Window* window) {
window; window;
} }
// True if |window| is the top window in BuildWindowForCycleList.
bool IsTopWindow(aura::Window* window) {
DCHECK(window);
return window == TabletModeWindowManager::GetTopWindow();
}
} // namespace } // namespace
// static // static
...@@ -479,9 +485,4 @@ void TabletModeWindowState::UpdateBounds(wm::WindowState* window_state, ...@@ -479,9 +485,4 @@ void TabletModeWindowState::UpdateBounds(wm::WindowState* window_state,
} }
} }
bool TabletModeWindowState::IsTopWindow(aura::Window* window) {
DCHECK(window);
return window == creator_->GetTopWindow();
}
} // namespace ash } // namespace ash
...@@ -79,9 +79,6 @@ class TabletModeWindowState : public wm::WindowState::State { ...@@ -79,9 +79,6 @@ class TabletModeWindowState : public wm::WindowState::State {
// window state. If |animated| is set we animate the change. // window state. If |animated| is set we animate the change.
void UpdateBounds(wm::WindowState* window_state, bool animated); void UpdateBounds(wm::WindowState* window_state, bool animated);
// True if |window| is the top window in BuildWindowForCycleList.
bool IsTopWindow(aura::Window* window);
// The original state object of the window. // The original state object of the window.
std::unique_ptr<wm::WindowState::State> old_state_; std::unique_ptr<wm::WindowState::State> old_state_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment