OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" | 5 #include "ash/common/wm/maximize_mode/maximize_mode_controller.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "ash/common/ash_switches.h" | 9 #include "ash/common/ash_switches.h" |
10 #include "ash/common/wm/maximize_mode/maximize_mode_window_manager.h" | 10 #include "ash/common/wm/maximize_mode/maximize_mode_window_manager.h" |
11 #include "ash/common/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard
.h" | 11 #include "ash/common/wm/maximize_mode/scoped_disable_internal_mouse_and_keyboard
.h" |
12 #include "ash/common/wm_shell.h" | 12 #include "ash/common/wm_shell.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
15 #include "base/time/default_tick_clock.h" | 15 #include "base/time/default_tick_clock.h" |
16 #include "base/time/tick_clock.h" | 16 #include "base/time/tick_clock.h" |
| 17 #include "chromeos/dbus/dbus_thread_manager.h" |
17 #include "ui/base/accelerators/accelerator.h" | 18 #include "ui/base/accelerators/accelerator.h" |
| 19 #include "ui/chromeos/accelerometer/accelerometer_util.h" |
18 #include "ui/display/display.h" | 20 #include "ui/display/display.h" |
19 #include "ui/events/event.h" | 21 #include "ui/events/event.h" |
20 #include "ui/events/keycodes/keyboard_codes.h" | 22 #include "ui/events/keycodes/keyboard_codes.h" |
21 #include "ui/gfx/geometry/vector3d_f.h" | 23 #include "ui/gfx/geometry/vector3d_f.h" |
22 | 24 |
23 #if defined(OS_CHROMEOS) | |
24 #include "chromeos/dbus/dbus_thread_manager.h" | |
25 #include "ui/chromeos/accelerometer/accelerometer_util.h" | |
26 #endif // OS_CHROMEOS | |
27 | |
28 namespace ash { | 25 namespace ash { |
29 | 26 |
30 namespace { | 27 namespace { |
31 | 28 |
32 #if defined(OS_CHROMEOS) | |
33 // The hinge angle at which to enter maximize mode. | 29 // The hinge angle at which to enter maximize mode. |
34 const float kEnterMaximizeModeAngle = 200.0f; | 30 const float kEnterMaximizeModeAngle = 200.0f; |
35 | 31 |
36 // The angle at which to exit maximize mode, this is specifically less than the | 32 // The angle at which to exit maximize mode, this is specifically less than the |
37 // angle to enter maximize mode to prevent rapid toggling when near the angle. | 33 // angle to enter maximize mode to prevent rapid toggling when near the angle. |
38 const float kExitMaximizeModeAngle = 160.0f; | 34 const float kExitMaximizeModeAngle = 160.0f; |
39 | 35 |
40 // Defines a range for which accelerometer readings are considered accurate. | 36 // Defines a range for which accelerometer readings are considered accurate. |
41 // When the lid is near open (or near closed) the accelerometer readings may be | 37 // When the lid is near open (or near closed) the accelerometer readings may be |
42 // inaccurate and a lid that is fully open may appear to be near closed (and | 38 // inaccurate and a lid that is fully open may appear to be near closed (and |
43 // vice versa). | 39 // vice versa). |
44 const float kMinStableAngle = 20.0f; | 40 const float kMinStableAngle = 20.0f; |
45 const float kMaxStableAngle = 340.0f; | 41 const float kMaxStableAngle = 340.0f; |
46 #endif // OS_CHROMEOS | |
47 | 42 |
48 // The time duration to consider the lid to be recently opened. | 43 // The time duration to consider the lid to be recently opened. |
49 // This is used to prevent entering maximize mode if an erroneous accelerometer | 44 // This is used to prevent entering maximize mode if an erroneous accelerometer |
50 // reading makes the lid appear to be fully open when the user is opening the | 45 // reading makes the lid appear to be fully open when the user is opening the |
51 // lid from a closed position. | 46 // lid from a closed position. |
52 const int kLidRecentlyOpenedDurationSeconds = 2; | 47 const int kLidRecentlyOpenedDurationSeconds = 2; |
53 | 48 |
54 #if defined(OS_CHROMEOS) | |
55 // When the device approaches vertical orientation (i.e. portrait orientation) | 49 // When the device approaches vertical orientation (i.e. portrait orientation) |
56 // the accelerometers for the base and lid approach the same values (i.e. | 50 // the accelerometers for the base and lid approach the same values (i.e. |
57 // gravity pointing in the direction of the hinge). When this happens abrupt | 51 // gravity pointing in the direction of the hinge). When this happens abrupt |
58 // small acceleration perpendicular to the hinge can lead to incorrect hinge | 52 // small acceleration perpendicular to the hinge can lead to incorrect hinge |
59 // angle calculations. To prevent this the accelerometer updates will be | 53 // angle calculations. To prevent this the accelerometer updates will be |
60 // smoothed over time in order to reduce this noise. | 54 // smoothed over time in order to reduce this noise. |
61 // This is the minimum acceleration parallel to the hinge under which to begin | 55 // This is the minimum acceleration parallel to the hinge under which to begin |
62 // smoothing in m/s^2. | 56 // smoothing in m/s^2. |
63 const float kHingeVerticalSmoothingStart = 7.0f; | 57 const float kHingeVerticalSmoothingStart = 7.0f; |
64 // This is the maximum acceleration parallel to the hinge under which smoothing | 58 // This is the maximum acceleration parallel to the hinge under which smoothing |
(...skipping 11 matching lines...) Expand all Loading... |
76 bool IsAngleBetweenAccelerometerReadingsStable( | 70 bool IsAngleBetweenAccelerometerReadingsStable( |
77 const chromeos::AccelerometerUpdate& update) { | 71 const chromeos::AccelerometerUpdate& update) { |
78 return std::abs( | 72 return std::abs( |
79 ui::ConvertAccelerometerReadingToVector3dF( | 73 ui::ConvertAccelerometerReadingToVector3dF( |
80 update.get(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) | 74 update.get(chromeos::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD)) |
81 .Length() - | 75 .Length() - |
82 ui::ConvertAccelerometerReadingToVector3dF( | 76 ui::ConvertAccelerometerReadingToVector3dF( |
83 update.get(chromeos::ACCELEROMETER_SOURCE_SCREEN)) | 77 update.get(chromeos::ACCELEROMETER_SOURCE_SCREEN)) |
84 .Length()) <= kNoisyMagnitudeDeviation; | 78 .Length()) <= kNoisyMagnitudeDeviation; |
85 } | 79 } |
86 #endif // OS_CHROMEOS | |
87 | 80 |
88 bool IsEnabled() { | 81 bool IsEnabled() { |
89 return base::CommandLine::ForCurrentProcess()->HasSwitch( | 82 return base::CommandLine::ForCurrentProcess()->HasSwitch( |
90 switches::kAshEnableTouchView); | 83 switches::kAshEnableTouchView); |
91 } | 84 } |
92 | 85 |
93 } // namespace | 86 } // namespace |
94 | 87 |
95 MaximizeModeController::MaximizeModeController() | 88 MaximizeModeController::MaximizeModeController() |
96 : have_seen_accelerometer_data_(false), | 89 : have_seen_accelerometer_data_(false), |
97 touchview_usage_interval_start_time_(base::Time::Now()), | 90 touchview_usage_interval_start_time_(base::Time::Now()), |
98 tick_clock_(new base::DefaultTickClock()), | 91 tick_clock_(new base::DefaultTickClock()), |
99 #if defined(OS_CHROMEOS) | |
100 tablet_mode_switch_is_on_(false), | 92 tablet_mode_switch_is_on_(false), |
101 #endif | |
102 lid_is_closed_(false) { | 93 lid_is_closed_(false) { |
103 WmShell::Get()->AddShellObserver(this); | 94 WmShell::Get()->AddShellObserver(this); |
104 WmShell::Get()->RecordUserMetricsAction(UMA_MAXIMIZE_MODE_INITIALLY_DISABLED); | 95 WmShell::Get()->RecordUserMetricsAction(UMA_MAXIMIZE_MODE_INITIALLY_DISABLED); |
105 | 96 |
106 // TODO(jonross): Do not create MaximizeModeController if the flag is | 97 // TODO(jonross): Do not create MaximizeModeController if the flag is |
107 // unavailable. This will require refactoring | 98 // unavailable. This will require refactoring |
108 // IsMaximizeModeWindowManagerEnabled to check for the existance of the | 99 // IsMaximizeModeWindowManagerEnabled to check for the existance of the |
109 // controller. | 100 // controller. |
110 const bool is_enabled = IsEnabled(); | 101 const bool is_enabled = IsEnabled(); |
111 if (is_enabled) | 102 if (is_enabled) |
112 WmShell::Get()->AddDisplayObserver(this); | 103 WmShell::Get()->AddDisplayObserver(this); |
113 | 104 |
114 #if defined(OS_CHROMEOS) | |
115 if (is_enabled) | 105 if (is_enabled) |
116 chromeos::AccelerometerReader::GetInstance()->AddObserver(this); | 106 chromeos::AccelerometerReader::GetInstance()->AddObserver(this); |
117 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( | 107 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->AddObserver( |
118 this); | 108 this); |
119 #endif // OS_CHROMEOS | |
120 } | 109 } |
121 | 110 |
122 MaximizeModeController::~MaximizeModeController() { | 111 MaximizeModeController::~MaximizeModeController() { |
123 WmShell::Get()->RemoveShellObserver(this); | 112 WmShell::Get()->RemoveShellObserver(this); |
124 const bool is_enabled = IsEnabled(); | 113 const bool is_enabled = IsEnabled(); |
125 if (is_enabled) | 114 if (is_enabled) |
126 WmShell::Get()->RemoveDisplayObserver(this); | 115 WmShell::Get()->RemoveDisplayObserver(this); |
127 | 116 |
128 #if defined(OS_CHROMEOS) | |
129 if (is_enabled) | 117 if (is_enabled) |
130 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this); | 118 chromeos::AccelerometerReader::GetInstance()->RemoveObserver(this); |
131 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( | 119 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver( |
132 this); | 120 this); |
133 #endif // OS_CHROMEOS | |
134 } | 121 } |
135 | 122 |
136 bool MaximizeModeController::CanEnterMaximizeMode() { | 123 bool MaximizeModeController::CanEnterMaximizeMode() { |
137 // If we have ever seen accelerometer data, then HandleHingeRotation may | 124 // If we have ever seen accelerometer data, then HandleHingeRotation may |
138 // trigger maximize mode at some point in the future. | 125 // trigger maximize mode at some point in the future. |
139 // The --enable-touch-view-testing switch can also mean that we may enter | 126 // The --enable-touch-view-testing switch can also mean that we may enter |
140 // maximize mode. | 127 // maximize mode. |
141 // TODO(mgiuca): This can result in false positives, as it returns true for | 128 // TODO(mgiuca): This can result in false positives, as it returns true for |
142 // any device with an accelerometer. Have TouchView-enabled devices explicitly | 129 // any device with an accelerometer. Have TouchView-enabled devices explicitly |
143 // set a flag, and change this implementation to simply return true iff the | 130 // set a flag, and change this implementation to simply return true iff the |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 void MaximizeModeController::AddWindow(WmWindow* window) { | 173 void MaximizeModeController::AddWindow(WmWindow* window) { |
187 if (IsMaximizeModeWindowManagerEnabled()) | 174 if (IsMaximizeModeWindowManagerEnabled()) |
188 maximize_mode_window_manager_->AddWindow(window); | 175 maximize_mode_window_manager_->AddWindow(window); |
189 } | 176 } |
190 | 177 |
191 void MaximizeModeController::BindRequest( | 178 void MaximizeModeController::BindRequest( |
192 mojom::TouchViewManagerRequest request) { | 179 mojom::TouchViewManagerRequest request) { |
193 bindings_.AddBinding(this, std::move(request)); | 180 bindings_.AddBinding(this, std::move(request)); |
194 } | 181 } |
195 | 182 |
196 #if defined(OS_CHROMEOS) | |
197 void MaximizeModeController::OnAccelerometerUpdated( | 183 void MaximizeModeController::OnAccelerometerUpdated( |
198 scoped_refptr<const chromeos::AccelerometerUpdate> update) { | 184 scoped_refptr<const chromeos::AccelerometerUpdate> update) { |
199 bool first_accelerometer_update = !have_seen_accelerometer_data_; | 185 bool first_accelerometer_update = !have_seen_accelerometer_data_; |
200 have_seen_accelerometer_data_ = true; | 186 have_seen_accelerometer_data_ = true; |
201 | 187 |
202 if (!update->has(chromeos::ACCELEROMETER_SOURCE_SCREEN)) | 188 if (!update->has(chromeos::ACCELEROMETER_SOURCE_SCREEN)) |
203 return; | 189 return; |
204 | 190 |
205 if (!display::Display::HasInternalDisplay()) | 191 if (!display::Display::HasInternalDisplay()) |
206 return; | 192 return; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 // Toggle maximize mode on or off when corresponding thresholds are passed. | 302 // Toggle maximize mode on or off when corresponding thresholds are passed. |
317 if (IsMaximizeModeWindowManagerEnabled() && is_angle_stable && | 303 if (IsMaximizeModeWindowManagerEnabled() && is_angle_stable && |
318 lid_angle <= kExitMaximizeModeAngle) { | 304 lid_angle <= kExitMaximizeModeAngle) { |
319 LeaveMaximizeMode(); | 305 LeaveMaximizeMode(); |
320 } else if (!IsMaximizeModeWindowManagerEnabled() && !lid_is_closed_ && | 306 } else if (!IsMaximizeModeWindowManagerEnabled() && !lid_is_closed_ && |
321 lid_angle >= kEnterMaximizeModeAngle && | 307 lid_angle >= kEnterMaximizeModeAngle && |
322 (is_angle_stable || !WasLidOpenedRecently())) { | 308 (is_angle_stable || !WasLidOpenedRecently())) { |
323 EnterMaximizeMode(); | 309 EnterMaximizeMode(); |
324 } | 310 } |
325 } | 311 } |
326 #endif // OS_CHROMEOS | |
327 | 312 |
328 void MaximizeModeController::EnterMaximizeMode() { | 313 void MaximizeModeController::EnterMaximizeMode() { |
329 // Always reset first to avoid creation before destruction of a previous | 314 // Always reset first to avoid creation before destruction of a previous |
330 // object. | 315 // object. |
331 event_blocker_ = | 316 event_blocker_ = |
332 WmShell::Get()->CreateScopedDisableInternalMouseAndKeyboard(); | 317 WmShell::Get()->CreateScopedDisableInternalMouseAndKeyboard(); |
333 | 318 |
334 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 319 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
335 switches::kAshEnableTouchViewTesting)) { | 320 switches::kAshEnableTouchViewTesting)) { |
336 // We don't let accelerometer updates interfere with the maximize mode | 321 // We don't let accelerometer updates interfere with the maximize mode |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
442 return elapsed_time.InSeconds() <= kLidRecentlyOpenedDurationSeconds; | 427 return elapsed_time.InSeconds() <= kLidRecentlyOpenedDurationSeconds; |
443 } | 428 } |
444 | 429 |
445 void MaximizeModeController::SetTickClockForTest( | 430 void MaximizeModeController::SetTickClockForTest( |
446 std::unique_ptr<base::TickClock> tick_clock) { | 431 std::unique_ptr<base::TickClock> tick_clock) { |
447 DCHECK(tick_clock_); | 432 DCHECK(tick_clock_); |
448 tick_clock_ = std::move(tick_clock); | 433 tick_clock_ = std::move(tick_clock); |
449 } | 434 } |
450 | 435 |
451 } // namespace ash | 436 } // namespace ash |
OLD | NEW |