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. 56 virtual void OnRotationLockChanged(bool rotation_locked) {} 57 58 protected: 59 virtual ~Observer() {} 60 }; 61 62 MaximizeModeController(); 63 virtual ~MaximizeModeController(); 64 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. 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