| 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 |