Home | History | Annotate | Download | only in cts
      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.text.method.cts;
     18 
     19 import static org.junit.Assert.assertEquals;
     20 import static org.junit.Assert.assertTrue;
     21 
     22 import android.app.Activity;
     23 import android.app.Instrumentation;
     24 import android.os.SystemClock;
     25 import android.support.test.InstrumentationRegistry;
     26 import android.support.test.annotation.UiThreadTest;
     27 import android.support.test.filters.MediumTest;
     28 import android.support.test.rule.ActivityTestRule;
     29 import android.support.test.runner.AndroidJUnit4;
     30 import android.text.Layout;
     31 import android.text.SpannableString;
     32 import android.text.TextPaint;
     33 import android.text.method.Touch;
     34 import android.util.DisplayMetrics;
     35 import android.util.TypedValue;
     36 import android.view.MotionEvent;
     37 import android.view.ViewGroup;
     38 import android.widget.TextView;
     39 
     40 import org.junit.Before;
     41 import org.junit.Rule;
     42 import org.junit.Test;
     43 import org.junit.runner.RunWith;
     44 
     45 @MediumTest
     46 @RunWith(AndroidJUnit4.class)
     47 public class TouchTest {
     48     private static final String LONG_TEXT = "Scrolls the specified widget to the specified " +
     49             "coordinates, except constrains the X scrolling position to the horizontal regions " +
     50             "of the text that will be visible after scrolling to the specified Y position." +
     51             "This is the description of the test." +
     52             "Scrolls the specified widget to the specified " +
     53             "coordinates, except constrains the X scrolling position to the horizontal regions " +
     54             "of the text that will be visible after scrolling to the specified Y position." +
     55             "This is the description of the test.";
     56 
     57     private Instrumentation mInstrumentation;
     58     private Activity mActivity;
     59     private boolean mReturnFromTouchEvent;
     60     private TextView mTextView;
     61 
     62     @Rule
     63     public ActivityTestRule<CtsActivity> mActivityRule = new ActivityTestRule<>(CtsActivity.class);
     64 
     65     @UiThreadTest
     66     @Before
     67     public void setup() {
     68         mInstrumentation = InstrumentationRegistry.getInstrumentation();
     69         mActivity = mActivityRule.getActivity();
     70         mTextView = new TextViewNoIme(mActivity);
     71         mTextView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 10);
     72     }
     73 
     74     @Test
     75     public void testScrollTo() throws Throwable {
     76         mActivityRule.runOnUiThread(() -> {
     77             final float pixelPerSp =
     78                 mActivity.getResources().getDisplayMetrics().scaledDensity;
     79             // Explicitly set the width so that |LONG_TEXT| causes horizontal scroll.
     80             mActivity.setContentView(mTextView, new ViewGroup.LayoutParams(
     81                 (int)(100 * pixelPerSp), ViewGroup.LayoutParams.MATCH_PARENT));
     82             mTextView.setSingleLine(true);
     83             mTextView.setLines(2);
     84         });
     85         mInstrumentation.waitForIdleSync();
     86         TextPaint paint = mTextView.getPaint();
     87         final Layout layout = mTextView.getLayout();
     88 
     89         mActivityRule.runOnUiThread(() -> mTextView.setText(LONG_TEXT));
     90         mInstrumentation.waitForIdleSync();
     91 
     92         // get the total length of string
     93         final int width = getTextWidth(LONG_TEXT, paint);
     94 
     95         mActivityRule.runOnUiThread(
     96                 () -> Touch.scrollTo(mTextView, layout, width - mTextView.getWidth() - 1, 0));
     97         mInstrumentation.waitForIdleSync();
     98         assertEquals(width - mTextView.getWidth() - 1, mTextView.getScrollX());
     99         assertEquals(0, mTextView.getScrollY());
    100 
    101         // the X to which scroll is greater than the total length of string.
    102         mActivityRule.runOnUiThread(() -> Touch.scrollTo(mTextView, layout, width + 100, 5));
    103         mInstrumentation.waitForIdleSync();
    104         assertEquals(width - mTextView.getWidth(), mTextView.getScrollX(), 1.0f);
    105         assertEquals(5, mTextView.getScrollY());
    106 
    107         mActivityRule.runOnUiThread(() -> Touch.scrollTo(mTextView, layout, width - 10, 5));
    108         mInstrumentation.waitForIdleSync();
    109         assertEquals(width - mTextView.getWidth(), mTextView.getScrollX(), 1.0f);
    110         assertEquals(5, mTextView.getScrollY());
    111     }
    112 
    113     @Test
    114     public void testOnTouchEvent() throws Throwable {
    115         // Create a string that is wider than the screen.
    116         DisplayMetrics metrics = mActivity.getResources().getDisplayMetrics();
    117         int screenWidth = metrics.widthPixels;
    118         TextPaint paint = mTextView.getPaint();
    119         String text = LONG_TEXT;
    120         int textWidth = Math.round(paint.measureText(text));
    121         while (textWidth < screenWidth) {
    122             text += LONG_TEXT;
    123             textWidth = Math.round(paint.measureText(text));
    124         }
    125 
    126         // Drag the difference between the text width and the screen width.
    127         int dragAmount = Math.min(screenWidth, textWidth - screenWidth);
    128         assertTrue(dragAmount > 0);
    129         final String finalText = text;
    130         final SpannableString spannable = new SpannableString(finalText);
    131         mActivityRule.runOnUiThread(() -> {
    132             mActivity.setContentView(mTextView);
    133             mTextView.setSingleLine(true);
    134             mTextView.setText(finalText);
    135         });
    136         mInstrumentation.waitForIdleSync();
    137 
    138         long downTime = SystemClock.uptimeMillis();
    139         long eventTime = SystemClock.uptimeMillis();
    140         final MotionEvent event1 = MotionEvent.obtain(downTime, eventTime,
    141                 MotionEvent.ACTION_DOWN, dragAmount, 0, 0);
    142         final MotionEvent event2 = MotionEvent.obtain(downTime, eventTime,
    143                 MotionEvent.ACTION_MOVE, 0, 0, 0);
    144         final MotionEvent event3 = MotionEvent.obtain(downTime, eventTime,
    145                 MotionEvent.ACTION_UP, 0, 0, 0);
    146         assertEquals(0, mTextView.getScrollX());
    147         assertEquals(0, mTextView.getScrollY());
    148         mReturnFromTouchEvent = false;
    149         mActivityRule.runOnUiThread(
    150                 () -> mReturnFromTouchEvent = Touch.onTouchEvent(mTextView, spannable, event1));
    151         mInstrumentation.waitForIdleSync();
    152         assertTrue(mReturnFromTouchEvent);
    153         // TextView has not been scrolled.
    154         assertEquals(0, mTextView.getScrollX());
    155         assertEquals(0, mTextView.getScrollY());
    156         assertEquals(0, Touch.getInitialScrollX(mTextView, spannable));
    157         assertEquals(0, Touch.getInitialScrollY(mTextView, spannable));
    158 
    159         mReturnFromTouchEvent = false;
    160         mActivityRule.runOnUiThread(
    161                 () -> mReturnFromTouchEvent = Touch.onTouchEvent(mTextView, spannable, event2));
    162         mInstrumentation.waitForIdleSync();
    163         assertTrue(mReturnFromTouchEvent);
    164         // TextView has been scrolled.
    165         assertEquals(dragAmount, mTextView.getScrollX());
    166         assertEquals(0, mTextView.getScrollY());
    167         assertEquals(0, Touch.getInitialScrollX(mTextView, spannable));
    168         assertEquals(0, Touch.getInitialScrollY(mTextView, spannable));
    169 
    170         mReturnFromTouchEvent = false;
    171         mActivityRule.runOnUiThread(
    172                 () -> mReturnFromTouchEvent = Touch.onTouchEvent(mTextView, spannable, event3));
    173         mInstrumentation.waitForIdleSync();
    174         assertTrue(mReturnFromTouchEvent);
    175         // TextView has not been scrolled.
    176         assertEquals(dragAmount, mTextView.getScrollX());
    177         assertEquals(0, mTextView.getScrollY());
    178         assertEquals(-1, Touch.getInitialScrollX(mTextView, spannable));
    179         assertEquals(-1, Touch.getInitialScrollY(mTextView, spannable));
    180     }
    181 
    182     private int getTextWidth(String str, TextPaint paint) {
    183         float totalWidth = 0f;
    184         float[] widths = new float[str.length()];
    185         paint.getTextWidths(str, widths);
    186         for (float f : widths) {
    187             totalWidth += f;
    188         }
    189         return (int) totalWidth;
    190     }
    191 }
    192