Chromium Code Reviews| Index: chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller.cc |
| diff --git a/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller.cc b/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..19a59157246777145254a3996869e41942e16c76 |
| --- /dev/null |
| +++ b/chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller.cc |
| @@ -0,0 +1,171 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_controller.h" |
| + |
| +#include "ash/shell.h" |
| +#include "ash/touch/touch_transformer_controller.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "chrome/browser/chromeos/display/touch_calibrator/touch_calibrator_view.h" |
| +#include "ui/display/screen.h" |
| +#include "ui/events/event.h" |
| +#include "ui/events/event_constants.h" |
| + |
| +namespace chromeos { |
| +namespace { |
| + |
| +// Time interval after a touch event during which all other touch events are |
| +// ignored during calibration. |
| +// If modified also update the value in touch_calibrator_controller_unittest.cc. |
| +const auto kTouchIntervalThreshold = base::TimeDelta::FromMilliseconds(200); |
|
stevenjb
2016/12/22 01:14:20
If this is used in a test it should really be a st
malaykeshav
2016/12/22 11:50:07
Done.
|
| + |
| +// Returns the index corresponding to the state the touch point is in currently. |
| +// Will return -1 if the touch point is not in a state where it is ready for |
| +// input(eg. will return -1 if the touch point is being animated or if the touch |
| +// point is currently not visible,) |
| +int GetDisplayPointStateIndex(TouchCalibratorView::State state) { |
| + switch (state) { |
| + case TouchCalibratorView::DISPLAY_POINT_1: |
| + return 0; |
| + case TouchCalibratorView::DISPLAY_POINT_2: |
| + return 1; |
| + case TouchCalibratorView::DISPLAY_POINT_3: |
| + return 2; |
| + case TouchCalibratorView::DISPLAY_POINT_4: |
| + return 3; |
| + default: |
| + return -1; |
| + } |
| +} |
| + |
| +// Returns true if the touch event needs to be processed for the given touch |
| +// calibration view state. |
| +bool CanTouch(TouchCalibratorView::State state) { |
| + if (GetDisplayPointStateIndex(state) + 1) |
|
stevenjb
2016/12/22 01:14:20
nit: This is confusing, just use if (GetDisplayPoi
malaykeshav
2016/12/22 11:50:07
Done
|
| + return true; |
| + if (state == TouchCalibratorView::CALIBRATION_COMPLETE) |
| + return true; |
|
stevenjb
2016/12/22 01:14:20
nit: Test this first (simpler test)
malaykeshav
2016/12/22 11:50:07
Done
|
| + return false; |
| +} |
| + |
| +} // namespace |
| + |
| +TouchCalibratorController::TouchCalibratorController() |
| + : last_touch_timestamp_(base::Time::Now()) { |
| + ash::Shell::GetInstance()->window_tree_host_manager()->AddObserver(this); |
| +} |
| + |
| +TouchCalibratorController::~TouchCalibratorController() { |
| + ash::Shell::GetInstance()->window_tree_host_manager()->RemoveObserver(this); |
| + touch_calibrator_views_.clear(); |
| + StopCalibration(); |
| +} |
| + |
| +void TouchCalibratorController::OnDisplayConfigurationChanged() { |
| + touch_calibrator_views_.clear(); |
| + StopCalibration(); |
| +} |
| + |
| +void TouchCalibratorController::StartCalibration( |
| + const display::Display& target_display) { |
| + is_calibrating_ = true; |
| + target_display_ = target_display; |
| + |
| + // Clear all touch calibrator views used in any previous calibration. |
| + touch_calibrator_views_.clear(); |
| + |
| + // Reset the calibration data. |
| + touch_point_quad_.fill(std::make_pair(gfx::Point(0, 0), gfx::Point(0, 0))); |
| + |
| + std::vector<display::Display> displays = |
| + display::Screen::GetScreen()->GetAllDisplays(); |
| + |
| + for (const display::Display& display : displays) { |
| + touch_calibrator_views_[display.id()] = |
| + base::MakeUnique<TouchCalibratorView>( |
| + display, display.id() == target_display_.id()); |
|
stevenjb
2016/12/22 01:14:20
nit: Define a local var for display.id() == target
malaykeshav
2016/12/22 11:50:07
Done
|
| + } |
| + |
| + // TODO(malaykeshav): Uncomment this when this patch lands. |
| + // ash::Shell::GetInstance()->touch_transformer_controller() |
| + // ->SetForCalibration(true); |
|
stevenjb
2016/12/22 01:14:20
We generally avoid committing commented out code l
malaykeshav
2016/12/22 11:50:07
Done
|
| + |
| + // Add self as an event handler target. |
| + ash::Shell::GetInstance()->AddPreTargetHandler(this); |
| +} |
| + |
| +void TouchCalibratorController::StopCalibration() { |
| + if (!is_calibrating_) |
| + return; |
| + is_calibrating_ = false; |
| + |
| + // TODO(malaykeshav): Uncomment this when this patch lands! |
| + // ash::Shell::GetInstance()->touch_transformer_controller() |
| + // ->SetForCalibration(false); |
|
stevenjb
2016/12/22 01:14:20
ditto
malaykeshav
2016/12/22 11:50:07
Done
|
| + |
| + // Remove self as the event handler. |
| + ash::Shell::GetInstance()->RemovePreTargetHandler(this); |
| + |
| + // Transition all touch calibrator views to their final state for a graceful |
| + // exit. |
| + for (const auto& it : touch_calibrator_views_) |
| + it.second->SkipToFinalState(); |
| +} |
| + |
| +// ui::EventHandler: |
| +void TouchCalibratorController::OnKeyEvent(ui::KeyEvent* key) { |
| + if (!is_calibrating_) |
| + return; |
| + // Detect ESC key press. |
| + if (key->type() == ui::ET_KEY_PRESSED && key->key_code() == ui::VKEY_ESCAPE) |
| + StopCalibration(); |
| + key->StopPropagation(); |
| +} |
| + |
| +void TouchCalibratorController::OnTouchEvent(ui::TouchEvent* touch) { |
| + LOG(ERROR) << "Received touch event"; |
|
stevenjb
2016/12/22 01:14:20
VLOG or remove
malaykeshav
2016/12/22 11:50:07
Remnant from when I was testing. Forgot to remove.
|
| + if (!is_calibrating_) |
| + return; |
| + if (touch->type() != ui::ET_TOUCH_RELEASED) |
| + return; |
| + if (base::Time::Now() - last_touch_timestamp_ < kTouchIntervalThreshold) |
| + return; |
| + |
| + last_touch_timestamp_ = base::Time::Now(); |
| + |
| + TouchCalibratorView* target_screen_calibration_view = |
| + touch_calibrator_views_[target_display_.id()].get(); |
| + |
| + TouchCalibratorView::State calibrator_view_state = |
| + target_screen_calibration_view->GetState(); |
| + |
| + // Check if the touch calibrator view is in a state when touch inputs have to |
| + // be ignored. |
| + if (!CanTouch(calibrator_view_state)) |
| + return; |
| + |
| + int state_index = GetDisplayPointStateIndex(calibrator_view_state); |
|
stevenjb
2016/12/22 01:14:20
We also call this in CanTouch, which is only calle
malaykeshav
2016/12/22 11:50:07
Done
|
| + |
| + // Store touch points if the state is a display point state. |
| + if (state_index + 1) { |
|
stevenjb
2016/12/22 01:14:20
state_index >= 0
malaykeshav
2016/12/22 11:50:07
Removed. Not required.
|
| + gfx::Point display_point; |
| + if (target_screen_calibration_view->GetTouchPointLocation(&display_point)) |
| + touch_point_quad_[state_index] = |
| + std::make_pair(display_point, touch->location()); |
|
stevenjb
2016/12/22 01:14:20
{}
malaykeshav
2016/12/22 11:50:07
done
|
| + } |
| + |
| + // If this is the final state, then store all calibration data and stop |
| + // calibration. |
| + if (calibrator_view_state == TouchCalibratorView::CALIBRATION_COMPLETE) { |
| + ash::Shell::GetInstance()->display_manager()->SetTouchCalibrationData( |
| + target_display_.id(), touch_point_quad_, |
| + target_screen_calibration_view->size()); |
| + StopCalibration(); |
| + return; |
| + } |
| + |
| + target_screen_calibration_view->NextState(); |
| +} |
| + |
| +} // namespace chromeos |