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

Side by Side Diff: ui/base/ime/android/cursor_anchor_info_controller_unittest.cc

Issue 643193003: Support InputMethodManager#updateCursorAnchorInfo for Android 5.0 (C++ version) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Send ImeCompositionRangeChanged only when necessary Created 5 years, 10 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
OLDNEW
(Empty)
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/ime/android/cursor_anchor_info_controller.h"
6
7 #include "base/strings/utf_string_conversions.h"
8 #include "base/tuple.h"
9 #include "cc/output/compositor_frame_metadata.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11 #include "ui/base/ime/android/cursor_anchor_info_builder.h"
12 #include "ui/base/ime/android/cursor_anchor_info_sender.h"
13
14 namespace ui {
15 namespace {
16
17 using ::testing::AssertionFailure;
18 using ::testing::AssertionResult;
19 using ::testing::AssertionSuccess;
20 using ::testing::FloatLE;
21
22 const uint32 kFlagHasVisibleRegion =
23 CursorAnchorInfoBuilder::kFlagHasVisibleRegion;
24 const uint32 kFlagHasInvisibleRegion =
25 CursorAnchorInfoBuilder::kFlagHasInvisibleRegion;
26
27 const uint32 kCursorUpdateModeImmediate =
28 CursorAnchorInfoController::kCursorUpdateModeImmediate;
29 const uint32 kCursorUpdateModeMonitor =
30 CursorAnchorInfoController::kCursorUpdateModeMonitor;
31
32 template <typename T>
33 std::vector<T> Vec() {
34 return std::vector<T>();
35 }
36
37 template <typename T>
38 std::vector<T> Vec(const T& param1) {
39 std::vector<T> result;
40 result.push_back(param1);
41 return result;
42 }
43
44 template <typename T>
45 std::vector<T> Vec(const T& param1, const T& param2) {
46 std::vector<T> result;
47 result.push_back(param1);
48 result.push_back(param2);
49 return result;
50 }
51
52 template <typename T>
53 std::vector<T> Vec(const T& param1, const T& param2, const T& param3) {
54 std::vector<T> result;
55 result.push_back(param1);
56 result.push_back(param2);
57 result.push_back(param3);
58 return result;
59 }
60
61 typedef Tuple<int, base::string16> SetComposingTextParams;
62 typedef Tuple<int, gfx::RectF, uint32> AddCharacterBoundsParams;
63 typedef Tuple<float, float, float, float, uint32>
64 SetInsertionMarkerLocationParams;
65 typedef Tuple<float, gfx::Vector2dF> SetScaleAndTranslateParams;
66 typedef Tuple<gfx::Range> SetSelectionRangeParams;
67
68 class CursorAnchorInfoBuilderMock final
69 : public CursorAnchorInfoBuilder {
70 public:
71
72 CursorAnchorInfoBuilderMock()
73 : build_count_(0),
74 reset_count_(0) {
75 }
76
77 ~CursorAnchorInfoBuilderMock() override {
78 }
79
80 void AddCharacterBounds(int index,
81 const gfx::RectF& rect,
82 uint32 flags) override {
83 add_character_bounds_call_log_.push_back(MakeTuple(index, rect, flags));
84 }
85
86 base::android::ScopedJavaLocalRef<jobject> Build() override {
87 ++build_count_;
88 return base::android::ScopedJavaLocalRef<jobject>();
89 }
90
91 void Reset() override {
92 ++reset_count_;
93 }
94
95 void SetComposingText(int composing_text_start,
96 base::StringPiece16 composing_text) override {
97 set_composing_text_call_log_.push_back(
98 MakeTuple(composing_text_start,
99 composing_text.as_string()));
100 }
101
102 void SetInsertionMarkerLocation(float horizontal_position,
103 float line_top,
104 float line_baseline,
105 float line_bottom,
106 uint32 flags) override {
107 set_insertion_marker_location_call_log_.push_back(MakeTuple(
108 horizontal_position, line_top, line_baseline, line_bottom, flags));
109 }
110
111 void SetScaleAndTranslate(float scale,
112 const gfx::Vector2dF& translate) override {
113 set_scale_and_translate_call_log_.push_back(MakeTuple(
114 scale, translate));
115 }
116
117 void SetSelectionRange(const gfx::Range& range) override {
118 set_selection_range_call_log_.push_back(MakeTuple(range));
119 }
120
121 size_t build_count() const {
122 return build_count_;
123 }
124
125 size_t reset_count() const {
126 return reset_count_;
127 }
128
129 const std::vector<SetComposingTextParams>&
130 set_composing_text_call_log() const {
131 return set_composing_text_call_log_;
132 }
133
134 const std::vector<SetInsertionMarkerLocationParams>&
135 set_insertion_marker_location_call_log() const {
136 return set_insertion_marker_location_call_log_;
137 }
138
139 const std::vector<SetScaleAndTranslateParams>&
140 set_scale_and_translate_call_log() const {
141 return set_scale_and_translate_call_log_;
142 }
143
144 const std::vector<AddCharacterBoundsParams>&
145 add_character_bounds_call_log() const {
146 return add_character_bounds_call_log_;
147 }
148
149 const std::vector<SetSelectionRangeParams>&
150 set_selection_range_call_log() const {
151 return set_selection_range_call_log_;
152 }
153
154 private:
155 size_t build_count_;
156 size_t reset_count_;
157 std::vector<SetComposingTextParams> set_composing_text_call_log_;
158 std::vector<SetInsertionMarkerLocationParams>
159 set_insertion_marker_location_call_log_;
160 std::vector<SetScaleAndTranslateParams> set_scale_and_translate_call_log_;
161 std::vector<AddCharacterBoundsParams> add_character_bounds_call_log_;
162 std::vector<SetSelectionRangeParams> set_selection_range_call_log_;
163
164 DISALLOW_COPY_AND_ASSIGN(CursorAnchorInfoBuilderMock);
165 };
166
167 class CursorAnchorInfoSenderMock final
168 : public CursorAnchorInfoSender {
169 public:
170
171 CursorAnchorInfoSenderMock()
172 : send_count_(0) {
173 }
174
175 ~CursorAnchorInfoSenderMock() override {
176 }
177
178 void SendCursorAnchorInfo(ui::CursorAnchorInfoBuilder* builder) override {
179 ++send_count_;
180 }
181
182 size_t send_count() const {
183 return send_count_;
184 }
185
186 private:
187 size_t send_count_;
188
189 DISALLOW_COPY_AND_ASSIGN(CursorAnchorInfoSenderMock);
190 };
191
192 enum UpdateControllerType {
193 kCallOnTextInputStateChanged = 1 << 0,
194 kCallOnCompositionRangeChanged = 1 << 1,
195 kCallOnFrameMetadataUpdated = 1 << 2,
196 };
197
198 cc::ViewportSelectionBound CreateViewportSelectionBoundForTest(
199 cc::SelectionBoundType type,
200 const gfx::PointF& edge_top,
201 const gfx::PointF& edge_bottom,
202 bool visible) {
203 cc::ViewportSelectionBound selection_bound;
204 selection_bound.type = type;
205 selection_bound.edge_top = edge_top;
206 selection_bound.edge_bottom = edge_bottom;
207 selection_bound.visible = visible;
208 return selection_bound;
209 }
210
211 cc::CompositorFrameMetadata CreateFrameMetadataForTest(
212 float device_scale_factor,
213 const gfx::Vector2dF& root_scroll_offset,
214 float page_scale_factor,
215 const gfx::Vector2dF& location_bar_offset,
216 const gfx::Vector2dF& location_bar_content_translation,
217 const cc::ViewportSelectionBound& selection_start) {
218 cc::CompositorFrameMetadata frame_metadata;
219 frame_metadata.device_scale_factor = device_scale_factor;
220 frame_metadata.root_scroll_offset = root_scroll_offset;
221 frame_metadata.page_scale_factor = page_scale_factor;
222 frame_metadata.location_bar_offset = location_bar_offset;
223 frame_metadata.location_bar_content_translation =
224 location_bar_content_translation;
225 frame_metadata.selection_start = selection_start;
226 return frame_metadata;
227 }
228
229 void UpdateController(CursorAnchorInfoController* controller,
230 int update_type,
231 int salt) {
232 if ((update_type & kCallOnTextInputStateChanged) != 0) {
233 const base::string16 kDummyText = base::ASCIIToUTF16("0123456789");
234 const gfx::Range kDummySelectionRange(0, salt);
235 const gfx::Range kDummyCompositionRange(3, 5);
236 controller->OnTextInputStateChanged(kDummyText,
237 kDummySelectionRange,
238 kDummyCompositionRange);
239 }
240
241 if ((update_type & kCallOnCompositionRangeChanged) != 0) {
242 const gfx::Range kDummyRange(0, salt);
243 std::vector<gfx::Rect> dummyCompositionRects;
244 dummyCompositionRects.push_back(gfx::Rect(10, 3, 5, 8));
245 dummyCompositionRects.push_back(gfx::Rect(15, 3, 5, 8));
246 controller->OnCompositionRangeChanged(kDummyRange, dummyCompositionRects);
247 }
248
249 if ((update_type & kCallOnFrameMetadataUpdated) != 0) {
250 const auto selection_start = CreateViewportSelectionBoundForTest(
251 cc::SELECTION_BOUND_CENTER,
252 gfx::PointF(240.0f, 41.0f),
253 gfx::PointF(240.0f, 64.0f),
254 true);
255 const cc::CompositorFrameMetadata dummy_frame_metadata =
256 CreateFrameMetadataForTest(
257 2.0f,
258 gfx::Vector2dF(0.0f, 0.0f),
259 1.0f,
260 gfx::Vector2dF(0.0f, 0.0f),
261 gfx::Vector2dF(0.0f, 0.0f),
262 selection_start);
263 const gfx::Vector2d kDummyViewOriginOffset(0, salt);
264 controller->OnFrameMetadataUpdated(dummy_frame_metadata,
265 kDummyViewOriginOffset);
266 }
267 }
268
269 bool FloatAlmostEqual(float a, float b) {
270 return FloatLE("a", "b", a, b) && FloatLE("b", "a", b, a);
271 }
272
273 AssertionResult AssertSetInsertionMarkerLocation(
274 const std::vector<SetInsertionMarkerLocationParams>& expected_call_log,
275 const cc::ViewportSelectionBound& selection_start) {
276
277 CursorAnchorInfoSenderMock sender_mock;
278 // This object will be owned by |controller|.
279 CursorAnchorInfoBuilderMock* builder_mock = new CursorAnchorInfoBuilderMock;
280 auto controller = CursorAnchorInfoController::CreateForTest(
281 &sender_mock,
282 scoped_ptr<CursorAnchorInfoBuilder>(builder_mock));
283 // Mark as editable.
284 controller->OnFocusedNodeChanged(true);
285
286 // Enable monitor.
287 controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor);
288
289 controller->OnFrameMetadataUpdated(
290 CreateFrameMetadataForTest(
291 1.0f,
292 gfx::Vector2dF(0.0f, 0.0f),
293 1.0f,
294 gfx::Vector2dF(0.0f, 0.0f),
295 gfx::Vector2dF(0.0f, 0.0f),
296 selection_start),
297 gfx::Vector2d(0, 0));
298
299 const auto& actual_call_log =
300 builder_mock->set_insertion_marker_location_call_log();
301 if (expected_call_log.size() != actual_call_log.size()) {
302 return AssertionFailure()
303 << "Call count of SetInsertionMarkerLocation is unexpected."
304 << "\nExpected call count: " << expected_call_log.size()
305 << "\n Actual call count: " << actual_call_log.size();
306 }
307
308 for (size_t i = 0; i < expected_call_log.size(); ++i) {
309 const auto& expected = expected_call_log[i];
310 const auto& actual = actual_call_log[i];
311 if (!FloatAlmostEqual(get<0>(expected), get<0>(actual))) {
312 return AssertionFailure()
313 << "SetInsertionMarkerLocation is called with an unexpected "
314 << "parameter."
315 << "\n parameter: horizontal_position"
316 << "\n expected: " << get<0>(expected)
317 << "\n actual: " << get<0>(actual);
318 }
319 if (!FloatAlmostEqual(get<1>(expected), get<1>(actual))) {
320 return AssertionFailure()
321 << "SetInsertionMarkerLocation is called with an unexpected "
322 << "parameter."
323 << "\n parameter: line_top"
324 << "\n expected: " << get<1>(expected)
325 << "\n actual: " << get<1>(actual);
326 }
327 if (!FloatAlmostEqual(get<2>(expected), get<2>(actual))) {
328 return AssertionFailure()
329 << "SetInsertionMarkerLocation is called with an unexpected "
330 << "parameter."
331 << "\n parameter: line_baseline"
332 << "\n expected: " << get<2>(expected)
333 << "\n actual: " << get<2>(actual);
334 }
335 if (!FloatAlmostEqual(get<3>(expected), get<3>(actual))) {
336 return AssertionFailure()
337 << "SetInsertionMarkerLocation is called with an unexpected parameter."
338 << "\n parameter: line_bottom"
339 << "\n expected: " << get<3>(expected)
340 << "\n actual: " << get<3>(actual);
341 }
342 if (get<4>(expected) != get<4>(actual)) {
343 return AssertionFailure()
344 << "SetInsertionMarkerLocation is called with an unexpected "
345 << "parameter."
346 << "\n parameter: flags"
347 << "\n expected: " << get<4>(expected)
348 << "\n actual: " << get<4>(actual);
349 }
350 }
351 return AssertionSuccess();
352 }
353
354 AssertionResult AssertSetScaleAndTranslate(
355 float expected_scale,
356 const gfx::Vector2dF& expected_translate,
357 const cc::CompositorFrameMetadata& frame_metadata,
358 const gfx::Vector2d& view_origin_offset) {
359 CursorAnchorInfoSenderMock sender_mock;
360 // This object will be owned by |controller|.
361 CursorAnchorInfoBuilderMock* builder_mock = new CursorAnchorInfoBuilderMock;
362 auto controller = CursorAnchorInfoController::CreateForTest(
363 &sender_mock,
364 scoped_ptr<CursorAnchorInfoBuilder>(builder_mock));
365
366 controller->OnFocusedNodeChanged(true);
367 controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor);
368
369 controller->OnFrameMetadataUpdated(frame_metadata, view_origin_offset);
370
371 const auto& log = builder_mock->set_scale_and_translate_call_log();
372 if (log.size() != 1) {
373 return AssertionFailure()
374 << "SetScaleAndTranslate is not called just once. "
375 << "Actual call count: " << log.size();
376 }
377
378 const float actual_scale = get<0>(log[0]);
379 if (!FloatAlmostEqual(expected_scale, actual_scale)) {
380 return AssertionFailure()
381 << "SetScaleAndTranslate is called with an unexpected parameter."
382 << "\n parameter: scale"
383 << "\n expected: " << expected_scale
384 << "\n actual: " << get<0>(log[0]);
385 }
386
387 const auto& actual_translate = get<1>(log[0]);
388 if (!FloatAlmostEqual(expected_translate.x(), actual_translate.x()) ||
389 !FloatAlmostEqual(expected_translate.y(), actual_translate.y())) {
390 return AssertionFailure()
391 << "SetScaleAndTranslate is called with an unexpected parameter."
392 << "\n parameter: translate"
393 << "\n expected: " << expected_translate.ToString()
394 << "\n actual: " << actual_translate.ToString();
395 }
396
397 return AssertionSuccess();
398 }
399
400 AssertionResult AssertOnTextInputStateChanged(
401 const std::vector<SetSelectionRangeParams>&
402 expected_set_selection_range_call_log,
403 const std::vector<SetComposingTextParams>&
404 expected_set_composing_text_call_log,
405 const base::string16& actual_text,
406 const gfx::Range& actual_selection_range,
407 const gfx::Range& actual_composition_range) {
408 CursorAnchorInfoSenderMock sender_mock;
409 // This object will be owned by |controller|.
410 CursorAnchorInfoBuilderMock* builder_mock = new CursorAnchorInfoBuilderMock;
411 auto controller = CursorAnchorInfoController::CreateForTest(
412 &sender_mock,
413 scoped_ptr<CursorAnchorInfoBuilder>(builder_mock));
414
415 controller->OnFocusedNodeChanged(true);
416 controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor);
417
418 controller->OnTextInputStateChanged(actual_text,
419 actual_selection_range,
420 actual_composition_range);
421 // Calling OnFrameMetadataUpdated is mandatory to build an object.
422 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, 0);
423
424 {
425 const auto& expected_call_log = expected_set_selection_range_call_log;
426 const auto& actual_call_log = builder_mock->set_selection_range_call_log();
427 if (expected_call_log.size() != actual_call_log.size()) {
428 return AssertionFailure()
429 << "Call count of SetSelectionRange is unexpected."
430 << "\nExpected call count: " << expected_call_log.size()
431 << "\n Actual call count: " << actual_call_log.size();
432 }
433
434 for (size_t i = 0; i < expected_call_log.size(); ++i) {
435 const auto& expected = expected_call_log[i];
436 const auto& actual = actual_call_log[i];
437 if (get<0>(expected) != get<0>(actual)) {
438 return AssertionFailure()
439 << "SetSelectionRange is called with an unexpected parameter."
440 << "\n parameter: range"
441 << "\n expected: " << get<0>(expected)
442 << "\n actual: " << get<0>(actual);
443 }
444 }
445 }
446
447 {
448 const auto& expected_call_log = expected_set_composing_text_call_log;
449 const auto& actual_call_log = builder_mock->set_composing_text_call_log();
450 if (expected_call_log.size() != actual_call_log.size()) {
451 return AssertionFailure()
452 << "Call count of SetComposingText is unexpected."
453 << "\nExpected call count: " << expected_call_log.size()
454 << "\n Actual call count: " << actual_call_log.size();
455 }
456
457 for (size_t i = 0; i < expected_call_log.size(); ++i) {
458 const auto& expected = expected_call_log[i];
459 const auto& actual = actual_call_log[i];
460 if (get<0>(expected) != get<0>(actual)) {
461 return AssertionFailure()
462 << "SetComposingText is called with an unexpected parameter."
463 << "\n parameter: range"
464 << "\n expected: " << get<0>(expected)
465 << "\n actual: " << get<0>(actual);
466 }
467 if (get<1>(expected) != get<1>(actual)) {
468 return AssertionFailure()
469 << "SetComposingText is called with an unexpected parameter."
470 << "\n parameter: range"
471 << "\n expected: " << get<1>(expected)
472 << "\n actual: " << get<1>(actual);
473 }
474 }
475 }
476
477 return AssertionSuccess();
478 }
479
480 AssertionResult AssertOnCompositionRangeChanged(
481 const std::vector<AddCharacterBoundsParams>& expected_call_log,
482 const gfx::Range& actual_range,
483 const std::vector<gfx::Rect>& actual_character_bounds) {
484
485 CursorAnchorInfoSenderMock sender_mock;
486 // This object will be owned by |controller|.
487 CursorAnchorInfoBuilderMock* builder_mock = new CursorAnchorInfoBuilderMock;
488 auto controller = CursorAnchorInfoController::CreateForTest(
489 &sender_mock,
490 scoped_ptr<CursorAnchorInfoBuilder>(builder_mock));
491
492 controller->OnFocusedNodeChanged(true);
493 controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor);
494
495 controller->OnCompositionRangeChanged(actual_range, actual_character_bounds);
496
497 // Calling OnFrameMetadataUpdated is mandatory to build an object.
498 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, 0);
499
500 {
501 const auto& actual_call_log = builder_mock->add_character_bounds_call_log();
502 if (expected_call_log.size() != actual_call_log.size()) {
503 return AssertionFailure()
504 << "Call count of AddCharacterBounds is unexpected."
505 << "\nExpected call count: " << expected_call_log.size()
506 << "\n Actual call count: " << actual_call_log.size();
507 }
508
509 for (size_t i = 0; i < expected_call_log.size(); ++i) {
510 const auto& expected = expected_call_log[i];
511 const auto& actual = actual_call_log[i];
512 if (get<0>(expected) != get<0>(actual)) {
513 return AssertionFailure()
514 << "AddCharacterBounds is called with an unexpected parameter."
515 << "\n parameter: index"
516 << "\n expected: " << get<0>(expected)
517 << "\n actual: " << get<0>(actual);
518 }
519 if (get<1>(expected) != get<1>(actual)) {
520 return AssertionFailure()
521 << "AddCharacterBounds is called with an unexpected parameter."
522 << "\n parameter: rect"
523 << "\n expected: " << get<1>(expected).ToString()
524 << "\n actual: " << get<1>(actual).ToString();
525 }
526 if (get<2>(expected) != get<2>(actual)) {
527 return AssertionFailure()
528 << "AddCharacterBounds is called with an unexpected parameter."
529 << "\n parameter: flags"
530 << "\n expected: " << get<2>(expected)
531 << "\n actual: " << get<2>(actual);
532 }
533 }
534
535 }
536
537 return AssertionSuccess();
538 }
539
540 /////////////////////////////////////////////////////
541
542 TEST(CursorAnchorInfoControllerTest, OnFocusedNodeChanged) {
543 CursorAnchorInfoSenderMock sender_mock;
544 // This object will be owned by |controller|.
545 CursorAnchorInfoBuilderMock* builder_mock = new CursorAnchorInfoBuilderMock;
546 auto controller = CursorAnchorInfoController::CreateForTest(
547 &sender_mock,
548 scoped_ptr<CursorAnchorInfoBuilder>(builder_mock));
549
550 // Check the initial state.
551 ASSERT_EQ(0u, sender_mock.send_count());
552
553 ASSERT_TRUE(controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor));
554
555 int salt = 0;
556 ASSERT_EQ(0u, sender_mock.send_count())
557 << "Data must not be sent when the node is not editable.";
558 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
559 ASSERT_EQ(0u, sender_mock.send_count())
560 << "Data must not be sent when the node is not editable.";
561
562 controller->OnFocusedNodeChanged(true);
563
564 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
565 ASSERT_EQ(1u, sender_mock.send_count())
566 << "Data can be sent when the node is editable.";
567
568 controller->OnFocusedNodeChanged(false);
569 ASSERT_TRUE(controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor));
570
571 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
572 ASSERT_EQ(1u, sender_mock.send_count())
573 << "Data must not be sent when the node is not editable.";
574
575 controller->OnFocusedNodeChanged(true);
576 ASSERT_TRUE(controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor));
577
578 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
579 ASSERT_EQ(2u, sender_mock.send_count()) <<
580 "Data must be sent even with the same data (derived from the same salt)"
581 " because OnFocusedNodeChanged resets internal state.";
582 }
583
584 TEST(CursorAnchorInfoControllerTest, CursorUpdateModeImmediate) {
585 CursorAnchorInfoSenderMock sender_mock;
586 // This object will be owned by |controller|.
587 CursorAnchorInfoBuilderMock* builder_mock = new CursorAnchorInfoBuilderMock;
588 auto controller = CursorAnchorInfoController::CreateForTest(
589 &sender_mock,
590 scoped_ptr<CursorAnchorInfoBuilder>(builder_mock));
591 controller->OnFocusedNodeChanged(true);
592
593 // Check the initial state.
594 ASSERT_EQ(0u, sender_mock.send_count());
595
596 int salt = 0;
597
598 ASSERT_TRUE(controller->OnRequestCursorUpdates(kCursorUpdateModeImmediate));
599 ASSERT_EQ(0u, sender_mock.send_count())
600 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
601 ++salt;
602 UpdateController(controller.get(), kCallOnTextInputStateChanged, salt);
603 ASSERT_EQ(0u, sender_mock.send_count())
604 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
605 ++salt;
606 UpdateController(controller.get(), kCallOnCompositionRangeChanged, salt);
607 ASSERT_EQ(0u, sender_mock.send_count())
608 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
609 ++salt;
610 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
611 ASSERT_EQ(1u, sender_mock.send_count())
612 << "Data must be sent from |OnFrameMetadataUpdated| when requested.";
613
614 ++salt;
615 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
616 ASSERT_EQ(1u, sender_mock.send_count())
617 << "Don't need to send data twice in the immediate mode.";
618 }
619
620 TEST(CursorAnchorInfoControllerTest, CursorUpdateModeMonitor) {
621 CursorAnchorInfoSenderMock sender_mock;
622 // This object will be owned by |controller|.
623 CursorAnchorInfoBuilderMock* builder_mock = new CursorAnchorInfoBuilderMock;
624 auto controller = CursorAnchorInfoController::CreateForTest(
625 &sender_mock,
626 scoped_ptr<CursorAnchorInfoBuilder>(builder_mock));
627 controller->OnFocusedNodeChanged(true);
628
629 // Check the initial state.
630 ASSERT_EQ(0u, sender_mock.send_count());
631
632 int frame_metadata_salt = 0;
633 int salt = 0;
634
635 // Test monitor mode:
636 ASSERT_TRUE(controller->OnRequestCursorUpdates(kCursorUpdateModeMonitor));
637 ASSERT_EQ(0u, sender_mock.send_count());
638
639 ++salt;
640 UpdateController(controller.get(), kCallOnTextInputStateChanged, salt);
641 ASSERT_EQ(0u, sender_mock.send_count())
642 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
643 ++salt;
644 UpdateController(controller.get(), kCallOnCompositionRangeChanged, salt);
645 ASSERT_EQ(0u, sender_mock.send_count())
646 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
647 ++salt;
648 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
649 ASSERT_EQ(1u, sender_mock.send_count())
650 << "Data must be sent from |OnFrameMetadataUpdated| when requested.";
651 frame_metadata_salt = salt;
652
653 UpdateController(controller.get(),
654 kCallOnFrameMetadataUpdated,
655 frame_metadata_salt);
656 ASSERT_EQ(1u, sender_mock.send_count())
657 << "Data must not be sent because no data is changed.";
658
659 ++salt;
660 UpdateController(controller.get(), kCallOnTextInputStateChanged, salt);
661 ASSERT_EQ(1u, sender_mock.send_count())
662 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
663 UpdateController(controller.get(),
664 kCallOnFrameMetadataUpdated,
665 frame_metadata_salt);
666 ASSERT_EQ(2u, sender_mock.send_count())
667 << "Data must be sent because |OnTextInputStateChanged| changed data.";
668 UpdateController(controller.get(), kCallOnTextInputStateChanged, salt);
669 ASSERT_EQ(2u, sender_mock.send_count())
670 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
671 UpdateController(controller.get(),
672 kCallOnFrameMetadataUpdated,
673 frame_metadata_salt);
674 ASSERT_EQ(2u, sender_mock.send_count())
675 << "Data must not be sent because no data is changed.";
676
677 ++salt;
678 UpdateController(controller.get(), kCallOnCompositionRangeChanged, salt);
679 ASSERT_EQ(2u, sender_mock.send_count())
680 << "Data must not be sent except for |OnFrameMetadataUpdated|.";
681 UpdateController(controller.get(),
682 kCallOnFrameMetadataUpdated,
683 frame_metadata_salt);
684 ASSERT_EQ(3u, sender_mock.send_count())
685 << "Data must be sent because |OnCompositionRangeChanged| changed data.";
686 UpdateController(controller.get(), kCallOnCompositionRangeChanged, salt);
687 UpdateController(controller.get(),
688 kCallOnFrameMetadataUpdated,
689 frame_metadata_salt);
690 ASSERT_EQ(3u, sender_mock.send_count())
691 << "Data must not be sent because no data is changed.";
692
693 // Test if we can turn off the monitor mode.
694 ASSERT_TRUE(controller->OnRequestCursorUpdates(0));
695
696 ++salt;
697 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
698 ASSERT_EQ(3u, sender_mock.send_count())
699 << "Data must not be sent because the monitor mode is turned off.";
700
701 // Test if we can turn on the monitor mode and immediate mode at the same
702 // time.
703 ASSERT_TRUE(controller->OnRequestCursorUpdates(
704 kCursorUpdateModeMonitor | kCursorUpdateModeImmediate));
705 ASSERT_EQ(4u, sender_mock.send_count())
706 << "Data must be sent because the immediate mode is requested.";
707
708 ++salt;
709 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
710 ASSERT_EQ(5u, sender_mock.send_count())
711 << "Data must be sent from |OnFrameMetadataUpdated| when requested.";
712
713
714 // Test if |OnFocusedNodeChanged(true)| resets the monitor mode.
715 controller->OnFocusedNodeChanged(true);
716
717 ++salt;
718 UpdateController(controller.get(), kCallOnFrameMetadataUpdated, salt);
719 ASSERT_EQ(6u, sender_mock.send_count())
720 << "Data must be sent because |Reset| doesn't reset the monitor "
721 << "mode";
722
723 }
724
725 TEST(CursorAnchorInfoControllerTest, SetInsertionMarkerLocation) {
726 // Case 1: The insertion marker is visible
727 EXPECT_TRUE(AssertSetInsertionMarkerLocation(
728 Vec(MakeTuple(3.0f, 4.0f, 14.0f, 14.0f, kFlagHasVisibleRegion)),
729 CreateViewportSelectionBoundForTest(
730 cc::SELECTION_BOUND_CENTER,
731 gfx::PointF(3.0f, 4.0f),
732 gfx::PointF(3.0f, 14.0f),
733 true)));
734
735 // Case 2: The insertion marker is invisible
736 EXPECT_TRUE(AssertSetInsertionMarkerLocation(
737 Vec(MakeTuple(3.0f, 4.0f, 14.0f, 14.0f, kFlagHasInvisibleRegion)),
738 CreateViewportSelectionBoundForTest(
739 cc::SELECTION_BOUND_CENTER,
740 gfx::PointF(3.0f, 4.0f),
741 gfx::PointF(3.0f, 14.0f),
742 false)));
743
744 // Case 3: No insertion marker
745 EXPECT_TRUE(AssertSetInsertionMarkerLocation(
746 Vec<SetInsertionMarkerLocationParams>(),
747 CreateViewportSelectionBoundForTest(
748 cc::SELECTION_BOUND_EMPTY,
749 gfx::PointF(0.0f, 0.0f),
750 gfx::PointF(0.0f, 0.0f),
751 false)));
752 }
753
754 TEST(CursorAnchorInfoControllerTest, SetScaleAndTranslate) {
755 const auto empty_selection_start = CreateViewportSelectionBoundForTest(
756 cc::SELECTION_BOUND_EMPTY,
757 gfx::PointF(0.0f, 0.0f),
758 gfx::PointF(0.0f, 0.0f),
759 false);
760
761 // No transformation
762 EXPECT_TRUE(AssertSetScaleAndTranslate(
763 1.0f,
764 gfx::Vector2dF(0.0f, 0.0f),
765 CreateFrameMetadataForTest(
766 1.0f,
767 gfx::Vector2dF(0.0f, 0.0f),
768 1.0f,
769 gfx::Vector2dF(0.0f, 0.0f),
770 gfx::Vector2dF(0.0f, 0.0f),
771 empty_selection_start),
772 gfx::Vector2d(0, 0)));
773
774 // device_scale_factor == 2.0
775 EXPECT_TRUE(AssertSetScaleAndTranslate(
776 2.0f,
777 gfx::Vector2dF(0.0f, 0.0f),
778 CreateFrameMetadataForTest(
779 2.0f,
780 gfx::Vector2dF(0.0f, 0.0f),
781 1.0f,
782 gfx::Vector2dF(0.0f, 0.0f),
783 gfx::Vector2dF(0.0f, 0.0f),
784 empty_selection_start),
785 gfx::Vector2d(0, 0)));
786
787 // device_scale_factor == 2.0f
788 // view_origin_offset == (10, 141)
789 EXPECT_TRUE(AssertSetScaleAndTranslate(
790 2.0f,
791 gfx::Vector2dF(10.0f, 141.0f),
792 CreateFrameMetadataForTest(
793 2.0f,
794 gfx::Vector2dF(0.0f, 0.0f),
795 1.0f,
796 gfx::Vector2dF(0.0f, 0.0f),
797 gfx::Vector2dF(0.0f, 0.0f),
798 empty_selection_start),
799 gfx::Vector2d(10, 141)));
800
801 // device_scale_factor == 2.0f
802 // root_scroll_offset == (1.0f, 2.0f)
803 // view_origin_offset == (10.0f, 141.0f)
804 EXPECT_TRUE(AssertSetScaleAndTranslate(
805 2.0f,
806 gfx::Vector2dF(10.0f - 2.0f, 141.0f - 4.0f),
807 CreateFrameMetadataForTest(
808 2.0f,
809 gfx::Vector2dF(1.0f, 2.0f),
810 1.0f,
811 gfx::Vector2dF(0.0f, 0.0f),
812 gfx::Vector2dF(0.0f, 0.0f),
813 empty_selection_start),
814 gfx::Vector2d(10, 141)));
815
816 // device_scale_factor == 2.0f
817 // page_scale_factor == 3.0f
818 // root_scroll_offset == (1.0f, 2.0f)
819 // view_origin_offset == (10.0f, 141.0f)
820 EXPECT_TRUE(AssertSetScaleAndTranslate(
821 6.0f,
822 gfx::Vector2dF(10.0f - 6.0f, 141.0f - 12.0f),
823 CreateFrameMetadataForTest(
824 2.0f,
825 gfx::Vector2dF(1.0f, 2.0f),
826 3.0f,
827 gfx::Vector2dF(0.0f, 0.0f),
828 gfx::Vector2dF(0.0f, 0.0f),
829 empty_selection_start),
830 gfx::Vector2d(10, 141)));
831
832 // device_scale_factor == 2.0f
833 // page_scale_factor == 3.0f
834 // root_scroll_offset == (1.0f, 2.0f)
835 // location_bar_offset == (20.0f, 30.0f)
836 // view_origin_offset == (10.0f, 141.0f)
837 EXPECT_TRUE(AssertSetScaleAndTranslate(
838 6.0f,
839 gfx::Vector2dF(30.0f - 6.0f, 171.0f - 12.0f),
840 CreateFrameMetadataForTest(
841 2.0f,
842 gfx::Vector2dF(1.0f, 2.0f),
843 3.0f,
844 gfx::Vector2dF(20.0f, 30.0f),
845 gfx::Vector2dF(0.0f, 0.0f),
846 empty_selection_start),
847 gfx::Vector2d(10, 141)));
848
849 // device_scale_factor == 2.0f
850 // page_scale_factor == 3.0f
851 // root_scroll_offset == (1.0f, 2.0f)
852 // location_bar_offset == (10.0f, 20.0f)
853 // location_bar_content_translation == (30.0f, 40.0f)
854 // view_origin_offset == (10.0f, 141.0f)
855 EXPECT_TRUE(AssertSetScaleAndTranslate(
856 6.0f,
857 gfx::Vector2dF(70.0f - 6.0f, 221.0f - 12.0f),
858 CreateFrameMetadataForTest(
859 2.0f,
860 gfx::Vector2dF(1.0f, 2.0f),
861 3.0f,
862 gfx::Vector2dF(20.0f, 30.0f),
863 gfx::Vector2dF(40.0f, 50.0f),
864 empty_selection_start),
865 gfx::Vector2d(10, 141)));
866 }
867
868 TEST(CursorAnchorInfoControllerTest, OnTextInputStateChanged) {
869 EXPECT_TRUE(AssertOnTextInputStateChanged(
870 Vec(MakeTuple(gfx::Range(1, 9))),
871 Vec(MakeTuple(3, base::ASCIIToUTF16("34"))),
872 base::ASCIIToUTF16("0123456789"),
873 gfx::Range(1, 9),
874 gfx::Range(3, 5)));
875
876 // Test if the composing range is out of range.
877 EXPECT_TRUE(AssertOnTextInputStateChanged(
878 Vec(MakeTuple(gfx::Range(1, 9))),
879 Vec(MakeTuple(100, base::ASCIIToUTF16(""))),
880 base::ASCIIToUTF16("0123456789"),
881 gfx::Range(1, 9),
882 gfx::Range(100, 0)));
883
884 // Test if the composing range is out of range.
885 EXPECT_TRUE(AssertOnTextInputStateChanged(
886 Vec(MakeTuple(gfx::Range(1, 9))),
887 Vec(MakeTuple(-1, base::ASCIIToUTF16(""))),
888 base::ASCIIToUTF16(""),
889 gfx::Range(1, 9),
890 gfx::Range(-1, 1)));
891 }
892
893 TEST(CursorAnchorInfoControllerTest, OnCompositionRangeChanged) {
894 EXPECT_TRUE(AssertOnCompositionRangeChanged(
895 Vec<AddCharacterBoundsParams>(),
896 gfx::Range(0, 0),
897 Vec<gfx::Rect>()));
898
899 EXPECT_TRUE(AssertOnCompositionRangeChanged(
900 Vec(MakeTuple(1,
901 gfx::RectF(1.0f, 2.0f, 3.0f, 4.0f),
902 kFlagHasVisibleRegion),
903 MakeTuple(2,
904 gfx::RectF(5.0f, 6.0f, 7.0f, 8.0f),
905 kFlagHasVisibleRegion)),
906 gfx::Range(1, 3),
907 Vec(gfx::Rect(1, 2, 3, 4),
908 gfx::Rect(5, 6, 7, 8))));
909
910 EXPECT_TRUE(AssertOnCompositionRangeChanged(
911 Vec(MakeTuple(5,
912 gfx::RectF(1.0f, 2.0f, 3.0f, 4.0f),
913 kFlagHasVisibleRegion),
914 MakeTuple(6,
915 gfx::RectF(5.0f, 6.0f, 7.0f, 8.0f),
916 kFlagHasVisibleRegion),
917 MakeTuple(7,
918 gfx::RectF(9.0f, 10.0f, 11.0f, 12.0f),
919 kFlagHasVisibleRegion)),
920 gfx::Range(5, 8),
921 Vec(gfx::Rect(1, 2, 3, 4),
922 gfx::Rect(5, 6, 7, 8),
923 gfx::Rect(9, 10, 11, 12))));
924 }
925
926 } // namespace
927 } // namespace ui
OLDNEW
« no previous file with comments | « ui/base/ime/android/cursor_anchor_info_controller.cc ('k') | ui/base/ime/android/cursor_anchor_info_sender.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698