• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_
6 #define ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_
7 
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"
17 
18 #if defined(OS_CHROMEOS)
19 #include "chromeos/dbus/power_manager_client.h"
20 #endif  // OS_CHROMEOS
21 
22 namespace base {
23 class TickClock;
24 }
25 
26 namespace ui {
27 class EventHandler;
28 }
29 
30 namespace ash {
31 
32 class MaximizeModeControllerTest;
33 class ScopedDisableInternalMouseAndKeyboard;
34 class MaximizeModeWindowManager;
35 class MaximizeModeWindowManagerTest;
36 namespace test {
37 class MultiUserWindowManagerChromeOSTest;
38 }
39 
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,
47 #endif  // OS_CHROMEOS
48       public ShellObserver,
49       public DisplayController::Observer {
50  public:
51   // Observer that reports changes to the state of MaximizeModeController's
52   // rotation lock.
53   class Observer {
54    public:
55     // Invoked whenever |rotation_locked_| is changed.
OnRotationLockChanged(bool rotation_locked)56     virtual void OnRotationLockChanged(bool rotation_locked) {}
57 
58    protected:
~Observer()59     virtual ~Observer() {}
60   };
61 
62   MaximizeModeController();
63   virtual ~MaximizeModeController();
64 
ignore_display_configuration_updates()65   bool ignore_display_configuration_updates() const {
66     return ignore_display_configuration_updates_;
67   }
68 
69   // True if |rotation_lock_| has been set, and OnAccelerometerUpdated will not
70   // change the display rotation.
rotation_locked()71   bool rotation_locked() {
72     return rotation_locked_;
73   }
74 
75   // If |rotation_locked| future calls to OnAccelerometerUpdated will not
76   // change the display rotation.
77   void SetRotationLocked(bool rotation_locked);
78 
79   // Add/Remove observers.
80   void AddObserver(Observer* observer);
81   void RemoveObserver(Observer* observer);
82 
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();
87 
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);
94 
95   // Test if the MaximizeModeWindowManager is enabled or not.
96   bool IsMaximizeModeWindowManagerEnabled() const;
97 
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);
103 
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.
109   void Shutdown();
110 
111   // AccelerometerObserver:
112   virtual void OnAccelerometerUpdated(
113       const ui::AccelerometerUpdate& update) OVERRIDE;
114 
115   // ShellObserver:
116   virtual void OnAppTerminating() OVERRIDE;
117   virtual void OnMaximizeModeStarted() OVERRIDE;
118   virtual void OnMaximizeModeEnded() OVERRIDE;
119 
120   // DisplayController::Observer:
121   virtual void OnDisplayConfigurationChanged() OVERRIDE;
122 
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
130 
131  private:
132   friend class MaximizeModeControllerTest;
133   friend class MaximizeModeWindowManagerTest;
134   friend class test::MultiUserWindowManagerChromeOSTest;
135 
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);
139 
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);
144 
145   // Detect screen rotation from |lid| accelerometer and automatically rotate
146   // screen.
147   void HandleScreenRotation(const gfx::Vector3dF& lid);
148 
149   // Sets the display rotation and suppresses display notifications.
150   void SetDisplayRotation(DisplayManager* display_manager,
151                           gfx::Display::Rotation rotation);
152 
153   // Returns true if the lid was recently opened.
154   bool WasLidOpenedRecently() const;
155 
156   // Enables MaximizeModeWindowManager, and determines the current state of
157   // rotation lock.
158   void EnterMaximizeMode();
159 
160   // Removes MaximizeModeWindowManager and resets the display rotation if there
161   // is no rotation lock.
162   void LeaveMaximizeMode();
163 
164   // Record UMA stats tracking touchview usage.
165   void RecordTouchViewStateTransition();
166 
167   // Checks DisplayManager for registered rotation lock, and rotation,
168   // preferences. These are then applied.
169   void LoadDisplayRotationProperties();
170 
171   // The maximized window manager (if enabled).
172   scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_;
173 
174   // A helper class which when instantiated will block native events from the
175   // internal keyboard and touchpad.
176   scoped_ptr<ScopedDisableInternalMouseAndKeyboard> event_blocker_;
177 
178   // When true calls to OnAccelerometerUpdated will not rotate the display.
179   bool rotation_locked_;
180 
181   // Whether we have ever seen accelerometer data.
182   bool have_seen_accelerometer_data_;
183 
184   // True when changes being applied cause OnDisplayConfigurationChanged() to be
185   // called, and for which these changes should be ignored.
186   bool ignore_display_configuration_updates_;
187 
188   // True when Shutdown has been called. When shutting down the non maximize
189   // mode state should be restored, however user preferences should not be
190   // altered.
191   bool shutting_down_;
192 
193   // The rotation of the display set by the user. This rotation will be
194   // restored upon exiting maximize mode.
195   gfx::Display::Rotation user_rotation_;
196 
197   // The current rotation set by MaximizeModeController for the internal
198   // display. Compared in OnDisplayConfigurationChanged to determine user
199   // display setting changes.
200   gfx::Display::Rotation current_rotation_;
201 
202   // Rotation Lock observers.
203   ObserverList<Observer> observers_;
204 
205   // Tracks time spent in (and out of) touchview mode.
206   base::Time last_touchview_transition_time_;
207   base::TimeDelta total_touchview_time_;
208   base::TimeDelta total_non_touchview_time_;
209 
210   // Tracks the last time we received a lid open event. This is used to suppress
211   // erroneous accelerometer readings as the lid is opened but the accelerometer
212   // reports readings that make the lid to appear near fully open.
213   base::TimeTicks last_lid_open_time_;
214 
215   // Source for the current time in base::TimeTicks.
216   scoped_ptr<base::TickClock> tick_clock_;
217 
218   // Tracks when the lid is closed. Used to prevent entering maximize mode.
219   bool lid_is_closed_;
220 
221   DISALLOW_COPY_AND_ASSIGN(MaximizeModeController);
222 };
223 
224 }  // namespace ash
225 
226 #endif  // ASH_WM_MAXIMIZE_MODE_MAXIMIZE_MODE_CONTROLLER_H_
227