Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: ui/views/touchui/touch_selection_controller_impl_unittest.cc

Issue 1947123003: Fixes a crash which occurs when a concealed selection handle in a textfield is exposed. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@touch_devices_crash
Patch Set: Fixing the unit test on Windows - start the selection at 0, so that the drag doesn't overshoot. Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/views/touchui/touch_selection_controller_impl.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 <stddef.h> 5 #include <stddef.h>
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/macros.h" 8 #include "base/macros.h"
9 #include "base/strings/utf_string_conversions.h" 9 #include "base/strings/utf_string_conversions.h"
10 #include "ui/aura/client/screen_position_client.h" 10 #include "ui/aura/client/screen_position_client.h"
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 grip_location.x(), grip_location.y(), 0, time_stamp, details); 174 grip_location.x(), grip_location.y(), 0, time_stamp, details);
175 handle->OnGestureEvent(&scroll_end); 175 handle->OnGestureEvent(&scroll_end);
176 } 176 }
177 test_cursor_client_->EnableMouseEvents(); 177 test_cursor_client_->EnableMouseEvents();
178 } 178 }
179 179
180 gfx::NativeView GetCursorHandleNativeView() { 180 gfx::NativeView GetCursorHandleNativeView() {
181 return GetSelectionController()->GetCursorHandleNativeView(); 181 return GetSelectionController()->GetCursorHandleNativeView();
182 } 182 }
183 183
184 ui::SelectionBound::Type GetSelectionHandle1Type() {
185 return GetSelectionController()->GetSelectionHandle1Type();
186 }
187
184 gfx::Rect GetSelectionHandle1Bounds() { 188 gfx::Rect GetSelectionHandle1Bounds() {
185 return GetSelectionController()->GetSelectionHandle1Bounds(); 189 return GetSelectionController()->GetSelectionHandle1Bounds();
186 } 190 }
187 191
188 gfx::Rect GetSelectionHandle2Bounds() { 192 gfx::Rect GetSelectionHandle2Bounds() {
189 return GetSelectionController()->GetSelectionHandle2Bounds(); 193 return GetSelectionController()->GetSelectionHandle2Bounds();
190 } 194 }
191 195
192 gfx::Rect GetCursorHandleBounds() { 196 gfx::Rect GetCursorHandleBounds() {
193 return GetSelectionController()->GetCursorHandleBounds(); 197 return GetSelectionController()->GetCursorHandleBounds();
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } else if (CompareTextSelectionBounds(anchor, focus) > 0) { 266 } else if (CompareTextSelectionBounds(anchor, focus) > 0) {
263 EXPECT_EQ(ui::SelectionBound::LEFT, focus.type()) << from_str; 267 EXPECT_EQ(ui::SelectionBound::LEFT, focus.type()) << from_str;
264 EXPECT_EQ(ui::SelectionBound::RIGHT, anchor.type()) << from_str; 268 EXPECT_EQ(ui::SelectionBound::RIGHT, anchor.type()) << from_str;
265 } else { 269 } else {
266 EXPECT_EQ(ui::SelectionBound::CENTER, focus.type()) << from_str; 270 EXPECT_EQ(ui::SelectionBound::CENTER, focus.type()) << from_str;
267 EXPECT_EQ(ui::SelectionBound::CENTER, anchor.type()) << from_str; 271 EXPECT_EQ(ui::SelectionBound::CENTER, anchor.type()) << from_str;
268 } 272 }
269 } 273 }
270 } 274 }
271 275
276 // Sets up a textfield with a long text string such that it doesn't all fit
277 // into the textfield. Then selects the text - the first handle is expected
278 // to be invisible. |selection_start| is the position of the first handle.
279 void SetupSelectionInvisibleHandle(uint32_t selection_start) {
280 // Create a textfield with lots of text in it.
281 CreateTextfield();
282 std::string some_text("some text");
283 std::string textfield_text;
284 for (int i = 0; i < 10; ++i)
285 textfield_text += some_text;
286 textfield_->SetText(ASCIIToUTF16(textfield_text));
287
288 // Tap the textfield to invoke selection.
289 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
290 details.set_tap_count(1);
291 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
292 textfield_->OnGestureEvent(&tap);
293
294 // Select some text such that one handle is hidden.
295 textfield_->SelectRange(gfx::Range(
296 selection_start, static_cast<uint32_t>(textfield_text.length())));
297
298 // Check that one selection handle is hidden.
299 EXPECT_FALSE(IsSelectionHandle1Visible());
300 EXPECT_TRUE(IsSelectionHandle2Visible());
301 EXPECT_EQ(gfx::Range(selection_start,
302 static_cast<uint32_t>(textfield_text.length())),
303 textfield_->GetSelectedRange());
304 }
305
272 Widget* textfield_widget_; 306 Widget* textfield_widget_;
273 Widget* widget_; 307 Widget* widget_;
274 308
275 Textfield* textfield_; 309 Textfield* textfield_;
276 std::unique_ptr<TextfieldTestApi> textfield_test_api_; 310 std::unique_ptr<TextfieldTestApi> textfield_test_api_;
277 std::unique_ptr<ViewsTouchEditingControllerFactory> views_tsc_factory_; 311 std::unique_ptr<ViewsTouchEditingControllerFactory> views_tsc_factory_;
278 std::unique_ptr<aura::test::TestCursorClient> test_cursor_client_; 312 std::unique_ptr<aura::test::TestCursorClient> test_cursor_client_;
279 313
280 private: 314 private:
281 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest); 315 DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerImplTest);
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 566
533 // Drag selection handle 2 to right by 1 char. 567 // Drag selection handle 2 to right by 1 char.
534 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list); 568 x = gfx::Canvas::GetStringWidth(WideToUTF16(L"\x05e2"), font_list);
535 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2); 569 SimulateSelectionHandleDrag(gfx::Vector2d(x, 0), 2);
536 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText()); 570 EXPECT_EQ(WideToUTF16(L"c\x05e1"), textfield_->GetSelectedText());
537 VerifyHandlePositions(false, false, FROM_HERE); 571 VerifyHandlePositions(false, false, FROM_HERE);
538 } 572 }
539 573
540 TEST_F(TouchSelectionControllerImplTest, 574 TEST_F(TouchSelectionControllerImplTest,
541 HiddenSelectionHandleRetainsCursorPosition) { 575 HiddenSelectionHandleRetainsCursorPosition) {
542 // Create a textfield with lots of text in it. 576 static const uint32_t selection_start = 10u;
543 CreateTextfield(); 577 SetupSelectionInvisibleHandle(selection_start);
544 std::string textfield_text("some text");
545 for (int i = 0; i < 10; ++i)
546 textfield_text += textfield_text;
547 textfield_->SetText(ASCIIToUTF16(textfield_text));
548
549 // Tap the textfield to invoke selection.
550 ui::GestureEventDetails details(ui::ET_GESTURE_TAP);
551 details.set_tap_count(1);
552 ui::GestureEvent tap(0, 0, 0, base::TimeDelta(), details);
553 textfield_->OnGestureEvent(&tap);
554
555 // Select some text such that one handle is hidden.
556 textfield_->SelectRange(
557 gfx::Range(10u, static_cast<uint32_t>(textfield_text.length())));
558
559 // Check that one selection handle is hidden.
560 EXPECT_FALSE(IsSelectionHandle1Visible());
561 EXPECT_TRUE(IsSelectionHandle2Visible());
562 EXPECT_EQ(
563 gfx::Range(10u, static_cast<uint32_t>(textfield_text.length())),
564 textfield_->GetSelectedRange());
565 578
566 // Drag the visible handle around and make sure the selection end point of the 579 // Drag the visible handle around and make sure the selection end point of the
567 // invisible handle does not change. 580 // invisible handle does not change.
568 size_t visible_handle_position = textfield_->GetSelectedRange().end(); 581 size_t visible_handle_position = textfield_->GetSelectedRange().end();
569 for (int i = 0; i < 10; ++i) { 582 for (int i = 0; i < 10; ++i) {
570 static const int drag_diff = -10; 583 static const int drag_diff = -10;
571 SimulateSelectionHandleDrag(gfx::Vector2d(drag_diff, 0), 2); 584 SimulateSelectionHandleDrag(gfx::Vector2d(drag_diff, 0), 2);
572 // Make sure that the visible handle is being dragged. 585 // Make sure that the visible handle is being dragged.
573 EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end()); 586 EXPECT_NE(visible_handle_position, textfield_->GetSelectedRange().end());
574 visible_handle_position = textfield_->GetSelectedRange().end(); 587 visible_handle_position = textfield_->GetSelectedRange().end();
575 EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start()); 588 EXPECT_EQ((size_t) 10, textfield_->GetSelectedRange().start());
576 } 589 }
577 } 590 }
578 591
592 // Tests that we can handle the hidden handle getting exposed as a result of a
593 // drag and that it maintains the correct orientation when exposed.
594 TEST_F(TouchSelectionControllerImplTest, HiddenSelectionHandleExposed) {
595 static const uint32_t selection_start = 0u;
596 SetupSelectionInvisibleHandle(selection_start);
597
598 // Drag the handle until the selection shrinks such that the other handle
599 // becomes visible.
600 while (!IsSelectionHandle1Visible()) {
601 static const int drag_diff = -10;
602 SimulateSelectionHandleDrag(gfx::Vector2d(drag_diff, 0), 2);
603 }
604
605 // Confirm that the exposed handle maintains the LEFT orientation
606 // (and does not reset to ui::SelectionBound::Type::CENTER).
607 EXPECT_EQ(ui::SelectionBound::Type::LEFT, GetSelectionHandle1Type());
608 }
609
579 TEST_F(TouchSelectionControllerImplTest, 610 TEST_F(TouchSelectionControllerImplTest,
580 DoubleTapInTextfieldWithCursorHandleShouldSelectText) { 611 DoubleTapInTextfieldWithCursorHandleShouldSelectText) {
581 CreateTextfield(); 612 CreateTextfield();
582 textfield_->SetText(ASCIIToUTF16("some text")); 613 textfield_->SetText(ASCIIToUTF16("some text"));
583 ui::test::EventGenerator generator( 614 ui::test::EventGenerator generator(
584 textfield_->GetWidget()->GetNativeView()->GetRootWindow()); 615 textfield_->GetWidget()->GetNativeView()->GetRootWindow());
585 616
586 // Tap the textfield to invoke touch selection. 617 // Tap the textfield to invoke touch selection.
587 generator.GestureTapAt(gfx::Point(10, 10)); 618 generator.GestureTapAt(gfx::Point(10, 10));
588 619
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 // Start touch editing; then press a key and ensure it deactivates touch 869 // Start touch editing; then press a key and ensure it deactivates touch
839 // selection. 870 // selection.
840 StartTouchEditing(); 871 StartTouchEditing();
841 EXPECT_TRUE(GetSelectionController()); 872 EXPECT_TRUE(GetSelectionController());
842 generator.PressKey(ui::VKEY_A, 0); 873 generator.PressKey(ui::VKEY_A, 0);
843 RunPendingMessages(); 874 RunPendingMessages();
844 EXPECT_FALSE(GetSelectionController()); 875 EXPECT_FALSE(GetSelectionController());
845 } 876 }
846 877
847 } // namespace views 878 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/touchui/touch_selection_controller_impl.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698