• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 android.view.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertNotNull;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.content.Context;
24 import android.graphics.Point;
25 import android.hardware.input.InputManager;
26 import android.util.TypedValue;
27 import android.view.Display;
28 import android.view.InputDevice;
29 import android.view.MotionEvent;
30 import android.view.ViewConfiguration;
31 import android.view.WindowManager;
32 
33 import androidx.test.InstrumentationRegistry;
34 import androidx.test.filters.SmallTest;
35 import androidx.test.runner.AndroidJUnit4;
36 
37 import java.util.ArrayList;
38 import java.util.List;
39 
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 /**
44  * Test {@link ViewConfiguration}.
45  */
46 @SmallTest
47 @RunWith(AndroidJUnit4.class)
48 public class ViewConfigurationTest {
49     @Test
testStaticValues()50     public void testStaticValues() {
51         ViewConfiguration.getScrollBarSize();
52         ViewConfiguration.getFadingEdgeLength();
53         ViewConfiguration.getPressedStateDuration();
54         ViewConfiguration.getLongPressTimeout();
55         assertTrue(ViewConfiguration.getMultiPressTimeout() > 0);
56         ViewConfiguration.getTapTimeout();
57         ViewConfiguration.getJumpTapTimeout();
58         ViewConfiguration.getEdgeSlop();
59         ViewConfiguration.getTouchSlop();
60         ViewConfiguration.getWindowTouchSlop();
61         ViewConfiguration.getMinimumFlingVelocity();
62         ViewConfiguration.getMaximumFlingVelocity();
63         ViewConfiguration.getMaximumDrawingCacheSize();
64         ViewConfiguration.getZoomControlsTimeout();
65         ViewConfiguration.getGlobalActionKeyTimeout();
66         ViewConfiguration.getScrollFriction();
67         ViewConfiguration.getScrollBarFadeDuration();
68         ViewConfiguration.getScrollDefaultDelay();
69         ViewConfiguration.getDoubleTapTimeout();
70         ViewConfiguration.getKeyRepeatTimeout();
71         ViewConfiguration.getKeyRepeatDelay();
72         ViewConfiguration.getDefaultActionModeHideDuration();
73     }
74 
75     @Test
testConstructor()76     public void testConstructor() {
77         new ViewConfiguration();
78     }
79 
80     @Test
testInstanceValues()81     public void testInstanceValues() {
82         Context context = InstrumentationRegistry.getTargetContext();
83         ViewConfiguration vc = ViewConfiguration.get(context);
84         assertNotNull(vc);
85 
86         vc.getScaledDoubleTapSlop();
87         vc.getScaledEdgeSlop();
88         vc.getScaledFadingEdgeLength();
89         vc.getScaledMaximumDrawingCacheSize();
90         vc.getScaledMaximumFlingVelocity();
91         vc.getScaledMinimumFlingVelocity();
92         vc.getScaledOverflingDistance();
93         vc.getScaledOverscrollDistance();
94         vc.getScaledPagingTouchSlop();
95         vc.getScaledScrollBarSize();
96         vc.getScaledHorizontalScrollFactor();
97         vc.getScaledVerticalScrollFactor();
98         vc.getScaledTouchSlop();
99         vc.getScaledHandwritingSlop();
100         vc.getScaledWindowTouchSlop();
101         vc.hasPermanentMenuKey();
102 
103         float pixelsToMmRatio = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, 1,
104                 context.getResources().getDisplayMetrics());
105 
106         // Verify that the min scaling span size is reasonable.
107         float scaledMinScalingSpanMm = vc.getScaledMinimumScalingSpan() / pixelsToMmRatio;
108         assertTrue(scaledMinScalingSpanMm > 0);
109         assertTrue(scaledMinScalingSpanMm < 40.5); // 1.5 times the recommended size of 27mm
110     }
111 
112     @Test
113     public void testExceptionsThrown() {
114         ViewConfiguration vc = new ViewConfiguration();
115         boolean correctExceptionThrown = false;
116         try {
117             vc.getScaledMinimumScalingSpan();
118         } catch (IllegalStateException e) {
119             if (e.getMessage().equals("Min scaling span cannot be determined when this "
120                     + "method is called on a ViewConfiguration that was instantiated using a "
121                     + "constructor with no Context parameter")) {
122                 correctExceptionThrown = true;
123             }
124         }
125         assertTrue(correctExceptionThrown);
126     }
127 
128     /**
129      * The purpose of the ambiguous gesture multiplier is to potentially increase the touch slop
130      * and the long press timeout to allow the gesture classifier an additional window to
131      * make the classification. Therefore, this multiplier should be always greater or equal to 1.
132      */
133     @Test
134     public void testGetAmbiguousGestureMultiplier() {
135         final float staticMultiplier = ViewConfiguration.getAmbiguousGestureMultiplier();
136         assertTrue(staticMultiplier >= 1);
137 
138         ViewConfiguration vc = ViewConfiguration.get(InstrumentationRegistry.getTargetContext());
139         final float instanceMultiplier = vc.getAmbiguousGestureMultiplier();
140         assertTrue(instanceMultiplier >= 1);
141     }
142 
143     @Test
testFlingThresholds_forInvalidInputDeviceIds()144     public void testFlingThresholds_forInvalidInputDeviceIds() {
145         Context context = InstrumentationRegistry.getTargetContext();
146         InputManager inputManager = context.getSystemService(InputManager.class);
147 
148         ViewConfiguration contextBasedVc = ViewConfiguration.get(context);
149         ViewConfiguration contextLessVc = new ViewConfiguration();
150         for (ViewConfiguration vc : new ViewConfiguration[] {contextBasedVc, contextLessVc}) {
151             // "50" randomly chosen to cover some array of integers.
152             for (int deviceId = -50; deviceId < 50; deviceId++) {
153                 InputDevice device = inputManager.getInputDevice(deviceId);
154                 if (device != null) {
155                     continue; // Test only invalid device IDs. Continue...
156                 }
157 
158                 // Test with some source-axis combinations. Any source-axis combination should
159                 // provide the no-fling thresholds, since the device ID is known to be invalid.
160                 verifyNoFlingThresholds(
161                         vc, deviceId, InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.AXIS_X);
162                 verifyNoFlingThresholds(
163                         vc, deviceId, InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.AXIS_Y);
164                 verifyNoFlingThresholds(
165                         vc, deviceId, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_SCROLL);
166             }
167         }
168     }
169 
170     @Test
testFlingThresholds_forAllAvailableDevices()171     public void testFlingThresholds_forAllAvailableDevices() {
172         Context context = InstrumentationRegistry.getTargetContext();
173         InputManager inputManager = context.getSystemService(InputManager.class);
174         int[] deviceIds = context.getSystemService(InputManager.class).getInputDeviceIds();
175 
176         ViewConfiguration contextBasedVc = ViewConfiguration.get(context);
177         ViewConfiguration contextLessVc = new ViewConfiguration();
178         for (ViewConfiguration vc : new ViewConfiguration[] {contextBasedVc, contextLessVc}) {
179             for (int deviceId : deviceIds) {
180                 InputDevice device = inputManager.getInputDevice(deviceId);
181                 for (InputDevice.MotionRange motionRange : device.getMotionRanges()) {
182                     int axis = motionRange.getAxis();
183                     int source = motionRange.getSource();
184 
185                     int minVel = vc.getScaledMinimumFlingVelocity(deviceId, axis, source);
186                     int maxVel = vc.getScaledMaximumFlingVelocity(deviceId, axis, source);
187 
188                     // These min/max thresholds are thresholds for a valid InputDevice ID, on a
189                     // source and axis applicable to the InputDevice represented by the ID. Check
190                     // that the provided thresholds are within the valid bounds.
191                     verifyFlingThresholdRange(minVel, maxVel);
192                 }
193 
194                 // Test with source-axis combinations that we know are not valid. Since the
195                 // source-axis combinations will be invalid, we expect the no-fling thresholds,
196                 // despite the fact that we're using a valid InputDevice ID.
197                 verifyNoFlingThresholds(
198                         vc, deviceId, InputDevice.SOURCE_ROTARY_ENCODER, MotionEvent.AXIS_X);
199                 verifyNoFlingThresholds(
200                         vc, deviceId, InputDevice.SOURCE_TOUCHSCREEN, MotionEvent.AXIS_WHEEL);
201             }
202         }
203     }
204 
205     @Test
testGetScaledAmbiguousGestureMultiplier()206     public void testGetScaledAmbiguousGestureMultiplier() {
207         ViewConfiguration vc = ViewConfiguration.get(InstrumentationRegistry.getTargetContext());
208         final float instanceMultiplier = vc.getScaledAmbiguousGestureMultiplier();
209         assertTrue(instanceMultiplier >= 1);
210     }
211 
212     @Test
testGetMaximumDrawingCacheSize()213     public void testGetMaximumDrawingCacheSize() {
214         Context context = InstrumentationRegistry.getTargetContext();
215         ViewConfiguration vc = ViewConfiguration.get(context);
216         assertNotNull(vc);
217 
218         // Should be at least the size of the screen we're supposed to draw into.
219         final WindowManager win = context.getSystemService(WindowManager.class);
220         final Display display = win.getDefaultDisplay();
221         final Point size = new Point();
222         display.getSize(size);
223         assertTrue(vc.getScaledMaximumDrawingCacheSize() >= size.x * size.y * 4);
224 
225         // This deprecated value should just be what it's historically hardcoded to be.
226         assertEquals(480 * 800 * 4, vc.getMaximumDrawingCacheSize());
227     }
228 
229     /** Verifies whether or not the given fling thresholds are within the valid range. */
verifyFlingThresholdRange(int minVel, int maxVel)230     private static void verifyFlingThresholdRange(int minVel, int maxVel) {
231         if (minVel > maxVel) {
232             // The only case where we expect the minimum velocity to exceed the maximum velocity is
233             // for InputDevices that do not support fling, in which case the minimum and maximum
234             // velocties are set to Integer's max and min values, respectively.
235             verifyNoFlingThresholds(minVel, maxVel);
236         } else {
237             // If the minimum velocity is <= the maximum velocity, the velocities should represent
238             // valid thresholds, which should not be negative values (as the thresholds are defined
239             // as absolute values).
240             assertTrue(minVel >= 0);
241             assertTrue(maxVel >= 0);
242         }
243     }
244 
verifyNoFlingThresholds( ViewConfiguration viewConfiguration, int deviceId, int source, int axis)245     private static void verifyNoFlingThresholds(
246             ViewConfiguration viewConfiguration, int deviceId, int source, int axis) {
247         verifyNoFlingThresholds(
248             viewConfiguration.getScaledMinimumFlingVelocity(deviceId, axis, source),
249             viewConfiguration.getScaledMaximumFlingVelocity(deviceId, axis, source));
250     }
251 
252     /**
253      * Verifies that the given min and max fling velocities represent the values used to suppress
254      * fling.
255      */
verifyNoFlingThresholds(int minVel, int maxVel)256     private static void verifyNoFlingThresholds(int minVel, int maxVel) {
257         assertEquals(Integer.MAX_VALUE, minVel);
258         assertEquals(Integer.MIN_VALUE, maxVel);
259     }
260 }
261