/* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget.scroll; import android.widget.scroll.RequestRectangleVisible; import com.android.frameworks.coretests.R; import android.test.ActivityInstrumentationTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.test.ViewAsserts; import android.widget.Button; import android.widget.ScrollView; import android.widget.TextView; import android.view.View; import android.view.KeyEvent; /** * {@link RequestRectangleVisible} is set up to exercise the cases of moving a * rectangle that is either off screen or not entirely on the screen onto the screen. */ public class RequestRectangleVisibleTest extends ActivityInstrumentationTestCase<RequestRectangleVisible> { private ScrollView mScrollView; private Button mClickToScrollFromAbove; private Button mClickToScrollToUpperBlob; private TextView mTopBlob; private View mChildToScrollTo; private TextView mBottomBlob; private Button mClickToScrollToBlobLowerBlob; private Button mClickToScrollFromBelow; public RequestRectangleVisibleTest() { super("com.android.frameworks.coretests", RequestRectangleVisible.class); } @Override protected void setUp() throws Exception { super.setUp(); RequestRectangleVisible a = getActivity(); mScrollView = (ScrollView) a.findViewById(R.id.scrollView); mClickToScrollFromAbove = (Button) a.findViewById(R.id.scrollToRectFromTop); mClickToScrollToUpperBlob = (Button) a.findViewById(R.id.scrollToRectFromTop2); mTopBlob = (TextView) a.findViewById(R.id.topBlob); mChildToScrollTo = a.findViewById(R.id.childToMakeVisible); mBottomBlob = (TextView) a.findViewById(R.id.bottomBlob); mClickToScrollToBlobLowerBlob = (Button) a.findViewById(R.id.scrollToRectFromBottom2); mClickToScrollFromBelow = (Button) a.findViewById(R.id.scrollToRectFromBottom); } @MediumTest public void testPreconditions() { assertNotNull(mScrollView); assertNotNull(mClickToScrollFromAbove); assertNotNull(mClickToScrollToUpperBlob); assertNotNull(mTopBlob); assertNotNull(mChildToScrollTo); assertNotNull(mBottomBlob); assertNotNull(mClickToScrollToBlobLowerBlob); assertNotNull(mClickToScrollFromBelow); assertTrue("top blob needs to be taller than the screen for many of the " + "tests below to work.", mTopBlob.getHeight() > mScrollView.getHeight()); assertTrue("bottom blob needs to be taller than the screen for many of the " + "tests below to work.", mBottomBlob.getHeight() > mScrollView.getHeight()); assertTrue("top blob needs to be lower than the fading edge region", mTopBlob.getTop() > mScrollView.getVerticalFadingEdgeLength()); } @MediumTest public void testScrollToOffScreenRectangleFromTop() { // view is off screen assertTrue(mClickToScrollFromAbove.hasFocus()); ViewAsserts.assertOffScreenBelow(mScrollView, mChildToScrollTo); // click sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); getInstrumentation().waitForIdleSync(); // wait for scrolling to finish // should be on screen, positioned at the bottom (with room for // fading edge) ViewAsserts.assertOnScreen(mScrollView, mChildToScrollTo); ViewAsserts.assertHasScreenCoordinates( mScrollView, mChildToScrollTo, 0, mScrollView.getHeight() - mChildToScrollTo.getHeight() - mScrollView.getVerticalFadingEdgeLength()); } @MediumTest public void testScrollToPartiallyOffScreenRectFromTop() { pressDownUntilViewInFocus(mClickToScrollToUpperBlob, 4); // make sure the blob is indeed partially on screen below assertOnBottomEdgeOfScreen(mScrollView, mTopBlob); // click sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); getInstrumentation().waitForIdleSync(); // wait for scrolling to finish // blob should have moved so top of it is at top of screen (with // room for the vertical fading edge ViewAsserts.assertHasScreenCoordinates( mScrollView, mTopBlob, 0, mScrollView.getVerticalFadingEdgeLength()); } @LargeTest public void testScrollToOffScreenRectangleFromBottom() { // go to bottom button pressDownUntilViewInFocus(mClickToScrollFromBelow, 10); // view is off screen above assertTrue(mClickToScrollFromBelow.hasFocus()); ViewAsserts.assertOffScreenAbove(mScrollView, mChildToScrollTo); // click sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); getInstrumentation().waitForIdleSync(); // wait for scrolling to finish // on screen, positioned at top (with room for fading edge) ViewAsserts.assertOnScreen(mScrollView, mChildToScrollTo); ViewAsserts.assertHasScreenCoordinates( mScrollView, mChildToScrollTo, 0, mScrollView.getVerticalFadingEdgeLength()); } @LargeTest public void testScrollToPartiallyOffScreenRectFromBottom() { pressDownUntilViewInFocus(mClickToScrollToBlobLowerBlob, 10); // make sure the blob is indeed partially on screen above assertOnTopEdgeOfScreen(mScrollView, mBottomBlob); // click sendKeys(KeyEvent.KEYCODE_DPAD_CENTER); getInstrumentation().waitForIdleSync(); // wait for scrolling to finish // blob should have moved so bottom of it is at bottom of screen // with room for vertical fading edge ViewAsserts.assertHasScreenCoordinates( mScrollView, mBottomBlob, 0, mScrollView.getHeight() - mBottomBlob.getHeight() - mScrollView.getVerticalFadingEdgeLength()); } /** * Press the down key until a particular view is in focus * @param view The view to get in focus. * @param maxKeyPress The maximum times to press down before failing. */ private void pressDownUntilViewInFocus(View view, int maxKeyPress) { int count = 0; while(!view.hasFocus()) { sendKeys(KeyEvent.KEYCODE_DPAD_DOWN); getInstrumentation().waitForIdleSync(); // just in case... if (++count > maxKeyPress) { fail("couldn't move down to bottom button within " + maxKeyPress + " key presses."); } } } /** * Assert that view overlaps the bottom edge of the screen * @param origin The root view of the screen. * @param view The view */ static public void assertOnBottomEdgeOfScreen(View origin, View view) { int[] xy = new int[2]; view.getLocationOnScreen(xy); int[] xyRoot = new int[2]; origin.getLocationOnScreen(xyRoot); int bottom = xy[1] + view.getHeight(); int bottomOfRoot = xyRoot[1] + origin.getHeight(); assertTrue(bottom > bottomOfRoot); assertTrue(xy[1] < bottomOfRoot); assertTrue(bottom > bottomOfRoot); } /** * Assert that view overlaps the bottom edge of the screen * @param origin The root view of the screen. * @param view The view */ static public void assertOnTopEdgeOfScreen(View origin, View view) { int[] xy = new int[2]; view.getLocationOnScreen(xy); int[] xyRoot = new int[2]; origin.getLocationOnScreen(xyRoot); int bottom = xy[1] + view.getHeight(); int bottomOfRoot = xyRoot[1] + origin.getHeight(); assertTrue(bottom < bottomOfRoot); assertTrue(bottom > xyRoot[1]); assertTrue(xy[1] < xyRoot[1]); } }