blob: 78a01f68cd03b044181737eb4f5665e9552c05c0 [file] [log] [blame]
jinsukkim5c3a1202017-03-10 00:02:141// Copyright 2017 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
jinsukkime98211462017-05-12 09:57:045#include "base/test/gtest_util.h"
jinsukkim5c3a1202017-03-10 00:02:146#include "testing/gtest/include/gtest/gtest.h"
7#include "ui/android/event_forwarder.h"
8#include "ui/android/view_android.h"
9#include "ui/android/view_client.h"
10#include "ui/events/android/motion_event_android.h"
11
12namespace ui {
13
14using base::android::JavaParamRef;
15
16class TestViewClient : public ViewClient {
17 public:
18 TestViewClient() : handle_event_(true), called_(false) {}
19
20 void SetHandleEvent(bool handle_event) { handle_event_ = handle_event; }
21 bool OnTouchEvent(const MotionEventAndroid& event,
22 bool for_touch_handle) override {
23 called_ = true;
24 return handle_event_;
25 }
26
27 bool EventHandled() { return called_ && handle_event_; }
28 bool EventCalled() { return called_; }
29 void Reset() { called_ = false; }
30
31 private:
32 bool handle_event_; // Marks as event was consumed. True by default.
33 bool called_;
34};
35
36class ViewAndroidBoundsTest : public testing::Test {
37 public:
38 ViewAndroidBoundsTest()
39 : root_(nullptr),
40 view1_(&client1_),
41 view2_(&client2_),
42 view3_(&client3_) {
43 root_.GetEventForwarder();
44 root_.SetLayout(ViewAndroid::LayoutParams::MatchParent());
45 }
46
47 void Reset() {
48 client1_.Reset();
49 client2_.Reset();
50 client3_.Reset();
51 }
52
53 void GenerateTouchEventAt(float x, float y) {
54 ui::MotionEventAndroid::Pointer pointer0(0, x, y, 0, 0, 0, 0, 0);
55 ui::MotionEventAndroid::Pointer pointer1(0, 0, 0, 0, 0, 0, 0, 0);
jinsukkimb40b402c2017-03-29 09:39:0856 ui::MotionEventAndroid event(nullptr, JavaParamRef<jobject>(nullptr), 1.f,
57 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
58 &pointer0, &pointer1);
jinsukkim5c3a1202017-03-10 00:02:1459 root_.OnTouchEvent(event, false);
60 }
61
62 void ExpectHit(const TestViewClient& hitClient) {
63 TestViewClient* clients[3] = {&client1_, &client2_, &client3_};
64 for (auto* client : clients) {
65 if (&hitClient == client)
66 EXPECT_TRUE(client->EventHandled());
67 else
68 EXPECT_FALSE(client->EventHandled());
69 }
70 Reset();
71 }
72
73 ViewAndroid root_;
74 ViewAndroid view1_;
75 ViewAndroid view2_;
76 ViewAndroid view3_;
77 TestViewClient client1_;
78 TestViewClient client2_;
79 TestViewClient client3_;
80};
81
82TEST_F(ViewAndroidBoundsTest, MatchesViewInFront) {
83 view1_.SetLayout(ViewAndroid::LayoutParams::Normal(50, 50, 400, 600));
84 view2_.SetLayout(ViewAndroid::LayoutParams::Normal(50, 50, 400, 600));
85 root_.AddChild(&view2_);
86 root_.AddChild(&view1_);
87
88 GenerateTouchEventAt(100.f, 100.f);
89 ExpectHit(client1_);
90
91 // View 2 moves up to the top, and events should hit it from now.
92 root_.MoveToFront(&view2_);
93 GenerateTouchEventAt(100.f, 100.f);
94 ExpectHit(client2_);
95}
96
97TEST_F(ViewAndroidBoundsTest, MatchesViewArea) {
98 view1_.SetLayout(ViewAndroid::LayoutParams::Normal(50, 50, 200, 200));
99 view2_.SetLayout(ViewAndroid::LayoutParams::Normal(20, 20, 400, 600));
100
101 root_.AddChild(&view2_);
102 root_.AddChild(&view1_);
103
104 // Falls within |view1_|'s bounds
105 GenerateTouchEventAt(100.f, 100.f);
106 ExpectHit(client1_);
107
108 // Falls within |view2_|'s bounds
109 GenerateTouchEventAt(300.f, 400.f);
110 ExpectHit(client2_);
111}
112
113TEST_F(ViewAndroidBoundsTest, MatchesViewAfterMove) {
114 view1_.SetLayout(ViewAndroid::LayoutParams::Normal(50, 50, 200, 200));
115 view2_.SetLayout(ViewAndroid::LayoutParams::Normal(20, 20, 400, 600));
116 root_.AddChild(&view2_);
117 root_.AddChild(&view1_);
118
119 GenerateTouchEventAt(100.f, 100.f);
120 ExpectHit(client1_);
121
122 view1_.SetLayout(ViewAndroid::LayoutParams::Normal(150, 150, 200, 200));
123 GenerateTouchEventAt(100.f, 100.f);
124 ExpectHit(client2_);
125}
126
127TEST_F(ViewAndroidBoundsTest, MatchesViewSizeOfkMatchParent) {
128 view1_.SetLayout(ViewAndroid::LayoutParams::Normal(20, 20, 400, 600));
129 view3_.SetLayout(ViewAndroid::LayoutParams::MatchParent());
130 view2_.SetLayout(ViewAndroid::LayoutParams::Normal(50, 50, 200, 200));
131
132 root_.AddChild(&view1_);
133 root_.AddChild(&view2_);
134 view1_.AddChild(&view3_);
135
136 GenerateTouchEventAt(100.f, 100.f);
137 ExpectHit(client2_);
138
139 GenerateTouchEventAt(300.f, 400.f);
140 ExpectHit(client1_);
141
142 client1_.SetHandleEvent(false);
143 GenerateTouchEventAt(300.f, 400.f);
144 EXPECT_TRUE(client1_.EventCalled());
145 ExpectHit(client3_);
146}
147
148TEST_F(ViewAndroidBoundsTest, MatchesViewsWithOffset) {
149 view1_.SetLayout(ViewAndroid::LayoutParams::Normal(10, 20, 150, 100));
150 view2_.SetLayout(ViewAndroid::LayoutParams::Normal(20, 30, 40, 30));
151 view3_.SetLayout(ViewAndroid::LayoutParams::Normal(70, 30, 40, 30));
152
153 root_.AddChild(&view1_);
154 view1_.AddChild(&view2_);
155 view1_.AddChild(&view3_);
156
157 GenerateTouchEventAt(70, 30);
158 ExpectHit(client1_);
159
160 client1_.SetHandleEvent(false);
161 GenerateTouchEventAt(40, 60);
162 EXPECT_TRUE(client1_.EventCalled());
163 ExpectHit(client2_);
164
165 GenerateTouchEventAt(100, 70);
166 EXPECT_TRUE(client1_.EventCalled());
167 ExpectHit(client3_);
168}
169
jinsukkime98211462017-05-12 09:57:04170TEST(ViewAndroidTest, ChecksMultipleEventForwarders) {
171 ViewAndroid parent;
172 ViewAndroid child;
173 parent.GetEventForwarder();
174 child.GetEventForwarder();
175 EXPECT_DCHECK_DEATH(parent.AddChild(&child));
176
177 ViewAndroid parent2;
178 ViewAndroid child2;
179 parent2.GetEventForwarder();
180 parent2.AddChild(&child2);
181 EXPECT_DCHECK_DEATH(child2.GetEventForwarder());
182
183 ViewAndroid window;
184 ViewAndroid wcv1, wcv2;
185 ViewAndroid rwhv1a, rwhv1b, rwhv2;
186 wcv1.GetEventForwarder();
187 wcv2.GetEventForwarder();
188
189 window.AddChild(&wcv1);
190 wcv1.AddChild(&rwhv1a);
191 wcv1.AddChild(&rwhv1b);
192
193 wcv2.AddChild(&rwhv2);
194
195 // window should be able to add wcv2 since there's only one event forwarder
196 // in the path window - wcv2* - rwvh2
197 window.AddChild(&wcv2);
198
199 // Additional event forwarder will cause failure.
200 EXPECT_DCHECK_DEATH(rwhv2.GetEventForwarder());
201}
202
jinsukkim5c3a1202017-03-10 00:02:14203} // namespace ui