1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_
6 #define ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_
8 #include "ash/accelerometer/accelerometer_observer.h"
9 #include "ash/ash_export.h"
10 #include "ash/display/display_controller.h"
11 #include "ash/display/display_manager.h"
12 #include "ash/shell_observer.h"
13 #include "base/macros.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/observer_list.h"
16 #include "ui/gfx/display.h"
18 #if defined(OS_CHROMEOS)
19 #include "chromeos/dbus/power_manager_client.h"
32 class MaximizeModeControllerTest;
33 class ScopedDisableInternalMouseAndKeyboard;
34 class MaximizeModeWindowManager;
35 class MaximizeModeWindowManagerTest;
37 class MultiUserWindowManagerChromeOSTest;
40 // MaximizeModeController listens to accelerometer events and automatically
41 // enters and exits maximize mode when the lid is opened beyond the triggering
42 // angle and rotates the display to match the device when in maximize mode.
43 class ASH_EXPORT MaximizeModeController
44 : public AccelerometerObserver,
45 #if defined(OS_CHROMEOS)
46 public chromeos::PowerManagerClient::Observer,
49 public DisplayController::Observer {
51 // Observer that reports changes to the state of MaximizeModeController's
55 // Invoked whenever |rotation_locked_| is changed.
56 virtual void OnRotationLockChanged(bool rotation_locked) {}
59 virtual ~Observer() {}
62 MaximizeModeController();
63 virtual ~MaximizeModeController();
65 bool in_set_screen_rotation() const {
66 return in_set_screen_rotation_;
69 // True if |rotation_lock_| has been set, and OnAccelerometerUpdated will not
70 // change the display rotation.
71 bool rotation_locked() {
72 return rotation_locked_;
75 // If |rotation_locked| future calls to OnAccelerometerUpdated will not
76 // change the display rotation.
77 void SetRotationLocked(bool rotation_locked);
79 // Add/Remove observers.
80 void AddObserver(Observer* observer);
81 void RemoveObserver(Observer* observer);
83 // True if it is possible to enter maximize mode in the current
84 // configuration. If this returns false, it should never be the case that
85 // maximize mode becomes enabled.
86 bool CanEnterMaximizeMode();
88 // TODO(jonross): Merge this with EnterMaximizeMode. Currently these are
89 // separate for several reasons: there is no internal display when running
90 // unittests; the event blocker prevents keyboard input when running ChromeOS
91 // on linux. http://crbug.com/362881
92 // Turn the always maximize mode window manager on or off.
93 void EnableMaximizeModeWindowManager(bool enable);
95 // Test if the MaximizeModeWindowManager is enabled or not.
96 bool IsMaximizeModeWindowManagerEnabled() const;
98 // Add a special window to the MaximizeModeWindowManager for tracking. This is
99 // only required for special windows which are handled by other window
100 // managers like the |MultiUserWindowManager|.
101 // If the maximize mode is not enabled no action will be performed.
102 void AddWindow(aura::Window* window);
104 // TODO(jonross): move this into the destructor. Currently separated as
105 // ShellOberver notifies of maximize mode ending, and the observers end up
106 // attempting to access MaximizeModeController via the Shell. If done in
107 // destructor the controller is null, and the observers segfault.
108 // Shuts down down the MaximizeModeWindowManager and notifies all observers.
111 // AccelerometerObserver:
112 virtual void OnAccelerometerUpdated(const gfx::Vector3dF& base,
113 const gfx::Vector3dF& lid) OVERRIDE;
116 virtual void OnAppTerminating() OVERRIDE;
117 virtual void OnMaximizeModeStarted() OVERRIDE;
118 virtual void OnMaximizeModeEnded() OVERRIDE;
120 // DisplayController::Observer:
121 virtual void OnDisplayConfigurationChanged() OVERRIDE;
123 #if defined(OS_CHROMEOS)
124 // PowerManagerClient::Observer:
125 virtual void LidEventReceived(bool open,
126 const base::TimeTicks& time) OVERRIDE;
127 virtual void SuspendImminent() OVERRIDE;
128 virtual void SuspendDone(const base::TimeDelta& sleep_duration) OVERRIDE;
129 #endif // OS_CHROMEOS
132 friend class MaximizeModeControllerTest;
133 friend class MaximizeModeWindowManagerTest;
134 friend class test::MultiUserWindowManagerChromeOSTest;
136 // Set the TickClock. This is only to be used by tests that need to
137 // artificially and deterministically control the current time.
138 void SetTickClockForTest(scoped_ptr<base::TickClock> tick_clock);
140 // Detect hinge rotation from |base| and |lid| accelerometers and
141 // automatically start / stop maximize mode.
142 void HandleHingeRotation(const gfx::Vector3dF& base,
143 const gfx::Vector3dF& lid);
145 // Detect screen rotation from |lid| accelerometer and automatically rotate
147 void HandleScreenRotation(const gfx::Vector3dF& lid);
149 // Sets the display rotation and suppresses display notifications.
150 void SetDisplayRotation(DisplayManager* display_manager,
151 gfx::Display::Rotation rotation);
153 // Returns true if the lid was recently opened.
154 bool WasLidOpenedRecently() const;
156 // Enables MaximizeModeWindowManager, and determines the current state of
158 void EnterMaximizeMode();
160 // Removes MaximizeModeWindowManager and resets the display rotation if there
161 // is no rotation lock.
162 void LeaveMaximizeMode();
164 // Record UMA stats tracking touchview usage.
165 void RecordTouchViewStateTransition();
167 // The maximized window manager (if enabled).
168 scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_;
170 // A helper class which when instantiated will block native events from the
171 // internal keyboard and touchpad.
172 scoped_ptr<ScopedDisableInternalMouseAndKeyboard> event_blocker_;
174 // An event handler used to detect screenshot actions while in maximize mode.
175 scoped_ptr<ui::EventHandler> event_handler_;
177 // When true calls to OnAccelerometerUpdated will not rotate the display.
178 bool rotation_locked_;
180 // Whether we have ever seen accelerometer data.
181 bool have_seen_accelerometer_data_;
183 // True when the screen's orientation is being changed.
184 bool in_set_screen_rotation_;
186 // The rotation of the display set by the user. This rotation will be
187 // restored upon exiting maximize mode.
188 gfx::Display::Rotation user_rotation_;
190 // The current rotation set by MaximizeModeController for the internal
191 // display. Compared in OnDisplayConfigurationChanged to determine user
192 // display setting changes.
193 gfx::Display::Rotation current_rotation_;
195 // Rotation Lock observers.
196 ObserverList<Observer> observers_;
198 // Tracks time spent in (and out of) touchview mode.
199 base::Time last_touchview_transition_time_;
200 base::TimeDelta total_touchview_time_;
201 base::TimeDelta total_non_touchview_time_;
203 // Tracks the last time we received a lid open event. This is used to suppress
204 // erroneous accelerometer readings as the lid is opened but the accelerometer
205 // reports readings that make the lid to appear near fully open.
206 base::TimeTicks last_lid_open_time_;
208 // Source for the current time in base::TimeTicks.
209 scoped_ptr<base::TickClock> tick_clock_;
211 // Tracks when the lid is closed. Used to prevent entering maximize mode.
214 DISALLOW_COPY_AND_ASSIGN(MaximizeModeController);
219 #endif // ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_