1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.keyboard.internal;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 
23 import androidx.test.filters.SmallTest;
24 import androidx.test.runner.AndroidJUnit4;
25 
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 
29 @SmallTest
30 @RunWith(AndroidJUnit4.class)
31 public class PointerTrackerQueueTests {
32     public static class Element implements PointerTrackerQueue.Element {
33         public static int sPhantomUpCount;
34         public static final long NOT_HAPPENED = -1;
35 
36         public final int mId;
37         public boolean mIsModifier;
38         public boolean mIsInDraggingFinger;
39         public long mPhantomUpEventTime = NOT_HAPPENED;
40 
Element(int id)41         public Element(int id) {
42             mId = id;
43         }
44 
45         @Override
isModifier()46         public boolean isModifier() {
47             return mIsModifier;
48         }
49 
50         @Override
isInDraggingFinger()51         public boolean isInDraggingFinger() {
52             return mIsInDraggingFinger;
53         }
54 
55         @Override
onPhantomUpEvent(long eventTime)56         public void onPhantomUpEvent(long eventTime) {
57             sPhantomUpCount++;
58             mPhantomUpEventTime = eventTime + sPhantomUpCount;
59         }
60 
61         @Override
cancelTrackingForAction()62         public void cancelTrackingForAction() {}
63 
64         @Override
toString()65         public String toString() {
66             return Integer.toString(mId);
67         }
68     }
69 
70     private final Element mElement1 = new Element(1);
71     private final Element mElement2 = new Element(2);
72     private final Element mElement3 = new Element(3);
73     private final Element mElement4 = new Element(4);
74     private final PointerTrackerQueue mQueue = new PointerTrackerQueue();
75 
76     @Test
testEmpty()77     public void testEmpty() {
78         assertEquals(0, mQueue.size());
79         assertEquals("[]", mQueue.toString());
80     }
81 
82     @Test
testAdd()83     public void testAdd() {
84         mQueue.add(mElement1);
85         assertEquals(1, mQueue.size());
86         assertEquals("[1]", mQueue.toString());
87         mQueue.add(mElement2);
88         assertEquals(2, mQueue.size());
89         assertEquals("[1 2]", mQueue.toString());
90         mQueue.add(mElement3);
91         assertEquals(3, mQueue.size());
92         assertEquals("[1 2 3]", mQueue.toString());
93         mQueue.add(mElement4);
94         assertEquals(4, mQueue.size());
95         assertEquals("[1 2 3 4]", mQueue.toString());
96     }
97 
98     @Test
testRemove()99     public void testRemove() {
100         Element.sPhantomUpCount = 0;
101 
102         mQueue.add(mElement1);
103         mQueue.add(mElement2);
104         mQueue.add(mElement3);
105         mQueue.add(mElement4);
106 
107         mQueue.remove(mElement2);
108         assertEquals(3, mQueue.size());
109         assertEquals("[1 3 4]", mQueue.toString());
110         mQueue.remove(mElement4);
111         assertEquals(2, mQueue.size());
112         assertEquals("[1 3]", mQueue.toString());
113         mQueue.remove(mElement4);
114         assertEquals(2, mQueue.size());
115         assertEquals("[1 3]", mQueue.toString());
116         mQueue.remove(mElement1);
117         assertEquals(1, mQueue.size());
118         assertEquals("[3]", mQueue.toString());
119         mQueue.remove(mElement3);
120         assertEquals(0, mQueue.size());
121         assertEquals("[]", mQueue.toString());
122         mQueue.remove(mElement1);
123         assertEquals(0, mQueue.size());
124         assertEquals("[]", mQueue.toString());
125 
126         assertEquals(0, Element.sPhantomUpCount);
127         assertEquals(Element.NOT_HAPPENED, mElement1.mPhantomUpEventTime);
128         assertEquals(Element.NOT_HAPPENED, mElement2.mPhantomUpEventTime);
129         assertEquals(Element.NOT_HAPPENED, mElement3.mPhantomUpEventTime);
130         assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
131     }
132 
133     @Test
testAddAndRemove()134     public void testAddAndRemove() {
135         Element.sPhantomUpCount = 0;
136 
137         mQueue.add(mElement1);
138         mQueue.add(mElement2);
139         mQueue.add(mElement3);
140         mQueue.add(mElement4);
141 
142         mQueue.remove(mElement2);
143         assertEquals(3, mQueue.size());
144         assertEquals("[1 3 4]", mQueue.toString());
145         mQueue.remove(mElement4);
146         assertEquals(2, mQueue.size());
147         assertEquals("[1 3]", mQueue.toString());
148         mQueue.add(mElement2);
149         assertEquals(3, mQueue.size());
150         assertEquals("[1 3 2]", mQueue.toString());
151         mQueue.remove(mElement4);
152         assertEquals(3, mQueue.size());
153         assertEquals("[1 3 2]", mQueue.toString());
154         mQueue.remove(mElement1);
155         assertEquals(2, mQueue.size());
156         assertEquals("[3 2]", mQueue.toString());
157         mQueue.add(mElement1);
158         assertEquals(3, mQueue.size());
159         assertEquals("[3 2 1]", mQueue.toString());
160         mQueue.remove(mElement3);
161         assertEquals(2, mQueue.size());
162         assertEquals("[2 1]", mQueue.toString());
163         mQueue.remove(mElement1);
164         assertEquals(1, mQueue.size());
165         assertEquals("[2]", mQueue.toString());
166 
167         assertEquals(Element.NOT_HAPPENED, mElement1.mPhantomUpEventTime);
168         assertEquals(Element.NOT_HAPPENED, mElement2.mPhantomUpEventTime);
169         assertEquals(Element.NOT_HAPPENED, mElement3.mPhantomUpEventTime);
170         assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
171     }
172 
173     @Test
testReleaseAllPointers()174     public void testReleaseAllPointers() {
175         mElement2.mIsModifier = true;
176         mQueue.add(mElement1);
177         mQueue.add(mElement2);
178         mQueue.add(mElement3);
179         mQueue.add(mElement4);
180 
181         final long eventTime = 123;
182         Element.sPhantomUpCount = 0;
183         mQueue.releaseAllPointers(eventTime);
184         assertEquals(4, Element.sPhantomUpCount);
185         assertEquals(0, mQueue.size());
186         assertEquals("[]", mQueue.toString());
187         assertEquals(eventTime + 1, mElement1.mPhantomUpEventTime);
188         assertEquals(eventTime + 2, mElement2.mPhantomUpEventTime);
189         assertEquals(eventTime + 3, mElement3.mPhantomUpEventTime);
190         assertEquals(eventTime + 4, mElement4.mPhantomUpEventTime);
191     }
192 
193     @Test
testReleaseAllPointersOlderThanFirst()194     public void testReleaseAllPointersOlderThanFirst() {
195         mElement2.mIsModifier = true;
196         mQueue.add(mElement1);
197         mQueue.add(mElement2);
198         mQueue.add(mElement3);
199 
200         final long eventTime = 123;
201         Element.sPhantomUpCount = 0;
202         mQueue.releaseAllPointersOlderThan(mElement1, eventTime);
203         assertEquals(0, Element.sPhantomUpCount);
204         assertEquals(3, mQueue.size());
205         assertEquals("[1 2 3]", mQueue.toString());
206         assertEquals(Element.NOT_HAPPENED, mElement1.mPhantomUpEventTime);
207         assertEquals(Element.NOT_HAPPENED, mElement2.mPhantomUpEventTime);
208         assertEquals(Element.NOT_HAPPENED, mElement3.mPhantomUpEventTime);
209     }
210 
211     @Test
testReleaseAllPointersOlderThanLast()212     public void testReleaseAllPointersOlderThanLast() {
213         mElement2.mIsModifier = true;
214         mQueue.add(mElement1);
215         mQueue.add(mElement2);
216         mQueue.add(mElement3);
217         mQueue.add(mElement4);
218 
219         final long eventTime = 123;
220         Element.sPhantomUpCount = 0;
221         mQueue.releaseAllPointersOlderThan(mElement4, eventTime);
222         assertEquals(2, Element.sPhantomUpCount);
223         assertEquals(2, mQueue.size());
224         assertEquals("[2 4]", mQueue.toString());
225         assertEquals(eventTime + 1, mElement1.mPhantomUpEventTime);
226         assertEquals(Element.NOT_HAPPENED, mElement2.mPhantomUpEventTime);
227         assertEquals(eventTime + 2, mElement3.mPhantomUpEventTime);
228         assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
229     }
230 
231     @Test
testReleaseAllPointersOlderThanWithoutModifierMiddle()232     public void testReleaseAllPointersOlderThanWithoutModifierMiddle() {
233         mQueue.add(mElement1);
234         mQueue.add(mElement2);
235         mQueue.add(mElement3);
236         mQueue.add(mElement4);
237 
238         final long eventTime = 123;
239         Element.sPhantomUpCount = 0;
240         mQueue.releaseAllPointersOlderThan(mElement3, eventTime);
241         assertEquals(2, Element.sPhantomUpCount);
242         assertEquals(2, mQueue.size());
243         assertEquals("[3 4]", mQueue.toString());
244         assertEquals(eventTime + 1, mElement1.mPhantomUpEventTime);
245         assertEquals(eventTime + 2, mElement2.mPhantomUpEventTime);
246         assertEquals(Element.NOT_HAPPENED, mElement3.mPhantomUpEventTime);
247         assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
248     }
249 
250     @Test
testReleaseAllPointersOlderThanWithoutModifierLast()251     public void testReleaseAllPointersOlderThanWithoutModifierLast() {
252         mQueue.add(mElement1);
253         mQueue.add(mElement2);
254         mQueue.add(mElement3);
255         mQueue.add(mElement4);
256 
257         final long eventTime = 123;
258         Element.sPhantomUpCount = 0;
259         mQueue.releaseAllPointersOlderThan(mElement4, eventTime);
260         assertEquals(3, Element.sPhantomUpCount);
261         assertEquals(1, mQueue.size());
262         assertEquals("[4]", mQueue.toString());
263         assertEquals(eventTime + 1, mElement1.mPhantomUpEventTime);
264         assertEquals(eventTime + 2, mElement2.mPhantomUpEventTime);
265         assertEquals(eventTime + 3, mElement3.mPhantomUpEventTime);
266         assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
267     }
268 
269     @Test
testReleaseAllPointersExcept()270     public void testReleaseAllPointersExcept() {
271         mElement2.mIsModifier = true;
272         mQueue.add(mElement1);
273         mQueue.add(mElement2);
274         mQueue.add(mElement3);
275         mQueue.add(mElement4);
276 
277         final long eventTime = 123;
278         Element.sPhantomUpCount = 0;
279         mQueue.releaseAllPointersExcept(mElement3, eventTime);
280         assertEquals(3, Element.sPhantomUpCount);
281         assertEquals(1, mQueue.size());
282         assertEquals("[3]", mQueue.toString());
283         assertEquals(eventTime + 1, mElement1.mPhantomUpEventTime);
284         assertEquals(eventTime + 2, mElement2.mPhantomUpEventTime);
285         assertEquals(Element.NOT_HAPPENED, mElement3.mPhantomUpEventTime);
286         assertEquals(eventTime + 3, mElement4.mPhantomUpEventTime);
287     }
288 
289     @Test
testHasModifierKeyOlderThan()290     public void testHasModifierKeyOlderThan() {
291         Element.sPhantomUpCount = 0;
292         assertFalse("hasModifierKeyOlderThan empty", mQueue.hasModifierKeyOlderThan(mElement1));
293 
294         mQueue.add(mElement1);
295         mQueue.add(mElement2);
296         mQueue.add(mElement3);
297         mQueue.add(mElement4);
298 
299         assertFalse(mQueue.hasModifierKeyOlderThan(mElement1));
300         assertFalse(mQueue.hasModifierKeyOlderThan(mElement2));
301         assertFalse(mQueue.hasModifierKeyOlderThan(mElement3));
302         assertFalse(mQueue.hasModifierKeyOlderThan(mElement4));
303 
304         mElement2.mIsModifier = true;
305         assertFalse(mQueue.hasModifierKeyOlderThan(mElement1));
306         assertFalse(mQueue.hasModifierKeyOlderThan(mElement2));
307         assertTrue(mQueue.hasModifierKeyOlderThan(mElement3));
308         assertTrue(mQueue.hasModifierKeyOlderThan(mElement4));
309 
310         assertEquals(0, Element.sPhantomUpCount);
311         assertEquals(4, mQueue.size());
312         assertEquals("[1 2 3 4]", mQueue.toString());
313         assertEquals(Element.NOT_HAPPENED, mElement1.mPhantomUpEventTime);
314         assertEquals(Element.NOT_HAPPENED, mElement2.mPhantomUpEventTime);
315         assertEquals(Element.NOT_HAPPENED, mElement3.mPhantomUpEventTime);
316         assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
317     }
318 
319     @Test
testIsAnyInDraggingFinger()320     public void testIsAnyInDraggingFinger() {
321         Element.sPhantomUpCount = 0;
322         assertFalse(mQueue.isAnyInDraggingFinger());
323 
324         mQueue.add(mElement1);
325         mQueue.add(mElement2);
326         mQueue.add(mElement3);
327         mQueue.add(mElement4);
328 
329         assertFalse(mQueue.isAnyInDraggingFinger());
330 
331         mElement3.mIsInDraggingFinger = true;
332         assertTrue(mQueue.isAnyInDraggingFinger());
333 
334         assertEquals(0, Element.sPhantomUpCount);
335         assertEquals(4, mQueue.size());
336         assertEquals("[1 2 3 4]", mQueue.toString());
337         assertEquals(Element.NOT_HAPPENED, mElement1.mPhantomUpEventTime);
338         assertEquals(Element.NOT_HAPPENED, mElement2.mPhantomUpEventTime);
339         assertEquals(Element.NOT_HAPPENED, mElement3.mPhantomUpEventTime);
340         assertEquals(Element.NOT_HAPPENED, mElement4.mPhantomUpEventTime);
341     }
342 }
343