| 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 "ui/chromeos/touch_exploration_controller.h" | 5 #include "ui/chromeos/touch_exploration_controller.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
| 11 #include "ui/accessibility/ax_enums.h" | 11 #include "ui/accessibility/ax_enums.h" |
| 12 #include "ui/aura/client/cursor_client.h" | 12 #include "ui/aura/client/cursor_client.h" |
| 13 #include "ui/aura/window.h" | 13 #include "ui/aura/window.h" |
| 14 #include "ui/aura/window_event_dispatcher.h" | 14 #include "ui/aura/window_event_dispatcher.h" |
| 15 #include "ui/aura/window_tree_host.h" | 15 #include "ui/aura/window_tree_host.h" |
| 16 #include "ui/events/event.h" | 16 #include "ui/events/event.h" |
| 17 #include "ui/events/event_processor.h" | 17 #include "ui/events/event_processor.h" |
| 18 #include "ui/events/event_utils.h" | 18 #include "ui/events/event_utils.h" |
| 19 #include "ui/gfx/geometry/rect.h" | 19 #include "ui/gfx/geometry/rect.h" |
| 20 | 20 |
| 21 #define SET_STATE(state) SetState(state, __func__) | 21 #define SET_STATE(state) SetState(state, __func__) |
| 22 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) | 22 #define VLOG_EVENT(event) \ |
| 23 if (VLOG_IS_ON(1)) \ |
| 24 VlogEvent(event, __func__) |
| 23 | 25 |
| 24 namespace ui { | 26 namespace ui { |
| 25 | 27 |
| 26 namespace { | 28 namespace { |
| 27 | 29 |
| 28 // Delay between adjustment sounds. | 30 // Delay between adjustment sounds. |
| 29 const int kSoundDelayInMS = 150; | 31 const int kSoundDelayInMS = 150; |
| 30 | 32 |
| 31 void SetTouchAccessibilityFlag(ui::Event* event) { | 33 void SetTouchAccessibilityFlag(ui::Event* event) { |
| 32 // This flag is used to identify mouse move events that were generated from | 34 // This flag is used to identify mouse move events that were generated from |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 void TouchExplorationController::SetExcludeBounds(const gfx::Rect& bounds) { | 68 void TouchExplorationController::SetExcludeBounds(const gfx::Rect& bounds) { |
| 67 exclude_bounds_ = bounds; | 69 exclude_bounds_ = bounds; |
| 68 } | 70 } |
| 69 | 71 |
| 70 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( | 72 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( |
| 71 const ui::Event& event, | 73 const ui::Event& event, |
| 72 std::unique_ptr<ui::Event>* rewritten_event) { | 74 std::unique_ptr<ui::Event>* rewritten_event) { |
| 73 if (!event.IsTouchEvent()) { | 75 if (!event.IsTouchEvent()) { |
| 74 if (event.IsKeyEvent()) { | 76 if (event.IsKeyEvent()) { |
| 75 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); | 77 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); |
| 76 VLOG(0) << "\nKeyboard event: " << key_event.name() | 78 VLOG(1) << "\nKeyboard event: " << key_event.name() |
| 77 << "\n Key code: " << key_event.key_code() | 79 << "\n Key code: " << key_event.key_code() |
| 78 << ", Flags: " << key_event.flags() | 80 << ", Flags: " << key_event.flags() |
| 79 << ", Is char: " << key_event.is_char(); | 81 << ", Is char: " << key_event.is_char(); |
| 80 } | 82 } |
| 81 return ui::EVENT_REWRITE_CONTINUE; | 83 return ui::EVENT_REWRITE_CONTINUE; |
| 82 } | 84 } |
| 83 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); | 85 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); |
| 84 | 86 |
| 85 if (!exclude_bounds_.IsEmpty()) { | 87 if (!exclude_bounds_.IsEmpty()) { |
| 86 gfx::Point location = touch_event.location(); | 88 gfx::Point location = touch_event.location(); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 return ui::EVENT_REWRITE_CONTINUE; | 155 return ui::EVENT_REWRITE_CONTINUE; |
| 154 } | 156 } |
| 155 VLOG_EVENT(touch_event); | 157 VLOG_EVENT(touch_event); |
| 156 | 158 |
| 157 // In order to avoid accidentally double tapping when moving off the edge | 159 // In order to avoid accidentally double tapping when moving off the edge |
| 158 // of the screen, the state will be rewritten to NoFingersDown. | 160 // of the screen, the state will be rewritten to NoFingersDown. |
| 159 if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) && | 161 if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) && |
| 160 FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != | 162 FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != |
| 161 NO_EDGE) { | 163 NO_EDGE) { |
| 162 if (VLOG_on_) | 164 if (VLOG_on_) |
| 163 VLOG(0) << "Leaving screen"; | 165 VLOG(1) << "Leaving screen"; |
| 164 | 166 |
| 165 // Indicates to the user that they are leaving the screen. | 167 // Indicates to the user that they are leaving the screen. |
| 166 delegate_->PlayExitScreenEarcon(); | 168 delegate_->PlayExitScreenEarcon(); |
| 167 | 169 |
| 168 if (current_touch_ids_.size() == 0) { | 170 if (current_touch_ids_.size() == 0) { |
| 169 SET_STATE(NO_FINGERS_DOWN); | 171 SET_STATE(NO_FINGERS_DOWN); |
| 170 if (VLOG_on_) { | 172 if (VLOG_on_) { |
| 171 VLOG(0) << "Reset to no fingers in Rewrite event because the touch " | 173 VLOG(1) << "Reset to no fingers in Rewrite event because the touch " |
| 172 "release or cancel was on the edge of the screen."; | 174 "release or cancel was on the edge of the screen."; |
| 173 } | 175 } |
| 174 return ui::EVENT_REWRITE_DISCARD; | 176 return ui::EVENT_REWRITE_DISCARD; |
| 175 } | 177 } |
| 176 } | 178 } |
| 177 | 179 |
| 178 // If the user is in a gesture state, or if there is a possiblity that the | 180 // If the user is in a gesture state, or if there is a possiblity that the |
| 179 // user will enter it in the future, we send the event to the gesture | 181 // user will enter it in the future, we send the event to the gesture |
| 180 // provider so it can keep track of the state of the fingers. When the user | 182 // provider so it can keep track of the state of the fingers. When the user |
| 181 // leaves one of these states, SET_STATE will set the gesture provider to | 183 // leaves one of these states, SET_STATE will set the gesture provider to |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 // If the user does not move far enough from the original position, then the | 325 // If the user does not move far enough from the original position, then the |
| 324 // resulting movement should not be considered to be a deliberate gesture or | 326 // resulting movement should not be considered to be a deliberate gesture or |
| 325 // touch exploration. | 327 // touch exploration. |
| 326 if (distance <= gesture_detector_config_.touch_slop) | 328 if (distance <= gesture_detector_config_.touch_slop) |
| 327 return EVENT_REWRITE_DISCARD; | 329 return EVENT_REWRITE_DISCARD; |
| 328 | 330 |
| 329 float delta_time = | 331 float delta_time = |
| 330 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); | 332 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); |
| 331 float velocity = distance / delta_time; | 333 float velocity = distance / delta_time; |
| 332 if (VLOG_on_) { | 334 if (VLOG_on_) { |
| 333 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance | 335 VLOG(1) << "\n Delta time: " << delta_time << "\n Distance: " << distance |
| 334 << "\n Velocity of click: " << velocity | 336 << "\n Velocity of click: " << velocity |
| 335 << "\n Minimum swipe velocity: " | 337 << "\n Minimum swipe velocity: " |
| 336 << gesture_detector_config_.minimum_swipe_velocity; | 338 << gesture_detector_config_.minimum_swipe_velocity; |
| 337 } | 339 } |
| 338 // Change to slide gesture if the slide occurred at the right edge. | 340 // Change to slide gesture if the slide occurred at the right edge. |
| 339 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); | 341 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); |
| 340 if (edge & RIGHT_EDGE && edge != BOTTOM_RIGHT_CORNER) { | 342 if (edge & RIGHT_EDGE && edge != BOTTOM_RIGHT_CORNER) { |
| 341 SET_STATE(SLIDE_GESTURE); | 343 SET_STATE(SLIDE_GESTURE); |
| 342 return InSlideGesture(event, rewritten_event); | 344 return InSlideGesture(event, rewritten_event); |
| 343 } | 345 } |
| (...skipping 547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 return; | 893 return; |
| 892 } | 894 } |
| 893 | 895 |
| 894 location = gesture->location(); | 896 location = gesture->location(); |
| 895 root_window_->GetHost()->ConvertPointFromNativeScreen(&location); | 897 root_window_->GetHost()->ConvertPointFromNativeScreen(&location); |
| 896 float volume_adjust_height = | 898 float volume_adjust_height = |
| 897 root_window_->bounds().height() - 2 * kMaxDistanceFromEdge; | 899 root_window_->bounds().height() - 2 * kMaxDistanceFromEdge; |
| 898 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; | 900 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; |
| 899 float volume = 100 - 100 * ratio; | 901 float volume = 100 - 100 * ratio; |
| 900 if (VLOG_on_) { | 902 if (VLOG_on_) { |
| 901 VLOG(0) << "\n Volume = " << volume | 903 VLOG(1) << "\n Volume = " << volume |
| 902 << "\n Location = " << location.ToString() | 904 << "\n Location = " << location.ToString() |
| 903 << "\n Bounds = " << root_window_->bounds().right(); | 905 << "\n Bounds = " << root_window_->bounds().right(); |
| 904 } | 906 } |
| 905 delegate_->SetOutputLevel(static_cast<int>(volume)); | 907 delegate_->SetOutputLevel(static_cast<int>(volume)); |
| 906 } | 908 } |
| 907 | 909 |
| 908 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { | 910 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { |
| 909 // A swipe gesture contains details for the direction in which the swipe | 911 // A swipe gesture contains details for the direction in which the swipe |
| 910 // occurred. TODO(evy) : Research which swipe results users most want and | 912 // occurred. TODO(evy) : Research which swipe results users most want and |
| 911 // remap these swipes to the best events. Hopefully in the near future | 913 // remap these swipes to the best events. Hopefully in the near future |
| 912 // there will also be a menu for users to pick custom mappings. | 914 // there will also be a menu for users to pick custom mappings. |
| 913 GestureEventDetails event_details = swipe_gesture->details(); | 915 GestureEventDetails event_details = swipe_gesture->details(); |
| 914 int num_fingers = event_details.touch_points(); | 916 int num_fingers = event_details.touch_points(); |
| 915 if (VLOG_on_) | 917 if (VLOG_on_) |
| 916 VLOG(0) << "\nSwipe with " << num_fingers << " fingers."; | 918 VLOG(1) << "\nSwipe with " << num_fingers << " fingers."; |
| 917 | 919 |
| 918 ui::AXGesture gesture = ui::AX_GESTURE_NONE; | 920 ui::AXGesture gesture = ui::AX_GESTURE_NONE; |
| 919 if (event_details.swipe_left()) { | 921 if (event_details.swipe_left()) { |
| 920 switch (num_fingers) { | 922 switch (num_fingers) { |
| 921 case 1: | 923 case 1: |
| 922 gesture = ui::AX_GESTURE_SWIPE_LEFT_1; | 924 gesture = ui::AX_GESTURE_SWIPE_LEFT_1; |
| 923 break; | 925 break; |
| 924 case 2: | 926 case 2: |
| 925 gesture = ui::AX_GESTURE_SWIPE_LEFT_2; | 927 gesture = ui::AX_GESTURE_SWIPE_LEFT_2; |
| 926 break; | 928 break; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 } | 1021 } |
| 1020 | 1022 |
| 1021 void TouchExplorationController::DispatchKeyWithFlags( | 1023 void TouchExplorationController::DispatchKeyWithFlags( |
| 1022 const ui::KeyboardCode key, | 1024 const ui::KeyboardCode key, |
| 1023 int flags) { | 1025 int flags) { |
| 1024 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags); | 1026 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags); |
| 1025 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags); | 1027 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags); |
| 1026 DispatchEvent(&key_down); | 1028 DispatchEvent(&key_down); |
| 1027 DispatchEvent(&key_up); | 1029 DispatchEvent(&key_up); |
| 1028 if (VLOG_on_) { | 1030 if (VLOG_on_) { |
| 1029 VLOG(0) << "\nKey down: key code : " << key_down.key_code() | 1031 VLOG(1) << "\nKey down: key code : " << key_down.key_code() |
| 1030 << ", flags: " << key_down.flags() | 1032 << ", flags: " << key_down.flags() |
| 1031 << "\nKey up: key code : " << key_up.key_code() | 1033 << "\nKey up: key code : " << key_up.key_code() |
| 1032 << ", flags: " << key_up.flags(); | 1034 << ", flags: " << key_up.flags(); |
| 1033 } | 1035 } |
| 1034 } | 1036 } |
| 1035 | 1037 |
| 1036 base::Closure TouchExplorationController::BindKeyEventWithFlags( | 1038 base::Closure TouchExplorationController::BindKeyEventWithFlags( |
| 1037 const ui::KeyboardCode key, | 1039 const ui::KeyboardCode key, |
| 1038 int flags) { | 1040 int flags) { |
| 1039 return base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | 1041 return base::Bind(&TouchExplorationController::DispatchKeyWithFlags, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 } | 1113 } |
| 1112 } | 1114 } |
| 1113 | 1115 |
| 1114 void TouchExplorationController::VlogState(const char* function_name) { | 1116 void TouchExplorationController::VlogState(const char* function_name) { |
| 1115 if (!VLOG_on_) | 1117 if (!VLOG_on_) |
| 1116 return; | 1118 return; |
| 1117 if (prev_state_ == state_) | 1119 if (prev_state_ == state_) |
| 1118 return; | 1120 return; |
| 1119 prev_state_ = state_; | 1121 prev_state_ = state_; |
| 1120 const char* state_string = EnumStateToString(state_); | 1122 const char* state_string = EnumStateToString(state_); |
| 1121 VLOG(0) << "\n Function name: " << function_name | 1123 VLOG(1) << "\n Function name: " << function_name |
| 1122 << "\n State: " << state_string; | 1124 << "\n State: " << state_string; |
| 1123 } | 1125 } |
| 1124 | 1126 |
| 1125 void TouchExplorationController::VlogEvent(const ui::TouchEvent& touch_event, | 1127 void TouchExplorationController::VlogEvent(const ui::TouchEvent& touch_event, |
| 1126 const char* function_name) { | 1128 const char* function_name) { |
| 1127 if (!VLOG_on_) | 1129 if (!VLOG_on_) |
| 1128 return; | 1130 return; |
| 1129 | 1131 |
| 1130 if (prev_event_ && prev_event_->type() == touch_event.type() && | 1132 if (prev_event_ && prev_event_->type() == touch_event.type() && |
| 1131 prev_event_->touch_id() == touch_event.touch_id()) { | 1133 prev_event_->touch_id() == touch_event.touch_id()) { |
| 1132 return; | 1134 return; |
| 1133 } | 1135 } |
| 1134 // The above statement prevents events of the same type and id from being | 1136 // The above statement prevents events of the same type and id from being |
| 1135 // printed in a row. However, if two fingers are down, they would both be | 1137 // printed in a row. However, if two fingers are down, they would both be |
| 1136 // moving and alternating printing move events unless we check for this. | 1138 // moving and alternating printing move events unless we check for this. |
| 1137 if (prev_event_ && prev_event_->type() == ET_TOUCH_MOVED && | 1139 if (prev_event_ && prev_event_->type() == ET_TOUCH_MOVED && |
| 1138 touch_event.type() == ET_TOUCH_MOVED) { | 1140 touch_event.type() == ET_TOUCH_MOVED) { |
| 1139 return; | 1141 return; |
| 1140 } | 1142 } |
| 1141 | 1143 |
| 1142 const std::string& type = touch_event.name(); | 1144 const std::string& type = touch_event.name(); |
| 1143 const gfx::PointF& location = touch_event.location_f(); | 1145 const gfx::PointF& location = touch_event.location_f(); |
| 1144 const int touch_id = touch_event.touch_id(); | 1146 const int touch_id = touch_event.touch_id(); |
| 1145 | 1147 |
| 1146 VLOG(0) << "\n Function name: " << function_name | 1148 VLOG(1) << "\n Function name: " << function_name << "\n Event Type: " << type |
| 1147 << "\n Event Type: " << type | |
| 1148 << "\n Location: " << location.ToString() | 1149 << "\n Location: " << location.ToString() |
| 1149 << "\n Touch ID: " << touch_id; | 1150 << "\n Touch ID: " << touch_id; |
| 1150 prev_event_.reset(new TouchEvent(touch_event)); | 1151 prev_event_.reset(new TouchEvent(touch_event)); |
| 1151 } | 1152 } |
| 1152 | 1153 |
| 1153 const char* TouchExplorationController::EnumStateToString(State state) { | 1154 const char* TouchExplorationController::EnumStateToString(State state) { |
| 1154 switch (state) { | 1155 switch (state) { |
| 1155 case NO_FINGERS_DOWN: | 1156 case NO_FINGERS_DOWN: |
| 1156 return "NO_FINGERS_DOWN"; | 1157 return "NO_FINGERS_DOWN"; |
| 1157 case SINGLE_TAP_PRESSED: | 1158 case SINGLE_TAP_PRESSED: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1182 return "TWO_FINGER_TAP"; | 1183 return "TWO_FINGER_TAP"; |
| 1183 } | 1184 } |
| 1184 return "Not a state"; | 1185 return "Not a state"; |
| 1185 } | 1186 } |
| 1186 | 1187 |
| 1187 float TouchExplorationController::GetSplitTapTouchSlop() { | 1188 float TouchExplorationController::GetSplitTapTouchSlop() { |
| 1188 return gesture_detector_config_.touch_slop * 3; | 1189 return gesture_detector_config_.touch_slop * 3; |
| 1189 } | 1190 } |
| 1190 | 1191 |
| 1191 } // namespace ui | 1192 } // namespace ui |
| OLD | NEW |