// Copyright 2014 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_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_ #define ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_ #include "ash/ash_export.h" #include "ash/shell_observer.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "ui/gfx/display.h" #include "ui/gfx/geometry/vector3d_f.h" #if defined(OS_CHROMEOS) #include "chromeos/accelerometer/accelerometer_reader.h" #include "chromeos/accelerometer/accelerometer_types.h" #include "chromeos/dbus/power_manager_client.h" #endif // OS_CHROMEOS namespace base { class TickClock; } namespace gfx { class Vector3dF; } namespace ui { class EventHandler; } namespace ash { class MaximizeModeControllerTest; class ScopedDisableInternalMouseAndKeyboard; class MaximizeModeWindowManager; class MaximizeModeWindowManagerTest; namespace test { class MultiUserWindowManagerChromeOSTest; class VirtualKeyboardControllerTest; } // MaximizeModeController listens to accelerometer events and automatically // enters and exits maximize mode when the lid is opened beyond the triggering // angle and rotates the display to match the device when in maximize mode. class ASH_EXPORT MaximizeModeController : #if defined(OS_CHROMEOS) public chromeos::AccelerometerReader::Observer, public chromeos::PowerManagerClient::Observer, #endif // OS_CHROMEOS public ShellObserver { public: MaximizeModeController(); ~MaximizeModeController() override; // True if it is possible to enter maximize mode in the current // configuration. If this returns false, it should never be the case that // maximize mode becomes enabled. bool CanEnterMaximizeMode(); // TODO(jonross): Merge this with EnterMaximizeMode. Currently these are // separate for several reasons: there is no internal display when running // unittests; the event blocker prevents keyboard input when running ChromeOS // on linux. http://crbug.com/362881 // Turn the always maximize mode window manager on or off. void EnableMaximizeModeWindowManager(bool should_enable); // Test if the MaximizeModeWindowManager is enabled or not. bool IsMaximizeModeWindowManagerEnabled() const; // Add a special window to the MaximizeModeWindowManager for tracking. This is // only required for special windows which are handled by other window // managers like the |MultiUserWindowManager|. // If the maximize mode is not enabled no action will be performed. void AddWindow(aura::Window* window); // ShellObserver: void OnAppTerminating() override; void OnMaximizeModeStarted() override; void OnMaximizeModeEnded() override; #if defined(OS_CHROMEOS) // chromeos::AccelerometerReader::Observer: void OnAccelerometerUpdated( scoped_refptr update) override; // PowerManagerClient::Observer: void LidEventReceived(bool open, const base::TimeTicks& time) override; void SuspendImminent() override; void SuspendDone(const base::TimeDelta& sleep_duration) override; #endif // OS_CHROMEOS private: friend class MaximizeModeControllerTest; friend class MaximizeModeWindowManagerTest; friend class test::MultiUserWindowManagerChromeOSTest; friend class test::VirtualKeyboardControllerTest; // Used for recording metrics for intervals of time spent in // and out of TouchView. enum TouchViewIntervalType { TOUCH_VIEW_INTERVAL_INACTIVE, TOUCH_VIEW_INTERVAL_ACTIVE }; // Set the TickClock. This is only to be used by tests that need to // artificially and deterministically control the current time. void SetTickClockForTest(scoped_ptr tick_clock); #if defined(OS_CHROMEOS) // Detect hinge rotation from base and lid accelerometers and automatically // start / stop maximize mode. void HandleHingeRotation( scoped_refptr update); #endif // Returns true if the lid was recently opened. bool WasLidOpenedRecently() const; // Enables MaximizeModeWindowManager, and determines the current state of // rotation lock. void EnterMaximizeMode(); // Removes MaximizeModeWindowManager and resets the display rotation if there // is no rotation lock. void LeaveMaximizeMode(); // Record UMA stats tracking TouchView usage. If |type| is // TOUCH_VIEW_INTERVAL_INACTIVE, then record that TouchView has been // inactive from |touchview_usage_interval_start_time_| until now. // Similarly, record that TouchView has been active if |type| is // TOUCH_VIEW_INTERVAL_ACTIVE. void RecordTouchViewUsageInterval(TouchViewIntervalType type); // Returns TOUCH_VIEW_INTERVAL_ACTIVE if TouchView is currently active, // otherwise returns TOUCH_VIEW_INTERNAL_INACTIVE. TouchViewIntervalType CurrentTouchViewIntervalType(); // The maximized window manager (if enabled). scoped_ptr maximize_mode_window_manager_; // A helper class which when instantiated will block native events from the // internal keyboard and touchpad. scoped_ptr event_blocker_; // Whether we have ever seen accelerometer data. bool have_seen_accelerometer_data_; // True when the hinge angle has been detected past 180 degrees. bool lid_open_past_180_; // Tracks time spent in (and out of) touchview mode. base::Time touchview_usage_interval_start_time_; base::TimeDelta total_touchview_time_; base::TimeDelta total_non_touchview_time_; // Tracks the last time we received a lid open event. This is used to suppress // erroneous accelerometer readings as the lid is opened but the accelerometer // reports readings that make the lid to appear near fully open. base::TimeTicks last_lid_open_time_; // Source for the current time in base::TimeTicks. scoped_ptr tick_clock_; // Tracks when the lid is closed. Used to prevent entering maximize mode. bool lid_is_closed_; // Tracks smoothed accelerometer data over time. This is done when the hinge // is approaching vertical to remove abrupt acceleration that can lead to // incorrect calculations of hinge angles. gfx::Vector3dF base_smoothed_; gfx::Vector3dF lid_smoothed_; DISALLOW_COPY_AND_ASSIGN(MaximizeModeController); }; } // namespace ash #endif // ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_