auto import from //depot/cupcake/@135843
diff --git a/tests/FrameworkTest/Android.mk b/tests/FrameworkTest/Android.mk
new file mode 100644
index 0000000..61cdbfa
--- /dev/null
+++ b/tests/FrameworkTest/Android.mk
@@ -0,0 +1,15 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := FrameworkTest
+
+include $(BUILD_PACKAGE)
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tests/FrameworkTest/AndroidManifest.xml b/tests/FrameworkTest/AndroidManifest.xml
new file mode 100644
index 0000000..c70302b
--- /dev/null
+++ b/tests/FrameworkTest/AndroidManifest.xml
@@ -0,0 +1,952 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworktest">
+
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.HARDWARE_TEST" />
+ <uses-permission android:name="android.permission.WRITE_SETTINGS" />
+
+ <application android:theme="@style/Theme">
+ <uses-library android:name="android.test.runner" />
+
+ <activity android:name=".FrameworkTestApplication" android:label="FrameworkTestApplication">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".performance.InvalidateCycle" android:label="InvalidateCycle">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.DescendantFocusability" android:label="DescendantFocusability">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.FocusAfterRemoval" android:label="FocusAfterRemoval">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.RequestFocus" android:label="RequestFocus">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />V
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.ListOfButtons" android:label="ListOfButtons">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.LinearLayoutGrid" android:label="LinearLayoutGrid">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.ListOfEditTexts" android:label="ListOfEditTexts">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.ListOfInternalSelectionViews" android:label="ListOfInternalSelectionViews">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.ListWithFooterViewAndNewLabels" android:label="FocusListWithFooter">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.ListWithMailMessages" android:label="ListWithMailMessages">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.HorizontalFocusSearch" android:label="HorizontalFocusSearch">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.VerticalFocusSearch" android:label="VerticalFocusSearch">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.AdjacentVerticalRectLists" android:label="AdjacentVerticalRectLists">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".focus.GoneParentFocusedChild" android:label="GoneParentFocusedChild">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.frame.FrameLayoutGravity" android:label="FrameLayoutGravity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.frame.FrameLayoutMargin" android:label="FrameLayoutMargin">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.BaselineAlignmentCenterGravity" android:label="BaselineAlignmentCenterGravity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.BaselineButtons" android:label="BaselineButtons">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.FillInWrap" android:label="FillInWrap">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.BaselineAlignmentZeroWidthAndWeight" android:label="Baseline0WidthAndWeight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.HorizontalOrientationVerticalAlignment" android:label="HorizontalOrientationVerticalAlignment">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.LLEditTextThenButton" android:label="LLEditTextThenButton">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.LLOfButtons1" android:label="LLOfButtons1">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.LinearLayoutEditTexts" android:label="LinearLayoutEditTexts">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.LLOfButtons2" android:label="LLOfButtons2">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.LLOfTwoFocusableInTouchMode" android:label="LLOfTwoFocusableInTouchMode">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.Weight" android:label="Weight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.linear.WeightSum" android:label="WeightSum">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.AdjacentListsWithAdjacentISVsInside" android:label="AdjacentListsWithAdjacentISVsInside">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListDividers" android:label="ListDividers">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListViewHeight" android:label="ListViewHeight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.table.FixedWidth" android:label="CellFixedWidth">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.table.Weight" android:label="CellWeight">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.table.HorizontalGravity" android:label="CellHorizontalGravity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.table.VerticalGravity" android:label="CellVerticalGravity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.table.AddColumn" android:label="AddColumnInTable">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".layout.table.CellSpan" android:label="CellSpan">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".scroll.ButtonAboveTallInternalSelectionView" android:label="ButtonAboveTallInternalSelectionView">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".scroll.ButtonsWithTallTextViewInBetween" android:label="scrollButtonsWithTallTextViewInBetween">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".scroll.RequestRectangleVisible" android:label="ScrollToChildRect">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".scroll.RequestRectangleVisibleWithInternalScroll" android:label="ScrollToChildRectWithInternalScroll">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".scroll.ScrollViewButtonsAndLabels" android:label="ScrollViewButtonsAndLabels">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".scroll.ShortButtons" android:label="scrollShortButtons">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".scroll.TallTextAboveButton" android:label="scrollTallTextAboveButton">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.Include" android:label="IncludeTag">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.Merge" android:label="MergeTag">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.StubbedView" android:label="ViewStub">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.RunQueue" android:label="RunQueue">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.Visibility" android:label="Visibility">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.BigCache" android:label="BigCache">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.ZeroSized" android:label="ZeroSized">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.Disabled" android:label="Disabled">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.PopupWindowVisibility" android:label="PopupWindowVisibility">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.PreDrawListener" android:label="PreDrawListener">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.GlobalFocusChange" android:label="GlobalFocusChange">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListSetSelection" android:label="ListSetSelection">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListSimple" android:label="ListSimple">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListFilter" android:label="ListFilter">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListScrollListener" android:label="ListScrollListener">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListThrasher" android:label="ListThrasher">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListTakeFocusFromSide" android:label="ListTakeFocusFromSide">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListBottomGravity" android:label="ListBottomGravity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListBottomGravityMany" android:label="ListBottomGravityMany">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+
+ <activity android:name=".listview.ListButtonsDiagonalAcrossItems" android:label="ListButtonsDiagonalAcrossItems">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListTopGravity" android:label="ListTopGravity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListTopGravityMany" android:label="ListTopGravityMany">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListEndingWithMultipleSeparators" android:label="ListEndingWithMultipleSeparators">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListGetSelectedView" android:label="ListGetSelectedView">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListInHorizontal" android:label="ListInHorizontal">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListInVertical" android:label="ListInVertical">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListInterleaveFocusables" android:label="ListInterleaveFocusables">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListOfItemsShorterThanScreen" android:label="ListOfItemsShorterThanScreen">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListOfItemsTallerThanScreen" android:label="ListOfItemsTallerThanScreen">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListOfThinItems" android:label="ListOfThinItems">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListOfShortTallShort" android:label="ListOfShortTallShort">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListOfShortShortTallShortShort" android:label="ListOfShortShortTallShortShort">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithOffScreenNextSelectable" android:label="ListWithOffScreenNextSelectable">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithFirstScreenUnSelectable" android:label="ListWithFirstScreenUnSelectable">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+
+ <activity android:name=".listview.ListWithSeparators" android:label="ListWithSeparators">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithHeaders" android:label="ListWithHeaders">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithEditTextHeader" android:label="ListWithEditTextHeader">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+
+ <activity android:name=".listview.ListWithNoFadingEdge" android:label="ListWithNoFadingEdge">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithScreenOfNoSelectables" android:label="ListWithScreenOfNoSelectables">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListItemFocusablesFarApart" android:label="ListItemFocusablesFarApart">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListItemFocusableAboveUnfocusable" android:label="ListItemFocusableAboveUnfocusable">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListItemFocusablesClose" android:label="ListItemFocusablesClose">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListLastItemPartiallyVisible" android:label="ListLastItemPartiallyVisible">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListItemsExpandOnSelection" android:label="ListItemsExpandOnSelection">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithOnItemSelectedAction" android:label="ListWithOnItemSelectedAction">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListItemISVAndButton" android:label="ListItemISVAndButton">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListOfTouchables" android:label="ListOfTouchables">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListRecyclerProfiling" android:label="ListRecyclerProfiling">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListHeterogeneous" android:label="ListHeterogeneous">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListHorizontalFocusWithinItemWins" android:label="ListHorizontalFocusWithinItemWins">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListManagedCursor" android:label="ListManagedCursor">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithEmptyView" android:label="ListWithEmptyView">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridInHorizontal" android:label="GridInHorizontal">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridPadding" android:label="GridPadding">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridInVertical" android:label="GridInVertical">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridScrollListener" android:label="GridScrollListener">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridThrasher" android:label="GridThrasher">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridSimple" android:label="GridSimple">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridDelete" android:label="GridDelete">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridSetSelection" android:label="GridSetSelection">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridSetSelectionMany" android:label="GridSetSelectionMany">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridSetSelectionStackFromBottom" android:label="GridSetSelectionStackFromBottom">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridSetSelectionStackFromBottomMany" android:label="GridSetSelectionStackFromBottomMany">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridStackFromBottom" android:label="GridStackFromBottom">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridStackFromBottomMany" android:label="GridStackFromBottomMany">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridVerticalSpacing" android:label="GridVerticalSpacing">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridVerticalSpacingStackFromBottom" android:label="GridVerticalSpacingStackFromBottom">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".gridview.GridSingleColumn" android:label="GridSingleColumn">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".menus.ListContextMenu" android:label="ListContextMenu">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.ViewGroupChildren" android:label="ViewGroup Children">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.RemoteViewsActivity" android:label="RemoteViewsActicity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".drawable.BitmapDrawable" android:label="BitmapDrawable">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".drawable.DrawableBgMinSize" android:label="DrawableBgMinSize">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".drawable.MutateDrawable" android:label="MutateDrawable">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".activity.TranslucentFancyActivity" android:label="TranslucentFancyActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".view.Longpress" android:label="Longpress">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".expandablelistview.ExpandableListWithHeaders" android:label="ExpandableListWithHeaders">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".listview.ListWithDisappearingItemBug" android:label="ListWithDisappearingItemBug">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".menus.MenuWith1Item" android:label="MenuWith1Item">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".menus.MenuLayoutPortrait" android:label="MenuLayoutPortrait"
+ android:screenOrientation="portrait">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".menus.MenuLayoutLandscape" android:label="MenuLayoutLandscape"
+ android:screenOrientation="landscape">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".expandablelistview.InflatedExpandableListView" android:label="ExpandableListView Inflated">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".expandablelistview.ExpandableListSimple" android:label="ExpandableListSimple">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".settings.RingtonePickerActivityLauncher" android:label="RingtonePickerActivityLauncher">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name=".settings.BrightnessLimit" android:label="BrightnessLimit">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ <activity android:name="android.widget.AutoCompleteTextViewSimple"
+ android:label="AutoCompleteTextViewSimple">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+ </intent-filter>
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/tests/FrameworkTest/README b/tests/FrameworkTest/README
new file mode 100644
index 0000000..d6d0042
--- /dev/null
+++ b/tests/FrameworkTest/README
@@ -0,0 +1,8 @@
+FrameworkTestApplication should hold snippets of functionality that are
+helpful for testing the UI framework code, but not appropriate for
+sample code. For instance, a layout contrived to exercise an edge case
+of scrolling behavior.
+
+InstrumentationTestCases should be added under tests and added to the
+list of tests in FrameworkInstrumentationTestRunner.
+
diff --git a/tests/FrameworkTest/res/drawable/big_drawable_background.9.png b/tests/FrameworkTest/res/drawable/big_drawable_background.9.png
new file mode 100644
index 0000000..aded635
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/big_drawable_background.9.png
Binary files differ
diff --git a/tests/FrameworkTest/res/drawable/bitmap_drawable.xml b/tests/FrameworkTest/res/drawable/bitmap_drawable.xml
new file mode 100644
index 0000000..35673ec
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/bitmap_drawable.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:gravity="top|right" />
diff --git a/tests/FrameworkTest/res/drawable/black_square.png b/tests/FrameworkTest/res/drawable/black_square.png
new file mode 100644
index 0000000..1bfe0a2
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/black_square.png
Binary files differ
diff --git a/tests/FrameworkTest/res/drawable/black_square_stretchable.9.png b/tests/FrameworkTest/res/drawable/black_square_stretchable.9.png
new file mode 100644
index 0000000..1fcbeb1
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/black_square_stretchable.9.png
Binary files differ
diff --git a/tests/FrameworkTest/res/drawable/box.xml b/tests/FrameworkTest/res/drawable/box.xml
new file mode 100644
index 0000000..6849bd34
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/box.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/res/drawable/box.xml
+**
+** Copyright 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.
+*/
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="#00000000"/>
+ <stroke android:width="1dp" color="#ff000000"/>
+ <padding android:left="1dp" android:top="1dp"
+ android:right="1dp" android:bottom="1dp" />
+</shape>
diff --git a/tests/FrameworkTest/res/drawable/drawable_background.9.png b/tests/FrameworkTest/res/drawable/drawable_background.9.png
new file mode 100644
index 0000000..1337ba9
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/drawable_background.9.png
Binary files differ
diff --git a/tests/FrameworkTest/res/drawable/sym_now_playing_pause_1.png b/tests/FrameworkTest/res/drawable/sym_now_playing_pause_1.png
new file mode 100644
index 0000000..2f19d08
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/sym_now_playing_pause_1.png
Binary files differ
diff --git a/tests/FrameworkTest/res/drawable/sym_now_playing_skip_backward_1.png b/tests/FrameworkTest/res/drawable/sym_now_playing_skip_backward_1.png
new file mode 100644
index 0000000..f945a81
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/sym_now_playing_skip_backward_1.png
Binary files differ
diff --git a/tests/FrameworkTest/res/drawable/sym_now_playing_skip_forward_1.png b/tests/FrameworkTest/res/drawable/sym_now_playing_skip_forward_1.png
new file mode 100644
index 0000000..da9361a
--- /dev/null
+++ b/tests/FrameworkTest/res/drawable/sym_now_playing_skip_forward_1.png
Binary files differ
diff --git a/tests/FrameworkTest/res/layout/add_column_in_table.xml b/tests/FrameworkTest/res/layout/add_column_in_table.xml
new file mode 100644
index 0000000..62c27f3
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/add_column_in_table.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TableLayout android:id="@+id/table"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1.0">
+
+ <TableRow>
+ <TextView
+ android:text="@string/table_layout_a"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_b"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_c"
+ android:padding="3dip" />
+ </TableRow>
+
+ </TableLayout>
+
+ <Button android:id="@+id/add_row_button"
+ android:text="@string/add_row_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/autocompletetextview_simple.xml b/tests/FrameworkTest/res/layout/autocompletetextview_simple.xml
new file mode 100644
index 0000000..d408a86
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/autocompletetextview_simple.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/baseline_1.xml
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <AutoCompleteTextView
+ android:id="@+id/autocompletetextview1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:inputType="text|textAutoComplete"
+ android:completionThreshold="1" />
+ />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/baseline_0width_and_weight.xml b/tests/FrameworkTest/res/layout/baseline_0width_and_weight.xml
new file mode 100644
index 0000000..83f3fcb
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/baseline_0width_and_weight.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+*
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+ <LinearLayout android:id="@+id/layout"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:visibility="gone">
+ <com.android.frameworktest.layout.linear.ExceptionTextView
+ android:id="@+id/routeToField"
+ android:textSize="16sp"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="wrap_content"
+ android:lines="2"
+ android:autoText="false"
+ android:capitalize="none"
+ android:maxLines="1" />
+ <Button
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="fill_vertical"
+ android:text="@string/side_button_label" />
+ </LinearLayout>
+ <Button android:id="@+id/show"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:text="@string/show" />
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/baseline_buttons.xml b/tests/FrameworkTest/res/layout/baseline_buttons.xml
new file mode 100644
index 0000000..ae942017
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/baseline_buttons.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+*
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView android:id="@+id/currenttime"
+ android:text="@string/time"
+ android:textSize="12sp"
+ android:textStyle="bold"
+ android:layout_gravity="bottom"
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content" />
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center">
+
+ <ImageButton android:id="@+id/prev"
+ android:src="@drawable/sym_now_playing_skip_backward_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageButton android:id="@+id/pause"
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageButton android:id="@+id/next"
+ android:src="@drawable/sym_now_playing_skip_forward_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+ <TextView android:id="@+id/totaltime"
+ android:textSize="12sp"
+ android:textStyle="bold"
+ android:gravity="right"
+ android:text="@string/time"
+ android:layout_gravity="bottom"
+ android:layout_weight="1"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/baseline_center_gravity.xml b/tests/FrameworkTest/res/layout/baseline_center_gravity.xml
new file mode 100644
index 0000000..9793ab4
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/baseline_center_gravity.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+*
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <Button android:id="@+id/button1"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/side_button_label" />
+ <Button android:id="@+id/button2"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/side_button_label" />
+ <Button android:id="@+id/button3"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/side_button_label" />
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/brightness_limit.xml b/tests/FrameworkTest/res/layout/brightness_limit.xml
new file mode 100644
index 0000000..46e5767
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/brightness_limit.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<!-- Tries to set brightness to 0. See corresponding Java code. -->
+
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/go"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/go"/>
+
diff --git a/tests/FrameworkTest/res/layout/descendant_focusability.xml b/tests/FrameworkTest/res/layout/descendant_focusability.xml
new file mode 100644
index 0000000..6a30d50d
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/descendant_focusability.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ >
+
+ <LinearLayout
+ android:id="@+id/beforeDescendants"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:descendantFocusability="beforeDescendants"
+ >
+ <Button
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/afterDescendants"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:descendantFocusability="afterDescendants"
+ >
+ <Button
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ </LinearLayout>
+
+ <LinearLayout
+ android:id="@+id/blocksDescendants"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:descendantFocusability="blocksDescendants"
+ >
+ <Button
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/disabled.xml b/tests/FrameworkTest/res/layout/disabled.xml
new file mode 100644
index 0000000..ed7ff06
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/disabled.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Demonstrates changing view visibility. See corresponding Java code. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/clickableParent"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Button android:id="@+id/disabledButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/disabled_button"/>
+
+ <Button android:id="@+id/disabledButtonA"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/disabled_button"/>
+
+ <Button android:id="@+id/disabledButtonB"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/disabled_button"/>
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/drawable_background_minimum_size.xml b/tests/FrameworkTest/res/layout/drawable_background_minimum_size.xml
new file mode 100644
index 0000000..ea0cbfa
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/drawable_background_minimum_size.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <Button
+ android:id="@+id/change_backgrounds"
+ android:text="@string/change_backgrounds"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <!-- Different views and layouts that should initially be small but still contain
+ some content (hence the minimal text inside each of the layouts). Each of these
+ will each be tested to make sure they expand to at least the minimum size
+ recommended by different backgrounds -->
+
+ <TextView
+ android:id="@+id/text_view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/minimal_text" />
+
+ <LinearLayout
+ android:id="@+id/linear_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/minimal_text" />
+
+ </LinearLayout>
+
+ <RelativeLayout
+ android:id="@+id/relative_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/minimal_text" />
+
+ </RelativeLayout>
+
+ <FrameLayout
+ android:id="@+id/frame_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/minimal_text" />
+
+ </FrameLayout>
+
+ <AbsoluteLayout
+ android:id="@+id/absolute_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/minimal_text" />
+
+ </AbsoluteLayout>
+
+ </LinearLayout>
+
+</ScrollView>
diff --git a/tests/FrameworkTest/res/layout/fill_in_wrap.xml b/tests/FrameworkTest/res/layout/fill_in_wrap.xml
new file mode 100644
index 0000000..b61fd30
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/fill_in_wrap.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight"
+ android:orientation="horizontal"
+ android:baselineAligned="false"
+ android:gravity="center_vertical">
+
+ <Button
+ android:layout_width="100dip"
+ android:layout_height="wrap_content"
+ android:gravity="left|center_vertical"
+ />
+
+ <LinearLayout android:id="@+id/layout"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="0dip"
+ android:paddingRight="0dip"
+ android:paddingTop="2dip"
+ android:paddingBottom="2dip"
+ android:orientation="horizontal"
+ android:baselineAligned="false"
+ android:addStatesFromChildren="true"
+ android:background="@android:drawable/edit_text"
+ android:gravity="center_vertical">
+
+ <EditText android:id="@+id/data"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="fill_parent"
+ android:layout_marginLeft="8dip"
+ android:paddingBottom="4dip"
+ android:layout_gravity="center_vertical"
+ android:background="@null"
+ />
+
+ <ImageButton
+ style="@android:style/Widget.Button.Inset"
+ android:src="@android:drawable/ic_delete"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="2dip"
+ android:gravity="center"
+ />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/focus_after_removal.xml b/tests/FrameworkTest/res/layout/focus_after_removal.xml
new file mode 100644
index 0000000..7cf6cbe
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/focus_after_removal.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/baseline_1.xml
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <LinearLayout android:id="@+id/leftLayout"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <Button android:id="@+id/topLeftButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dip"
+ android:text="@string/left_top" />
+ <Button android:id="@+id/bottomLeftButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dip"
+ android:text="@string/left_bottom" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <Button android:id="@+id/topRightButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dip"
+ android:text="@string/right_top" />
+ <Button android:id="@+id/bottomRightButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dip"
+ android:text="@string/right_bottom" />
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/focus_listener.xml b/tests/FrameworkTest/res/layout/focus_listener.xml
new file mode 100644
index 0000000..a838205
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/focus_listener.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/baseline_1.xml
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <Button android:id="@+id/left"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dip"
+ android:text="@string/left_top" />
+
+ <Button android:id="@+id/right"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="3dip"
+ android:text="@string/left_bottom" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/framelayout_gravity.xml b/tests/FrameworkTest/res/layout/framelayout_gravity.xml
new file mode 100644
index 0000000..ce48825
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/framelayout_gravity.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/parent"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Button android:id="@+id/left"
+ android:layout_gravity="left"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/right"
+ android:layout_gravity="right"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/center_horizontal"
+ android:layout_gravity="center_horizontal"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/left_center_vertical"
+ android:layout_gravity="center_vertical|left"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/right_center_vertical"
+ android:layout_gravity="center_vertical|right"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/center"
+ android:layout_gravity="center"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/left_bottom"
+ android:layout_gravity="bottom|left"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/right_bottom"
+ android:layout_gravity="bottom|right"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/center_horizontal_bottom"
+ android:layout_gravity="bottom|center_horizontal"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</FrameLayout>
diff --git a/tests/FrameworkTest/res/layout/framelayout_margin.xml b/tests/FrameworkTest/res/layout/framelayout_margin.xml
new file mode 100644
index 0000000..1e14899
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/framelayout_margin.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/parent"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Button android:id="@+id/left"
+ android:layout_gravity="left"
+ android:layout_marginLeft="12dip"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/right"
+ android:layout_gravity="right"
+ android:layout_marginRight="12dip"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/top"
+ android:layout_gravity="top|center_horizontal"
+ android:layout_marginTop="12dip"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/bottom"
+ android:layout_gravity="bottom|center_horizontal"
+ android:layout_marginBottom="12dip"
+ android:text="@string/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</FrameLayout>
diff --git a/tests/FrameworkTest/res/layout/grid_in_horizontal.xml b/tests/FrameworkTest/res/layout/grid_in_horizontal.xml
new file mode 100644
index 0000000..835dce3
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/grid_in_horizontal.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <GridView android:id="@+id/grid"
+ android:layout_width="0dip"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:padding="10dip"
+ android:verticalSpacing="10dp"
+ android:horizontalSpacing="10dp"
+ android:numColumns="auto_fit"
+ android:columnWidth="60dp"
+ android:stretchMode="columnWidth" />
+
+ <ImageButton
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/grid_in_vertical.xml b/tests/FrameworkTest/res/layout/grid_in_vertical.xml
new file mode 100644
index 0000000..731bc54
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/grid_in_vertical.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <GridView android:id="@+id/grid"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:numColumns="auto_fit" />
+
+ <ImageButton
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageButton
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageButton
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/grid_padding.xml b/tests/FrameworkTest/res/layout/grid_padding.xml
new file mode 100644
index 0000000..bd666e1
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/grid_padding.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<GridView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/grid"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="10dip"
+ android:verticalSpacing="10dp"
+ android:horizontalSpacing="10dp"
+ android:numColumns="auto_fit"
+ android:columnWidth="50dp" />
diff --git a/tests/FrameworkTest/res/layout/grid_scroll_listener.xml b/tests/FrameworkTest/res/layout/grid_scroll_listener.xml
new file mode 100644
index 0000000..c02aed9
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/grid_scroll_listener.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <GridView android:id="@+id/grid"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:padding="10dip"
+ android:verticalSpacing="10dp"
+ android:horizontalSpacing="10dp"
+ android:numColumns="auto_fit"
+ android:columnWidth="60dp"
+ android:stretchMode="columnWidth"
+ android:gravity="center"/>
+
+ <TextView android:id="@+id/text"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/grid_thrasher.xml b/tests/FrameworkTest/res/layout/grid_thrasher.xml
new file mode 100644
index 0000000..1a260df
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/grid_thrasher.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <GridView android:id="@+id/grid"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="10dip"
+ android:verticalSpacing="10dp"
+ android:horizontalSpacing="10dp"
+ android:numColumns="auto_fit"
+ android:columnWidth="60dp"
+ android:stretchMode="columnWidth"
+ android:gravity="center"/>
+
+ <TextView android:id="@+id/text"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/include_button.xml b/tests/FrameworkTest/res/layout/include_button.xml
new file mode 100644
index 0000000..5857fa3
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/include_button.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/included_button"
+ android:text="@string/include_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
diff --git a/tests/FrameworkTest/res/layout/include_button_with_size.xml b/tests/FrameworkTest/res/layout/include_button_with_size.xml
new file mode 100644
index 0000000..0cd8eaa
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/include_button_with_size.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/included_button"
+ android:text="@string/include_button"
+ android:layout_width="23dip"
+ android:layout_height="23dip" />
diff --git a/tests/FrameworkTest/res/layout/include_tag.xml b/tests/FrameworkTest/res/layout/include_tag.xml
new file mode 100644
index 0000000..d1047f1
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/include_tag.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <include
+ layout="@layout/include_button" />
+
+ <include
+ layout="@layout/include_button"
+ android:id="@+id/included_button_overriden"
+ android:layout_width="237dip"
+ android:layout_height="123dip" />
+
+ <include
+ layout="@layout/include_button"
+ android:id="@+id/included_button_visibility"
+ android:visibility="invisible" />
+
+ <include
+ layout="@layout/include_button_with_size"
+ android:id="@+id/included_button_with_size" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/inflated_expandablelistview.xml b/tests/FrameworkTest/res/layout/inflated_expandablelistview.xml
new file mode 100644
index 0000000..d01e7c5
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/inflated_expandablelistview.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<ExpandableListView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/elv"
+ android:layout_height="fill_parent"
+ android:layout_width="fill_parent" />
diff --git a/tests/FrameworkTest/res/layout/linear_layout_buttons.xml b/tests/FrameworkTest/res/layout/linear_layout_buttons.xml
new file mode 100644
index 0000000..f60692a
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/linear_layout_buttons.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/baseline_1.xml
+**
+** Copyright 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"
+ android:text="@string/keypad_one"/>
+
+ <Button
+ android:id="@+id/button2"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"
+ android:text="@string/keypad_two"/>
+
+ <Button
+ android:id="@+id/button3"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"
+ android:text="@string/keypad_three"/>
+
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/linear_layout_edittext_then_button.xml b/tests/FrameworkTest/res/layout/linear_layout_edittext_then_button.xml
new file mode 100644
index 0000000..21e7399
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/linear_layout_edittext_then_button.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/baseline_1.xml
+**
+** Copyright 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <EditText
+ android:id="@+id/editText"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"/>
+
+ <Button
+ android:id="@+id/button"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"
+ android:text="@string/keypad_one"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/linear_layout_grid.xml b/tests/FrameworkTest/res/layout/linear_layout_grid.xml
new file mode 100644
index 0000000..81f7b15
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/linear_layout_grid.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/baseline_1.xml
+**
+** Copyright 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <LinearLayout android:id="@+id/column1"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"
+ android:orientation="horizontal">
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_one"/>
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_two"/>
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_three"/>
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/column2"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"
+ android:orientation="horizontal">
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_four"/>
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_five"/>
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_six"/>
+ </LinearLayout>
+
+ <LinearLayout android:id="@+id/column3"
+ android:layout_width="fill_parent"
+ android:layout_height="0sp"
+ android:layout_weight="1"
+ android:orientation="horizontal">
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_seven"/>
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_eight"/>
+
+ <Button
+ android:layout_width="0sp"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"
+ android:text="@string/keypad_nine"/>
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/linear_layout_listview_height.xml b/tests/FrameworkTest/res/layout/linear_layout_listview_height.xml
new file mode 100644
index 0000000..10ef2ce
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/linear_layout_listview_height.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <!-- Outer linear layout providing vertical layout -->
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <!-- The control buttons -->
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:id="@+id/button1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/linear_listheight_fixed"/>
+
+ <Button
+ android:id="@+id/button2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/linear_listheight_fill"/>
+
+ <Button
+ android:id="@+id/button3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/linear_listheight_hide"/>
+ </LinearLayout>
+
+ <!-- The list view -->
+ <ListView
+ android:id="@+id/inner_list"
+ android:layout_width="200dip"
+ android:layout_height="fill_parent"
+ android:background="@android:drawable/spinner_dropdown_background"
+ android:divider="@android:drawable/divider_horizontal_bright" />
+
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/linear_layout_spinner_then_button.xml b/tests/FrameworkTest/res/layout/linear_layout_spinner_then_button.xml
new file mode 100644
index 0000000..7ed245b
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/linear_layout_spinner_then_button.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <Spinner android:id="@+id/reminder_value"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.7"
+ android:entries="@array/reminder_minutes_labels"/>
+
+ <Button android:id="@+id/reminder_remove"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="0.3"
+ android:text="@string/show" />
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/linear_layout_textviews.xml b/tests/FrameworkTest/res/layout/linear_layout_textviews.xml
new file mode 100644
index 0000000..84a898c
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/linear_layout_textviews.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:background="#FFFF0000"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <EditText
+ android:id="@+id/editText1"
+ android:text="@string/text"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+ <EditText
+ android:id="@+id/editText2"
+ android:text="@string/text"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/linear_layout_weight.xml b/tests/FrameworkTest/res/layout/linear_layout_weight.xml
new file mode 100644
index 0000000..bb138df
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/linear_layout_weight.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:background="#FFFFFFFF"
+ android:orientation="horizontal"
+ android:layout_width="87dip"
+ android:layout_height="wrap_content">
+
+ <View
+ android:id="@+id/child1"
+ android:background="#FFFF0000"
+ android:layout_width="20dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+ <View
+ android:id="@+id/child2"
+ android:background="#FF00FF00"
+ android:layout_width="20dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+ <View
+ android:background="#FF0000FF"
+ android:id="@+id/child3"
+ android:layout_width="20dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+ <View
+ android:background="#FFFF00FF"
+ android:id="@+id/child4"
+ android:layout_width="20dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.0" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_dividers.xml b/tests/FrameworkTest/res/layout/list_dividers.xml
new file mode 100644
index 0000000..b56511e
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_dividers.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ListView android:id="@android:id/list"
+ android:paddingRight="15dip"
+ android:layout_marginLeft="50dip"
+ android:layout_width="150dip"
+ android:layout_height="300dip" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_filter.xml b/tests/FrameworkTest/res/layout/list_filter.xml
new file mode 100644
index 0000000..cea518c
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_filter.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <FrameLayout android:id="@+id/frame"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1">
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:drawSelectorOnTop="false" />
+
+ </FrameLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <Button android:id="@+id/hide"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/hide" />
+
+ <Button android:id="@+id/show"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/show" />
+
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_in_horizontal.xml b/tests/FrameworkTest/res/layout/list_in_horizontal.xml
new file mode 100644
index 0000000..371cb84
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_in_horizontal.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TableRow>
+
+ <ListView android:id="@+id/list" />
+
+ <ImageButton android:src="@drawable/sym_now_playing_pause_1" />
+
+ </TableRow>
+
+</TableLayout>
diff --git a/tests/FrameworkTest/res/layout/list_in_vertical.xml b/tests/FrameworkTest/res/layout/list_in_vertical.xml
new file mode 100644
index 0000000..0ea2475
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_in_vertical.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <ListView android:id="@+id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
+
+ <ImageButton
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageButton
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageButton
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+</ScrollView>
diff --git a/tests/FrameworkTest/res/layout/list_recycler_profiling.xml b/tests/FrameworkTest/res/layout/list_recycler_profiling.xml
new file mode 100644
index 0000000..9678eb7
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_recycler_profiling.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <ListView android:id="@+id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1.0" />
+
+ <ImageButton android:id="@+id/pause"
+ android:src="@drawable/sym_now_playing_pause_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_scroll_listener.xml b/tests/FrameworkTest/res/layout/list_scroll_listener.xml
new file mode 100644
index 0000000..001296a
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_scroll_listener.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:drawSelectorOnTop="false"/>
+
+ <TextView android:id="@+id/text"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_take_focus_from_side.xml b/tests/FrameworkTest/res/layout/list_take_focus_from_side.xml
new file mode 100644
index 0000000..cf141cc
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_take_focus_from_side.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="fill_parent"
+ android:drawSelectorOnTop="false"/>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent">
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ <Button
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/side_button_label" />
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_thrasher.xml b/tests/FrameworkTest/res/layout/list_thrasher.xml
new file mode 100644
index 0000000..001296a
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_thrasher.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:drawSelectorOnTop="false"/>
+
+ <TextView android:id="@+id/text"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_with_button_above.xml b/tests/FrameworkTest/res/layout/list_with_button_above.xml
new file mode 100644
index 0000000..25db016
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_with_button_above.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Simple layout with a button and a list below, can be used to build more
+ sophisticated test cases by adding stuff to the list programatically.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+
+ <Button android:id="@+id/button"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/button_above_list_label"/>
+
+
+ <ListView android:id="@android:id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:paddingTop="2dip"
+ android:drawSelectorOnTop="false"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_with_disappearing_item_bug_item.xml b/tests/FrameworkTest/res/layout/list_with_disappearing_item_bug_item.xml
new file mode 100644
index 0000000..0163d96
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_with_disappearing_item_bug_item.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 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.
+-->
+
+<!-- A layout is needed to reprod the bug. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="?android:attr/listPreferredItemHeight">
+
+ <TextView
+ android:id="@+id/text1"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:gravity="center_vertical"
+ android:paddingLeft="27dip"
+ />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/list_with_empty_view.xml b/tests/FrameworkTest/res/layout/list_with_empty_view.xml
new file mode 100644
index 0000000..00d81a7
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/list_with_empty_view.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" >
+
+ <ListView android:id="@android:id/list"
+ android:drawSelectorOnTop="false"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"/>
+
+ <TextView android:id="@+id/empty"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:gravity="center"
+ android:textSize="36sp"
+ android:textColor="#999"
+ android:visibility="gone"
+ android:text="@string/empty_list" />
+
+</FrameLayout>
diff --git a/tests/FrameworkTest/res/layout/longpress.xml b/tests/FrameworkTest/res/layout/longpress.xml
new file mode 100644
index 0000000..ef3672c
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/longpress.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <View android:id="@+id/simple_view"
+ android:background="@drawable/blue"
+ android:layout_width="20dip"
+ android:layout_height="20dip"
+ android:focusable="true" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/mail_message.xml b/tests/FrameworkTest/res/layout/mail_message.xml
new file mode 100644
index 0000000..ed52751
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/mail_message.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- A layout similar to a gmail message. useful for setting up tests, like
+ a list with a list of messages.-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TextView android:id="@+id/subject"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ <WebView android:id="@+id/body"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/merge_child.xml b/tests/FrameworkTest/res/layout/merge_child.xml
new file mode 100644
index 0000000..9972924
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/merge_child.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</merge>
diff --git a/tests/FrameworkTest/res/layout/merge_tag.xml b/tests/FrameworkTest/res/layout/merge_tag.xml
new file mode 100644
index 0000000..9eec493
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/merge_tag.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <TextView
+ android:text="@string/include_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <include layout="@layout/merge_child" />
+
+</merge>
diff --git a/tests/FrameworkTest/res/layout/popup_window_visibility.xml b/tests/FrameworkTest/res/layout/popup_window_visibility.xml
new file mode 100644
index 0000000..21c94bb
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/popup_window_visibility.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <FrameLayout android:id="@+id/frame"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1">
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Spinner android:id="@+id/spinner"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
+
+ <AutoCompleteTextView android:id="@+id/auto"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+ </FrameLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <Button android:id="@+id/hide"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/hide" />
+
+ <Button android:id="@+id/show"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/show" />
+
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/pre_draw_listener.xml b/tests/FrameworkTest/res/layout/pre_draw_listener.xml
new file mode 100644
index 0000000..d348d9f
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/pre_draw_listener.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+
+ <ScrollView
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1">
+
+ <view class="com.android.frameworktest.view.PreDrawListener$MyLinearLayout" android:id="@+id/frame"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+
+ </ScrollView>
+
+ <Button android:id="@+id/go"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/go" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/remote_view_host.xml b/tests/FrameworkTest/res/layout/remote_view_host.xml
new file mode 100644
index 0000000..dc52181
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/remote_view_host.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/remote_view_test_bad_1.xml b/tests/FrameworkTest/res/layout/remote_view_test_bad_1.xml
new file mode 100644
index 0000000..6a65976
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/remote_view_test_bad_1.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linear"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <EditText android:id="@+id/edit"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/remote_view_test_bad_2.xml b/tests/FrameworkTest/res/layout/remote_view_test_bad_2.xml
new file mode 100644
index 0000000..70613c3
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/remote_view_test_bad_2.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linear"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <WebView android:id="@+id/web"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/remote_view_test_good.xml b/tests/FrameworkTest/res/layout/remote_view_test_good.xml
new file mode 100644
index 0000000..54f4db9
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/remote_view_test_good.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/linear"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <TextView android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView android:id="@+id/image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <FrameLayout android:id="@+id/frame"
+ android:layout_width="10dip"
+ android:layout_height="10dip" />
+
+ <RelativeLayout android:id="@+id/relative"
+ android:layout_width="10dip"
+ android:layout_height="10dip" />
+
+ <AbsoluteLayout android:id="@+id/absolute"
+ android:layout_width="10dip"
+ android:layout_height="10dip" />
+
+ <ProgressBar android:id="@+id/progress"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageButton android:id="@+id/image_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <Button android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/scroll_to_rect_with_internal_scroll.xml b/tests/FrameworkTest/res/layout/scroll_to_rect_with_internal_scroll.xml
new file mode 100644
index 0000000..d22122d
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/scroll_to_rect_with_internal_scroll.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/scroll_view_1.xml
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/scrollView"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+
+ <Button android:id="@+id/scrollToBlob"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/scroll_top_button"/>
+
+ <TextView android:id="@+id/blob"
+ android:layout_width="fill_parent"
+ android:layout_height="80dip"
+ android:layout_marginTop="500dip"
+ android:layout_marginBottom="5dip"/>
+
+
+ </LinearLayout>
+</ScrollView>
diff --git a/tests/FrameworkTest/res/layout/scroll_to_rectangle.xml b/tests/FrameworkTest/res/layout/scroll_to_rectangle.xml
new file mode 100644
index 0000000..0839b1a
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/scroll_to_rectangle.xml
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/layout/scroll_view_1.xml
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Demonstrates scrolling with a ScrollView. -->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/scrollView"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+
+ <Button android:id="@+id/scrollToRectFromTop"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/scroll_top_button"/>
+
+ <Button android:id="@+id/scrollToRectFromTop2"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingBottom="10dip"
+ android:text="@string/scroll_top_button2"/>
+
+ <TextView android:id="@+id/topBlob"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="5dip"
+ android:layout_marginBottom="5dip"/>
+
+ <TextView android:id="@+id/childToMakeVisible"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="5dip"
+ android:layout_marginBottom="5dip"
+ android:text="@string/scroll_to_me"/>
+
+ <TextView android:id="@+id/bottomBlob"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="5dip"
+ android:layout_marginBottom="5dip"/>
+
+ <Button android:id="@+id/scrollToRectFromBottom2"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="10dip"
+ android:text="@string/scroll_bottom_button2"/>
+
+ <Button android:id="@+id/scrollToRectFromBottom"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/scroll_bottom_button"/>
+
+
+ </LinearLayout>
+</ScrollView>
diff --git a/tests/FrameworkTest/res/layout/scrollview_linear_layout.xml b/tests/FrameworkTest/res/layout/scrollview_linear_layout.xml
new file mode 100644
index 0000000..536d2ed
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/scrollview_linear_layout.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/scrollView"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ </LinearLayout>
+
+
+</ScrollView>
diff --git a/tests/FrameworkTest/res/layout/scrollview_with_webviews.xml b/tests/FrameworkTest/res/layout/scrollview_with_webviews.xml
new file mode 100644
index 0000000..79634752
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/scrollview_with_webviews.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/scrollView"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:scrollbars="none">
+
+ <LinearLayout
+ android:id="@+id/layout"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+
+ <WebView android:id="@+id/wb1"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ <Button android:id="@+id/button"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ <WebView android:id="@+id/wb2"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
+
+ </LinearLayout>
+
+
+</ScrollView>
diff --git a/tests/FrameworkTest/res/layout/table_layout_cell_span.xml b/tests/FrameworkTest/res/layout/table_layout_cell_span.xml
new file mode 100644
index 0000000..26831e4
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/table_layout_cell_span.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TableRow>
+ <TextView android:id="@+id/a"
+ android:text="@string/table_layout_a"
+ android:background="#FFFF0000"
+ android:padding="3dip" />
+ <TextView android:id="@+id/b"
+ android:text="@string/table_layout_b"
+ android:background="#FF00FF00"
+ android:padding="3dip" />
+ <TextView android:id="@+id/c"
+ android:text="@string/table_layout_c"
+ android:background="#FF0000FF"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <TextView android:id="@+id/spanThenCell"
+ android:text="@string/table_layout_d"
+ android:layout_span="2"
+ android:gravity="center_horizontal"
+ android:background="#FF0000FF"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_e"
+ android:background="#FF00FF00"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <TextView
+ android:text="@string/table_layout_f"
+ android:background="#FFFF00FF"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_g"
+ android:background="#FF00FF00"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_h"
+ android:background="#FFFF0000"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <TextView
+ android:text="@string/table_layout_a"
+ android:background="#FF00FF00"
+ android:padding="3dip" />
+ <TextView android:id="@+id/cellThenSpan"
+ android:text="@string/table_layout_b"
+ android:layout_span="2"
+ android:gravity="center_horizontal"
+ android:background="#FF0000FF"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <TextView android:id="@+id/span"
+ android:text="@string/table_layout_g"
+ android:layout_span="3"
+ android:gravity="center_horizontal"
+ android:background="#FFC0C0C0"
+ android:padding="3dip" />
+ </TableRow>
+</TableLayout>
diff --git a/tests/FrameworkTest/res/layout/table_layout_fixed_width.xml b/tests/FrameworkTest/res/layout/table_layout_fixed_width.xml
new file mode 100644
index 0000000..91d9128
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/table_layout_fixed_width.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TableRow>
+ <View android:id="@+id/fixed_height"
+ android:layout_height="48dip"
+ android:background="#FF909090" />
+ <TextView android:id="@+id/fixed_width"
+ android:layout_width="150dip"
+ android:text="@string/table_layout_export"
+ android:background="#FFFF0000"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_export_shortcut"
+ android:background="#FF00FFFF"
+ android:gravity="right"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <View
+ android:layout_height="48dip"
+ android:background="#FF909090" />
+ <TextView android:id="@+id/non_fixed_width"
+ android:text="@string/table_layout_export"
+ android:background="#FFFF0000"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_export_shortcut"
+ android:background="#FF00FFFF"
+ android:gravity="right"
+ android:padding="3dip" />
+ </TableRow>
+
+</TableLayout>
diff --git a/tests/FrameworkTest/res/layout/table_layout_horizontal_gravity.xml b/tests/FrameworkTest/res/layout/table_layout_horizontal_gravity.xml
new file mode 100644
index 0000000..dee81a5
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/table_layout_horizontal_gravity.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:stretchColumns="1">
+
+ <TableRow>
+ <TextView android:id="@+id/reference"
+ android:layout_column="1"
+ android:background="#FF0000FF"
+ android:text="@string/table_layout_open"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_open_shortcut"
+ android:gravity="right"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <!-- Horizontally centers the content of the cell -->
+ <TextView android:id="@+id/center"
+ android:layout_column="1"
+ android:text="@string/table_layout_save_as"
+ android:background="#FFFF0000"
+ android:layout_gravity="center_horizontal"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_save_as_shortcut"
+ android:background="#FFFF00FF"
+ android:gravity="right"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <View
+ android:layout_height="24dip"
+ android:background="#FF909090" />
+ <!-- Aligns the content of the cell to the bottom right -->
+ <TextView android:id="@+id/bottomRight"
+ android:text="@string/table_layout_export"
+ android:background="#FFFF0000"
+ android:layout_gravity="right|bottom"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_export_shortcut"
+ android:background="#FF00FFFF"
+ android:gravity="right"
+ android:padding="3dip" />
+ </TableRow>
+
+
+ <TableRow>
+ <TextView android:id="@+id/left"
+ android:layout_column="1"
+ android:background="#FF0000FF"
+ android:text="@string/table_layout_open"
+ android:padding="3dip" />
+ <TextView
+ android:text="@string/table_layout_open_shortcut"
+ android:gravity="right"
+ android:padding="3dip" />
+ </TableRow>
+</TableLayout>
diff --git a/tests/FrameworkTest/res/layout/table_layout_vertical_gravity.xml b/tests/FrameworkTest/res/layout/table_layout_vertical_gravity.xml
new file mode 100644
index 0000000..6a8b784
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/table_layout_vertical_gravity.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TableRow>
+ <View android:id="@+id/reference1"
+ android:layout_height="96dip"
+ android:background="#FF909090" />
+ <TextView
+ android:background="#FF0000FF"
+ android:text="@string/table_layout_open"
+ android:padding="3dip" />
+ <TextView android:id="@+id/cell_top"
+ android:background="#FF00FF00"
+ android:layout_gravity="top"
+ android:text="@string/table_layout_open_shortcut"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <View android:id="@+id/reference2"
+ android:layout_height="96dip"
+ android:background="#FF909090" />
+ <TextView
+ android:background="#FF0000FF"
+ android:text="@string/table_layout_open"
+ android:padding="3dip" />
+ <TextView android:id="@+id/cell_center"
+ android:background="#FF00FF00"
+ android:layout_gravity="center_vertical"
+ android:text="@string/table_layout_open_shortcut"
+ android:padding="3dip" />
+ </TableRow>
+
+ <TableRow>
+ <View android:id="@+id/reference3"
+ android:layout_height="96dip"
+ android:background="#FF909090" />
+ <TextView
+ android:background="#FF0000FF"
+ android:text="@string/table_layout_open"
+ android:padding="3dip" />
+ <TextView android:id="@+id/cell_bottom"
+ android:background="#FF00FF00"
+ android:layout_gravity="bottom"
+ android:text="@string/table_layout_open_shortcut"
+ android:padding="3dip" />
+ </TableRow>
+
+</TableLayout>
diff --git a/tests/FrameworkTest/res/layout/table_layout_weight.xml b/tests/FrameworkTest/res/layout/table_layout_weight.xml
new file mode 100644
index 0000000..432c04a
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/table_layout_weight.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TableRow android:id="@+id/row"
+ android:weightSum="0.9">
+ <View android:id="@+id/cell1"
+ android:layout_width="0dip"
+ android:layout_weight="0.3"
+ android:layout_height="190dip"
+ android:background="#FF0000FF" />
+ <View android:id="@+id/cell2"
+ android:layout_width="0dip"
+ android:layout_weight="0.3"
+ android:layout_height="190dip"
+ android:background="#FFFFFFFF" />
+ <View android:id="@+id/cell3"
+ android:layout_width="0dip"
+ android:layout_weight="0.3"
+ android:layout_height="190dip"
+ android:background="#FFFF0000" />
+ </TableRow>
+
+</TableLayout>
diff --git a/tests/FrameworkTest/res/layout/translucent_background.xml b/tests/FrameworkTest/res/layout/translucent_background.xml
new file mode 100644
index 0000000..6b6e1cf
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/translucent_background.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- Demonstrates an activity with a fancy translucent background.
+ See corresponding Java code com.android.sdk.app.TranslucentBackground.java. -->
+
+<!-- This screen consists of a single text field that displays some text. -->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/text"
+ android:layout_width="fill_parent" android:layout_height="fill_parent"
+ android:gravity="center_vertical|center_horizontal"
+ android:text="@string/translucent_background"/>
diff --git a/tests/FrameworkTest/res/layout/viewgroupchildren.xml b/tests/FrameworkTest/res/layout/viewgroupchildren.xml
new file mode 100644
index 0000000..a5bb7cb
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/viewgroupchildren.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Demonstrates adding/removing views from ViewGroup. See corresponding Java code. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/group"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/viewstub.xml b/tests/FrameworkTest/res/layout/viewstub.xml
new file mode 100644
index 0000000..9a6f376
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/viewstub.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Button android:id="@+id/vis"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_vis" />
+
+ <ViewStub android:id="@+id/viewStub"
+ android:layout="@layout/linear_layout_buttons"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ViewStub android:id="@+id/viewStubWithId"
+ android:inflatedId="@+id/stub_inflated"
+ android:layout="@layout/linear_layout_buttons"
+ android:layout_width="47dip"
+ android:layout_height="127dip" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/visibility.xml b/tests/FrameworkTest/res/layout/visibility.xml
new file mode 100644
index 0000000..b4f9d8b
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/visibility.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Demonstrates changing view visibility. See corresponding Java code. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:background="@drawable/box"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+
+ <TextView android:id="@+id/refUp"
+ android:background="@drawable/red"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_view_1"/>
+
+ <TextView android:id="@+id/victim"
+ android:background="@drawable/green"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_view_2"/>
+
+ <TextView android:id="@+id/refDown"
+ android:background="@drawable/blue"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_view_3"/>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <Button android:id="@+id/vis"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_vis"/>
+
+ <Button android:id="@+id/invis"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_invis"/>
+
+ <Button android:id="@+id/gone"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_gone"/>
+
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/weight_sum.xml b/tests/FrameworkTest/res/layout/weight_sum.xml
new file mode 100644
index 0000000..249dc68
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/weight_sum.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout android:id="@+id/container" xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:weightSum="1.0"
+ android:gravity="center_horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <Button android:id="@+id/child"
+ android:layout_width="0dip"
+ android:layout_weight="0.5"
+ android:layout_height="wrap_content"
+ android:text="@string/visibility_1_vis"/>
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/with_bitmap_background.xml b/tests/FrameworkTest/res/layout/with_bitmap_background.xml
new file mode 100644
index 0000000..b32d99e
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/with_bitmap_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, 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.
+*/
+-->
+
+<LinearLayout android:id="@+id/container" xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:background="@drawable/bitmap_drawable">
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/layout/zero_sized.xml b/tests/FrameworkTest/res/layout/zero_sized.xml
new file mode 100644
index 0000000..c837bf9
--- /dev/null
+++ b/tests/FrameworkTest/res/layout/zero_sized.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+
+<!-- Demonstrates changing view visibility. See corresponding Java code. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent">
+
+ <View android:id="@+id/dimension"
+ android:background="#ffff0000"
+ android:layout_width="42dip"
+ android:layout_height="42dip" />
+
+ <View android:id="@+id/noWidth"
+ android:background="#ff00ff00"
+ android:layout_width="0dip"
+ android:layout_height="42dip" />
+
+ <View android:id="@+id/noHeight"
+ android:background="#ff0000ff"
+ android:layout_width="42dip"
+ android:layout_height="0dip" />
+
+ <View android:id="@+id/noDimension"
+ android:background="#ffffffff"
+ android:layout_width="0dip"
+ android:layout_height="0dip" />
+
+</LinearLayout>
diff --git a/tests/FrameworkTest/res/values/arrays.xml b/tests/FrameworkTest/res/values/arrays.xml
new file mode 100644
index 0000000..f76da85
--- /dev/null
+++ b/tests/FrameworkTest/res/values/arrays.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 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.
+-->
+
+<resources>
+ <string-array name="reminder_minutes_labels">
+ <item>5 minutes</item>
+ <item>10 minutes</item>
+ <item>15 minutes</item>
+ <item>20 minutes</item>
+ <item>25 minutes</item>
+ <item>30 minutes</item>
+ <item>45 minutes</item>
+ <item>1 hour</item>
+ <item>2 hours</item>
+ <item>3 hours</item>
+ <item>12 hours</item>
+ <item>24 hours</item>
+ <item>2 days</item>
+ <item>1 week</item>
+ </string-array>
+</resources>
diff --git a/tests/FrameworkTest/res/values/attrs.xml b/tests/FrameworkTest/res/values/attrs.xml
new file mode 100644
index 0000000..bf59e74
--- /dev/null
+++ b/tests/FrameworkTest/res/values/attrs.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+ <declare-styleable name="SelectableRowView">
+ <attr name="numRows" format="integer" />
+ </declare-styleable>
+</resources>
diff --git a/tests/FrameworkTest/res/values/colors.xml b/tests/FrameworkTest/res/values/colors.xml
new file mode 100644
index 0000000..f881660
--- /dev/null
+++ b/tests/FrameworkTest/res/values/colors.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/samples/SampleCode/res/values/colors.xml
+**
+** Copyright 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.
+*/
+-->
+
+<resources>
+ <drawable name="red">#ffff0000</drawable>
+ <drawable name="blue">#ff0000ff</drawable>
+ <drawable name="green">#ff00ff00</drawable>
+ <drawable name="yellow">#ffffff00</drawable>
+</resources>
diff --git a/tests/FrameworkTest/res/values/strings.xml b/tests/FrameworkTest/res/values/strings.xml
new file mode 100644
index 0000000..05b57e0
--- /dev/null
+++ b/tests/FrameworkTest/res/values/strings.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="app_name">FrameworkTestApplication</string>
+
+ <!-- FocusAfterRemoval -->
+ <string name="left_top">parent GONE</string>
+ <string name="left_bottom">parent INVISIBLE</string>
+ <string name="right_top">me GONE</string>
+ <string name="right_bottom">me INVISIBLE</string>
+
+ <!-- Strings for the 12 key dialer -->
+ <string name="keypad_one">1</string>
+ <string name="keypad_two">"2\nabc"</string>
+ <string name="keypad_three">"3\ndef"</string>
+ <string name="keypad_four">"4\nghi"</string>
+ <string name="keypad_five">"5\njkl"</string>
+ <string name="keypad_six">"6\nmno"</string>
+ <string name="keypad_seven">"7\npqrs"</string>
+ <string name="keypad_eight">"8\ntuv"</string>
+ <string name="keypad_nine">"9\nwxyz"</string>
+ <string name="keypad_zero">0</string>
+ <string name="keypad_star">*</string>
+ <string name="keypad_pound">"#"</string>
+
+
+ <!-- HorizontalGravity -->
+ <string name="table_layout_open">Open\u2026</string>
+ <string name="table_layout_open_shortcut">Ctrl-O</string>
+ <string name="table_layout_save_as">Save As\u2026</string>
+ <string name="table_layout_save_as_shortcut">Ctrl-Shift-S</string>
+ <string name="table_layout_export">Export\u2026</string>
+ <string name="table_layout_export_shortcut">Ctrl-E</string>
+
+ <!-- CellSpan -->
+ <string name="table_layout_a">A</string>
+ <string name="table_layout_b">BB</string>
+ <string name="table_layout_c">CCCC</string>
+ <string name="table_layout_d">D</string>
+ <string name="table_layout_e">E</string>
+ <string name="table_layout_f">F</string>
+ <string name="table_layout_g">G</string>
+ <string name="table_layout_h">H</string>
+
+ <!-- scroll_to_rectangle -->
+ <string name="scroll_top_button">Click to make "hi!" on screen</string>
+ <string name="scroll_top_button2">Click to make blob on screen</string>
+ <string name="scroll_to_me">hi!</string>
+ <string name="scroll_bottom_button2">Click to make blob on screen</string>
+ <string name="scroll_bottom_button">Click to make "hi!" on screen</string>
+
+ <!-- Visibility -->
+ <string name="visibility_1_view_1">View A</string>
+ <string name="visibility_1_view_2">View B</string>
+ <string name="visibility_1_view_3">View C</string>
+ <string name="visibility_1_vis">Visible</string>
+ <string name="visibility_1_invis">Invisible</string>
+ <string name="visibility_1_gone">Gone</string>
+
+ <string name="submit">submit</string>
+ <string name="cancel">cancel</string>
+ <string name="enter_title">enter title</string>
+ <string name="enter_url">enter url</string>
+
+ <!-- List with button above -->
+ <string name="button_above_list_label">Button above list</string>
+
+ <!-- List take focus from side -->
+ <string name="side_button_label">X</string>
+
+ <!-- Linear Layout show/hide & sizing -->
+ <string name="linear_listheight_fixed">Fixed Size</string>
+ <string name="linear_listheight_fill">Fill Screen</string>
+ <string name="linear_listheight_hide">Hide</string>
+
+ <!-- Baseline -->
+ <string name="show">Show</string>
+ <string name="time">00:00:00</string>
+
+ <!-- Drawable -->
+ <string name="minimal_text">a</string>
+ <string name="change_backgrounds">Change backgrounds</string>
+
+ <!-- List with empty view -->
+ <string name="empty_list">Empty list</string>
+ <string name="menu_add">Add</string>
+ <string name="menu_remove">Remove</string>
+
+ <!-- Misc. -->
+ <string name="add_row_button">Add Row</string>
+ <string name="disabled_button">Disabled</string>
+ <string name="translucent_background">Example of how you can make an
+ activity have a translucent background, compositing over
+ whatever is behind it.</string>
+ <string name="text">Lorem ipsum datum carat casus belli honorare</string>
+
+ <string name="hide">Hide</string>
+ <string name="go">Go</string>
+
+ <string name="include_label">Included views below:</string>
+ <string name="include_button">I was included!</string>
+
+ <string name="view">View</string>
+</resources>
diff --git a/tests/FrameworkTest/res/values/styles.xml b/tests/FrameworkTest/res/values/styles.xml
new file mode 100644
index 0000000..7a90197
--- /dev/null
+++ b/tests/FrameworkTest/res/values/styles.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<resources>
+ <style name="Theme" parent="android:Theme">
+ <item name="android:windowAnimationStyle">@style/Animation</item>
+ </style>
+
+ <style name="Animation">
+ <item name="android:activityOpenEnterAnimation">@null</item>
+ <item name="android:activityOpenExitAnimation">@null</item>
+ <item name="android:activityCloseEnterAnimation">@null</item>
+ <item name="android:activityCloseExitAnimation">@null</item>
+ <item name="android:taskOpenEnterAnimation">@null</item>
+ <item name="android:taskOpenExitAnimation">@null</item>
+ <item name="android:taskCloseEnterAnimation">@null</item>
+ <item name="android:taskCloseExitAnimation">@null</item>
+ <item name="android:taskToFrontEnterAnimation">@null</item>
+ <item name="android:taskToFrontExitAnimation">@null</item>
+ <item name="android:taskToBackEnterAnimation">@null</item>
+ <item name="android:taskToBackExitAnimation">@null</item>
+ </style>
+</resources>
diff --git a/tests/FrameworkTest/src/android/widget/AutoCompleteTextViewSimple.java b/tests/FrameworkTest/src/android/widget/AutoCompleteTextViewSimple.java
new file mode 100644
index 0000000..af16cf8
--- /dev/null
+++ b/tests/FrameworkTest/src/android/widget/AutoCompleteTextViewSimple.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008 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;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemSelectedListener;
+
+public class AutoCompleteTextViewSimple extends Activity
+ implements OnItemClickListener, OnItemSelectedListener {
+
+ private final String LOG_TAG = "AutoCompleteTextViewSimple";
+
+ private AutoCompleteTextView mTextView;
+
+ /** These are cleared by resetItemListeners(), and set by the callback listeners */
+ public boolean mItemClickCalled;
+ public int mItemClickPosition;
+ public boolean mItemSelectedCalled;
+ public int mItemSelectedPosition;
+ public boolean mNothingSelectedCalled;
+
+ @Override
+ protected void onCreate(Bundle icicle)
+ {
+ // Be sure to call the super class.
+ super.onCreate(icicle);
+
+ // setup layout & views
+ setContentView(R.layout.autocompletetextview_simple);
+ mTextView = (AutoCompleteTextView) findViewById(R.id.autocompletetextview1);
+
+ // configure callbacks used for monitoring
+ mTextView.setOnItemClickListener(this);
+ mTextView.setOnItemSelectedListener(this);
+ resetItemListeners();
+
+ setStringAdapter(5, "a");
+ }
+
+ /**
+ * @return The AutoCompleteTextView used in this test activity.
+ */
+ public AutoCompleteTextView getTextView() {
+ return mTextView;
+ }
+
+ /**
+ * Set the autocomplete data to an adapter containing 0..n strings with a consistent prefix.
+ */
+ public void setStringAdapter(int numSuggestions, String prefix) {
+ // generate the string array
+ String[] strings = new String[numSuggestions];
+ for (int i = 0; i < numSuggestions; ++i) {
+ strings[i] = prefix + String.valueOf(i);
+ }
+
+ // install it with an adapter
+ ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_dropdown_item_1line, strings);
+ mTextView.setAdapter(adapter);
+ }
+
+ /**
+ * For monitoring OnItemClickListener & OnItemSelectedListener
+ *
+ * An alternative here would be to provide a set of pass-through callbacks
+ */
+ public void resetItemListeners() {
+ mItemClickCalled = false;
+ mItemClickPosition = -1;
+ mItemSelectedCalled = false;
+ mItemSelectedPosition = -1;
+ mNothingSelectedCalled = false;
+ }
+
+ /**
+ * Implements OnItemClickListener
+ */
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ Log.d(LOG_TAG, "onItemClick() position " + position);
+ mItemClickCalled = true;
+ mItemClickPosition = position;
+ }
+
+ /**
+ * Implements OnItemSelectedListener
+ */
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ Log.d(LOG_TAG, "onItemSelected() position " + position);
+ mItemSelectedCalled = true;
+ mItemSelectedPosition = position;
+ }
+
+ /**
+ * Implements OnItemSelectedListener
+ */
+ public void onNothingSelected(AdapterView<?> parent) {
+ Log.d(LOG_TAG, "onNothingSelected()");
+ mNothingSelectedCalled = true;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/FrameworkTestApplication.java b/tests/FrameworkTest/src/com/android/frameworktest/FrameworkTestApplication.java
new file mode 100644
index 0000000..e76f387
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/FrameworkTestApplication.java
@@ -0,0 +1,19 @@
+package com.android.frameworktest;
+
+import android.app.LauncherActivity;
+import android.content.Intent;
+
+/**
+ * Holds little snippets of functionality used as code under test for
+ * instrumentation tests of framework code.
+ */
+public class FrameworkTestApplication extends LauncherActivity {
+
+ protected Intent getTargetIntent() {
+ // TODO: partition into categories by label like the sample code app
+ Intent targetIntent = new Intent(Intent.ACTION_MAIN, null);
+ targetIntent.addCategory(Intent.CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST);
+ targetIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ return targetIntent;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/activity/TranslucentFancyActivity.java b/tests/FrameworkTest/src/com/android/frameworktest/activity/TranslucentFancyActivity.java
new file mode 100644
index 0000000..9492f91
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/activity/TranslucentFancyActivity.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.android.frameworktest.activity;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.WindowManager;
+
+
+/**
+ * <h3>Fancy Translucent Activity</h3>
+ *
+ * <p>This demonstrates the how to write an activity that is translucent,
+ * allowing windows underneath to show through, with a fancy
+ * compositing effect.</p>
+ *
+ * <h4>Demo</h4>
+ * App/Activity/Translucent Fancy
+ *
+ * <h4>Source files</h4>
+ * <table class="LinkTable">
+ * <tr>
+ * <td >src/com/android/samples/app/TranslucentFancyActivity.java</td>
+ * <td >The Translucent Fancy Screen implementation</td>
+ * </tr>
+ * <tr>
+ * <td >/res/any/layout/translucent_background.xml</td>
+ * <td >Defines contents of the screen</td>
+ * </tr>
+ * </table>
+ */
+public class TranslucentFancyActivity extends Activity
+{
+ /**
+ * Initialization of the Activity after it is first created. Must at least
+ * call {@link android.app.Activity#setContentView setContentView()} to
+ * describe what is to be displayed in the screen.
+ */
+ @Override
+ protected void onCreate(Bundle icicle)
+ {
+ // Be sure to call the super class.
+ super.onCreate(icicle);
+
+ // Have the system blur any windows behind this one.
+ getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
+ WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+ // See assets/res/any/layout/translucent_background.xml for this
+ // view layout definition, which is being set here as
+ // the content of our screen.
+ setContentView(R.layout.translucent_background);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/drawable/BitmapDrawable.java b/tests/FrameworkTest/src/com/android/frameworktest/drawable/BitmapDrawable.java
new file mode 100644
index 0000000..e88ebf9
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/drawable/BitmapDrawable.java
@@ -0,0 +1,40 @@
+/*
+ * 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 com.android.frameworktest.drawable;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AbsoluteLayout;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+public class BitmapDrawable extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.with_bitmap_background);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/drawable/DrawableBgMinSize.java b/tests/FrameworkTest/src/com/android/frameworktest/drawable/DrawableBgMinSize.java
new file mode 100644
index 0000000..a382995
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/drawable/DrawableBgMinSize.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.android.frameworktest.drawable;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.AbsoluteLayout;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+/**
+ * Views should obey their background {@link Drawable}'s minimum size
+ * requirements ({@link Drawable#getMinimumHeight()} and
+ * {@link Drawable#getMinimumWidth()}) when possible.
+ * <p>
+ * This Activity exercises a few Views with background {@link Drawable}s.
+ */
+public class DrawableBgMinSize extends Activity implements OnClickListener {
+ private boolean mUsingBigBg = false;
+ private Drawable mBackgroundDrawable;
+ private Drawable mBigBackgroundDrawable;
+ private Button mChangeBackgroundsButton;
+
+ private TextView mTextView;
+ private LinearLayout mLinearLayout;
+ private RelativeLayout mRelativeLayout;
+ private FrameLayout mFrameLayout;
+ private AbsoluteLayout mAbsoluteLayout;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.drawable_background_minimum_size);
+
+ mBackgroundDrawable = getResources().getDrawable(R.drawable.drawable_background);
+ mBigBackgroundDrawable = getResources().getDrawable(R.drawable.big_drawable_background);
+
+ mChangeBackgroundsButton = (Button) findViewById(R.id.change_backgrounds);
+ mChangeBackgroundsButton.setOnClickListener(this);
+
+ mTextView = (TextView) findViewById(R.id.text_view);
+ mLinearLayout = (LinearLayout) findViewById(R.id.linear_layout);
+ mRelativeLayout = (RelativeLayout) findViewById(R.id.relative_layout);
+ mFrameLayout = (FrameLayout) findViewById(R.id.frame_layout);
+ mAbsoluteLayout = (AbsoluteLayout) findViewById(R.id.absolute_layout);
+
+ changeBackgrounds(mBackgroundDrawable);
+ }
+
+ private void changeBackgrounds(Drawable newBg) {
+ mTextView.setBackgroundDrawable(newBg);
+ mLinearLayout.setBackgroundDrawable(newBg);
+ mRelativeLayout.setBackgroundDrawable(newBg);
+ mFrameLayout.setBackgroundDrawable(newBg);
+ mAbsoluteLayout.setBackgroundDrawable(newBg);
+ }
+
+ public void onClick(View v) {
+ if (mUsingBigBg) {
+ changeBackgrounds(mBackgroundDrawable);
+ } else {
+ changeBackgrounds(mBigBackgroundDrawable);
+ }
+
+ mUsingBigBg = !mUsingBigBg;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/drawable/MutateDrawable.java b/tests/FrameworkTest/src/com/android/frameworktest/drawable/MutateDrawable.java
new file mode 100644
index 0000000..2fcaea3
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/drawable/MutateDrawable.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2009 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 com.android.frameworktest.drawable;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.Button;
+import com.android.frameworktest.R;
+
+public class MutateDrawable extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ LinearLayout layout = new LinearLayout(this);
+
+ Button ok = new Button(this);
+ ok.setId(R.id.a);
+ ok.setBackgroundDrawable(getResources().getDrawable(
+ R.drawable.sym_now_playing_skip_forward_1));
+
+ Button cancel = new Button(this);
+ cancel.setId(R.id.b);
+ cancel.setBackgroundDrawable(getResources().getDrawable(
+ R.drawable.sym_now_playing_skip_forward_1));
+
+ layout.addView(ok);
+ layout.addView(cancel);
+
+ ok.getBackground().mutate().setAlpha(127);
+
+ setContentView(layout);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/ExpandableListSimple.java b/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/ExpandableListSimple.java
new file mode 100644
index 0000000..cee1d4d
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/ExpandableListSimple.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.expandablelistview;
+
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
+import android.widget.BaseExpandableListAdapter;
+
+import com.android.frameworktest.util.ExpandableListScenario;
+
+public class ExpandableListSimple extends ExpandableListScenario {
+ private static final int[] NUM_CHILDREN = {4, 3, 2, 1, 0};
+
+ @Override
+ protected void init(ExpandableParams params) {
+ params.setNumChildren(NUM_CHILDREN)
+ .setItemScreenSizeFactor(0.14);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+
+ menu.add("Add item").setOnMenuItemClickListener(new OnMenuItemClickListener() {
+ public boolean onMenuItemClick(MenuItem item) {
+ mGroups.add(0, new MyGroup(2));
+ ((BaseExpandableListAdapter) mAdapter).notifyDataSetChanged();
+ return true;
+ }
+ });
+
+ return true;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeaders.java b/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeaders.java
new file mode 100644
index 0000000..0155f09
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeaders.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.android.frameworktest.expandablelistview;
+
+import com.android.frameworktest.util.ExpandableListScenario;
+
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.ExpandableListView;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+public class ExpandableListWithHeaders extends ExpandableListScenario {
+ private static final int[] sNumChildren = {1, 4, 3, 2, 6};
+ private static final int sNumOfHeadersAndFooters = 12;
+
+ @Override
+ protected void init(ExpandableParams params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setNumChildren(sNumChildren)
+ .setItemScreenSizeFactor(0.14)
+ .setConnectAdapter(false);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ final ExpandableListView expandableListView = getExpandableListView();
+ expandableListView.setItemsCanFocus(true);
+
+ for (int i = 0; i < sNumOfHeadersAndFooters; i++) {
+ Button header = new Button(this);
+ header.setText("Header View");
+ expandableListView.addHeaderView(header);
+ }
+
+ for (int i = 0; i < sNumOfHeadersAndFooters; i++) {
+ Button footer = new Button(this);
+ footer.setText("Footer View");
+ expandableListView.addFooterView(footer);
+ }
+
+ // Set adapter here AFTER we set header and footer views
+ setAdapter(expandableListView);
+ }
+
+ /**
+ * @return The number of headers (and the same number of footers)
+ */
+ public int getNumOfHeadersAndFooters() {
+ return sNumOfHeadersAndFooters;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/InflatedExpandableListView.java b/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/InflatedExpandableListView.java
new file mode 100644
index 0000000..f1089a1
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/expandablelistview/InflatedExpandableListView.java
@@ -0,0 +1,115 @@
+/*
+ * 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 com.android.frameworktest.expandablelistview;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.TextView;
+
+public class InflatedExpandableListView extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.inflated_expandablelistview);
+
+ ExpandableListView elv = (ExpandableListView) findViewById(R.id.elv);
+ elv.setAdapter(new MyExpandableListAdapter());
+ }
+
+ public class MyExpandableListAdapter extends BaseExpandableListAdapter {
+ // Sample data set. children[i] contains the children (String[]) for groups[i].
+ private String[] groups = { "People Names", "Dog Names", "Cat Names", "Fish Names" };
+ private String[][] children = {
+ { "Arnold", "Barry", "Chuck", "David" },
+ { "Ace", "Bandit", "Cha-Cha", "Deuce" },
+ { "Fluffy", "Snuggles" },
+ { "Goldy", "Bubbles" }
+ };
+
+ public Object getChild(int groupPosition, int childPosition) {
+ return children[groupPosition][childPosition];
+ }
+
+ public long getChildId(int groupPosition, int childPosition) {
+ return childPosition;
+ }
+
+ public int getChildrenCount(int groupPosition) {
+ return children[groupPosition].length;
+ }
+
+ public TextView getGenericView() {
+ // Layout parameters for the ExpandableListView
+ AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, 64);
+
+ TextView textView = new TextView(InflatedExpandableListView.this);
+ textView.setLayoutParams(lp);
+ // Center the text vertically
+ textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
+ // Set the text starting position
+ textView.setPadding(36, 0, 0, 0);
+ return textView;
+ }
+
+ public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+ View convertView, ViewGroup parent) {
+ TextView textView = getGenericView();
+ textView.setText(getChild(groupPosition, childPosition).toString());
+ return textView;
+ }
+
+ public Object getGroup(int groupPosition) {
+ return groups[groupPosition];
+ }
+
+ public int getGroupCount() {
+ return groups.length;
+ }
+
+ public long getGroupId(int groupPosition) {
+ return groupPosition;
+ }
+
+ public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
+ ViewGroup parent) {
+ TextView textView = getGenericView();
+ textView.setText(getGroup(groupPosition).toString());
+ return textView;
+ }
+
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return true;
+ }
+
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/AdjacentVerticalRectLists.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/AdjacentVerticalRectLists.java
new file mode 100644
index 0000000..c4e2705
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/AdjacentVerticalRectLists.java
@@ -0,0 +1,94 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.util.InternalSelectionView;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.view.ViewGroup;
+
+/**
+ * {@link android.view.FocusFinder#findNextFocus(android.view.ViewGroup, android.view.View, int)}
+ * and
+ * {@link android.view.View#requestFocus(int, android.graphics.Rect)}
+ * work together to give a newly focused item a hint about the most interesting
+ * rectangle of the previously focused view. The view taking focus can use this
+ * to set an internal selection more appropriate using this rect.
+ *
+ * This Activity excercises that behavior using three adjacent {@link com.android.frameworktest.util.InternalSelectionView}
+ * that report interesting rects when giving up focus, and use interesting rects
+ * when taking focus to best select the internal row to show as selected.
+ */
+public class AdjacentVerticalRectLists extends Activity {
+
+ private LinearLayout mLayout;
+ private InternalSelectionView mLeftColumn;
+ private InternalSelectionView mMiddleColumn;
+ private InternalSelectionView mRightColumn;
+
+
+ public LinearLayout getLayout() {
+ return mLayout;
+ }
+
+ public InternalSelectionView getLeftColumn() {
+ return mLeftColumn;
+ }
+
+ public InternalSelectionView getMiddleColumn() {
+ return mMiddleColumn;
+ }
+
+ public InternalSelectionView getRightColumn() {
+ return mRightColumn;
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mLayout = new LinearLayout(this);
+ mLayout.setOrientation(LinearLayout.HORIZONTAL);
+ mLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,
+ ViewGroup.LayoutParams.FILL_PARENT, 1);
+
+ mLeftColumn = new InternalSelectionView(this, 5, "left column");
+ mLeftColumn.setLayoutParams(params);
+ mLeftColumn.setPadding(10, 10, 10, 10);
+ mLayout.addView(mLeftColumn);
+
+ mMiddleColumn = new InternalSelectionView(this, 5, "middle column");
+ mMiddleColumn.setLayoutParams(params);
+ mMiddleColumn.setPadding(10, 10, 10, 10);
+ mLayout.addView(mMiddleColumn);
+
+ mRightColumn = new InternalSelectionView(this, 5, "right column");
+ mRightColumn.setLayoutParams(params);
+ mRightColumn.setPadding(10, 10, 10, 10);
+ mLayout.addView(mRightColumn);
+
+ setContentView(mLayout);
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/DescendantFocusability.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/DescendantFocusability.java
new file mode 100644
index 0000000..f0c1980
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/DescendantFocusability.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+public class DescendantFocusability extends Activity {
+
+ public ViewGroup beforeDescendants;
+ public Button beforeDescendantsChild;
+
+ public ViewGroup afterDescendants;
+ public Button afterDescendantsChild;
+
+ public ViewGroup blocksDescendants;
+ public Button blocksDescendantsChild;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.descendant_focusability);
+
+ beforeDescendants = (ViewGroup) findViewById(R.id.beforeDescendants);
+ beforeDescendantsChild = (Button) beforeDescendants.getChildAt(0);
+
+ afterDescendants = (ViewGroup) findViewById(R.id.afterDescendants);
+ afterDescendantsChild = (Button) afterDescendants.getChildAt(0);
+
+ blocksDescendants = (ViewGroup) findViewById(R.id.blocksDescendants);
+ blocksDescendantsChild = (Button) blocksDescendants.getChildAt(0);
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/FocusAfterRemoval.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/FocusAfterRemoval.java
new file mode 100644
index 0000000..6c5f1c4
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/FocusAfterRemoval.java
@@ -0,0 +1,78 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.Button;
+import android.view.View;
+
+/**
+ * Exercises cases where elements of the UI are removed (and
+ * focus should go somewhere).
+ */
+public class FocusAfterRemoval extends Activity {
+
+
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.focus_after_removal);
+
+ final LinearLayout left = (LinearLayout) findViewById(R.id.leftLayout);
+
+ // top left makes parent layout GONE
+ Button topLeftButton = (Button) findViewById(R.id.topLeftButton);
+ topLeftButton.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ left.setVisibility(View.GONE);
+ }
+ });
+
+ // bottom left makes parent layout INVISIBLE
+ // top left makes parent layout GONE
+ Button bottomLeftButton = (Button) findViewById(R.id.bottomLeftButton);
+ bottomLeftButton.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ left.setVisibility(View.INVISIBLE);
+ }
+ });
+
+ // top right button makes top right button GONE
+ final Button topRightButton = (Button) findViewById(R.id.topRightButton);
+ topRightButton.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ topRightButton.setVisibility(View.GONE);
+ }
+ });
+
+ // bottom right button makes bottom right button INVISIBLE
+ final Button bottomRightButton = (Button) findViewById(R.id.bottomRightButton);
+ bottomRightButton.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ bottomRightButton.setVisibility(View.INVISIBLE);
+ }
+ });
+
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/GoneParentFocusedChild.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/GoneParentFocusedChild.java
new file mode 100644
index 0000000..91bd7b4
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/GoneParentFocusedChild.java
@@ -0,0 +1,88 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+/**
+ * An activity that helps test the scenario where a parent is
+ * GONE and one of its children has focus; the activity should get
+ * the key event. see bug 945150.
+ */
+public class GoneParentFocusedChild extends Activity {
+ private LinearLayout mGoneGroup;
+ private Button mButton;
+
+ private boolean mUnhandledKeyEvent = false;
+ private LinearLayout mLayout;
+
+ public boolean isUnhandledKeyEvent() {
+ return mUnhandledKeyEvent;
+ }
+
+ public LinearLayout getLayout() {
+ return mLayout;
+ }
+
+ public LinearLayout getGoneGroup() {
+ return mGoneGroup;
+ }
+
+ public Button getButton() {
+ return mButton;
+ }
+
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mLayout = new LinearLayout(this);
+ mLayout.setOrientation(LinearLayout.HORIZONTAL);
+ mLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+
+ mGoneGroup = new LinearLayout(this);
+ mGoneGroup.setOrientation(LinearLayout.HORIZONTAL);
+ mGoneGroup.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ mButton = new Button(this);
+ mButton.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+
+
+ mGoneGroup.addView(mButton);
+ setContentView(mLayout);
+
+ mGoneGroup.setVisibility(View.GONE);
+ mButton.requestFocus();
+ }
+
+ public boolean onKeyUp(int keyCode, KeyEvent event) {
+ mUnhandledKeyEvent = true;
+ return true;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/HorizontalFocusSearch.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/HorizontalFocusSearch.java
new file mode 100644
index 0000000..01a9821
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/HorizontalFocusSearch.java
@@ -0,0 +1,134 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.app.Activity;
+import android.widget.LinearLayout;
+import android.widget.Button;
+import android.widget.TextView;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.content.Context;
+
+public class HorizontalFocusSearch extends Activity {
+
+ private LinearLayout mLayout;
+
+ private Button mLeftTall;
+ private Button mMidShort1Top;
+ private Button mMidShort2Bottom;
+ private Button mRightTall;
+
+
+ public LinearLayout getLayout() {
+ return mLayout;
+ }
+
+ public Button getLeftTall() {
+ return mLeftTall;
+ }
+
+ public Button getMidShort1Top() {
+ return mMidShort1Top;
+ }
+
+ public Button getMidShort2Bottom() {
+ return mMidShort2Bottom;
+ }
+
+ public Button getRightTall() {
+ return mRightTall;
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mLayout = new LinearLayout(this);
+ mLayout.setOrientation(LinearLayout.HORIZONTAL);
+ mLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ mLeftTall = makeTall("left tall");
+ mLayout.addView(mLeftTall);
+
+ mMidShort1Top = addShort(mLayout, "mid(1) top", false);
+ mMidShort2Bottom = addShort(mLayout, "mid(2) bottom", true);
+
+ mRightTall = makeTall("right tall");
+ mLayout.addView(mRightTall);
+
+ setContentView(mLayout);
+ }
+
+ // just to get toString non-sucky
+ private static class MyButton extends Button {
+
+ public MyButton(Context context) {
+ super(context);
+ }
+
+
+ @Override
+ public String toString() {
+ return getText().toString();
+ }
+ }
+
+ private Button makeTall(String label) {
+ Button button = new MyButton(this);
+ button.setText(label);
+ button.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ return button;
+ }
+
+ private Button addShort(LinearLayout root, String label, boolean atBottom) {
+ Button button = new MyButton(this);
+ button.setText(label);
+ button.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 0, // height
+ 490));
+
+ TextView filler = new TextView(this);
+ filler.setText("filler");
+ filler.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 0, // height
+ 510));
+
+ LinearLayout ll = new LinearLayout(this);
+ ll.setOrientation(LinearLayout.VERTICAL);
+ ll.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ if (atBottom) {
+ ll.addView(filler);
+ ll.addView(button);
+ root.addView(ll);
+ } else {
+ ll.addView(button);
+ ll.addView(filler);
+ root.addView(ll);
+ }
+ return button;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/LinearLayoutGrid.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/LinearLayoutGrid.java
new file mode 100644
index 0000000..9aec0d5
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/LinearLayoutGrid.java
@@ -0,0 +1,65 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import com.android.frameworktest.R;
+
+public class LinearLayoutGrid extends Activity {
+
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.linear_layout_grid);
+ }
+
+ public ViewGroup getRootView() {
+ return (ViewGroup) findViewById(R.id.layout);
+ }
+
+ public Button getButtonAt(int column, int row) {
+ if (row < 0 || row > 2) {
+ throw new IllegalArgumentException("row out of range");
+ }
+ if (column < 0 || column > 2) {
+ throw new IllegalArgumentException("column out of range");
+ }
+ return (Button) getColumn(column).getChildAt(row);
+ }
+
+
+
+ private LinearLayout getColumn(int column) {
+ switch (column) {
+ case 0:
+ return (LinearLayout) findViewById(R.id.column1);
+ case 1:
+ return (LinearLayout) findViewById(R.id.column2);
+ case 2:
+ return (LinearLayout) findViewById(R.id.column3);
+ default:
+ throw new IllegalArgumentException("column out of range");
+ }
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfButtons.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfButtons.java
new file mode 100644
index 0000000..0abcebb
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfButtons.java
@@ -0,0 +1,76 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.R;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+
+/**
+ * A layout with a ListView containing buttons.
+ */
+public class ListOfButtons extends ListActivity {
+
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_with_button_above);
+ getListView().setItemsCanFocus(true);
+ setListAdapter(new MyAdapter(this, mLabels));
+ }
+
+ String[] mLabels = {
+ "Alabama", "Alaska", "Arizona", "apple sauce!",
+ "California", "Colorado", "Connecticut", "Delaware"
+ };
+
+
+ public String[] getLabels() {
+ return mLabels;
+ }
+
+ public static class MyAdapter extends ArrayAdapter<String> {
+
+
+ public MyAdapter(Context context, String[] labels) {
+ super(context, 0, labels);
+ }
+
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ String label = getItem(position);
+
+ Button button = new Button(parent.getContext());
+ button.setText(label);
+ return button;
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfEditTexts.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfEditTexts.java
new file mode 100644
index 0000000..f59e2b7
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfEditTexts.java
@@ -0,0 +1,125 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.*;
+import com.google.android.collect.Lists;
+
+import java.util.List;
+
+public class ListOfEditTexts extends Activity {
+
+ private int mLinesPerEditText = 12;
+
+ private ListView mListView;
+ private LinearLayout mLinearLayout;
+
+ public ListView getListView() {
+ return mListView;
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // create linear layout
+ mLinearLayout = new LinearLayout(this);
+ mLinearLayout.setOrientation(LinearLayout.VERTICAL);
+ mLinearLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ // add a button above
+ Button buttonAbove = new Button(this);
+ buttonAbove.setLayoutParams(
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ buttonAbove.setText("button above list");
+ mLinearLayout.addView(buttonAbove);
+
+ // add a list view to it
+ mListView = new ListView(this);
+ mListView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mListView.setDrawSelectorOnTop(false);
+ mListView.setItemsCanFocus(true);
+ mListView.setLayoutParams((new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ 0,
+ 1f)));
+
+ List<String> bodies = Lists.newArrayList(
+ getBody("zero hello, my name is android"),
+ getBody("one i'm a paranoid android"),
+ getBody("two i robot. huh huh."),
+ getBody("three not the g-phone!"));
+
+ mListView.setAdapter(new MyAdapter(this, bodies));
+ mLinearLayout.addView(mListView);
+
+ // add button below
+ Button buttonBelow = new Button(this);
+ buttonBelow.setLayoutParams(
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ buttonBelow.setText("button below list");
+ mLinearLayout.addView(buttonBelow);
+
+ setContentView(mLinearLayout);
+ }
+
+ String getBody(String line) {
+ StringBuilder sb = new StringBuilder((line.length() + 5) * mLinesPerEditText);
+ for (int i = 0; i < mLinesPerEditText; i++) {
+ sb.append(i + 1).append(' ').append(line);
+ if (i < mLinesPerEditText - 1) {
+ sb.append('\n'); // all but last line
+ }
+ }
+ return sb.toString();
+ }
+
+
+ private static class MyAdapter extends ArrayAdapter<String> {
+
+ public MyAdapter(Context context, List<String> bodies) {
+ super(context, 0, bodies);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ String body = getItem(position);
+
+ if (convertView != null) {
+ ((EditText) convertView).setText(body);
+ return convertView;
+ }
+
+ EditText editText = new EditText(getContext());
+ editText.setText(body);
+ return editText;
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfInternalSelectionViews.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfInternalSelectionViews.java
new file mode 100644
index 0000000..4bbca74
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListOfInternalSelectionViews.java
@@ -0,0 +1,170 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.ListView;
+import com.android.frameworktest.util.InternalSelectionView;
+
+/**
+ * A list of {@link InternalSelectionView}s paramatarized by the number of items,
+ * how many rows in each item, and how tall each item is.
+ */
+public class ListOfInternalSelectionViews extends Activity {
+
+ private ListView mListView;
+
+
+ // keys for initializing via Intent params
+ public static final String BUNDLE_PARAM_NUM_ITEMS = "com.google.test.numItems";
+ public static final String BUNDLE_PARAM_NUM_ROWS_PER_ITEM = "com.google.test.numRowsPerItem";
+ public static final String BUNDLE_PARAM_ITEM_SCREEN_HEIGHT_FACTOR = "com.google.test.itemScreenHeightFactor";
+
+ private int mScreenHeight;
+
+ private int mNumItems = 5;
+ private int mNumRowsPerItem = 4;
+ private double mItemScreenSizeFactor = 5 / 4;
+
+ public ListView getListView() {
+ return mListView;
+ }
+
+ /**
+ * Each item is screen height * this factor tall.
+ */
+ public double getItemScreenSizeFactor() {
+ return mItemScreenSizeFactor;
+ }
+
+ /**
+ * @return The number of rows per item.
+ */
+ public int getNumRowsPerItem() {
+ return mNumRowsPerItem;
+ }
+
+ /**
+ * @return The number of items in the list.
+ */
+ public int getNumItems() {
+ return mNumItems;
+ }
+
+ /**
+ * @param position The position
+ * @return The label (closest thing to a value) for the item at position
+ */
+ public String getLabelForPosition(int position) {
+ return "position " + position;
+ }
+
+ /**
+ * Get the currently selected view.
+ */
+ public InternalSelectionView getSelectedView() {
+ return (InternalSelectionView) getListView().getSelectedView();
+ }
+
+ /**
+ * Get the screen height.
+ */
+ public int getScreenHeight() {
+ return mScreenHeight;
+ }
+
+ /**
+ * Initialize a bundle suitable for sending as the params of the intent that
+ * launches this activity.
+ * @param numItems The number of items in the list.
+ * @param numRowsPerItem The number of rows per item.
+ * @param itemScreenHeightFactor see {@link #getScreenHeight()}
+ * @return the intialized bundle.
+ */
+ public static Bundle getBundleFor(int numItems, int numRowsPerItem, double itemScreenHeightFactor) {
+ Bundle bundle = new Bundle();
+ bundle.putInt(BUNDLE_PARAM_NUM_ITEMS, numItems);
+ bundle.putInt(BUNDLE_PARAM_NUM_ROWS_PER_ITEM, numRowsPerItem);
+ bundle.putDouble(BUNDLE_PARAM_ITEM_SCREEN_HEIGHT_FACTOR, itemScreenHeightFactor);
+ return bundle;
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
+
+ Bundle extras = getIntent().getExtras();
+ if (extras != null) {
+ initFromBundle(extras);
+ }
+
+ mListView = new ListView(this);
+ mListView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mListView.setDrawSelectorOnTop(false);
+ mListView.setAdapter(new MyAdapter());
+ mListView.setItemsCanFocus(true);
+ setContentView(mListView);
+ }
+
+ private void initFromBundle(Bundle icicle) {
+
+ int numItems = icicle.getInt(BUNDLE_PARAM_NUM_ITEMS, -1);
+ if (numItems != -1) {
+ mNumItems = numItems;
+ }
+ int numRowsPerItem = icicle.getInt(BUNDLE_PARAM_NUM_ROWS_PER_ITEM, -1);
+ if (numRowsPerItem != -1) {
+ mNumRowsPerItem = numRowsPerItem;
+ }
+ double screenHeightFactor = icicle.getDouble(BUNDLE_PARAM_ITEM_SCREEN_HEIGHT_FACTOR, -1.0);
+ if (screenHeightFactor > 0) {
+ mItemScreenSizeFactor = screenHeightFactor;
+ }
+ }
+
+ private class MyAdapter extends BaseAdapter {
+
+ public int getCount() {
+ return mNumItems;
+ }
+
+ public Object getItem(int position) {
+ return getLabelForPosition(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ InternalSelectionView item =
+ new InternalSelectionView(
+ parent.getContext(),
+ mNumRowsPerItem,
+ getLabelForPosition(position));
+ item.setDesiredHeight((int) (mScreenHeight * mItemScreenSizeFactor));
+ return item;
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/ListWithFooterViewAndNewLabels.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListWithFooterViewAndNewLabels.java
new file mode 100644
index 0000000..730f9aa
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListWithFooterViewAndNewLabels.java
@@ -0,0 +1,111 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.google.android.collect.Lists;
+import com.android.frameworktest.R;
+
+import java.util.List;
+
+public class ListWithFooterViewAndNewLabels extends ListActivity {
+
+ private MyAdapter mMyAdapter;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_with_button_above);
+
+ Button footerButton = new Button(this);
+ footerButton.setText("hi");
+ footerButton.setLayoutParams(
+ new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ getListView().addFooterView(footerButton);
+
+ mMyAdapter = new MyAdapter(this);
+ setListAdapter(mMyAdapter);
+
+ // not in list
+ Button topButton = (Button) findViewById(R.id.button);
+ topButton.setText("click to add new item");
+ topButton.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ mMyAdapter.addLabel("yo");
+ }
+ });
+
+ mMyAdapter.addLabel("first");
+ }
+
+ /**
+ * An adapter that can take new string labels.
+ */
+ static class MyAdapter extends BaseAdapter {
+
+ private final Context mContext;
+ private List<String> mLabels = Lists.newArrayList();
+
+ public MyAdapter(Context context) {
+ mContext = context;
+ }
+
+ public int getCount() {
+ return mLabels.size();
+ }
+
+ public Object getItem(int position) {
+ return mLabels.get(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ String label = mLabels.get(position);
+
+ LayoutInflater inflater = (LayoutInflater)
+ mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ TextView tv = (TextView) inflater.inflate(
+ android.R.layout.simple_list_item_1,
+ null);
+ tv.setText(label);
+ return tv;
+ }
+
+ public void addLabel(String s) {
+ mLabels.add(s + mLabels.size());
+ notifyDataSetChanged();
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/ListWithMailMessages.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListWithMailMessages.java
new file mode 100644
index 0000000..27c642a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/ListWithMailMessages.java
@@ -0,0 +1,147 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.R;
+import com.google.android.collect.Lists;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.webkit.WebView;
+
+import java.util.List;
+
+public class ListWithMailMessages extends ListActivity {
+
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.list_with_button_above);
+
+ List<MailMessage> messages = Lists.newArrayList();
+ messages.add(new MailMessage("hello!", "<p>this is a test "
+ + "message, with a bunch of text and stuff.</p>", true));
+
+// String android = "android";
+ String android = "<a href=\"www.android.com\">android</a>";
+
+ String sentance = "all work and no play makes "
+ + android + " a dull... robot!";
+ StringBuffer longBody = new StringBuffer().append("<ol>\n");
+ for (int i = 0; i < 12; i++) {
+ longBody.append("<li>").append(sentance).append("</li>");
+ }
+ longBody.append("</ol>");
+
+ messages.add(new MailMessage("hello2!", longBody.toString(), true));
+ messages.add(new MailMessage("phone number?", "<p>hey man, what's ur "
+ + "contact info? i need to mail you this photo of my two"
+ + " cats, they've gotten soooo fat!</p>", true));
+
+ setListAdapter(new MyAdapter(this, R.layout.mail_message, messages));
+ getListView().setItemsCanFocus(true);
+ }
+
+
+ /**
+ * POJO mail message.
+ */
+ static class MailMessage {
+ private String mSubject;
+ private String mBody;
+ private boolean mFocusable;
+
+
+ public MailMessage(String subject, String body) {
+ this(subject, body, false);
+ }
+
+
+ public MailMessage(String subject, String body, boolean focusable) {
+ mSubject = subject;
+ mBody = body;
+ mFocusable = focusable;
+ }
+
+ public String getSubject() {
+ return mSubject;
+ }
+
+ public void setSubject(String subject) {
+ this.mSubject = subject;
+ }
+
+ public String getBody() {
+ return mBody;
+ }
+
+ public void setBody(String body) {
+ this.mBody = body;
+ }
+
+
+ public boolean isFocusable() {
+ return mFocusable;
+ }
+
+ public void setFocusable(boolean focusable) {
+ mFocusable = focusable;
+ }
+ }
+
+
+ public static class MyAdapter extends ArrayAdapter<MailMessage> {
+
+ public MyAdapter(Context context, int resource,
+ List<MailMessage> objects) {
+ super(context, resource, objects);
+ }
+
+ final String mimeType = "text/html";
+ final String encoding = "utf-8";
+
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ MailMessage message = getItem(position);
+
+ LayoutInflater inflater = (LayoutInflater)
+ getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ LinearLayout messageUi = (LinearLayout) inflater
+ .inflate(R.layout.mail_message, null);
+
+ TextView subject = (TextView) messageUi.findViewById(R.id.subject);
+ subject.setText(message.getSubject());
+
+ WebView body = (WebView) messageUi.findViewById(R.id.body);
+ body.loadData(message.getBody(), mimeType, encoding);
+// body.setText(message.getBody());
+ body.setFocusable(message.isFocusable());
+
+ return messageUi;
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/RequestFocus.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/RequestFocus.java
new file mode 100644
index 0000000..803815b
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/RequestFocus.java
@@ -0,0 +1,47 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.LinearLayout;
+import android.widget.Button;
+import android.view.View;
+
+/**
+ * Exercises cases where elements of the UI are requestFocus()ed.
+ */
+public class RequestFocus extends Activity {
+ protected final Handler mHandler = new Handler();
+
+ @Override protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.focus_after_removal);
+
+ // bottom right button starts with the focus.
+ final Button bottomRightButton = (Button) findViewById(R.id.bottomRightButton);
+ bottomRightButton.requestFocus();
+ bottomRightButton.setText("I should have focus");
+ }
+
+ public Handler getHandler() {
+ return mHandler;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/focus/VerticalFocusSearch.java b/tests/FrameworkTest/src/com/android/frameworktest/focus/VerticalFocusSearch.java
new file mode 100644
index 0000000..d1b83a3
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/focus/VerticalFocusSearch.java
@@ -0,0 +1,151 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.Button;
+import android.widget.TextView;
+import android.view.Gravity;
+import android.view.ViewGroup;
+import android.content.Context;
+
+/**
+ * Holds a few buttons of various sizes and horizontal placements in a
+ * vertical layout to excercise some core focus searching.
+ */
+public class VerticalFocusSearch extends Activity {
+
+ private LinearLayout mLayout;
+
+ private Button mTopWide;
+ private Button mMidSkinny1Left;
+ private Button mBottomWide;
+
+ private Button mMidSkinny2Right;
+
+
+ public LinearLayout getLayout() {
+ return mLayout;
+ }
+
+ public Button getTopWide() {
+ return mTopWide;
+ }
+
+ public Button getMidSkinny1Left() {
+ return mMidSkinny1Left;
+ }
+
+ public Button getMidSkinny2Right() {
+ return mMidSkinny2Right;
+ }
+
+ public Button getBottomWide() {
+ return mBottomWide;
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mLayout = new LinearLayout(this);
+ mLayout.setOrientation(LinearLayout.VERTICAL);
+ mLayout.setHorizontalGravity(Gravity.LEFT);
+ mLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ mTopWide = makeWide("top wide");
+ mLayout.addView(mTopWide);
+
+ mMidSkinny1Left = addSkinny(mLayout, "mid skinny 1(L)", false);
+
+ mMidSkinny2Right = addSkinny(mLayout, "mid skinny 2(R)", true);
+
+ mBottomWide = makeWide("bottom wide");
+ mLayout.addView(mBottomWide);
+
+ setContentView(mLayout);
+ }
+
+ // just to get toString non-sucky
+ private static class MyButton extends Button {
+
+ public MyButton(Context context) {
+ super(context);
+ }
+
+
+ @Override
+ public String toString() {
+ return getText().toString();
+ }
+ }
+
+ private Button makeWide(String label) {
+ Button button = new MyButton(this);
+ button.setText(label);
+ button.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ return button;
+ }
+
+ /**
+ * Add a skinny button that takes up just less than half of the screen
+ * horizontally.
+ * @param root The layout to add the button to.
+ * @param label The label of the button.
+ * @param atRight Which side to put the button on.
+ * @return The newly created button.
+ */
+ private Button addSkinny(LinearLayout root, String label, boolean atRight) {
+ Button button = new MyButton(this);
+ button.setText(label);
+ button.setLayoutParams(new LinearLayout.LayoutParams(
+ 0, // width
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 480));
+
+ TextView filler = new TextView(this);
+ filler.setText("filler");
+ filler.setLayoutParams(new LinearLayout.LayoutParams(
+ 0, // width
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 520));
+
+ LinearLayout ll = new LinearLayout(this);
+ ll.setOrientation(LinearLayout.HORIZONTAL);
+ ll.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ if (atRight) {
+ ll.addView(filler);
+ ll.addView(button);
+ root.addView(ll);
+ } else {
+ ll.addView(button);
+ ll.addView(filler);
+ root.addView(ll);
+ }
+ return button;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridDelete.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridDelete.java
new file mode 100644
index 0000000..4c0d23b
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridDelete.java
@@ -0,0 +1,108 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ListAdapter;
+
+import com.android.frameworktest.util.GridScenario;
+
+import java.util.ArrayList;
+
+/**
+ * A grid with vertical spacing between rows
+ */
+public class GridDelete extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(1001)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.20)
+ .setVerticalSpacing(20);
+ }
+
+
+
+ @Override
+ protected ListAdapter createAdapter() {
+ return new DeleteAdapter(getInitialNumItems());
+ }
+
+
+
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ if (keyCode == KeyEvent.KEYCODE_DEL) {
+ GridView g = getGridView();
+ ((DeleteAdapter)g.getAdapter()).deletePosition(g.getSelectedItemPosition());
+ return true;
+ } else {
+ return super.onKeyDown(keyCode, event);
+ }
+ }
+
+
+
+
+ private class DeleteAdapter extends BaseAdapter {
+
+ private ArrayList<Integer> mData;
+
+ public DeleteAdapter(int initialNumItems) {
+ super();
+ mData = new ArrayList<Integer>(initialNumItems);
+
+ int i;
+ for (i=0; i<initialNumItems; ++i) {
+ mData.add(new Integer(10000 + i));
+ }
+
+ }
+
+ public void deletePosition(int selectedItemPosition) {
+ if (selectedItemPosition >=0 && selectedItemPosition < mData.size()) {
+ mData.remove(selectedItemPosition);
+ notifyDataSetChanged();
+ }
+
+ }
+
+ public int getCount() {
+ return mData.size();
+ }
+
+ public Object getItem(int position) {
+ return mData.get(position);
+ }
+
+ public long getItemId(int position) {
+ return mData.get(position);
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ int desiredHeight = getDesiredItemHeight();
+ return createView(mData.get(position), parent, desiredHeight);
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridInHorizontal.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridInHorizontal.java
new file mode 100644
index 0000000..c10a53b
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridInHorizontal.java
@@ -0,0 +1,59 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises a grid in a horizontal linear layout
+ */
+public class GridInHorizontal extends Activity {
+ Handler mHandler = new Handler();
+ TextView mText;
+ GridView mGridView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.grid_in_horizontal);
+
+ String values[] = new String[1000];
+ int i=0;
+ for(i=0; i<1000; i++) {
+ values[i] = ((Integer)i).toString();
+ }
+
+ mText = (TextView) findViewById(R.id.text);
+ mGridView = (GridView) findViewById(R.id.grid);
+ mGridView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+ }
+
+ public GridView getGridView() {
+ return mGridView;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridInVertical.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridInVertical.java
new file mode 100644
index 0000000..acde73e
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridInVertical.java
@@ -0,0 +1,59 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises a grid in a vertical linear layout
+ */
+public class GridInVertical extends Activity {
+ Handler mHandler = new Handler();
+ TextView mText;
+ GridView mGridView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.grid_in_vertical);
+
+ String values[] = new String[1000];
+ int i=0;
+ for(i=0; i<1000; i++) {
+ values[i] = ((Integer)i).toString();
+ }
+
+ mText = (TextView) findViewById(R.id.text);
+ mGridView = (GridView) findViewById(R.id.grid);
+ mGridView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+ }
+
+ public GridView getGridView() {
+ return mGridView;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridPadding.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridPadding.java
new file mode 100644
index 0000000..41909ac2
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridPadding.java
@@ -0,0 +1,52 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises a grid with padding
+ */
+public class GridPadding extends Activity {
+ private GridView mGridView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.grid_padding);
+
+ String values[] = new String[1000];
+ for(int i = 0; i < 1000; i++) {
+ values[i] = String.valueOf(i);
+ }
+
+ mGridView = (GridView) findViewById(R.id.grid);
+ mGridView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+ }
+
+ public GridView getGridView() {
+ return mGridView;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridScrollListener.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridScrollListener.java
new file mode 100644
index 0000000..4655230
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridScrollListener.java
@@ -0,0 +1,68 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.AbsListView;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises change notification in a list
+ */
+public class GridScrollListener extends Activity implements AbsListView.OnScrollListener {
+ Handler mHandler = new Handler();
+ TextView mText;
+ GridView mGridView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.grid_scroll_listener);
+
+ String values[] = new String[1000];
+ int i=0;
+ for(i=0; i<1000; i++) {
+ values[i] = ((Integer)i).toString();
+ }
+
+ mText = (TextView) findViewById(R.id.text);
+ mGridView = (GridView) findViewById(R.id.grid);
+ mGridView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+ mGridView.setOnScrollListener(this);
+ }
+
+ public GridView getGridView() {
+ return mGridView;
+ }
+
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ int lastItem = firstVisibleItem + visibleItemCount - 1;
+ mText.setText("Showing " + firstVisibleItem + "-" + lastItem + "/" + totalItemCount);
+ }
+
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelection.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelection.java
new file mode 100644
index 0000000..38f629d
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelection.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * Basic stacking from top scenario, nothing fancy. Items do not
+ * fill the screen.
+ */
+public class GridSetSelection extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(15)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.12);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionMany.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionMany.java
new file mode 100644
index 0000000..34aeb75
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionMany.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * Basic stacking from top scenario, nothing fancy. Items do
+ * fill the screen.
+ */
+public class GridSetSelectionMany extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(150)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.12);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottom.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottom.java
new file mode 100644
index 0000000..6a2445f
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottom.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * Basic stacking from bottom scenario, nothing fancy. Items do not
+ * fill the screen.
+ */
+public class GridSetSelectionStackFromBottom extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(true)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(15)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.12);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomMany.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomMany.java
new file mode 100644
index 0000000..838c431
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomMany.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * Basic stacking from bottom scenario, nothing fancy. Items do
+ * fill the screen.
+ */
+public class GridSetSelectionStackFromBottomMany extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(true)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(150)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.12);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSimple.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSimple.java
new file mode 100644
index 0000000..f7f68f5
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSimple.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.gridview;
+
+import android.graphics.drawable.PaintDrawable;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.android.frameworktest.util.GridScenario;
+
+public class GridSimple extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setNumItems(1000)
+ .setNumColumns(3)
+ .setItemScreenSizeFactor(0.14);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ getGridView().setSelector(new PaintDrawable(0xFFFF0000));
+ getGridView().setPadding(0, 0, 0, 0);
+ getGridView().setFadingEdgeLength(64);
+ getGridView().setVerticalFadingEdgeEnabled(true);
+ getGridView().setBackgroundColor(0xFFC0C0C0);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ View view = super.createView(position, parent, desiredHeight);
+ view.setBackgroundColor(0xFF000000);
+ ((TextView) view).setTextSize(16.0f);
+ return view;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSingleColumn.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSingleColumn.java
new file mode 100644
index 0000000..a909bd8
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridSingleColumn.java
@@ -0,0 +1,37 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+import android.widget.GridView;
+
+/**
+ * A grid with vertical spacing between rows
+ */
+public class GridSingleColumn extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(101)
+ .setNumColumns(1)
+ .setColumnWidth(60)
+ .setItemScreenSizeFactor(0.20)
+ .setVerticalSpacing(20)
+ .setStretchMode(GridView.STRETCH_SPACING);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridStackFromBottom.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridStackFromBottom.java
new file mode 100644
index 0000000..304110e
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridStackFromBottom.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * Basic bottom stacking from bottom scenario, nothing fancy. Items do not
+ * fill the screen
+ */
+public class GridStackFromBottom extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(true)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(15)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.12);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridStackFromBottomMany.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridStackFromBottomMany.java
new file mode 100644
index 0000000..94d801e
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridStackFromBottomMany.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * Basic bottom stacking from bottom scenario, nothing fancy. The grid items do not fit on the
+ * screen (to exercise scrolling.)
+ */
+public class GridStackFromBottomMany extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(true)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(54)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.12);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridThrasher.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridThrasher.java
new file mode 100644
index 0000000..d628f2d
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridThrasher.java
@@ -0,0 +1,135 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+
+import java.util.Random;
+
+/**
+ * Exercises change notification in a list
+ */
+public class GridThrasher extends Activity implements AdapterView.OnItemSelectedListener
+{
+ Handler mHandler = new Handler();
+ ThrashListAdapter mAdapter;
+ Random mRandomizer = new Random();
+ TextView mText;
+
+ Runnable mThrash = new Runnable() {
+ public void run() {
+ mAdapter.bumpVersion();
+ mHandler.postDelayed(mThrash, 500);
+ }
+ };
+
+ private class ThrashListAdapter extends BaseAdapter {
+ private LayoutInflater mInflater;
+
+ /**
+ * Our data, part 1.
+ */
+ private String[] mTitles = new String[100];
+
+ /**
+ * Our data, part 2.
+ */
+ private int[] mVersion = new int[100];
+
+ public ThrashListAdapter(Context context) {
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mTitles = new String[100];
+ mVersion = new int[100];
+
+ int i;
+ for (i=0; i<100; i++) {
+ mTitles[i] = "[" + i + "]";
+ mVersion[i] = 0;
+ }
+ }
+
+ public int getCount() {
+ return mTitles.length;
+ }
+
+ public Object getItem(int position) {
+ return position;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView view;
+
+ if (convertView == null) {
+ view = (TextView) mInflater.inflate(android.R.layout.simple_list_item_1, null);
+ } else {
+ view = (TextView) convertView;
+ }
+ view.setText(mTitles[position] + " " + mVersion[position]);
+ return view;
+ }
+
+
+ public void bumpVersion() {
+ int position = mRandomizer.nextInt(getCount());
+ mVersion[position]++;
+ notifyDataSetChanged();
+ }
+
+
+ }
+
+ @Override
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.grid_thrasher);
+
+ mText = (TextView) findViewById(R.id.text);
+ mAdapter = new ThrashListAdapter(this);
+ GridView g = (GridView) findViewById(R.id.grid);
+ g.setAdapter(mAdapter);
+
+ mHandler.postDelayed(mThrash, 5000);
+
+ g.setOnItemSelectedListener(this);
+ }
+
+ public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ mText.setText("Position " + position);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ mText.setText("Nothing");
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridVerticalSpacing.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridVerticalSpacing.java
new file mode 100644
index 0000000..3f6b8d6
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridVerticalSpacing.java
@@ -0,0 +1,34 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * A grid with vertical spacing between rows
+ */
+public class GridVerticalSpacing extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(101)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.20)
+ .setVerticalSpacing(20);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridVerticalSpacingStackFromBottom.java b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridVerticalSpacingStackFromBottom.java
new file mode 100644
index 0000000..1a39ffb
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/gridview/GridVerticalSpacingStackFromBottom.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+/**
+ * A grid with vertical spacing between rows that stacks from the bottom
+ */
+public class GridVerticalSpacingStackFromBottom extends GridScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(true)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(101)
+ .setNumColumns(4)
+ .setItemScreenSizeFactor(0.20)
+ .setVerticalSpacing(20);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/frame/FrameLayoutGravity.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/frame/FrameLayoutGravity.java
new file mode 100644
index 0000000..1383dae
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/frame/FrameLayoutGravity.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.android.frameworktest.layout.frame;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class FrameLayoutGravity extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.framelayout_gravity);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/frame/FrameLayoutMargin.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/frame/FrameLayoutMargin.java
new file mode 100644
index 0000000..0434726
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/frame/FrameLayoutMargin.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.android.frameworktest.layout.frame;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class FrameLayoutMargin extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.framelayout_margin);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineAlignmentCenterGravity.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineAlignmentCenterGravity.java
new file mode 100644
index 0000000..5087c62
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineAlignmentCenterGravity.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class BaselineAlignmentCenterGravity extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.baseline_center_gravity);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineAlignmentZeroWidthAndWeight.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineAlignmentZeroWidthAndWeight.java
new file mode 100644
index 0000000..3c1d7fd
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineAlignmentZeroWidthAndWeight.java
@@ -0,0 +1,37 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class BaselineAlignmentZeroWidthAndWeight extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.baseline_0width_and_weight);
+
+ findViewById(R.id.show).setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ findViewById(R.id.layout).setVisibility(View.VISIBLE);
+ }
+ });
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineButtons.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineButtons.java
new file mode 100644
index 0000000..9bb9bff
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/BaselineButtons.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class BaselineButtons extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.baseline_buttons);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/ExceptionTextView.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/ExceptionTextView.java
new file mode 100644
index 0000000..54f6b98
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/ExceptionTextView.java
@@ -0,0 +1,65 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import junit.framework.Assert;
+
+import android.widget.EditText;
+import android.content.Context;
+import android.util.AttributeSet;
+import android.text.BoringLayout;
+
+
+/**
+ * A special EditText that sets {@link #isFailed()} to true as its internal makeNewLayout() method is called
+ * with a width lower than 0. This is used to fail the unit test in
+ * BaselineAlignmentZeroWidthAndWeightTest.
+ */
+public class ExceptionTextView extends EditText {
+
+ private boolean mFailed = false;
+
+ public ExceptionTextView(Context context) {
+ super(context);
+ }
+
+ public ExceptionTextView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ExceptionTextView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ }
+
+ public boolean isFailed() {
+ return mFailed;
+ }
+
+ @Override
+ protected void makeNewLayout(int w, int hintWidth,
+ BoringLayout.Metrics boring,
+ BoringLayout.Metrics hintMetrics,
+ int ellipsizedWidth, boolean bringIntoView) {
+ if (w < 0) {
+ mFailed = true;
+ w = 100;
+ }
+
+ super.makeNewLayout(w, hintWidth, boring, hintMetrics, ellipsizedWidth,
+ bringIntoView);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/FillInWrap.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/FillInWrap.java
new file mode 100644
index 0000000..a95cf17
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/FillInWrap.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class FillInWrap extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.fill_in_wrap);
+ ((TextView) findViewById(R.id.data)).setText("1\n2\n3\n4\n5");
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/HorizontalOrientationVerticalAlignment.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/HorizontalOrientationVerticalAlignment.java
new file mode 100644
index 0000000..1308b8b
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/HorizontalOrientationVerticalAlignment.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class HorizontalOrientationVerticalAlignment extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.linear_layout_spinner_then_button);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLEditTextThenButton.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLEditTextThenButton.java
new file mode 100644
index 0000000..db868cb
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLEditTextThenButton.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+
+public class LLEditTextThenButton extends Activity {
+ private EditText mEditText;
+ private Button mButton;
+
+ private LinearLayout mLayout;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.linear_layout_edittext_then_button);
+
+ mLayout = (LinearLayout) findViewById(R.id.layout);
+ mEditText = (EditText) findViewById(R.id.editText);
+ mButton = (Button) findViewById(R.id.button);
+ }
+
+ public LinearLayout getLayout() {
+ return mLayout;
+ }
+
+ public EditText getEditText() {
+ return mEditText;
+ }
+
+ public Button getButton() {
+ return mButton;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfButtons1.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfButtons1.java
new file mode 100644
index 0000000..33189e5
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfButtons1.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.view.View;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import com.android.frameworktest.R;
+
+/**
+ * One of two simple vertical linear layouts of buttons used to test out
+ * the transistion between touch and focus mode.
+ */
+public class LLOfButtons1 extends Activity {
+
+ private boolean mButtonPressed = false;
+ private Button mFirstButton;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.linear_layout_buttons);
+ mFirstButton = (Button) findViewById(R.id.button1);
+
+ mFirstButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mButtonPressed = true;
+ }
+ });
+
+ }
+
+ public LinearLayout getLayout() {
+ return (LinearLayout) findViewById(R.id.layout);
+ }
+
+ public Button getFirstButton() {
+ return mFirstButton;
+ }
+
+ public boolean buttonClickListenerFired() {
+ return mButtonPressed;
+ }
+
+ public boolean isInTouchMode() {
+ return mFirstButton.isInTouchMode();
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfButtons2.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfButtons2.java
new file mode 100644
index 0000000..1e0c97a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfButtons2.java
@@ -0,0 +1,26 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+/**
+ * One of two simple vertical linear layouts of buttons used to test out
+ * the transistion between touch and focus mode.
+ */
+public class LLOfButtons2 extends LLOfButtons1 {
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfTwoFocusableInTouchMode.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfTwoFocusableInTouchMode.java
new file mode 100644
index 0000000..201c8f9
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LLOfTwoFocusableInTouchMode.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class LLOfTwoFocusableInTouchMode extends Activity {
+
+ private View mButton1;
+ private View mButton2;
+ private View mButton3;
+
+ private boolean mB1Fired = false;
+ private boolean mB2Fired = false;
+ private boolean mB3Fired = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.linear_layout_buttons);
+
+ mButton1 = findViewById(R.id.button1);
+ mButton2 = findViewById(R.id.button2);
+ mButton3 = findViewById(R.id.button3);
+
+ mButton1.setFocusableInTouchMode(true);
+ mButton2.setFocusableInTouchMode(true);
+ mButton3.setFocusableInTouchMode(true);
+
+ mButton1.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mB1Fired = true;
+ }
+ });
+
+ mButton2.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mB2Fired = true;
+ }
+ });
+
+ mButton3.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mB3Fired = true;
+ }
+ });
+ }
+
+ public View getButton1() {
+ return mButton1;
+ }
+
+ public View getButton2() {
+ return mButton2;
+ }
+
+ public View getButton3() {
+ return mButton3;
+ }
+
+ public boolean isB1Fired() {
+ return mB1Fired;
+ }
+
+ public boolean isB2Fired() {
+ return mB2Fired;
+ }
+
+ public boolean isB3Fired() {
+ return mB3Fired;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LinearLayoutEditTexts.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LinearLayoutEditTexts.java
new file mode 100644
index 0000000..4877a63
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/LinearLayoutEditTexts.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class LinearLayoutEditTexts extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.linear_layout_textviews);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/Weight.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/Weight.java
new file mode 100644
index 0000000..0535f00
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/Weight.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Weight extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.linear_layout_weight);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/WeightSum.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/WeightSum.java
new file mode 100644
index 0000000..8b9a497
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/linear/WeightSum.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+
+public class WeightSum extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.weight_sum);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/table/AddColumn.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/AddColumn.java
new file mode 100644
index 0000000..c490e0f
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/AddColumn.java
@@ -0,0 +1,54 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+import android.widget.TextView;
+
+/**
+ * This test adds an extra row with an extra column in the table.
+ */
+public class AddColumn extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.add_column_in_table);
+
+ final Button addRowButton = (Button) findViewById(R.id.add_row_button);
+ addRowButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ final TableLayout table = (TableLayout) findViewById(R.id.table);
+ final TableRow newRow = new TableRow(AddColumn.this);
+ for (int i = 0; i < 4; i++) {
+ final TextView view = new TextView(AddColumn.this);
+ view.setText("Column " + (i + 1));
+ view.setPadding(3, 3, 3, 3);
+ newRow.addView(view, new TableRow.LayoutParams());
+ }
+ table.addView(newRow, new TableLayout.LayoutParams());
+ newRow.requestLayout();
+ }
+ });
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/table/CellSpan.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/CellSpan.java
new file mode 100644
index 0000000..243efc7
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/CellSpan.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Exercise table layout with cells spanning.
+ */
+public class CellSpan extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.table_layout_cell_span);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/table/FixedWidth.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/FixedWidth.java
new file mode 100644
index 0000000..2e2defc
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/FixedWidth.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Exercise table layout with cells having a fixed width and height.
+ */
+public class FixedWidth extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.table_layout_fixed_width);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/table/HorizontalGravity.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/HorizontalGravity.java
new file mode 100644
index 0000000..fdafa12
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/HorizontalGravity.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Exercise table layout with cells using a horizontal gravity.
+ */
+public class HorizontalGravity extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.table_layout_horizontal_gravity);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/table/VerticalGravity.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/VerticalGravity.java
new file mode 100644
index 0000000..1f161d9
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/VerticalGravity.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Exercise table layout with cells using a vertical gravity.
+ */
+public class VerticalGravity extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.table_layout_vertical_gravity);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/layout/table/Weight.java b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/Weight.java
new file mode 100644
index 0000000..4c3835f
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/layout/table/Weight.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Exercise table layout with cells having a weight.
+ */
+public class Weight extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.table_layout_weight);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/AdjacentListsWithAdjacentISVsInside.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/AdjacentListsWithAdjacentISVsInside.java
new file mode 100644
index 0000000..5c38ef0
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/AdjacentListsWithAdjacentISVsInside.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.InternalSelectionView;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+
+/**
+ * Most bodacious scenario yet!
+ */
+public class AdjacentListsWithAdjacentISVsInside extends Activity {
+
+ private ListView mLeftListView;
+ private ListView mRightListView;
+
+ public ListView getLeftListView() {
+ return mLeftListView;
+ }
+
+ public ListView getRightListView() {
+ return mRightListView;
+ }
+
+ public InternalSelectionView getLeftIsv() {
+ return (InternalSelectionView)
+ ((ViewGroup) mLeftListView.getChildAt(0)).getChildAt(0);
+ }
+
+ public InternalSelectionView getLeftMiddleIsv() {
+ return (InternalSelectionView)
+ ((ViewGroup) mLeftListView.getChildAt(0)).getChildAt(1);
+ }
+
+ public InternalSelectionView getRightMiddleIsv() {
+ return (InternalSelectionView)
+ ((ViewGroup) mRightListView.getChildAt(0)).getChildAt(0);
+ }
+
+ public InternalSelectionView getRightIsv() {
+ return (InternalSelectionView)
+ ((ViewGroup) mRightListView.getChildAt(0)).getChildAt(1);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ final int desiredHeight = (int) (0.8 * getWindowManager().getDefaultDisplay().getHeight());
+
+ mLeftListView = new ListView(this);
+ mLeftListView.setAdapter(new AdjacentISVAdapter(desiredHeight));
+ mLeftListView.setItemsCanFocus(true);
+
+
+ mRightListView = new ListView(this);
+ mRightListView.setAdapter(new AdjacentISVAdapter(desiredHeight));
+ mRightListView.setItemsCanFocus(true);
+
+
+
+ setContentView(combineAdjacent(mLeftListView, mRightListView));
+ }
+
+ private static View combineAdjacent(View... views) {
+ if (views.length < 2) {
+ throw new IllegalArgumentException("you should pass at least 2 views in");
+ }
+
+ final LinearLayout ll = new LinearLayout(views[0].getContext());
+ ll.setOrientation(LinearLayout.HORIZONTAL);
+ final LinearLayout.LayoutParams lp =
+ new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f);
+
+ for (View view : views) {
+ ll.addView(view, lp);
+ }
+ return ll;
+ }
+
+ static class AdjacentISVAdapter extends BaseAdapter {
+
+ private final int mItemHeight;
+
+ AdjacentISVAdapter(int itemHeight) {
+ mItemHeight = itemHeight;
+ }
+
+ public int getCount() {
+ return 1;
+ }
+
+ public Object getItem(int position) {
+ return position;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final InternalSelectionView isvLeft = new InternalSelectionView(
+ parent.getContext(), 5, "isv left");
+ isvLeft.setDesiredHeight(mItemHeight);
+ final InternalSelectionView isvRight = new InternalSelectionView(
+ parent.getContext(), 5, "isv right");
+ isvRight.setDesiredHeight(mItemHeight);
+ return combineAdjacent(isvLeft, isvRight);
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListBottomGravity.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListBottomGravity.java
new file mode 100644
index 0000000..e729d52
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListBottomGravity.java
@@ -0,0 +1,37 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.Gravity;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Basic bottom gravity scenario, nothing fancy. Items do not
+ * fill the screen
+ */
+public class ListBottomGravity extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(true)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(2)
+ .setItemScreenSizeFactor(0.22);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListBottomGravityMany.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListBottomGravityMany.java
new file mode 100644
index 0000000..1225b9a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListBottomGravityMany.java
@@ -0,0 +1,36 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.Gravity;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Basic bottom gravity scenario, nothing fancy. There are
+ * more items than fit on the screen
+ */
+public class ListBottomGravityMany extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(true)
+ .setStartingSelectionPosition(-1)
+ .setNumItems(10)
+ .setItemScreenSizeFactor(0.22);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListButtonsDiagonalAcrossItems.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListButtonsDiagonalAcrossItems.java
new file mode 100644
index 0000000..bda2cd1
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListButtonsDiagonalAcrossItems.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListItemFactory;
+import static com.android.frameworktest.util.ListItemFactory.Slot;
+import com.android.frameworktest.util.ListScenario;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+public class ListButtonsDiagonalAcrossItems extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setItemsFocusable(true)
+ .setNumItems(3)
+ .setItemScreenSizeFactor(0.2)
+ .setMustFillScreen(false);
+ }
+
+ public Button getLeftButton() {
+ return (Button) ((ViewGroup) getListView().getChildAt(0)).getChildAt(0);
+ }
+
+ public Button getCenterButton() {
+ return (Button) ((ViewGroup) getListView().getChildAt(1)).getChildAt(1);
+ }
+
+ public Button getRightButton() {
+ return (Button) ((ViewGroup) getListView().getChildAt(2)).getChildAt(2);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent,
+ int desiredHeight) {
+ final Slot slot = position == 0 ? Slot.Left :
+ (position == 1 ? Slot.Middle : Slot.Right);
+ return ListItemFactory.horizontalButtonSlots(
+ parent.getContext(), desiredHeight, slot);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListDividers.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListDividers.java
new file mode 100644
index 0000000..62045d8
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListDividers.java
@@ -0,0 +1,52 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises a list width dividers and padding.
+ */
+public class ListDividers extends Activity {
+ private ListView mListView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_dividers);
+
+ String values[] = new String[1000];
+ for (int i = 0; i < 1000; i++) {
+ values[i] = ((Integer) i).toString();
+ }
+
+ mListView = (ListView) findViewById(android.R.id.list);
+ mListView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+ }
+
+ public ListView getListView() {
+ return mListView;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListEndingWithMultipleSeparators.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListEndingWithMultipleSeparators.java
new file mode 100644
index 0000000..4ab1eef6
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListEndingWithMultipleSeparators.java
@@ -0,0 +1,32 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+public class ListEndingWithMultipleSeparators extends ListScenario {
+
+ protected void init(Params params) {
+ params.setItemsFocusable(false)
+ .setNumItems(5)
+ .setItemScreenSizeFactor(0.22)
+ .setPositionUnselectable(3)
+ .setPositionUnselectable(4);
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListFilter.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListFilter.java
new file mode 100644
index 0000000..b164d86
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListFilter.java
@@ -0,0 +1,193 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+
+import com.android.frameworktest.R;
+
+
+/**
+ * Tests hiding and showing the list filter by hiding and showing an ancestor of the
+ * ListView
+ */
+public class ListFilter extends ListActivity implements OnClickListener {
+
+ private View mFrame;
+ private Button mHide;
+ private Button mShow;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.list_filter);
+ setListAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, mStrings));
+ getListView().setTextFilterEnabled(true);
+ mFrame = findViewById(R.id.frame);
+
+ mHide = (Button) findViewById(R.id.hide);
+ mHide.setOnClickListener(this);
+
+ mShow = (Button) findViewById(R.id.show);
+ mShow.setOnClickListener(this);
+ }
+
+
+ public void onClick(View v) {
+ mFrame.setVisibility(v == mHide ? View.INVISIBLE : View.VISIBLE);
+ }
+
+ private String[] mStrings = {
+ "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi",
+ "Acorn", "Adelost", "Affidelice au Chablis", "Afuega'l Pitu", "Airag", "Airedale",
+ "Aisy Cendre", "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese",
+ "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", "Anthoriro", "Appenzell",
+ "Aragon", "Ardi Gasna", "Ardrahan", "Armenian String", "Aromes au Gene de Marc",
+ "Asadero", "Asiago", "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss",
+ "Babybel", "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", "Banon",
+ "Barry's Bay Cheddar", "Basing", "Basket Cheese", "Bath Cheese", "Bavarian Bergkase",
+ "Baylough", "Beaufort", "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese",
+ "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", "Bierkase", "Bishop Kennedy",
+ "Blarney", "Bleu d'Auvergne", "Bleu de Gex", "Bleu de Laqueuille",
+ "Bleu de Septmoncel", "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore",
+ "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", "Bocconcini (Australian)",
+ "Boeren Leidenkaas", "Bonchester", "Bosworth", "Bougon", "Boule Du Roves",
+ "Boulette d'Avesnes", "Boursault", "Boursin", "Bouyssou", "Bra", "Braudostur",
+ "Breakfast Cheese", "Brebis du Lavort", "Brebis du Lochois", "Brebis du Puyfaucon",
+ "Bresse Bleu", "Brick", "Brie", "Brie de Meaux", "Brie de Melun", "Brillat-Savarin",
+ "Brin", "Brin d' Amour", "Brin d'Amour", "Brinza (Burduf Brinza)",
+ "Briquette de Brebis", "Briquette du Forez", "Broccio", "Broccio Demi-Affine",
+ "Brousse du Rove", "Bruder Basil", "Brusselae Kaas (Fromage de Bruxelles)", "Bryndza",
+ "Buchette d'Anjou", "Buffalo", "Burgos", "Butte", "Butterkase", "Button (Innes)",
+ "Buxton Blue", "Cabecou", "Caboc", "Cabrales", "Cachaille", "Caciocavallo", "Caciotta",
+ "Caerphilly", "Cairnsmore", "Calenzana", "Cambazola", "Camembert de Normandie",
+ "Canadian Cheddar", "Canestrato", "Cantal", "Caprice des Dieux", "Capricorn Goat",
+ "Capriole Banon", "Carre de l'Est", "Casciotta di Urbino", "Cashel Blue", "Castellano",
+ "Castelleno", "Castelmagno", "Castelo Branco", "Castigliano", "Cathelain",
+ "Celtic Promise", "Cendre d'Olivet", "Cerney", "Chabichou", "Chabichou du Poitou",
+ "Chabis de Gatine", "Chaource", "Charolais", "Chaumes", "Cheddar",
+ "Cheddar Clothbound", "Cheshire", "Chevres", "Chevrotin des Aravis", "Chontaleno",
+ "Civray", "Coeur de Camembert au Calvados", "Coeur de Chevre", "Colby", "Cold Pack",
+ "Comte", "Coolea", "Cooleney", "Coquetdale", "Corleggy", "Cornish Pepper",
+ "Cotherstone", "Cotija", "Cottage Cheese", "Cottage Cheese (Australian)",
+ "Cougar Gold", "Coulommiers", "Coverdale", "Crayeux de Roncq", "Cream Cheese",
+ "Cream Havarti", "Crema Agria", "Crema Mexicana", "Creme Fraiche", "Crescenza",
+ "Croghan", "Crottin de Chavignol", "Crottin du Chavignol", "Crowdie", "Crowley",
+ "Cuajada", "Curd", "Cure Nantais", "Curworthy", "Cwmtawe Pecorino",
+ "Cypress Grove Chevre", "Danablu (Danish Blue)", "Danbo", "Danish Fontina",
+ "Daralagjazsky", "Dauphin", "Delice des Fiouves", "Denhany Dorset Drum", "Derby",
+ "Dessertnyj Belyj", "Devon Blue", "Devon Garland", "Dolcelatte", "Doolin",
+ "Doppelrhamstufel", "Dorset Blue Vinney", "Double Gloucester", "Double Worcester",
+ "Dreux a la Feuille", "Dry Jack", "Duddleswell", "Dunbarra", "Dunlop", "Dunsyre Blue",
+ "Duroblando", "Durrus", "Dutch Mimolette (Commissiekaas)", "Edam", "Edelpilz",
+ "Emental Grand Cru", "Emlett", "Emmental", "Epoisses de Bourgogne", "Esbareich",
+ "Esrom", "Etorki", "Evansdale Farmhouse Brie", "Evora De L'Alentejo", "Exmoor Blue",
+ "Explorateur", "Feta", "Feta (Australian)", "Figue", "Filetta", "Fin-de-Siecle",
+ "Finlandia Swiss", "Finn", "Fiore Sardo", "Fleur du Maquis", "Flor de Guia",
+ "Flower Marie", "Folded", "Folded cheese with mint", "Fondant de Brebis",
+ "Fontainebleau", "Fontal", "Fontina Val d'Aosta", "Formaggio di capra", "Fougerus",
+ "Four Herb Gouda", "Fourme d' Ambert", "Fourme de Haute Loire", "Fourme de Montbrison",
+ "Fresh Jack", "Fresh Mozzarella", "Fresh Ricotta", "Fresh Truffles", "Fribourgeois",
+ "Friesekaas", "Friesian", "Friesla", "Frinault", "Fromage a Raclette", "Fromage Corse",
+ "Fromage de Montagne de Savoie", "Fromage Frais", "Fruit Cream Cheese",
+ "Frying Cheese", "Fynbo", "Gabriel", "Galette du Paludier", "Galette Lyonnaise",
+ "Galloway Goat's Milk Gems", "Gammelost", "Gaperon a l'Ail", "Garrotxa", "Gastanberra",
+ "Geitost", "Gippsland Blue", "Gjetost", "Gloucester", "Golden Cross", "Gorgonzola",
+ "Gornyaltajski", "Gospel Green", "Gouda", "Goutu", "Gowrie", "Grabetto", "Graddost",
+ "Grafton Village Cheddar", "Grana", "Grana Padano", "Grand Vatel",
+ "Grataron d' Areches", "Gratte-Paille", "Graviera", "Greuilh", "Greve",
+ "Gris de Lille", "Gruyere", "Gubbeen", "Guerbigny", "Halloumi",
+ "Halloumy (Australian)", "Haloumi-Style Cheese", "Harbourne Blue", "Havarti",
+ "Heidi Gruyere", "Hereford Hop", "Herrgardsost", "Herriot Farmhouse", "Herve",
+ "Hipi Iti", "Hubbardston Blue Cow", "Hushallsost", "Iberico", "Idaho Goatster",
+ "Idiazabal", "Il Boschetto al Tartufo", "Ile d'Yeu", "Isle of Mull", "Jarlsberg",
+ "Jermi Tortes", "Jibneh Arabieh", "Jindi Brie", "Jubilee Blue", "Juustoleipa",
+ "Kadchgall", "Kaseri", "Kashta", "Kefalotyri", "Kenafa", "Kernhem", "Kervella Affine",
+ "Kikorangi", "King Island Cape Wickham Brie", "King River Gold", "Klosterkaese",
+ "Knockalara", "Kugelkase", "L'Aveyronnais", "L'Ecir de l'Aubrac", "La Taupiniere",
+ "La Vache Qui Rit", "Laguiole", "Lairobell", "Lajta", "Lanark Blue", "Lancashire",
+ "Langres", "Lappi", "Laruns", "Lavistown", "Le Brin", "Le Fium Orbo", "Le Lacandou",
+ "Le Roule", "Leafield", "Lebbene", "Leerdammer", "Leicester", "Leyden", "Limburger",
+ "Lincolnshire Poacher", "Lingot Saint Bousquet d'Orb", "Liptauer", "Little Rydings",
+ "Livarot", "Llanboidy", "Llanglofan Farmhouse", "Loch Arthur Farmhouse",
+ "Loddiswell Avondale", "Longhorn", "Lou Palou", "Lou Pevre", "Lyonnais", "Maasdam",
+ "Macconais", "Mahoe Aged Gouda", "Mahon", "Malvern", "Mamirolle", "Manchego",
+ "Manouri", "Manur", "Marble Cheddar", "Marbled Cheeses", "Maredsous", "Margotin",
+ "Maribo", "Maroilles", "Mascares", "Mascarpone", "Mascarpone (Australian)",
+ "Mascarpone Torta", "Matocq", "Maytag Blue", "Meira", "Menallack Farmhouse",
+ "Menonita", "Meredith Blue", "Mesost", "Metton (Cancoillotte)", "Meyer Vintage Gouda",
+ "Mihalic Peynir", "Milleens", "Mimolette", "Mine-Gabhar", "Mini Baby Bells", "Mixte",
+ "Molbo", "Monastery Cheeses", "Mondseer", "Mont D'or Lyonnais", "Montasio",
+ "Monterey Jack", "Monterey Jack Dry", "Morbier", "Morbier Cru de Montagne",
+ "Mothais a la Feuille", "Mozzarella", "Mozzarella (Australian)",
+ "Mozzarella di Bufala", "Mozzarella Fresh, in water", "Mozzarella Rolls", "Munster",
+ "Murol", "Mycella", "Myzithra", "Naboulsi", "Nantais", "Neufchatel",
+ "Neufchatel (Australian)", "Niolo", "Nokkelost", "Northumberland", "Oaxaca",
+ "Olde York", "Olivet au Foin", "Olivet Bleu", "Olivet Cendre",
+ "Orkney Extra Mature Cheddar", "Orla", "Oschtjepka", "Ossau Fermier", "Ossau-Iraty",
+ "Oszczypek", "Oxford Blue", "P'tit Berrichon", "Palet de Babligny", "Paneer", "Panela",
+ "Pannerone", "Pant ys Gawn", "Parmesan (Parmigiano)", "Parmigiano Reggiano",
+ "Pas de l'Escalette", "Passendale", "Pasteurized Processed", "Pate de Fromage",
+ "Patefine Fort", "Pave d'Affinois", "Pave d'Auge", "Pave de Chirac", "Pave du Berry",
+ "Pecorino", "Pecorino in Walnut Leaves", "Pecorino Romano", "Peekskill Pyramid",
+ "Pelardon des Cevennes", "Pelardon des Corbieres", "Penamellera", "Penbryn",
+ "Pencarreg", "Perail de Brebis", "Petit Morin", "Petit Pardou", "Petit-Suisse",
+ "Picodon de Chevre", "Picos de Europa", "Piora", "Pithtviers au Foin",
+ "Plateau de Herve", "Plymouth Cheese", "Podhalanski", "Poivre d'Ane", "Polkolbin",
+ "Pont l'Eveque", "Port Nicholson", "Port-Salut", "Postel", "Pouligny-Saint-Pierre",
+ "Pourly", "Prastost", "Pressato", "Prince-Jean", "Processed Cheddar", "Provolone",
+ "Provolone (Australian)", "Pyengana Cheddar", "Pyramide", "Quark",
+ "Quark (Australian)", "Quartirolo Lombardo", "Quatre-Vents", "Quercy Petit",
+ "Queso Blanco", "Queso Blanco con Frutas --Pina y Mango", "Queso de Murcia",
+ "Queso del Montsec", "Queso del Tietar", "Queso Fresco", "Queso Fresco (Adobera)",
+ "Queso Iberico", "Queso Jalapeno", "Queso Majorero", "Queso Media Luna",
+ "Queso Para Frier", "Queso Quesadilla", "Rabacal", "Raclette", "Ragusano", "Raschera",
+ "Reblochon", "Red Leicester", "Regal de la Dombes", "Reggianito", "Remedou",
+ "Requeson", "Richelieu", "Ricotta", "Ricotta (Australian)", "Ricotta Salata", "Ridder",
+ "Rigotte", "Rocamadour", "Rollot", "Romano", "Romans Part Dieu", "Roncal", "Roquefort",
+ "Roule", "Rouleau De Beaulieu", "Royalp Tilsit", "Rubens", "Rustinu", "Saaland Pfarr",
+ "Saanenkaese", "Saga", "Sage Derby", "Sainte Maure", "Saint-Marcellin",
+ "Saint-Nectaire", "Saint-Paulin", "Salers", "Samso", "San Simon", "Sancerre",
+ "Sap Sago", "Sardo", "Sardo Egyptian", "Sbrinz", "Scamorza", "Schabzieger", "Schloss",
+ "Selles sur Cher", "Selva", "Serat", "Seriously Strong Cheddar", "Serra da Estrela",
+ "Sharpam", "Shelburne Cheddar", "Shropshire Blue", "Siraz", "Sirene", "Smoked Gouda",
+ "Somerset Brie", "Sonoma Jack", "Sottocenare al Tartufo", "Soumaintrain",
+ "Sourire Lozerien", "Spenwood", "Sraffordshire Organic", "St. Agur Blue Cheese",
+ "Stilton", "Stinking Bishop", "String", "Sussex Slipcote", "Sveciaost", "Swaledale",
+ "Sweet Style Swiss", "Swiss", "Syrian (Armenian String)", "Tala", "Taleggio", "Tamie",
+ "Tasmania Highland Chevre Log", "Taupiniere", "Teifi", "Telemea", "Testouri",
+ "Tete de Moine", "Tetilla", "Texas Goat Cheese", "Tibet", "Tillamook Cheddar",
+ "Tilsit", "Timboon Brie", "Toma", "Tomme Brulee", "Tomme d'Abondance",
+ "Tomme de Chevre", "Tomme de Romans", "Tomme de Savoie", "Tomme des Chouans", "Tommes",
+ "Torta del Casar", "Toscanello", "Touree de L'Aubier", "Tourmalet",
+ "Trappe (Veritable)", "Trois Cornes De Vendee", "Tronchon", "Trou du Cru", "Truffe",
+ "Tupi", "Turunmaa", "Tymsboro", "Tyn Grug", "Tyning", "Ubriaco", "Ulloa",
+ "Vacherin-Fribourgeois", "Valencay", "Vasterbottenost", "Venaco", "Vendomois",
+ "Vieux Corse", "Vignotte", "Vulscombe", "Waimata Farmhouse Blue",
+ "Washed Rind Cheese (Australian)", "Waterloo", "Weichkaese", "Wellington",
+ "Wensleydale", "White Stilton", "Whitestone Farmhouse", "Wigmore", "Woodside Cabecou",
+ "Xanadu", "Xynotyro", "Yarg Cornish", "Yarra Valley Pyramid", "Yorkshire Blue",
+ "Zamorano", "Zanetti Grana Padano", "Zanetti Parmigiano Reggiano"};
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListGetSelectedView.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListGetSelectedView.java
new file mode 100644
index 0000000..28fa21a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListGetSelectedView.java
@@ -0,0 +1,30 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Basic top gravity scenario. This test is made to check that getSelectedView() will return
+ * null in touch mode.
+ */
+public class ListGetSelectedView extends ListScenario {
+ @Override
+ protected void init(Params params) {
+ params.setMustFillScreen(false).setNumItems(2).setItemScreenSizeFactor(0.22);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListHeterogeneous.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListHeterogeneous.java
new file mode 100644
index 0000000..93abd78
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListHeterogeneous.java
@@ -0,0 +1,83 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.frameworktest.util.ListItemFactory;
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * List that has different view types
+ */
+public class ListHeterogeneous extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setNumItems(50)
+ .setItemScreenSizeFactor(1.0 / 8)
+ .setItemsFocusable(true)
+ .setHeaderViewCount(3)
+ .setFooterViewCount(2);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ switch (position % 3) {
+ case 0:
+ return ListItemFactory.text(
+ position, parent.getContext(), getValueAtPosition(position), desiredHeight);
+ case 1:
+ return ListItemFactory.button(
+ position, parent.getContext(), getValueAtPosition(position), desiredHeight);
+ case 2:
+ return ListItemFactory.doubleText(
+ position, parent.getContext(), getValueAtPosition(position), desiredHeight);
+ }
+
+ return null;
+ }
+
+ @Override
+ public View convertView(int position, View convertView, ViewGroup parent) {
+ switch (position % 3) {
+ case 0:
+ return ListItemFactory.convertText(convertView, getValueAtPosition(position), position);
+ case 1:
+ return ListItemFactory.convertButton(convertView, getValueAtPosition(position),
+ position);
+ case 2:
+ return ListItemFactory.convertDoubleText(convertView, getValueAtPosition(position),
+ position);
+ }
+
+ return null;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return position % 3;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 3;
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListHorizontalFocusWithinItemWins.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListHorizontalFocusWithinItemWins.java
new file mode 100644
index 0000000..c5e1e97
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListHorizontalFocusWithinItemWins.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListItemFactory;
+import static com.android.frameworktest.util.ListItemFactory.Slot;
+import com.android.frameworktest.util.ListScenario;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+public class ListHorizontalFocusWithinItemWins extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setItemsFocusable(true)
+ .setNumItems(2)
+ .setItemScreenSizeFactor(0.2)
+ .setMustFillScreen(false);
+ }
+
+ public Button getTopLeftButton() {
+ return (Button) ((ViewGroup) getListView().getChildAt(0)).getChildAt(0);
+ }
+
+ public Button getTopRightButton() {
+ return (Button) ((ViewGroup) getListView().getChildAt(0)).getChildAt(2);
+ }
+
+ public Button getBottomMiddleButton() {
+ return (Button) ((ViewGroup) getListView().getChildAt(1)).getChildAt(1);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent,
+ int desiredHeight) {
+ final Context context = parent.getContext();
+ if (position == 0) {
+ return ListItemFactory.horizontalButtonSlots(
+ context, desiredHeight, Slot.Left, Slot.Right);
+ } else if (position == 1) {
+ return ListItemFactory.horizontalButtonSlots(
+ context, desiredHeight, Slot.Middle);
+ } else {
+ throw new IllegalArgumentException("expecting position 0 or 1");
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInHorizontal.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInHorizontal.java
new file mode 100644
index 0000000..2128746
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInHorizontal.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+import android.widget.ListView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises a list in a horizontal linear layout
+ */
+public class ListInHorizontal extends Activity {
+ private ListView mListView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_in_horizontal);
+
+ String values[] = new String[1000];
+ for (int i = 0; i < 1000; i++) {
+ values[i] = ((Integer) i).toString();
+ }
+
+ mListView = (ListView) findViewById(R.id.list);
+ mListView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+ }
+
+ public ListView getListView() {
+ return mListView;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInVertical.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInVertical.java
new file mode 100644
index 0000000..f4c93c8
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInVertical.java
@@ -0,0 +1,56 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.widget.ArrayAdapter;
+import android.widget.GridView;
+import android.widget.TextView;
+import android.widget.ListView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises a list in a vertical linear layout
+ */
+public class ListInVertical extends Activity {
+ private ListView mListView;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_in_vertical);
+
+ String values[] = new String[1000];
+ for (int i = 0; i < 1000; i++) {
+ values[i] = ((Integer) i).toString();
+ }
+
+ mListView = (ListView) findViewById(R.id.list);
+ mListView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+ }
+
+ public ListView getListView() {
+ return mListView;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInterleaveFocusables.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInterleaveFocusables.java
new file mode 100644
index 0000000..e45297e
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListInterleaveFocusables.java
@@ -0,0 +1,63 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.View;
+ import android.view.ViewGroup;
+ import com.google.android.collect.Sets;
+ import com.android.frameworktest.util.ListScenario;
+ import com.android.frameworktest.util.ListItemFactory;
+
+ import java.util.Set;
+
+/**
+ * List that interleaves focusable items.
+ */
+public class ListInterleaveFocusables extends ListScenario {
+
+ private Set<Integer> mFocusablePositions = Sets.newHashSet(1, 3, 6);
+
+ @Override
+ protected void init(Params params) {
+ params.setNumItems(7)
+ .setItemScreenSizeFactor(1.0 / 8)
+ .setItemsFocusable(true)
+ .setMustFillScreen(false);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ if (mFocusablePositions.contains(position)) {
+ return ListItemFactory.button(
+ position, parent.getContext(), getValueAtPosition(position), desiredHeight);
+ } else {
+ return super.createView(position, parent, desiredHeight);
+ }
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return mFocusablePositions.contains(position) ? 0 : 1;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 2;
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusableAboveUnfocusable.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusableAboveUnfocusable.java
new file mode 100644
index 0000000..e14da5b
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusableAboveUnfocusable.java
@@ -0,0 +1,48 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+import com.android.frameworktest.util.ListItemFactory;
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * A list where the items may befocusable, but the second item isn't actually focusabe.
+ */
+public class ListItemFocusableAboveUnfocusable extends ListScenario {
+
+
+ protected void init(Params params) {
+ params.setNumItems(2)
+ .setItemsFocusable(true)
+ .setItemScreenSizeFactor(0.2)
+ .setMustFillScreen(false);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ if (position == 0) {
+ return ListItemFactory.button(
+ position, parent.getContext(), getValueAtPosition(position), desiredHeight);
+ } else {
+ return super.createView(position, parent, desiredHeight);
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusablesClose.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusablesClose.java
new file mode 100644
index 0000000..e20f633
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusablesClose.java
@@ -0,0 +1,54 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+import com.android.frameworktest.util.ListItemFactory;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ * Each list item has two focusables that are close enough together that
+ * it shouldn't require panning to move focus.
+ */
+public class ListItemFocusablesClose extends ListScenario {
+
+
+ /**
+ * Get the child of a list item.
+ * @param listIndex The index of the currently visible items
+ * @param index The index of the child.
+ */
+ public View getChildOfItem(int listIndex, int index) {
+ return ((ViewGroup) getListView().getChildAt(listIndex)).getChildAt(index);
+
+ }
+
+ @Override
+ protected void init(Params params) {
+ params.setItemsFocusable(true)
+ .setNumItems(2)
+ .setItemScreenSizeFactor(0.55);
+ }
+
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ return ListItemFactory.twoButtonsSeparatedByFiller(
+ position, parent.getContext(), desiredHeight);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusablesFarApart.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusablesFarApart.java
new file mode 100644
index 0000000..e974478
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemFocusablesFarApart.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.frameworktest.util.ListItemFactory;
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * A list where each item is tall with buttons that are farther apart than the screen
+ * size. We don't want to jump over content off screen to the next button, we need to
+ * pan across the intermediate part.
+ */
+public class ListItemFocusablesFarApart extends ListScenario {
+
+
+ @Override
+ protected void init(Params params) {
+ params.setItemsFocusable(true)
+ .setNumItems(2)
+ .setItemScreenSizeFactor(2);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ return ListItemFactory.twoButtonsSeparatedByFiller(
+ position, parent.getContext(), desiredHeight);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemISVAndButton.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemISVAndButton.java
new file mode 100644
index 0000000..d6c11b7
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemISVAndButton.java
@@ -0,0 +1,75 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.android.frameworktest.util.InternalSelectionView;
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Each item is an internal selection view, a button, and some filler
+ */
+public class ListItemISVAndButton extends ListScenario {
+
+
+ @Override
+ protected void init(Params params) {
+ params.setItemScreenSizeFactor(2.0)
+ .setNumItems(3)
+ .setItemsFocusable(true);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ Context context = parent.getContext();
+
+ final LinearLayout ll = new LinearLayout(context);
+ ll.setOrientation(LinearLayout.VERTICAL);
+
+ final InternalSelectionView isv = new InternalSelectionView(context, 8, "ISV postion " + position);
+ isv.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ desiredHeight - 240));
+ ll.addView(isv);
+
+ final LinearLayout.LayoutParams buttonLp =
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ 40);
+ final Button topButton = new Button(context);
+ topButton.setLayoutParams(
+ buttonLp);
+ topButton.setText("button " + position + ")");
+ ll.addView(topButton);
+
+ final TextView filler = new TextView(context);
+ filler.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ 200));
+ filler.setText("filler");
+ ll.addView(filler);
+
+
+ return ll;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemsExpandOnSelection.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemsExpandOnSelection.java
new file mode 100644
index 0000000..a137116
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListItemsExpandOnSelection.java
@@ -0,0 +1,80 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.TextView;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * A list where each item expands by 1.5 when selected.
+ */
+public class ListItemsExpandOnSelection extends ListScenario {
+
+
+ @Override
+ protected void init(Params params) {
+ params.setNumItems(10)
+ .setItemScreenSizeFactor(1.0/5);
+ }
+
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ TextView result = new ExpandWhenSelectedView(parent.getContext(), desiredHeight);
+ result.setHeight(desiredHeight);
+ result.setFocusable(mItemsFocusable);
+ result.setText(getValueAtPosition(position));
+ final AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ result.setLayoutParams(lp);
+ return result;
+ }
+
+
+ @Override
+ public View convertView(int position, View convertView, ViewGroup parent) {
+ ((ExpandWhenSelectedView)convertView).setText(getValueAtPosition(position));
+ return convertView;
+ }
+
+
+ static private class ExpandWhenSelectedView extends TextView {
+
+ private final int mDesiredHeight;
+
+ public ExpandWhenSelectedView(Context context, int desiredHeight) {
+ super(context);
+ mDesiredHeight = desiredHeight;
+ }
+
+ @Override
+ public void setSelected(boolean selected) {
+ super.setSelected(selected);
+ if (selected) {
+ setHeight((int) (mDesiredHeight * 1.5));
+ } else {
+ setHeight(mDesiredHeight);
+ }
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListLastItemPartiallyVisible.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListLastItemPartiallyVisible.java
new file mode 100644
index 0000000..23b76a9
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListLastItemPartiallyVisible.java
@@ -0,0 +1,31 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * A list where the very last item is partially visible, but still requires scrolling
+ * to bring it into view.
+ */
+public class ListLastItemPartiallyVisible extends ListScenario {
+
+ protected void init(Params params) {
+ params.setNumItems(5)
+ .setItemScreenSizeFactor(0.22);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListManagedCursor.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListManagedCursor.java
new file mode 100644
index 0000000..0cc242f
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListManagedCursor.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.provider.Contacts.People;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.ListAdapter;
+import android.widget.SimpleCursorAdapter;
+import android.widget.AdapterView.OnItemClickListener;
+
+
+public class ListManagedCursor extends ListActivity implements OnItemClickListener {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Get a cursor with all people
+ Cursor c = getContentResolver().query(Settings.System.CONTENT_URI, null, null, null, null);
+ startManagingCursor(c);
+
+ ListAdapter adapter = new SimpleCursorAdapter(this,
+ // Use a template that displays a text view
+ android.R.layout.simple_list_item_1,
+ // Give the cursor to the list adatper
+ c,
+ // Map the NAME column in the people database to...
+ new String[] {People.NAME} ,
+ // The "text1" view defined in the XML template
+ new int[] {android.R.id.text1});
+ setListAdapter(adapter);
+ getListView().setOnItemClickListener(this);
+ }
+
+ public void onItemClick(AdapterView parent, View view, int position, long id) {
+ Intent dummyIntent = new Intent(this, ListSimple.class);
+ startActivity(dummyIntent);
+ }
+}
+
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfItemsShorterThanScreen.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfItemsShorterThanScreen.java
new file mode 100644
index 0000000..475ab31
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfItemsShorterThanScreen.java
@@ -0,0 +1,28 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+public class ListOfItemsShorterThanScreen extends ListScenario {
+
+ protected void init(Params params) {
+ params.setNumItems(5)
+ .setItemScreenSizeFactor(1.1 / 4)
+ .setItemsFocusable(false);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfItemsTallerThanScreen.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfItemsTallerThanScreen.java
new file mode 100644
index 0000000..0d70abf
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfItemsTallerThanScreen.java
@@ -0,0 +1,29 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+public class ListOfItemsTallerThanScreen extends ListScenario {
+
+
+ protected void init(Params params) {
+ params.setNumItems(3)
+ .setItemScreenSizeFactor(4.0 / 3)
+ .setItemsFocusable(false);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfShortShortTallShortShort.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfShortShortTallShortShort.java
new file mode 100644
index 0000000..62c5aa7
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfShortShortTallShortShort.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Exposes fading in and out multiple items.
+ */
+public class ListOfShortShortTallShortShort extends ListScenario {
+
+
+ protected void init(Params params) {
+ params.setNumItems(5)
+ .setItemScreenSizeFactor(0.1)
+ .setFadingEdgeScreenSizeFactor(0.22)
+ .setPositionScreenSizeFactorOverride(2, 1.1);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfShortTallShort.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfShortTallShort.java
new file mode 100644
index 0000000..e60dee7
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfShortTallShort.java
@@ -0,0 +1,32 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Two short items separated by one that is taller than the screen.
+ */
+public class ListOfShortTallShort extends ListScenario {
+
+
+ protected void init(Params params) {
+ params.setItemScreenSizeFactor(1.0 / 8)
+ .setNumItems(3)
+ .setPositionScreenSizeFactorOverride(1, 1.2);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfThinItems.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfThinItems.java
new file mode 100644
index 0000000..d613c9b
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfThinItems.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+public class ListOfThinItems extends ListScenario {
+
+ protected void init(Params params) {
+
+ final int numItemsOnScreen = getScreenHeight() / 18;
+
+ params.setNumItems(numItemsOnScreen + 5)
+ .setItemScreenSizeFactor(18.0 / getScreenHeight())
+ .setItemsFocusable(false);
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfTouchables.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfTouchables.java
new file mode 100644
index 0000000..0e09190
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListOfTouchables.java
@@ -0,0 +1,47 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Each list item has two focusables that are close enough together that
+ * it shouldn't require panning to move focus.
+ */
+public class ListOfTouchables extends ListScenario {
+
+
+ @Override
+ protected void init(Params params) {
+ params.setItemsFocusable(true)
+ .setItemScreenSizeFactor(0.2)
+ .setNumItems(100);
+ }
+
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ Button b = new Button(this);
+ b.setText("Position " + position);
+ b.setId(position);
+ return b;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListRecyclerProfiling.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListRecyclerProfiling.java
new file mode 100644
index 0000000..3df3b9a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListRecyclerProfiling.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.ImageButton;
+import android.view.ViewDebug;
+import android.view.View;
+
+import com.android.frameworktest.R;
+
+public class ListRecyclerProfiling extends Activity {
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_recycler_profiling);
+
+ String values[] = new String[1000];
+ for (int i = 0; i < 1000; i++) {
+ values[i] = ((Integer) i).toString();
+ }
+
+ ListView listView = (ListView) findViewById(R.id.list);
+
+ ViewDebug.startRecyclerTracing("SimpleList", listView);
+
+ listView.setAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+ ImageButton stopProfiling = (ImageButton) findViewById(R.id.pause);
+ stopProfiling.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ ViewDebug.stopRecyclerTracing();
+ }
+ });
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListScrollListener.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListScrollListener.java
new file mode 100644
index 0000000..f5e4faf
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListScrollListener.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.ListActivity;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercises change notification in a list
+ */
+public class ListScrollListener extends ListActivity implements AbsListView.OnScrollListener {
+ Handler mHandler = new Handler();
+ TextView mText;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_scroll_listener);
+
+ String values[] = new String[1000];
+ int i=0;
+ for(i=0; i<1000; i++) {
+ values[i] = ((Integer)i).toString();
+ }
+
+ mText = (TextView) findViewById(R.id.text);
+ setListAdapter(new ArrayAdapter<String>(this,
+ android.R.layout.simple_list_item_1, values));
+
+
+ getListView().setOnScrollListener(this);
+ }
+
+ public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ mText.setText("Position " + position);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ mText.setText("Nothing");
+ }
+
+ public void onScroll(AbsListView view, int firstCell, int cellCount, int itemCount) {
+ int last = firstCell + cellCount - 1;
+ mText.setText("Showing " + firstCell + "-" + last + "/" + itemCount);
+ }
+
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListSetSelection.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListSetSelection.java
new file mode 100644
index 0000000..87888ca
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListSetSelection.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+import android.view.KeyEvent;
+import android.view.View;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.Button;
+
+/**
+ * List of 1,000 items used to test calls to setSelection() in touch mode.
+ * Pressing the S key will call setSelection(0) on the list.
+ */
+public class ListSetSelection extends ListScenario {
+ private Button mButton;
+
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setNumItems(1000)
+ .setItemScreenSizeFactor(0.22);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mButton = new Button(this);
+ mButton.setText("setSelection(0)");
+ mButton.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ getListView().setSelection(0);
+ }
+ });
+
+ getListViewContainer().addView(mButton, new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.FILL_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ));
+ }
+
+ public Button getButton() {
+ return mButton;
+ }
+
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ if (event.getKeyCode() == KeyEvent.KEYCODE_S) {
+ getListView().setSelection(0);
+ return true;
+ }
+
+ return super.dispatchKeyEvent(event);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListSimple.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListSimple.java
new file mode 100644
index 0000000..e7517d6
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListSimple.java
@@ -0,0 +1,51 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+import android.view.View;
+import android.view.ViewGroup;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class ListSimple extends ListScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setNumItems(1000)
+ .setItemScreenSizeFactor(0.14);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ getListView().setVerticalScrollBarEnabled(true);
+ getListView().setFadingEdgeLength(12);
+ getListView().setVerticalFadingEdgeEnabled(true);
+ }
+
+ @Override
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ View view = super.createView(position, parent, desiredHeight);
+ view.setBackgroundColor(0xFF191919);
+ ((TextView) view).setTextSize(16.0f);
+ return view;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTakeFocusFromSide.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTakeFocusFromSide.java
new file mode 100644
index 0000000..e576ea2
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTakeFocusFromSide.java
@@ -0,0 +1,84 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.R;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+/**
+ * Exercises moving focus into the list from the side
+ */
+public class ListTakeFocusFromSide extends ListActivity {
+
+
+ private class ThrashListAdapter extends BaseAdapter {
+ private LayoutInflater mInflater;
+
+ private String[] mTitles = new String[100];
+
+ public ThrashListAdapter(Context context) {
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mTitles = new String[100];
+
+ int i;
+ for (i = 0; i < 100; i++) {
+ mTitles[i] = "[" + i + "]";
+ }
+ }
+
+ public int getCount() {
+ return mTitles.length;
+ }
+
+ public Object getItem(int position) {
+ return position;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView view;
+
+ if (convertView == null) {
+ view = (TextView) mInflater.inflate(android.R.layout.simple_list_item_1, null);
+ } else {
+ view = (TextView) convertView;
+ }
+ view.setText(mTitles[position]);
+ return view;
+ }
+
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_take_focus_from_side);
+ setListAdapter(new ThrashListAdapter(this));
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListThrasher.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListThrasher.java
new file mode 100644
index 0000000..e0b18a2
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListThrasher.java
@@ -0,0 +1,131 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.R;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.Handler;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import java.util.Random;
+
+/**
+ * Exercises change notification in a list
+ */
+public class ListThrasher extends ListActivity implements AdapterView.OnItemSelectedListener {
+ Handler mHandler = new Handler();
+ ThrashListAdapter mAdapter;
+ Random mRandomizer = new Random();
+ TextView mText;
+
+ Runnable mThrash = new Runnable() {
+ public void run() {
+ mAdapter.bumpVersion();
+ mHandler.postDelayed(mThrash, 500);
+ }
+ };
+
+ private class ThrashListAdapter extends BaseAdapter {
+ private LayoutInflater mInflater;
+
+ /**
+ * Our data, part 1.
+ */
+ private String[] mTitles = new String[100];
+
+ /**
+ * Our data, part 2.
+ */
+ private int[] mVersion = new int[100];
+
+ public ThrashListAdapter(Context context) {
+ mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mTitles = new String[100];
+ mVersion = new int[100];
+
+ int i;
+ for (i = 0; i < 100; i++) {
+ mTitles[i] = "[" + i + "]";
+ mVersion[i] = 0;
+ }
+ }
+
+ public int getCount() {
+ return mTitles.length;
+ }
+
+ public Object getItem(int position) {
+ return position;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView view;
+
+ if (convertView == null) {
+ view = (TextView) mInflater.inflate(android.R.layout.simple_list_item_1, null);
+ } else {
+ view = (TextView) convertView;
+ }
+ view.setText(mTitles[position] + " " + mVersion[position]);
+ return view;
+ }
+
+
+ public void bumpVersion() {
+ int position = mRandomizer.nextInt(getCount());
+ mVersion[position]++;
+ notifyDataSetChanged();
+ }
+
+
+ }
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.list_thrasher);
+
+ mText = (TextView) findViewById(R.id.text);
+ mAdapter = new ThrashListAdapter(this);
+ setListAdapter(mAdapter);
+
+ mHandler.postDelayed(mThrash, 5000);
+
+ getListView().setOnItemSelectedListener(this);
+ }
+
+ public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ mText.setText("Position " + position);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ mText.setText("Nothing");
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTopGravity.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTopGravity.java
new file mode 100644
index 0000000..6eb65a9
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTopGravity.java
@@ -0,0 +1,37 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.view.Gravity;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Basic top gravity scenario, nothing fancy. Items do not
+ * fill the screen
+ */
+public class ListTopGravity extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setMustFillScreen(false)
+ .setNumItems(2)
+ .setItemScreenSizeFactor(0.22);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTopGravityMany.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTopGravityMany.java
new file mode 100644
index 0000000..8cff8ca
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListTopGravityMany.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Basic top gravity scenario, nothing fancy. There are
+ * more items than fit on the screen
+ */
+public class ListTopGravityMany extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setNumItems(10)
+ .setItemScreenSizeFactor(0.22);
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListViewHeight.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListViewHeight.java
new file mode 100644
index 0000000..17222d9
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListViewHeight.java
@@ -0,0 +1,109 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import com.android.frameworktest.R;
+
+public class ListViewHeight extends Activity {
+
+ private View mButton1;
+ private View mButton2;
+ private View mButton3;
+
+ private View mOuterLayout;
+ private ListView mInnerList;
+
+ ArrayAdapter<String> mAdapter;
+ private String[] mStrings = {
+ "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", "Abondance", "Ackawi" };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.linear_layout_listview_height);
+
+ mButton1 = findViewById(R.id.button1);
+ mButton2 = findViewById(R.id.button2);
+ mButton3 = findViewById(R.id.button3);
+
+ mOuterLayout = findViewById(R.id.layout);
+ mInnerList = (ListView)findViewById(R.id.inner_list);
+
+ mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line,
+ mStrings);
+
+ // Clicking this button will show the list view and set it to a fixed height
+ // If you then hide the views, there is no problem.
+ mButton1.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ // set listview to fixed height
+ ViewGroup.MarginLayoutParams lp;
+ lp = (ViewGroup.MarginLayoutParams) mInnerList.getLayoutParams();
+ lp.height = 200;
+ mInnerList.setLayoutParams(lp);
+ // enable list adapter
+ mInnerList.setAdapter(mAdapter);
+ // and show it
+ mOuterLayout.setVisibility(View.VISIBLE);
+ }
+ });
+
+ // Clicking this button will show the list view and set it fill_parent height
+ // If you then hide the views, there is an NPE when calculating the ListView height.
+ mButton2.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ // set listview to fill screen
+ ViewGroup.MarginLayoutParams lp;
+ lp = (ViewGroup.MarginLayoutParams) mInnerList.getLayoutParams();
+ lp.height = lp.FILL_PARENT;
+ mInnerList.setLayoutParams(lp);
+ // enable list adapter
+ mInnerList.setAdapter(mAdapter);
+ // and show it
+ mOuterLayout.setVisibility(View.VISIBLE);
+ }
+ });
+
+ // Clicking this button will remove the list adapter and hide the outer enclosing view.
+ // We have to climb all the way to the top because the bug (not checking visibility)
+ // only occurs at the very outer loop of ViewRoot.performTraversals and in the case of
+ // an Activity, this means you have to crawl all the way out to the root view.
+ // In the search manager, it's sufficient to simply show/hide the outer search manager
+ // view to trigger the same bug.
+ mButton3.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mInnerList.setAdapter(null);
+ // hide listview's owner
+ // as it turns out, the owner doesn't take us high enough
+ // because our activity includes a title bar, thus another layer
+ View parent = (View) mOuterLayout.getParent(); // FrameLayout (app container)
+ View grandpa = (View) parent.getParent(); // LinearLayout (title+app)
+ View great = (View) grandpa.getParent(); // PhoneWindow.DecorView
+ great.setVisibility(View.GONE);
+ }
+ });
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithDisappearingItemBug.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithDisappearingItemBug.java
new file mode 100644
index 0000000..3a968af
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithDisappearingItemBug.java
@@ -0,0 +1,80 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.R;
+
+import android.app.ListActivity;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.provider.Contacts.People;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.LayoutAnimationController;
+import android.view.animation.TranslateAnimation;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.Toast;
+
+/**
+ * See 1080989. You need some contacts for this adapter.
+ */
+public class ListWithDisappearingItemBug extends ListActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Toast.makeText(this, "Make sure you rotate screen to see bug", Toast.LENGTH_LONG).show();
+
+ // Get a cursor with all people
+ Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
+ startManagingCursor(c);
+
+ ListAdapter adapter = new SimpleCursorAdapter(this,
+ // Use a template that displays a text view
+ R.layout.list_with_disappearing_item_bug_item,
+ // Give the cursor to the list adatper
+ c,
+ // Map the NAME column in the people database to...
+ new String[] {People.NAME} ,
+ // The "text1" view defined in the XML template
+ new int[] {R.id.text1});
+ setListAdapter(adapter);
+
+ AnimationSet set = new AnimationSet(true);
+
+ Animation animation = new AlphaAnimation(0.0f, 1.0f);
+ animation.setDuration(50);
+ set.addAnimation(animation);
+
+ animation = new TranslateAnimation(
+ Animation.RELATIVE_TO_SELF, 0.0f,Animation.RELATIVE_TO_SELF, 0.0f,
+ Animation.RELATIVE_TO_SELF, -1.0f,Animation.RELATIVE_TO_SELF, 0.0f
+ );
+ animation.setDuration(100);
+ set.addAnimation(animation);
+
+ LayoutAnimationController controller =
+ new LayoutAnimationController(set, 0.5f);
+ ListView listView = getListView();
+ listView.setLayoutAnimation(controller);
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithEditTextHeader.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithEditTextHeader.java
new file mode 100644
index 0000000..b5cac2a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithEditTextHeader.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * A list view with a single edit text in a header.
+ */
+public class ListWithEditTextHeader extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setHeaderViewCount(1)
+ .setHeaderFocusable(true)
+ .setItemsFocusable(true)
+ .setNumItems(6)
+ .setItemScreenSizeFactor(0.2);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithEmptyView.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithEmptyView.java
new file mode 100644
index 0000000..6f43551
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithEmptyView.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.R;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.ArrayAdapter;
+
+
+/**
+ * Tests using an empty view with a list */
+public class ListWithEmptyView extends ListActivity {
+
+ private class CarefulAdapter<T> extends ArrayAdapter<T> {
+
+ public CarefulAdapter(Context context, int textViewResourceId) {
+ super(context, textViewResourceId);
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public long getItemId(int position) {
+ if (position < 0 || position >= this.getCount()) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ return super.getItemId(position);
+ }
+
+
+ }
+
+ public static final int MENU_ADD = Menu.FIRST + 1;
+ public static final int MENU_REMOVE = Menu.FIRST + 2;
+
+ private CarefulAdapter<String> mAdapter;
+
+ private int mNextItem = 0;
+
+ private View mEmptyView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mAdapter = new CarefulAdapter<String>(this,
+ android.R.layout.simple_list_item_1);
+ setContentView(R.layout.list_with_empty_view);
+ setListAdapter(mAdapter);
+
+ mEmptyView = findViewById(R.id.empty);
+ getListView().setEmptyView(mEmptyView);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ super.onCreateOptionsMenu(menu);
+ menu.add(0, MENU_ADD, 0, R.string.menu_add)
+ .setIcon(android.R.drawable.ic_menu_add);
+ menu.add(0, MENU_REMOVE, 0, R.string.menu_remove)
+ .setIcon(android.R.drawable.ic_menu_delete);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case MENU_ADD:
+ String str = "Item + " + mNextItem++;
+ mAdapter.add(str);
+ return true;
+ case MENU_REMOVE:
+ if (mAdapter.getCount() > 0) {
+ mAdapter.remove(mAdapter.getItem(0));
+ }
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ public View getEmptyView() {
+ return mEmptyView;
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithFirstScreenUnSelectable.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithFirstScreenUnSelectable.java
new file mode 100644
index 0000000..4ad72fd
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithFirstScreenUnSelectable.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * The first item is unselectable, and takes up the whole screen.
+ */
+public class ListWithFirstScreenUnSelectable extends ListScenario {
+
+ @Override
+ protected void init(Params params) {
+ params.setItemScreenSizeFactor(1.2)
+ .setNumItems(2)
+ .setPositionsUnselectable(0);
+
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithHeaders.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithHeaders.java
new file mode 100644
index 0000000..d523094
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithHeaders.java
@@ -0,0 +1,57 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+import android.os.Bundle;
+import android.widget.Button;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+public class ListWithHeaders extends ListScenario {
+ @Override
+ protected void init(Params params) {
+ params.setStackFromBottom(false)
+ .setStartingSelectionPosition(-1)
+ .setNumItems(24)
+ .setItemScreenSizeFactor(0.14);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ final ListView listView = getListView();
+ listView.setItemsCanFocus(true);
+
+ for (int i = 0; i < 12; i++) {
+ Button header = new Button(this);
+ header.setText("Header View");
+ listView.addHeaderView(header);
+ }
+
+ for (int i = 0; i < 12; i++) {
+ Button footer = new Button(this);
+ footer.setText("Footer View");
+ listView.addFooterView(footer);
+ }
+
+ final ListAdapter adapter = listView.getAdapter();
+ listView.setAdapter(adapter);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithNoFadingEdge.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithNoFadingEdge.java
new file mode 100644
index 0000000..ecfc793
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithNoFadingEdge.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+public class ListWithNoFadingEdge extends ListScenario {
+
+ protected void init(Params params) {
+ params.setFadingEdgeScreenSizeFactor(0.0)
+ .setNumItems(10)
+ .setItemScreenSizeFactor(0.2);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithOffScreenNextSelectable.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithOffScreenNextSelectable.java
new file mode 100644
index 0000000..71525c0
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithOffScreenNextSelectable.java
@@ -0,0 +1,37 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Pressing down from position 0 requires looking past positions 1, 2 and 3 to
+ * an offscreen item to know that it is the next selectable.
+ */
+public class ListWithOffScreenNextSelectable extends ListScenario {
+
+
+ protected void init(Params params) {
+ params.setItemsFocusable(false)
+ .setNumItems(5)
+ .setItemScreenSizeFactor(0.25)
+ .setPositionUnselectable(1)
+ .setPositionUnselectable(2)
+ .setPositionUnselectable(3);
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithOnItemSelectedAction.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithOnItemSelectedAction.java
new file mode 100644
index 0000000..2683040
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithOnItemSelectedAction.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.widget.TextView;
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * The header text view echos the value of the selected item by using (indirectly)
+ * the {@link android.widget.AdapterView.OnItemSelectedListener}.
+ */
+public class ListWithOnItemSelectedAction extends ListScenario {
+ protected void init(Params params) {
+ params.setNumItems(8)
+ .setItemScreenSizeFactor(0.2)
+ .includeHeaderAboveList(true);
+
+ }
+
+ @Override
+ protected void positionSelected(int positon) {
+ if (positon != getListView().getSelectedItemPosition()) {
+ throw new IllegalStateException("something is fishy... the selected postion does not " +
+ "match what the list reports.");
+ }
+ setHeaderValue(
+ ((TextView) getListView().getSelectedView()).getText().toString());
+
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithScreenOfNoSelectables.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithScreenOfNoSelectables.java
new file mode 100644
index 0000000..a2f3dc2
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithScreenOfNoSelectables.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+public class ListWithScreenOfNoSelectables extends ListScenario {
+
+ protected void init(Params params) {
+ params.setNumItems(10)
+ .setItemScreenSizeFactor(0.2)
+ .setPositionsUnselectable(1, 2, 3, 4, 5, 6, 7, 8, 9);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithSeparators.java b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithSeparators.java
new file mode 100644
index 0000000..71ce4e7
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/listview/ListWithSeparators.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.util.ListScenario;
+
+/**
+ * Basic separator scenario, nothing fancy.
+ */
+public class ListWithSeparators extends ListScenario {
+
+ protected void init(Params params) {
+ params.setItemsFocusable(false)
+ .setNumItems(5)
+ .setItemScreenSizeFactor(0.22)
+ .setPositionUnselectable(0)
+ .setPositionUnselectable(2);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/menus/ListContextMenu.java b/tests/FrameworkTest/src/com/android/frameworktest/menus/ListContextMenu.java
new file mode 100644
index 0000000..13c7552
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/menus/ListContextMenu.java
@@ -0,0 +1,201 @@
+/*
+ * 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 com.android.frameworktest.menus;
+
+import com.android.frameworktest.R;
+
+import android.app.ListActivity;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.SubMenu;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+/**
+ * Exercises context menus in lists
+ */
+public class ListContextMenu extends ListActivity implements View.OnCreateContextMenuListener
+{
+ static final String TAG = "ListContextMenu";
+
+ ThrashListAdapter mAdapter;
+
+ private class ThrashListAdapter extends BaseAdapter {
+ private LayoutInflater mInflater;
+
+ private String[] mTitles = new String[100];
+
+ public ThrashListAdapter(Context context) {
+ mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mTitles = new String[100];
+
+ int i;
+ for (i=0; i<100; i++) {
+ mTitles[i] = "[" + i + "]";
+ }
+ }
+
+ public int getCount() {
+ return mTitles.length;
+ }
+
+ public Object getItem(int position) {
+ return position;
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView view;
+
+ if (convertView == null) {
+ view = (TextView) mInflater.inflate(android.R.layout.simple_list_item_1, null);
+ } else {
+ view = (TextView) convertView;
+ }
+ view.setText("List item " + mTitles[position]);
+ return view;
+ }
+
+ }
+
+ @Override
+ public void onCreate(Bundle icicle)
+ {
+ super.onCreate(icicle);
+
+ mAdapter = new ThrashListAdapter(this);
+ getListView().setOnCreateContextMenuListener(this);
+ setListAdapter(mAdapter);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuItem item = menu.add(0, 0, 0, "Really long menu item name");
+ item.setTitleCondensed("Long name");
+ item.setIcon(R.drawable.black_square);
+
+ SubMenu sm = menu.addSubMenu(0, 0, 0, "The 2nd item, a sub menu").setIcon(R.drawable.black_square_stretchable);
+ item = sm.getItem();
+ item.setTitleCondensed("Sub menu");
+ sm.add(1, 0, 0, "Subitem 1");
+ sm.add(1, 0, 0, "Subitem 2");
+ sm.add(1, 0, 0, "Subitem 3");
+ sm.setGroupCheckable(1, true, true);
+ menu.add(0, 0, 0, "Item 3");
+ menu.add(0, 0, 0, "Item 4");
+ menu.add(0, 0, 0, "Item 5");
+ menu.add(0, 0, 0, "Item 6");
+ menu.add(0, 0, 0, "Item 7");
+ menu.add(0, 0, 0, "Item 8");
+ menu.add(0, 0, 0, "Item 9");
+ sm = menu.addSubMenu(0, 0, 0, "Item 10 SM");
+ sm.add(0, 0, 0, "Subitem 1");
+ sm.add(0, 0, 0, "Subitem 2");
+ sm.add(0, 0, 0, "Subitem 3");
+ sm.add(0, 0, 0, "Subitem 4");
+ sm.add(0, 0, 0, "Subitem 5");
+ sm.add(0, 0, 0, "Subitem 6");
+ sm.add(0, 0, 0, "Subitem 7");
+ sm.add(0, 0, 0, "Subitem 8");
+
+ return true;
+ }
+
+ public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
+
+ AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)menuInfo;
+
+ String text = ((TextView) info.targetView).getText().toString();
+ if (text.contains("[0]")) {
+ menu.setHeaderTitle("This is a test of the title and the icon").setHeaderIcon(
+ android.R.drawable.sym_def_app_icon);
+ } else if (text.contains("[1]")) {
+ menu.setHeaderTitle("This is a test of just the title");
+ } else {
+ TextView textView = new TextView(this);
+ textView.setText("This is a test of a custom View");
+ menu.setHeaderView(textView);
+ }
+
+ menu.add(0, 0, 0, "Test 1");
+ SubMenu sm = menu.addSubMenu(0, 0, 0, "Test 1.5 SM");
+ sm.add(0, 0, 0, "CM Subitem 1");
+ sm.add(0, 0, 0, "CM Subitem 2");
+ sm.add(0, 0, 0, "CM Subitem 3");
+ menu.add(0, 0, 0, "Test 2");
+ menu.add(0, 0, 0, "Test 3");
+ menu.add(0, 0, 0, "Test 4");
+ menu.add(0, 0, 0, "Test 5");
+ menu.add(0, 0, 0, "Test 6");
+ menu.add(0, 0, 0, "Test 7");
+ menu.add(0, 0, 0, "Test 8");
+ menu.add(0, 0, 0, "Test 9");
+ menu.add(0, 0, 0, "Test 10");
+ menu.add(0, 0, 0, "Test 11");
+ menu.add(0, 0, 0, "Test 12");
+ menu.add(0, 0, 0, "Test 13");
+ menu.add(0, 0, 0, "Test 14");
+ menu.add(0, 0, 0, "Test 15");
+ menu.add(0, 0, 0, "Test 16");
+ menu.add(0, 0, 0, "Test 17");
+ menu.add(0, 0, 0, "Test 18");
+ menu.add(0, 0, 0, "Test 19");
+ menu.add(0, 0, 0, "Test 20");
+ menu.add(0, 0, 0, "Test 21");
+ menu.add(0, 0, 0, "Test 22");
+ menu.add(0, 0, 0, "Test 23");
+ menu.add(0, 0, 0, "Test 24");
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ Log.i(TAG, "Options item " + item.toString() + " selected.");
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onOptionsMenuClosed(Menu menu) {
+ Log.i(TAG, "Options menu closed");
+ }
+
+ @Override
+ public boolean onContextItemSelected(MenuItem item) {
+ Log.i(TAG, "Context item " + item.toString() + " selected.");
+
+ return super.onContextItemSelected(item);
+ }
+
+ @Override
+ public void onContextMenuClosed(Menu menu) {
+ Log.i(TAG, "Context menu closed");
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayout.java b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayout.java
new file mode 100644
index 0000000..6ed6433
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayout.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2008 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 com.android.frameworktest.menus;
+
+import com.android.frameworktest.menus.MenuScenario.Params;
+
+import android.os.Bundle;
+import android.view.Menu;
+import android.widget.Button;
+
+public class MenuLayout extends MenuScenario {
+ private static final String LONG_TITLE = "Really really really really really really really really really really long title";
+ private static final String SHORT_TITLE = "Item";
+
+ private Button mButton;
+
+ @Override
+ protected void onInitParams(Params params) {
+ super.onInitParams(params);
+ params
+ .setNumItems(2)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE);
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+
+ /*
+ * This activity is meant to try a bunch of different menu layouts. So,
+ * we recreate the menu every time it is prepared.
+ */
+ menu.clear();
+ onCreateOptionsMenu(menu);
+
+ return true;
+ }
+
+ public Button getButton() {
+ return mButton;
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mButton = new Button(this);
+ setContentView(mButton);
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayoutLandscape.java b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayoutLandscape.java
new file mode 100644
index 0000000..8a98610
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayoutLandscape.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (C) 2008 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 com.android.frameworktest.menus;
+
+/**
+ * An activity (inherits from MenuLayout) that shows in landscape.
+ */
+public class MenuLayoutLandscape extends MenuLayout {
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayoutPortrait.java b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayoutPortrait.java
new file mode 100644
index 0000000..71e7e49
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuLayoutPortrait.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (C) 2008 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 com.android.frameworktest.menus;
+
+/**
+ * An activity (inherits from MenuLayout) that shows in portrait.
+ */
+public class MenuLayoutPortrait extends MenuLayout {
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuScenario.java b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuScenario.java
new file mode 100644
index 0000000..4df9b1b
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuScenario.java
@@ -0,0 +1,212 @@
+/*
+ * 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 com.android.frameworktest.menus;
+
+import com.android.frameworktest.util.ListScenario;
+import com.android.internal.view.menu.MenuBuilder;
+import com.android.internal.view.menu.MenuBuilder.MenuAdapter;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.util.SparseArray;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * Utility base class for creating various Menu scenarios. Configurable by the
+ * number of menu items. Used @link {@link ListScenario} as a reference.
+ */
+public class MenuScenario extends Activity implements MenuItem.OnMenuItemClickListener {
+ private Params mParams = new Params();
+ private Menu mMenu;
+ private MenuItem[] mItems;
+ private boolean[] mWasItemClicked;
+ private MenuAdapter[] mMenuAdapters = new MenuAdapter[MenuBuilder.NUM_TYPES];
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ dispatchInitParams();
+ }
+
+ private void dispatchInitParams() {
+ onInitParams(mParams);
+ onParamsChanged();
+ }
+
+ public void setParams(Params params) {
+ mParams = params;
+ onParamsChanged();
+ }
+
+ public void onParamsChanged() {
+ mItems = new MenuItem[mParams.numItems];
+ mWasItemClicked = new boolean[mParams.numItems];
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ // Safe to hold on to
+ mMenu = menu;
+
+ if (!mParams.shouldShowMenu) return false;
+
+ MenuItem item;
+ for (int i = 0; i < mParams.numItems; i++) {
+ if ((item = onAddMenuItem(menu, i)) == null) {
+ // Add a default item for this position if the subclasses
+ // haven't
+ CharSequence givenTitle = mParams.itemTitles.get(i);
+ item = menu.add(0, 0, 0, (givenTitle != null) ? givenTitle : ("Item " + i));
+ }
+
+ if (item != null) {
+ mItems[i] = item;
+
+ if (mParams.listenForClicks) {
+ item.setOnMenuItemClickListener(this);
+ }
+ }
+
+ }
+
+ return true;
+ }
+
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ // Safe to hold on to
+ mMenu = menu;
+
+ return mParams.shouldShowMenu;
+ }
+
+ /**
+ * Override this to add an item to the menu.
+ *
+ * @param itemPosition The position of the item to add (only for your
+ * reference).
+ * @return The item that was added to the menu, or null if nothing was
+ * added.
+ */
+ protected MenuItem onAddMenuItem(Menu menu, int itemPosition) {
+ return null;
+ }
+
+ /**
+ * Override this to set the parameters for the scenario. Call through to super first.
+ *
+ * @param params
+ */
+ protected void onInitParams(Params params) {
+ }
+
+ public Menu getMenu() {
+ return mMenu;
+ }
+
+ public boolean onMenuItemClick(MenuItem item) {
+ final int position = findItemPosition(item);
+ if (position < 0) return false;
+
+ mWasItemClicked[position] = true;
+
+ return true;
+ }
+
+ public boolean wasItemClicked(int position) {
+ return mWasItemClicked[position];
+ }
+
+ /**
+ * Finds the position for a given Item.
+ *
+ * @param item The item to find.
+ * @return The position, or -1 if not found.
+ */
+ public int findItemPosition(MenuItem item) {
+ // Could create reverse mapping, but optimizations aren't important (yet :P)
+ for (int i = 0; i < mParams.numItems; i++) {
+ if (mItems[i] == item) return i;
+ }
+
+ return -1;
+ }
+
+ /**
+ * @see MenuBuilder#getMenuAdapter(int)
+ */
+ public MenuAdapter getMenuAdapter(int menuType) {
+ if (mMenuAdapters[menuType] == null) {
+ mMenuAdapters[menuType] = ((MenuBuilder) mMenu).getMenuAdapter(menuType);
+ }
+
+ return mMenuAdapters[menuType];
+ }
+
+ /**
+ * Gets a menu view. Call this after you're sure it has been shown,
+ * otherwise it may not have the proper layout_* attributes set.
+ *
+ * @param menuType The type of menu.
+ * @return The MenuView for that type.
+ */
+ public View getMenuView(int menuType) {
+ return ((MenuBuilder) mMenu).getMenuView(menuType, null);
+ }
+
+ /**
+ * Gets the menu item view for a given position.
+ *
+ * @param menuType The type of menu.
+ * @param position The position of the item.
+ * @return The menu item view for the given item in the given menu type.
+ */
+ public View getItemView(int menuType, int position) {
+ return getMenuAdapter(menuType).getView(position, null, null);
+ }
+
+ public static class Params {
+ // Using as data structure, so no m prefix
+ private boolean shouldShowMenu = true;
+ private int numItems = 10;
+ private boolean listenForClicks = true;
+ private SparseArray<CharSequence> itemTitles = new SparseArray<CharSequence>();
+
+ public Params setShouldShowMenu(boolean shouldShowMenu) {
+ this.shouldShowMenu = shouldShowMenu;
+ return this;
+ }
+
+ public Params setNumItems(int numItems) {
+ this.numItems = numItems;
+ return this;
+ }
+
+ public Params setListenForClicks(boolean listenForClicks) {
+ this.listenForClicks = listenForClicks;
+ return this;
+ }
+
+ public Params setItemTitle(int itemPos, CharSequence title) {
+ itemTitles.put(itemPos, title);
+ return this;
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuWith1Item.java b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuWith1Item.java
new file mode 100644
index 0000000..d7468f5
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/menus/MenuWith1Item.java
@@ -0,0 +1,44 @@
+/*
+ * 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 com.android.frameworktest.menus;
+
+import android.os.Bundle;
+import android.widget.Button;
+
+public class MenuWith1Item extends MenuScenario {
+
+ private Button mButton;
+
+ @Override
+ protected void onInitParams(Params params) {
+ super.onInitParams(params);
+
+ params.setNumItems(1);
+ }
+
+ public Button getButton() {
+ return mButton;
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mButton = new Button(this);
+ setContentView(mButton);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/performance/InvalidateCycle.java b/tests/FrameworkTest/src/com/android/frameworktest/performance/InvalidateCycle.java
new file mode 100644
index 0000000..8663f06
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/performance/InvalidateCycle.java
@@ -0,0 +1,49 @@
+package com.android.frameworktest.performance;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Handler;
+import android.view.View;
+import android.view.ViewGroup;
+import android.content.Context;
+import android.graphics.Canvas;
+
+public class InvalidateCycle extends Activity {
+ private boolean mStartProfiling;
+ private InvalidateCycle.AutoInvalidateView mView;
+
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mView = new AutoInvalidateView(this);
+ mView.setLayoutParams(new ViewGroup.LayoutParams(16, 16));
+ setContentView(mView);
+
+ new Handler().postDelayed(new Runnable() {
+ public void run() {
+ mStartProfiling = true;
+ android.util.Log.d("Performance", "Profiling started");
+ Debug.startMethodTracing("invalidateCycle");
+ mView.invalidate();
+ }
+ }, 15000);
+ }
+
+ private class AutoInvalidateView extends View {
+ private boolean mFirstDraw;
+
+ public AutoInvalidateView(Context context) {
+ super(context);
+ }
+
+ protected void onDraw(Canvas canvas) {
+ if (mStartProfiling && !mFirstDraw) {
+ Debug.stopMethodTracing();
+ android.util.Log.d("Performance", "Profiling ended");
+ mFirstDraw = true;
+ }
+ canvas.drawColor(0xFFFF0000);
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/scroll/ButtonAboveTallInternalSelectionView.java b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ButtonAboveTallInternalSelectionView.java
new file mode 100644
index 0000000..986b800
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ButtonAboveTallInternalSelectionView.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.util.InternalSelectionView;
+import com.android.frameworktest.util.ScrollViewScenario;
+
+import android.widget.Button;
+
+/**
+ * A button above a tall internal selection view, wrapped in a scroll view.
+ */
+public class ButtonAboveTallInternalSelectionView extends ScrollViewScenario {
+
+ private final int mNumRowsInIsv = 5;
+
+
+ public Button getButtonAbove() {
+ return getContentChildAt(0);
+ }
+
+ public InternalSelectionView getIsv() {
+ return getContentChildAt(1);
+ }
+
+
+ protected void init(Params params) {
+ params.addButton("howdy", 0.1f)
+ .addInternalSelectionView(mNumRowsInIsv, 1.1f)
+ .addButton("below", 0.1f);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/scroll/ButtonsWithTallTextViewInBetween.java b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ButtonsWithTallTextViewInBetween.java
new file mode 100644
index 0000000..ed098aa
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ButtonsWithTallTextViewInBetween.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.util.ScrollViewScenario;
+
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Two buttons sandwiching a tall text view (good for testing panning across
+ * before getting to next button).
+ */
+public class ButtonsWithTallTextViewInBetween extends ScrollViewScenario {
+
+ public Button getTopButton() {
+ return getContentChildAt(0);
+ }
+
+ public TextView getMiddleFiller() {
+ return getContentChildAt(1);
+ }
+
+ public Button getBottomButton() {
+ LinearLayout ll = getContentChildAt(2);
+ return (Button) ll.getChildAt(0);
+ }
+
+ protected void init(Params params) {
+
+ params.addButton("top button", 0.2f)
+ .addTextView("middle filler", 1.51f)
+ .addVerticalLLOfButtons("bottom", 1, 0.2f);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/scroll/RequestRectangleVisible.java b/tests/FrameworkTest/src/com/android/frameworktest/scroll/RequestRectangleVisible.java
new file mode 100644
index 0000000..affd3c7
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/scroll/RequestRectangleVisible.java
@@ -0,0 +1,94 @@
+/*
+ * 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.graphics.Rect;
+import android.view.View;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+/**
+ * A screen with some scenarios that exercise {@link ScrollView}'s implementation
+ * of {@link android.view.ViewGroup#requestChildRectangleOnScreen}:
+ * <li>Scrolling to something off screen (from top and from bottom)
+ * <li>Scrolling to bring something that is larger than the screen on screen
+ * (from top and from bottom).
+ */
+public class RequestRectangleVisible extends Activity {
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.scroll_to_rectangle);
+
+ final Rect rect = new Rect();
+ final View childToMakeVisible = findViewById(R.id.childToMakeVisible);
+
+ final TextView topBlob = (TextView) findViewById(R.id.topBlob);
+ final TextView bottomBlob = (TextView) findViewById(R.id.bottomBlob);
+
+ // estimate to get blobs larger than screen
+ int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
+ int numLinesForScreen = screenHeight / 18;
+
+ for (int i = 0; i < numLinesForScreen; i++) {
+ topBlob.append(i + " another line in the blob\n");
+ bottomBlob.append(i + " another line in the blob\n");
+ }
+
+ findViewById(R.id.scrollToRectFromTop).setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ rect.set(0, 0, childToMakeVisible.getLeft(), childToMakeVisible.getHeight());
+ childToMakeVisible.requestRectangleOnScreen(rect, true);
+ }
+ });
+
+ findViewById(R.id.scrollToRectFromTop2).setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ rect.set(0, 0, topBlob.getWidth(), topBlob.getHeight());
+ topBlob.requestRectangleOnScreen(rect, true);
+ }
+ });
+
+ findViewById(R.id.scrollToRectFromBottom).setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ rect.set(0, 0, childToMakeVisible.getLeft(), childToMakeVisible.getHeight());
+ childToMakeVisible.requestRectangleOnScreen(rect, true);
+ }
+ });
+
+ findViewById(R.id.scrollToRectFromBottom2).setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ rect.set(0, 0, bottomBlob.getWidth(), bottomBlob.getHeight());
+ bottomBlob.requestRectangleOnScreen(rect, true);
+ }
+ });
+
+ }
+
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/scroll/RequestRectangleVisibleWithInternalScroll.java b/tests/FrameworkTest/src/com/android/frameworktest/scroll/RequestRectangleVisibleWithInternalScroll.java
new file mode 100644
index 0000000..0a8dc30
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/scroll/RequestRectangleVisibleWithInternalScroll.java
@@ -0,0 +1,76 @@
+/*
+ * 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Button;
+import android.view.View;
+import android.graphics.Rect;
+
+public class RequestRectangleVisibleWithInternalScroll extends Activity {
+
+ private int scrollYofBlob = 52;
+
+ private TextView mTextBlob;
+ private Button mScrollToBlob;
+
+
+ public int getScrollYofBlob() {
+ return scrollYofBlob;
+ }
+
+
+ public TextView getTextBlob() {
+ return mTextBlob;
+ }
+
+
+ public Button getScrollToBlob() {
+ return mScrollToBlob;
+ }
+
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ setContentView(R.layout.scroll_to_rect_with_internal_scroll);
+
+ mTextBlob = (TextView) findViewById(R.id.blob);
+ mTextBlob.scrollBy(0, scrollYofBlob);
+
+
+ mScrollToBlob = (Button) findViewById(R.id.scrollToBlob);
+ mScrollToBlob.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+
+ // the rect we want to make visible is offset to match
+ // the internal scroll
+ Rect rect = new Rect();
+ rect.set(0, 0, 0, mTextBlob.getHeight());
+ rect.offset(0, mTextBlob.getScrollY());
+ mTextBlob.requestRectangleOnScreen(rect);
+ }
+ });
+ }
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/scroll/ScrollViewButtonsAndLabels.java b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ScrollViewButtonsAndLabels.java
new file mode 100644
index 0000000..4763ab1
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ScrollViewButtonsAndLabels.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import android.widget.Button;
+
+
+/**
+ * Basic scroll view example
+ */
+public class ScrollViewButtonsAndLabels extends Activity {
+
+ private ScrollView mScrollView;
+ private LinearLayout mLinearLayout;
+
+ private int mNumGroups = 10;
+
+
+ public ScrollView getScrollView() {
+ return mScrollView;
+ }
+
+ public LinearLayout getLinearLayout() {
+ return mLinearLayout;
+ }
+
+ public int getNumButtons() {
+ return mNumGroups;
+ }
+
+ public Button getButton(int groupNum) {
+ if (groupNum > mNumGroups) {
+ throw new IllegalArgumentException("groupNum > " + mNumGroups);
+ }
+ return (Button) mLinearLayout.getChildAt(2*groupNum);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.scrollview_linear_layout);
+
+
+ // estimated ratio to get enough buttons so a couple are off screen
+ int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
+ mNumGroups = screenHeight / 30;
+
+ mScrollView = (ScrollView) findViewById(R.id.scrollView);
+ mLinearLayout = (LinearLayout) findViewById(R.id.layout);
+
+ LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.FILL_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ );
+
+ for (int i = 0; i < mNumGroups; i++) {
+ // want button to be first and last
+ if (i > 0) {
+ TextView textView = new TextView(this);
+ textView.setText("Text View " + i);
+ mLinearLayout.addView(textView, p);
+ }
+
+ Button button = new Button(this);
+ button.setText("Button " + (i + 1));
+ mLinearLayout.addView(button, p);
+ }
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/scroll/ShortButtons.java b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ShortButtons.java
new file mode 100644
index 0000000..b903382
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/scroll/ShortButtons.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.util.ScrollViewScenario;
+
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+/**
+ * A series of short buttons, some of which are embedded within another
+ * layout.
+ */
+public class ShortButtons extends ScrollViewScenario {
+
+ private final int mNumButtons = 10;
+ protected final float mButtonHeightFactor = 0.2f;
+
+ public int getNumButtons() {
+ return mNumButtons;
+ }
+
+ public Button getButtonAt(int index) {
+ if (index < 3) {
+ return getContentChildAt(index);
+ } else {
+ LinearLayout ll = getContentChildAt(3);
+ return (Button) ll.getChildAt(index - 3);
+ }
+ }
+
+ @Override
+ protected void init(Params params) {
+ final int numButtonsInSubLayout = getNumButtons() - 3;
+ params.addButtons(3, "top-level", mButtonHeightFactor)
+ .addVerticalLLOfButtons("embedded",
+ numButtonsInSubLayout,
+ numButtonsInSubLayout * mButtonHeightFactor);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/scroll/TallTextAboveButton.java b/tests/FrameworkTest/src/com/android/frameworktest/scroll/TallTextAboveButton.java
new file mode 100644
index 0000000..8b2e4f9
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/scroll/TallTextAboveButton.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.util.ScrollViewScenario;
+
+/**
+ * An (unfocusable) text view that takes up more than the height
+ * of the screen followed by a button.
+ */
+public class TallTextAboveButton extends ScrollViewScenario {
+
+ protected void init(Params params) {
+ params.addTextView("top tall", 1.1f)
+ .addButton("button", 0.2f);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java b/tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java
new file mode 100644
index 0000000..b812181
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/settings/BrightnessLimit.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.settings;
+
+import android.os.IHardwareService;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.provider.Settings;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.android.frameworktest.R;
+
+/**
+ * Tries to set the brightness to 0. Should be silently thwarted by the framework.
+ */
+public class BrightnessLimit extends Activity implements OnClickListener {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.brightness_limit);
+
+ Button b = (Button) findViewById(R.id.go);
+ b.setOnClickListener(this);
+ }
+
+ public void onClick(View v) {
+ IHardwareService hardware = IHardwareService.Stub.asInterface(
+ ServiceManager.getService("hardware"));
+ if (hardware != null) {
+ try {
+ hardware.setScreenBacklight(0);
+ } catch (RemoteException darn) {
+
+ }
+ }
+ Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0);
+ }
+}
+
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/settings/RingtonePickerActivityLauncher.java b/tests/FrameworkTest/src/com/android/frameworktest/settings/RingtonePickerActivityLauncher.java
new file mode 100644
index 0000000..19113da
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/settings/RingtonePickerActivityLauncher.java
@@ -0,0 +1,79 @@
+/*
+ * 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 com.android.frameworktest.settings;
+
+import com.android.internal.app.RingtonePickerActivity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.os.Bundle;
+
+/**
+ * Activity that will launch the RingtonePickerActivity as a subactivity, and
+ * waits for its result.
+ */
+public class RingtonePickerActivityLauncher extends Activity {
+
+ private static final String TAG = "RingtonePickerActivityLauncher";
+
+ public boolean resultReceived = false;
+
+ public int resultCode;
+ public Intent result;
+
+ public Uri pickedUri;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(android.R.layout.simple_list_item_1);
+ }
+
+ /**
+ * Launches the {@link RingtonePickerActivity} and blocks until it returns.
+ *
+ * @param showDefault {@link RingtonePickerActivity#EXTRA_SHOW_DEFAULT}
+ * @param existingUri {@link RingtonePickerActivity#EXTRA_EXISTING_URI}
+ * @param filterColumns {@link RingtonePickerActivity#EXTRA_RINGTONE_COLUMNS}
+ */
+ public void launchRingtonePickerActivity(boolean showDefault, Uri existingUri,
+ int types) {
+ Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, showDefault);
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, existingUri);
+ intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, types);
+ startActivityForResult(intent, 0);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+
+ resultReceived = true;
+
+ this.resultCode = resultCode;
+ this.result = data;
+
+ if (data != null) {
+ this.pickedUri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
+ }
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/ExpandableListScenario.java b/tests/FrameworkTest/src/com/android/frameworktest/util/ExpandableListScenario.java
new file mode 100644
index 0000000..f72cbe8
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/ExpandableListScenario.java
@@ -0,0 +1,387 @@
+/*
+ * 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 com.android.frameworktest.util;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.ListView;
+import android.widget.TextView;
+
+/**
+ * Utility base class for creating various Expandable List scenarios.
+ * <p>
+ * WARNING: A lot of the features are mixed between ListView's expected position
+ * (flat list position) and an ExpandableListView's expected position. You must add/change
+ * features as you need them.
+ *
+ * @see ListScenario
+ */
+public abstract class ExpandableListScenario extends ListScenario {
+ protected ExpandableListAdapter mAdapter;
+ protected List<MyGroup> mGroups;
+
+ @Override
+ protected ListView createListView() {
+ return new ExpandableListView(this);
+ }
+
+ @Override
+ protected Params createParams() {
+ return new ExpandableParams();
+ }
+
+ @Override
+ protected void setAdapter(ListView listView) {
+ ((ExpandableListView) listView).setAdapter(mAdapter = createAdapter());
+ }
+
+ protected ExpandableListAdapter createAdapter() {
+ return new MyAdapter();
+ }
+
+ @Override
+ protected void readAndValidateParams(Params params) {
+ ExpandableParams expandableParams = (ExpandableParams) params;
+
+ int[] numChildren = expandableParams.mNumChildren;
+
+ mGroups = new ArrayList<MyGroup>(numChildren.length);
+ for (int i = 0; i < numChildren.length; i++) {
+ mGroups.add(new MyGroup(numChildren[i]));
+ }
+
+ expandableParams.superSetNumItems();
+
+ super.readAndValidateParams(params);
+ }
+
+ /**
+ * Get the ExpandableListView widget.
+ * @return The main widget.
+ */
+ public ExpandableListView getExpandableListView() {
+ return (ExpandableListView) super.getListView();
+ }
+
+ public static class ExpandableParams extends Params {
+ private int[] mNumChildren;
+
+ /**
+ * Sets the number of children per group.
+ *
+ * @param numChildrenPerGroup The number of children per group.
+ */
+ public ExpandableParams setNumChildren(int[] numChildren) {
+ mNumChildren = numChildren;
+ return this;
+ }
+
+ /**
+ * Sets the number of items on the superclass based on the number of
+ * groups and children per group.
+ */
+ private ExpandableParams superSetNumItems() {
+ int numItems = 0;
+
+ if (mNumChildren != null) {
+ for (int i = mNumChildren.length - 1; i >= 0; i--) {
+ numItems += mNumChildren[i];
+ }
+ }
+
+ super.setNumItems(numItems);
+
+ return this;
+ }
+
+ @Override
+ public Params setNumItems(int numItems) {
+ throw new IllegalStateException("Use setNumGroups and setNumChildren instead.");
+ }
+
+ @Override
+ public ExpandableParams setFadingEdgeScreenSizeFactor(double fadingEdgeScreenSizeFactor) {
+ return (ExpandableParams) super.setFadingEdgeScreenSizeFactor(fadingEdgeScreenSizeFactor);
+ }
+
+ @Override
+ public ExpandableParams setItemScreenSizeFactor(double itemScreenSizeFactor) {
+ return (ExpandableParams) super.setItemScreenSizeFactor(itemScreenSizeFactor);
+ }
+
+ @Override
+ public ExpandableParams setItemsFocusable(boolean itemsFocusable) {
+ return (ExpandableParams) super.setItemsFocusable(itemsFocusable);
+ }
+
+ @Override
+ public ExpandableParams setMustFillScreen(boolean fillScreen) {
+ return (ExpandableParams) super.setMustFillScreen(fillScreen);
+ }
+
+ @Override
+ public ExpandableParams setPositionScreenSizeFactorOverride(int position, double itemScreenSizeFactor) {
+ return (ExpandableParams) super.setPositionScreenSizeFactorOverride(position, itemScreenSizeFactor);
+ }
+
+ @Override
+ public ExpandableParams setPositionUnselectable(int position) {
+ return (ExpandableParams) super.setPositionUnselectable(position);
+ }
+
+ @Override
+ public ExpandableParams setStackFromBottom(boolean stackFromBottom) {
+ return (ExpandableParams) super.setStackFromBottom(stackFromBottom);
+ }
+
+ @Override
+ public ExpandableParams setStartingSelectionPosition(int startingSelectionPosition) {
+ return (ExpandableParams) super.setStartingSelectionPosition(startingSelectionPosition);
+ }
+
+ @Override
+ public ExpandableParams setConnectAdapter(boolean connectAdapter) {
+ return (ExpandableParams) super.setConnectAdapter(connectAdapter);
+ }
+ }
+
+ /**
+ * Gets a string for the value of some item.
+ * @param packedPosition The position of the item.
+ * @return The string.
+ */
+ public final String getValueAtPosition(long packedPosition) {
+ final int type = ExpandableListView.getPackedPositionType(packedPosition);
+
+ if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
+ return mGroups.get(ExpandableListView.getPackedPositionGroup(packedPosition))
+ .children.get(ExpandableListView.getPackedPositionChild(packedPosition))
+ .name;
+ } else if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {
+ return mGroups.get(ExpandableListView.getPackedPositionGroup(packedPosition))
+ .name;
+ } else {
+ throw new IllegalStateException("packedPosition is not a valid position.");
+ }
+ }
+
+ /**
+ * Whether a particular position is out of bounds.
+ *
+ * @param packedPosition The packed position.
+ * @return Whether it's out of bounds.
+ */
+ private boolean isOutOfBounds(long packedPosition) {
+ final int type = ExpandableListView.getPackedPositionType(packedPosition);
+
+ if (type == ExpandableListView.PACKED_POSITION_TYPE_NULL) {
+ throw new IllegalStateException("packedPosition is not a valid position.");
+ }
+
+ final int group = ExpandableListView.getPackedPositionGroup(packedPosition);
+ if (group >= mGroups.size() || group < 0) {
+ return true;
+ }
+
+ if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
+ final int child = ExpandableListView.getPackedPositionChild(packedPosition);
+ if (child >= mGroups.get(group).children.size() || child < 0) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets a view for the packed position, possibly reusing the convertView.
+ *
+ * @param packedPosition The position to get a view for.
+ * @param convertView Optional view to convert.
+ * @param parent The future parent.
+ * @return A view.
+ */
+ private View getView(long packedPosition, View convertView, ViewGroup parent) {
+ if (isOutOfBounds(packedPosition)) {
+ throw new IllegalStateException("position out of range for adapter!");
+ }
+
+ final ExpandableListView elv = getExpandableListView();
+ final int flPos = elv.getFlatListPosition(packedPosition);
+
+ if (convertView != null) {
+ ((TextView) convertView).setText(getValueAtPosition(packedPosition));
+ convertView.setId(flPos);
+ return convertView;
+ }
+
+ int desiredHeight = getHeightForPosition(flPos);
+ return createView(packedPosition, flPos, parent, desiredHeight);
+ }
+
+ /**
+ * Create a view for a group or child position.
+ *
+ * @param packedPosition The packed position (has type, group pos, and optionally child pos).
+ * @param flPos The flat list position (the position that the ListView goes by).
+ * @param parent The parent view.
+ * @param desiredHeight The desired height.
+ * @return A view.
+ */
+ protected View createView(long packedPosition, int flPos, ViewGroup parent, int desiredHeight) {
+ TextView result = new TextView(parent.getContext());
+ result.setHeight(desiredHeight);
+ result.setText(getValueAtPosition(packedPosition));
+ final ViewGroup.LayoutParams lp = new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ result.setLayoutParams(lp);
+ result.setGravity(Gravity.CENTER_VERTICAL);
+ result.setPadding(36, 0, 0, 0);
+ result.setId(flPos);
+ return result;
+ }
+
+ /**
+ * Returns a group index containing either the number of children or at
+ * least one child.
+ *
+ * @param numChildren The group must have this amount, or -1 if using
+ * atLeastOneChild.
+ * @param atLeastOneChild The group must have at least one child, or false
+ * if using numChildren.
+ * @return A group index with the requirements.
+ */
+ public int findGroupWithNumChildren(int numChildren, boolean atLeastOneChild) {
+ final ExpandableListAdapter adapter = mAdapter;
+
+ for (int i = adapter.getGroupCount() - 1; i >= 0; i--) {
+ final int curNumChildren = adapter.getChildrenCount(i);
+
+ if (numChildren == curNumChildren || atLeastOneChild && curNumChildren > 0) {
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+ public List<MyGroup> getGroups() {
+ return mGroups;
+ }
+
+ public ExpandableListAdapter getAdapter() {
+ return mAdapter;
+ }
+
+ /**
+ * Simple expandable list adapter.
+ */
+ protected class MyAdapter extends BaseExpandableListAdapter {
+ public Object getChild(int groupPosition, int childPosition) {
+ return getValueAtPosition(ExpandableListView.getPackedPositionForChild(groupPosition,
+ childPosition));
+ }
+
+ public long getChildId(int groupPosition, int childPosition) {
+ return mGroups.get(groupPosition).children.get(childPosition).id;
+ }
+
+ public int getChildrenCount(int groupPosition) {
+ return mGroups.get(groupPosition).children.size();
+ }
+
+ public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+ View convertView, ViewGroup parent) {
+ return getView(ExpandableListView.getPackedPositionForChild(groupPosition,
+ childPosition), convertView, parent);
+ }
+
+ public Object getGroup(int groupPosition) {
+ return getValueAtPosition(ExpandableListView.getPackedPositionForGroup(groupPosition));
+ }
+
+ public int getGroupCount() {
+ return mGroups.size();
+ }
+
+ public long getGroupId(int groupPosition) {
+ return mGroups.get(groupPosition).id;
+ }
+
+ public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
+ ViewGroup parent) {
+ return getView(ExpandableListView.getPackedPositionForGroup(groupPosition),
+ convertView, parent);
+ }
+
+ public boolean isChildSelectable(int groupPosition, int childPosition) {
+ return true;
+ }
+
+ public boolean hasStableIds() {
+ return true;
+ }
+
+ }
+
+ public static class MyGroup {
+ private static long mNextId = 1000;
+
+ String name;
+ long id = mNextId++;
+ List<MyChild> children;
+
+ public MyGroup(int numChildren) {
+ name = "Group " + id;
+ children = new ArrayList<MyChild>(numChildren);
+ for (int i = 0; i < numChildren; i++) {
+ children.add(new MyChild());
+ }
+ }
+ }
+
+ public static class MyChild {
+ private static long mNextId = 2000;
+
+ String name;
+ long id = mNextId++;
+
+ public MyChild() {
+ name = "Child " + id;
+ }
+ }
+
+ @Override
+ protected final void init(Params params) {
+ init((ExpandableParams) params);
+ }
+
+ /**
+ * @see ListScenario#init
+ */
+ protected abstract void init(ExpandableParams params);
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/GridScenario.java b/tests/FrameworkTest/src/com/android/frameworktest/util/GridScenario.java
new file mode 100644
index 0000000..746cf23
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/GridScenario.java
@@ -0,0 +1,370 @@
+/*
+ * 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 com.android.frameworktest.util;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.AbsListView;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.GridView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import com.google.android.collect.Maps;
+
+import java.util.Map;
+
+/**
+ * Utility base class for creating various GridView scenarios. Configurable by the number
+ * of items, how tall each item should be (in relation to the screen height), and
+ * what item should start with selection.
+ */
+public abstract class GridScenario extends Activity {
+
+ private GridView mGridView;
+
+ private int mNumItems;
+
+ private int mStartingSelectionPosition;
+ private double mItemScreenSizeFactor;
+ private Map<Integer, Double> mOverrideItemScreenSizeFactors = Maps.newHashMap();
+
+ private int mScreenHeight;
+
+ private boolean mStackFromBottom;
+
+ private int mColumnWidth;
+
+ private int mNumColumns;
+
+ private int mStretchMode;
+
+ private int mVerticalSpacing;
+
+ public GridView getGridView() {
+ return mGridView;
+ }
+
+ protected int getScreenHeight() {
+ return mScreenHeight;
+ }
+
+ /**
+ * @return The initial number of items in the grid as specified by the scenario.
+ * This number may change over time.
+ */
+ protected int getInitialNumItems() {
+ return mNumItems;
+ }
+
+ /**
+ * @return The desired height of 1 item, ignoring overrides
+ */
+ public int getDesiredItemHeight() {
+ return (int) (mScreenHeight * mItemScreenSizeFactor);
+ }
+
+ /**
+ * Better way to pass in optional params than a honkin' paramater list :)
+ */
+ public static class Params {
+ private int mNumItems = 4;
+ private int mStartingSelectionPosition = -1;
+ private double mItemScreenSizeFactor = 1 / 5;
+
+ private Map<Integer, Double> mOverrideItemScreenSizeFactors = Maps.newHashMap();
+
+ private boolean mStackFromBottom = false;
+ private boolean mMustFillScreen = true;
+
+ private int mColumnWidth = 0;
+ private int mNumColumns = GridView.AUTO_FIT;
+ private int mStretchMode = GridView.STRETCH_COLUMN_WIDTH;
+ private int mVerticalSpacing = 0;
+
+ /**
+ * Set the number of items in the grid.
+ */
+ public Params setNumItems(int numItems) {
+ mNumItems = numItems;
+ return this;
+ }
+
+ /**
+ * Set the position that starts selected.
+ *
+ * @param startingSelectionPosition The selected position within the adapter's data set.
+ * Pass -1 if you do not want to force a selection.
+ * @return
+ */
+ public Params setStartingSelectionPosition(int startingSelectionPosition) {
+ mStartingSelectionPosition = startingSelectionPosition;
+ return this;
+ }
+
+ /**
+ * Set the factor that determines how tall each item is in relation to the
+ * screen height.
+ */
+ public Params setItemScreenSizeFactor(double itemScreenSizeFactor) {
+ mItemScreenSizeFactor = itemScreenSizeFactor;
+ return this;
+ }
+
+ /**
+ * Override the item screen size factor for a particular item. Useful for
+ * creating grids with non-uniform item height.
+ * @param position The position in the grid.
+ * @param itemScreenSizeFactor The screen size factor to use for the height.
+ */
+ public Params setPositionScreenSizeFactorOverride(
+ int position, double itemScreenSizeFactor) {
+ mOverrideItemScreenSizeFactors.put(position, itemScreenSizeFactor);
+ return this;
+ }
+
+ /**
+ * Sets the stacking direction
+ * @param stackFromBottom
+ * @return
+ */
+ public Params setStackFromBottom(boolean stackFromBottom) {
+ mStackFromBottom = stackFromBottom;
+ return this;
+ }
+
+ /**
+ * Sets whether the sum of the height of the grid items must be at least the
+ * height of the grid view.
+ */
+ public Params setMustFillScreen(boolean fillScreen) {
+ mMustFillScreen = fillScreen;
+ return this;
+ }
+
+ /**
+ * Sets the individual width of each column.
+ *
+ * @param requestedWidth the width in pixels of the column
+ */
+ public Params setColumnWidth(int requestedWidth) {
+ mColumnWidth = requestedWidth;
+ return this;
+ }
+
+ /**
+ * Sets the number of columns in the grid.
+ */
+ public Params setNumColumns(int numColumns) {
+ mNumColumns = numColumns;
+ return this;
+ }
+
+ /**
+ * Sets the stretch mode.
+ */
+ public Params setStretchMode(int stretchMode) {
+ mStretchMode = stretchMode;
+ return this;
+ }
+
+ /**
+ * Sets the spacing between rows in the grid
+ */
+ public Params setVerticalSpacing(int verticalSpacing) {
+ mVerticalSpacing = verticalSpacing;
+ return this;
+ }
+ }
+
+ /**
+ * How each scenario customizes its behavior.
+ * @param params
+ */
+ protected abstract void init(Params params);
+
+ /**
+ * Override this to provide an different adapter for your scenario
+ * @return The adapter that this scenario will use
+ */
+ protected ListAdapter createAdapter() {
+ return new MyAdapter();
+ }
+
+ /**
+ * Override this if you want to know when something has been selected (perhaps
+ * more importantly, that {@link android.widget.AdapterView.OnItemSelectedListener} has
+ * been triggered).
+ */
+ @SuppressWarnings({ "UnusedDeclaration" })
+ protected void positionSelected(int positon) {
+
+ }
+
+ /**
+ * Override this if you want to know that nothing is selected.
+ */
+ protected void nothingSelected() {
+
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // turn off title bar
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+ mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
+
+ final Params params = new Params();
+ init(params);
+
+ readAndValidateParams(params);
+
+ mGridView = new GridView(this);
+ mGridView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mGridView.setDrawSelectorOnTop(false);
+ if (mNumColumns >= GridView.AUTO_FIT) {
+ mGridView.setNumColumns(mNumColumns);
+ }
+ if (mColumnWidth > 0) {
+ mGridView.setColumnWidth(mColumnWidth);
+ }
+ if (mVerticalSpacing > 0) {
+ mGridView.setVerticalSpacing(mVerticalSpacing);
+ }
+ mGridView.setStretchMode(mStretchMode);
+ mGridView.setAdapter(createAdapter());
+ if (mStartingSelectionPosition >= 0) {
+ mGridView.setSelection(mStartingSelectionPosition);
+ }
+ mGridView.setPadding(10, 10, 10, 10);
+ mGridView.setStackFromBottom(mStackFromBottom);
+
+ mGridView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ positionSelected(position);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ nothingSelected();
+ }
+ });
+
+ setContentView(mGridView);
+ }
+
+
+
+ /**
+ * Read in and validate all of the params passed in by the scenario.
+ * @param params
+ */
+ private void readAndValidateParams(Params params) {
+ if (params.mMustFillScreen ) {
+ double totalFactor = 0.0;
+ for (int i = 0; i < params.mNumItems; i++) {
+ if (params.mOverrideItemScreenSizeFactors.containsKey(i)) {
+ totalFactor += params.mOverrideItemScreenSizeFactors.get(i);
+ } else {
+ totalFactor += params.mItemScreenSizeFactor;
+ }
+ }
+ if (totalFactor < 1.0) {
+ throw new IllegalArgumentException("grid items must combine to be at least " +
+ "the height of the screen. this is not the case with " + params.mNumItems
+ + " items and " + params.mItemScreenSizeFactor + " screen factor and " +
+ "screen height of " + mScreenHeight);
+ }
+ }
+
+ mNumItems = params.mNumItems;
+ mStartingSelectionPosition = params.mStartingSelectionPosition;
+ mItemScreenSizeFactor = params.mItemScreenSizeFactor;
+
+ mOverrideItemScreenSizeFactors.putAll(params.mOverrideItemScreenSizeFactors);
+
+ mStackFromBottom = params.mStackFromBottom;
+ mColumnWidth = params.mColumnWidth;
+ mNumColumns = params.mNumColumns;
+ mStretchMode = params.mStretchMode;
+ mVerticalSpacing = params.mVerticalSpacing;
+ }
+
+ public final String getValueAtPosition(int position) {
+ return "postion " + position;
+ }
+
+ /**
+ * Create a view for a grid item. Override this to create a custom view beyond
+ * the simple focusable / unfocusable text view.
+ * @param position The position.
+ * @param parent The parent
+ * @param desiredHeight The height the view should be to respect the desired item
+ * to screen height ratio.
+ * @return a view for the grid.
+ */
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ TextView result = new TextView(parent.getContext());
+ result.setHeight(desiredHeight);
+ result.setText(getValueAtPosition(position));
+ final ViewGroup.LayoutParams lp = new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ result.setLayoutParams(lp);
+ result.setId(position);
+ result.setBackgroundColor(0x55ffffff);
+ return result;
+ }
+
+
+
+ private class MyAdapter extends BaseAdapter {
+ public int getCount() {
+ return mNumItems;
+ }
+
+ public Object getItem(int position) {
+ return getValueAtPosition(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView != null) {
+ ((TextView) convertView).setText(getValueAtPosition(position));
+ convertView.setId(position);
+ return convertView;
+ }
+
+ int desiredHeight = getDesiredItemHeight();
+ if (mOverrideItemScreenSizeFactors.containsKey(position)) {
+ desiredHeight = (int) (mScreenHeight * mOverrideItemScreenSizeFactors.get(position));
+ }
+ return createView(position, parent, desiredHeight);
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/InternalSelectionView.java b/tests/FrameworkTest/src/com/android/frameworktest/util/InternalSelectionView.java
new file mode 100644
index 0000000..e500b94
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/InternalSelectionView.java
@@ -0,0 +1,273 @@
+/*
+ * 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 com.android.frameworktest.util;
+
+import com.android.frameworktest.R;
+
+import android.view.View;
+import android.view.KeyEvent;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Paint;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.Color;
+import android.util.AttributeSet;
+
+
+
+/**
+ * A view that has a known number of selectable rows, and maintains a notion of which
+ * row is selected. The rows take up the
+ * entire width of the view. The height of the view is divided evenly among
+ * the rows.
+ *
+ * Notice what this view does to be a good citizen w.r.t its internal selection:
+ * 1) calls {@link View#requestRectangleOnScreen} each time the selection changes due to
+ * internal navigation.
+ * 2) implements {@link View#getFocusedRect} by filling in the rectangle of the currently
+ * selected row
+ * 3) overrides {@link View#onFocusChanged} and sets selection appropriately according to
+ * the previously focused rectangle.
+ */
+public class InternalSelectionView extends View {
+
+ private Paint mPainter = new Paint();
+ private Paint mTextPaint = new Paint();
+ private Rect mTempRect = new Rect();
+
+ private int mNumRows = 5;
+ private int mSelectedRow = 0;
+ private final int mEstimatedPixelHeight = 10;
+
+ private Integer mDesiredHeight = null;
+ private String mLabel = null;
+
+ public InternalSelectionView(Context context, int numRows, String label) {
+ super(context);
+ mNumRows = numRows;
+ mLabel = label;
+ init();
+ }
+
+ public InternalSelectionView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ TypedArray a =
+ context.obtainStyledAttributes(
+ attrs, R.styleable.SelectableRowView);
+ mNumRows = a.getInt(R.styleable.SelectableRowView_numRows, 5);
+ init();
+ }
+
+ private void init() {
+ setFocusable(true);
+ mTextPaint.setAntiAlias(true);
+ mTextPaint.setTextSize(10);
+ mTextPaint.setColor(Color.WHITE);
+ }
+
+ public int getNumRows() {
+ return mNumRows;
+ }
+
+ public int getSelectedRow() {
+ return mSelectedRow;
+ }
+
+ public void setDesiredHeight(int desiredHeight) {
+ mDesiredHeight = desiredHeight;
+ }
+
+ public String getLabel() {
+ return mLabel;
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(
+ measureWidth(widthMeasureSpec),
+ measureHeight(heightMeasureSpec));
+ }
+
+ private int measureWidth(int measureSpec) {
+ int specMode = MeasureSpec.getMode(measureSpec);
+ int specSize = MeasureSpec.getSize(measureSpec);
+
+ int desiredWidth = 300 + mPaddingLeft + mPaddingRight;
+ if (specMode == MeasureSpec.EXACTLY) {
+ // We were told how big to be
+ return specSize;
+ } else if (specMode == MeasureSpec.AT_MOST) {
+ return desiredWidth < specSize ? desiredWidth : specSize;
+ } else {
+ return desiredWidth;
+ }
+ }
+
+ private int measureHeight(int measureSpec) {
+ int specMode = MeasureSpec.getMode(measureSpec);
+ int specSize = MeasureSpec.getSize(measureSpec);
+
+ int desiredHeight = mDesiredHeight != null ?
+ mDesiredHeight :
+ mNumRows * mEstimatedPixelHeight + mPaddingTop + mPaddingBottom;
+ if (specMode == MeasureSpec.EXACTLY) {
+ // We were told how big to be
+ return specSize;
+ } else if (specMode == MeasureSpec.AT_MOST) {
+ return desiredHeight < specSize ? desiredHeight : specSize;
+ } else {
+ return desiredHeight;
+ }
+ }
+
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+
+ int rowHeight = getRowHeight();
+
+ int rectTop = mPaddingTop;
+ int rectLeft = mPaddingLeft;
+ int rectRight = getWidth() - mPaddingRight;
+ for (int i = 0; i < mNumRows; i++) {
+
+ mPainter.setColor(Color.BLACK);
+ mPainter.setAlpha(0x20);
+
+ // draw background rect
+ mTempRect.set(rectLeft, rectTop, rectRight, rectTop + rowHeight);
+ canvas.drawRect(mTempRect, mPainter);
+
+ // draw forground rect
+ if (i == mSelectedRow && hasFocus()) {
+ mPainter.setColor(Color.RED);
+ mPainter.setAlpha(0xF0);
+ mTextPaint.setAlpha(0xFF);
+ } else {
+ mPainter.setColor(Color.BLACK);
+ mPainter.setAlpha(0x40);
+ mTextPaint.setAlpha(0xF0);
+ }
+ mTempRect.set(rectLeft + 2, rectTop + 2,
+ rectRight - 2, rectTop + rowHeight - 2);
+ canvas.drawRect(mTempRect, mPainter);
+
+ // draw text to help when visually inspecting
+ canvas.drawText(
+ Integer.toString(i),
+ rectLeft + 2,
+ rectTop + 2 - (int) mTextPaint.ascent(),
+ mTextPaint);
+
+ rectTop += rowHeight;
+ }
+ }
+
+ private int getRowHeight() {
+ return (getHeight() - mPaddingTop - mPaddingBottom) / mNumRows;
+ }
+
+ public void getRectForRow(Rect rect, int row) {
+ final int rowHeight = getRowHeight();
+ final int top = mPaddingTop + row * rowHeight;
+ rect.set(mPaddingLeft,
+ top,
+ getWidth() - mPaddingRight,
+ top + rowHeight);
+ }
+
+
+ void ensureRectVisible() {
+ getRectForRow(mTempRect, mSelectedRow);
+ requestRectangleOnScreen(mTempRect);
+ }
+
+
+ /* (non-Javadoc)
+ * @see android.view.KeyEvent.Callback#onKeyDown(int, android.view.KeyEvent)
+ */
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ switch(event.getKeyCode()) {
+ case KeyEvent.KEYCODE_DPAD_UP:
+ if (mSelectedRow > 0) {
+ mSelectedRow--;
+ invalidate();
+ ensureRectVisible();
+ return true;
+ }
+ break;
+ case KeyEvent.KEYCODE_DPAD_DOWN:
+ if (mSelectedRow < (mNumRows - 1)) {
+ mSelectedRow++;
+ invalidate();
+ ensureRectVisible();
+ return true;
+ }
+ break;
+ }
+ return false;
+ }
+
+
+ @Override
+ public void getFocusedRect(Rect r) {
+ getRectForRow(r, mSelectedRow);
+ }
+
+ @Override
+ protected void onFocusChanged(boolean focused, int direction,
+ Rect previouslyFocusedRect) {
+ super.onFocusChanged(focused, direction, previouslyFocusedRect);
+
+ if (focused) {
+ switch (direction) {
+ case View.FOCUS_DOWN:
+ mSelectedRow = 0;
+ break;
+ case View.FOCUS_UP:
+ mSelectedRow = mNumRows - 1;
+ break;
+ case View.FOCUS_LEFT: // fall through
+ case View.FOCUS_RIGHT:
+ // set the row that is closest to the rect
+ if (previouslyFocusedRect != null) {
+ int y = previouslyFocusedRect.top
+ + (previouslyFocusedRect.height() / 2);
+ int yPerRow = getHeight() / mNumRows;
+ mSelectedRow = y / yPerRow;
+ } else {
+ mSelectedRow = 0;
+ }
+ break;
+ default:
+ // can't gleam any useful information about what internal
+ // selection should be...
+ return;
+ }
+ invalidate();
+ }
+ }
+
+ @Override
+ public String toString() {
+ if (mLabel != null) {
+ return mLabel;
+ }
+ return super.toString();
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/KeyUtils.java b/tests/FrameworkTest/src/com/android/frameworktest/util/KeyUtils.java
new file mode 100644
index 0000000..06feab4
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/KeyUtils.java
@@ -0,0 +1,88 @@
+/*
+ * 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 com.android.frameworktest.util;
+
+import android.app.Instrumentation;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.InstrumentationTestCase;
+import android.view.Gravity;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+
+/**
+ * Reusable methods for generating key events.
+ * <p>
+ * Definitions:
+ * <li> Tap refers to pushing and releasing a button (down and up event).
+ * <li> Chord refers to pushing a modifier key, tapping a regular key, and
+ * releasing the modifier key.
+ */
+public class KeyUtils {
+ /**
+ * Simulates tapping the menu key.
+ *
+ * @param test The test case that is being run.
+ */
+ public static void tapMenuKey(ActivityInstrumentationTestCase test) {
+ final Instrumentation inst = test.getInstrumentation();
+
+ inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU));
+ inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU));
+ }
+
+ /**
+ * Simulates chording the menu key.
+ *
+ * @param test The test case that is being run.
+ * @param shortcutKey The shortcut key to tap while chording the menu key.
+ */
+ public static void chordMenuKey(ActivityInstrumentationTestCase test, char shortcutKey) {
+ final Instrumentation inst = test.getInstrumentation();
+
+ final KeyEvent pushMenuKey = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_MENU);
+ final KeyCharacterMap keyCharMap = KeyCharacterMap.load(pushMenuKey.getDeviceId());
+ final KeyEvent shortcutKeyEvent = keyCharMap.getEvents(new char[] { shortcutKey })[0];
+ final int shortcutKeyCode = shortcutKeyEvent.getKeyCode();
+
+ inst.sendKeySync(pushMenuKey);
+ inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, shortcutKeyCode));
+ inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, shortcutKeyCode));
+ inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_MENU));
+ }
+
+ /**
+ * Simulates a long click via the keyboard.
+ *
+ * @param test The test case that is being run.
+ */
+ public static void longClick(ActivityInstrumentationTestCase test) {
+ final Instrumentation inst = test.getInstrumentation();
+
+ inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_CENTER));
+ try {
+ Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.5f));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ inst.sendKeySync(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DPAD_CENTER));
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/ListItemFactory.java b/tests/FrameworkTest/src/com/android/frameworktest/util/ListItemFactory.java
new file mode 100644
index 0000000..4327a8a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/ListItemFactory.java
@@ -0,0 +1,291 @@
+/*
+ * 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 com.android.frameworktest.util;
+
+import android.content.Context;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AbsListView;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Reusable methods for creating more complex list items.
+ */
+public class ListItemFactory {
+
+ /**
+ * Create a view with a button at the top and bottom, with filler in between.
+ * The filler is sized to take up any space left over within desiredHeight.
+ *
+ * @param position The position within the list.
+ * @param context The context.
+ * @param desiredHeight The desired height of the entire view.
+ * @return The created view.
+ */
+ public static View twoButtonsSeparatedByFiller(int position, Context context, int desiredHeight) {
+ if (desiredHeight < 90) {
+ throw new IllegalArgumentException("need at least 90 pixels of height " +
+ "to create the two buttons and leave 10 pixels for the filler");
+ }
+
+ final LinearLayout ll = new LinearLayout(context);
+ ll.setOrientation(LinearLayout.VERTICAL);
+
+ final LinearLayout.LayoutParams buttonLp =
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ 50);
+
+ final Button topButton = new Button(context);
+ topButton.setLayoutParams(
+ buttonLp);
+ topButton.setText("top (position " + position + ")");
+ ll.addView(topButton);
+
+ final TextView middleFiller = new TextView(context);
+ middleFiller.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ desiredHeight - 100));
+ middleFiller.setText("filler");
+ ll.addView(middleFiller);
+
+ final Button bottomButton = new Button(context);
+ bottomButton.setLayoutParams(buttonLp);
+ bottomButton.setText("bottom (position " + position + ")");
+ ll.addView(bottomButton);
+ ll.setTag("twoButtons");
+ return ll;
+ }
+
+ public enum Slot {
+ Left,
+ Middle,
+ Right
+ }
+
+ /**
+ * Create a horizontal linear layout divided into thirds (with some margins
+ * separating the thirds), filled with buttons into some slots.
+ * @param context The context.
+ * @param desiredHeight The height of the LL.
+ * @param slots Which slots to fill with buttons.
+ * @return The linear layout.
+ */
+ public static View horizontalButtonSlots(Context context, int desiredHeight, Slot... slots) {
+
+ final LinearLayout ll = new LinearLayout(context);
+ ll.setOrientation(LinearLayout.HORIZONTAL);
+
+ final LinearLayout.LayoutParams lp
+ = new LinearLayout.LayoutParams(0, desiredHeight);
+ lp.setMargins(10, 0, 10, 0);
+ lp.weight = 0.33f;
+
+ boolean left = false;
+ boolean middle = false;
+ boolean right = false;
+ for (Slot slot : slots) {
+ switch (slot) {
+ case Left:
+ left = true;
+ break;
+ case Middle:
+ middle = true;
+ break;
+ case Right:
+ right = true;
+ break;
+ }
+ }
+
+ if (left) {
+ final Button button = new Button(context);
+ button.setText("left");
+ ll.addView(button, lp);
+ } else {
+ ll.addView(new View(context), lp);
+ }
+
+ if (middle) {
+ final Button button = new Button(context);
+ button.setText("center");
+ ll.addView(button, lp);
+ } else {
+ ll.addView(new View(context), lp);
+ }
+
+ if (right) {
+ final Button button = new Button(context);
+ button.setText("right");
+ ll.addView(button, lp);
+ } else {
+ ll.addView(new View(context), lp);
+ }
+
+ return ll;
+ }
+
+
+ /**
+ * Create a button ready to be a list item.
+ *
+ * @param position The position within the list.
+ * @param context The context.
+ * @param text The text of the button
+ * @param desiredHeight The desired height of the button
+ * @return The created view.
+ */
+ public static View button(int position, Context context, String text, int desiredHeight) {
+ TextView result = new Button(context);
+ result.setHeight(desiredHeight);
+ result.setText(text);
+ final ViewGroup.LayoutParams lp = new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ result.setLayoutParams(lp);
+ result.setId(position);
+ result.setTag("button");
+ return result;
+ }
+
+ /**
+ * Convert an existing button view to display the data at a new position.
+ *
+ * @param convertView Non-null Button created by {@link #button}
+ * @param text The text of the button
+ * @param position The position withion the list
+ * @return The converted view
+ */
+ public static View convertButton(View convertView, String text, int position) {
+ if (((String) convertView.getTag()).equals("button")) {
+ ((Button) convertView).setText(text);
+ convertView.setId(position);
+ return convertView;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Create a text view ready to be a list item.
+ *
+ * @param position The position within the list.
+ * @param context The context.
+ * @param text The text to display
+ * @param desiredHeight The desired height of the text view
+ * @return The created view.
+ */
+ public static View text(int position, Context context, String text, int desiredHeight) {
+ TextView result = new TextView(context);
+ result.setHeight(desiredHeight);
+ result.setText(text);
+ final ViewGroup.LayoutParams lp = new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT);
+ result.setLayoutParams(lp);
+ result.setId(position);
+ result.setTag("text");
+ return result;
+ }
+
+ /**
+ * Convert an existing text view to display the data at a new position.
+ *
+ * @param convertView Non-null TextView created by {@link #text}
+ * @param text The text to display
+ * @param position The position withion the list
+ * @return The converted view
+ */
+ public static View convertText(View convertView, String text, int position) {
+ if(convertView.getTag() != null && ((String) convertView.getTag()).equals("text")) {
+ ((TextView) convertView).setText(text);
+ convertView.setId(position);
+ return convertView;
+
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Create a text view ready to be a list item.
+ *
+ * @param position The position within the list.
+ * @param context The context.
+ * @param text The text of the button
+ * @param desiredHeight The desired height of the button
+ * @return The created view.
+ */
+ public static View doubleText(int position, Context context, String text, int desiredHeight) {
+ final LinearLayout ll = new LinearLayout(context);
+ ll.setOrientation(LinearLayout.HORIZONTAL);
+
+ final AbsListView.LayoutParams lp =
+ new AbsListView.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ desiredHeight);
+ ll.setLayoutParams(lp);
+ ll.setId(position);
+
+ TextView t1 = new TextView(context);
+ t1.setHeight(desiredHeight);
+ t1.setText(text);
+ t1.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
+ final ViewGroup.LayoutParams lp1 = new LinearLayout.LayoutParams(
+ 0,
+ ViewGroup.LayoutParams.WRAP_CONTENT, 1.0f);
+ ll.addView(t1, lp1);
+
+ TextView t2 = new TextView(context);
+ t2.setHeight(desiredHeight);
+ t2.setText(text);
+ t2.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
+ final ViewGroup.LayoutParams lp2 = new LinearLayout.LayoutParams(
+ 0,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ 1.0f);
+
+ ll.addView(t2, lp2);
+ ll.setTag("double");
+ return ll;
+ }
+
+
+ /**
+ * Convert an existing button view to display the data at a new position.
+ *
+ * @param convertView Non-null view created by {@link #doubleText}
+ * @param text The text of the button
+ * @param position The position withion the list
+ * @return The converted view
+ */
+ public static View convertDoubleText(View convertView, String text, int position) {
+ if (((String) convertView.getTag()).equals("double")) {
+ TextView t1 = (TextView) ((LinearLayout) convertView).getChildAt(0);
+ TextView t2 = (TextView) ((LinearLayout) convertView).getChildAt(1);
+ t1.setText(text);
+ t2.setText(text);
+ convertView.setId(position);
+ return convertView;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/ListScenario.java b/tests/FrameworkTest/src/com/android/frameworktest/util/ListScenario.java
new file mode 100644
index 0000000..5889658
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/ListScenario.java
@@ -0,0 +1,662 @@
+/*
+ * 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 com.android.frameworktest.util;
+
+import android.app.Activity;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.BaseAdapter;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.TextView;
+import com.google.android.collect.Maps;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Utility base class for creating various List scenarios. Configurable by the number
+ * of items, how tall each item should be (in relation to the screen height), and
+ * what item should start with selection.
+ */
+public abstract class ListScenario extends Activity {
+
+ private ListView mListView;
+ private TextView mHeaderTextView;
+
+ private int mNumItems;
+ protected boolean mItemsFocusable;
+
+ private int mStartingSelectionPosition;
+ private double mItemScreenSizeFactor;
+ private Map<Integer, Double> mOverrideItemScreenSizeFactors = Maps.newHashMap();
+
+ private int mScreenHeight;
+
+ // whether to include a text view above the list
+ private boolean mIncludeHeader;
+
+ // separators
+ private Set<Integer> mUnselectableItems = new HashSet<Integer>();
+
+ private boolean mStackFromBottom;
+
+ private int mClickedPosition = -1;
+
+ private int mLongClickedPosition = -1;
+
+ private int mConvertMisses = 0;
+
+ private int mHeaderViewCount;
+ private boolean mHeadersFocusable;
+
+ private int mFooterViewCount;
+ private LinearLayout mLinearLayout;
+
+ public ListView getListView() {
+ return mListView;
+ }
+
+ protected int getScreenHeight() {
+ return mScreenHeight;
+ }
+
+ /**
+ * Return whether the item at position is selectable (i.e is a separator).
+ * (external users can access this info using the adapter)
+ */
+ private boolean isItemAtPositionSelectable(int position) {
+ return !mUnselectableItems.contains(position);
+ }
+
+ /**
+ * Better way to pass in optional params than a honkin' paramater list :)
+ */
+ public static class Params {
+ private int mNumItems = 4;
+ private boolean mItemsFocusable = false;
+ private int mStartingSelectionPosition = 0;
+ private double mItemScreenSizeFactor = 1 / 5;
+ private Double mFadingEdgeScreenSizeFactor = null;
+
+ private Map<Integer, Double> mOverrideItemScreenSizeFactors = Maps.newHashMap();
+
+ // separators
+ private List<Integer> mUnselectableItems = new ArrayList<Integer>(8);
+ // whether to include a text view above the list
+ private boolean mIncludeHeader = false;
+ private boolean mStackFromBottom = false;
+ public boolean mMustFillScreen = true;
+ private int mHeaderViewCount;
+ private boolean mHeaderFocusable = false;
+ private int mFooterViewCount;
+
+ private boolean mConnectAdapter = true;
+
+ /**
+ * Set the number of items in the list.
+ */
+ public Params setNumItems(int numItems) {
+ mNumItems = numItems;
+ return this;
+ }
+
+ /**
+ * Set whether the items are focusable.
+ */
+ public Params setItemsFocusable(boolean itemsFocusable) {
+ mItemsFocusable = itemsFocusable;
+ return this;
+ }
+
+ /**
+ * Set the position that starts selected.
+ *
+ * @param startingSelectionPosition The selected position within the adapter's data set.
+ * Pass -1 if you do not want to force a selection.
+ * @return
+ */
+ public Params setStartingSelectionPosition(int startingSelectionPosition) {
+ mStartingSelectionPosition = startingSelectionPosition;
+ return this;
+ }
+
+ /**
+ * Set the factor that determines how tall each item is in relation to the
+ * screen height.
+ */
+ public Params setItemScreenSizeFactor(double itemScreenSizeFactor) {
+ mItemScreenSizeFactor = itemScreenSizeFactor;
+ return this;
+ }
+
+ /**
+ * Override the item screen size factor for a particular item. Useful for
+ * creating lists with non-uniform item height.
+ * @param position The position in the list.
+ * @param itemScreenSizeFactor The screen size factor to use for the height.
+ */
+ public Params setPositionScreenSizeFactorOverride(
+ int position, double itemScreenSizeFactor) {
+ mOverrideItemScreenSizeFactors.put(position, itemScreenSizeFactor);
+ return this;
+ }
+
+ /**
+ * Set a position as unselectable (a.k.a a separator)
+ * @param position
+ * @return
+ */
+ public Params setPositionUnselectable(int position) {
+ mUnselectableItems.add(position);
+ return this;
+ }
+
+ /**
+ * Set positions as unselectable (a.k.a a separator)
+ */
+ public Params setPositionsUnselectable(int ...positions) {
+ for (int pos : positions) {
+ setPositionUnselectable(pos);
+ }
+ return this;
+ }
+
+ /**
+ * Include a header text view above the list.
+ * @param includeHeader
+ * @return
+ */
+ public Params includeHeaderAboveList(boolean includeHeader) {
+ mIncludeHeader = includeHeader;
+ return this;
+ }
+
+ /**
+ * Sets the stacking direction
+ * @param stackFromBottom
+ * @return
+ */
+ public Params setStackFromBottom(boolean stackFromBottom) {
+ mStackFromBottom = stackFromBottom;
+ return this;
+ }
+
+ /**
+ * Sets whether the sum of the height of the list items must be at least the
+ * height of the list view.
+ */
+ public Params setMustFillScreen(boolean fillScreen) {
+ mMustFillScreen = fillScreen;
+ return this;
+ }
+
+ /**
+ * Set the factor for the fading edge length.
+ */
+ public Params setFadingEdgeScreenSizeFactor(double fadingEdgeScreenSizeFactor) {
+ mFadingEdgeScreenSizeFactor = fadingEdgeScreenSizeFactor;
+ return this;
+ }
+
+ /**
+ * Set the number of header views to appear within the list
+ */
+ public Params setHeaderViewCount(int headerViewCount) {
+ mHeaderViewCount = headerViewCount;
+ return this;
+ }
+
+ /**
+ * Set whether the headers should be focusable.
+ * @param headerFocusable Whether the headers should be focusable (i.e
+ * created as edit texts rather than text views).
+ */
+ public Params setHeaderFocusable(boolean headerFocusable) {
+ mHeaderFocusable = headerFocusable;
+ return this;
+ }
+
+ /**
+ * Set the number of footer views to appear within the list
+ */
+ public Params setFooterViewCount(int footerViewCount) {
+ mFooterViewCount = footerViewCount;
+ return this;
+ }
+
+ /**
+ * Sets whether the {@link ListScenario} will automatically set the
+ * adapter on the list view. If this is false, the client MUST set it
+ * manually (this is useful when adding headers to the list view, which
+ * must be done before the adapter is set).
+ */
+ public Params setConnectAdapter(boolean connectAdapter) {
+ mConnectAdapter = connectAdapter;
+ return this;
+ }
+ }
+
+ /**
+ * How each scenario customizes its behavior.
+ * @param params
+ */
+ protected abstract void init(Params params);
+
+ /**
+ * Override this if you want to know when something has been selected (perhaps
+ * more importantly, that {@link android.widget.AdapterView.OnItemSelectedListener} has
+ * been triggered).
+ */
+ protected void positionSelected(int positon) {
+ }
+
+ /**
+ * Override this if you want to know that nothing is selected.
+ */
+ protected void nothingSelected() {
+ }
+
+ /**
+ * Override this if you want to know when something has been clicked (perhaps
+ * more importantly, that {@link android.widget.AdapterView.OnItemClickListener} has
+ * been triggered).
+ */
+ protected void positionClicked(int position) {
+ setClickedPosition(position);
+ }
+
+ /**
+ * Override this if you want to know when something has been long clicked (perhaps
+ * more importantly, that {@link android.widget.AdapterView.OnItemLongClickListener} has
+ * been triggered).
+ */
+ protected void positionLongClicked(int position) {
+ setLongClickedPosition(position);
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ // for test stability, turn off title bar
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+
+ mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
+
+ final Params params = createParams();
+ init(params);
+
+ readAndValidateParams(params);
+
+
+ mListView = createListView();
+ mListView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mListView.setDrawSelectorOnTop(false);
+
+ for (int i=0; i<mHeaderViewCount; i++) {
+ TextView header = mHeadersFocusable ?
+ new EditText(this) :
+ new TextView(this);
+ header.setText("Header: " + i);
+ mListView.addHeaderView(header);
+ }
+
+ for (int i=0; i<mFooterViewCount; i++) {
+ TextView header = new TextView(this);
+ header.setText("Footer: " + i);
+ mListView.addFooterView(header);
+ }
+
+ if (params.mConnectAdapter) {
+ setAdapter(mListView);
+ }
+
+ mListView.setItemsCanFocus(mItemsFocusable);
+ if (mStartingSelectionPosition >= 0) {
+ mListView.setSelection(mStartingSelectionPosition);
+ }
+ mListView.setPadding(0, 0, 0, 0);
+ mListView.setStackFromBottom(mStackFromBottom);
+ mListView.setDivider(null);
+
+ mListView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+ public void onItemSelected(AdapterView parent, View v, int position, long id) {
+ positionSelected(position);
+ }
+
+ public void onNothingSelected(AdapterView parent) {
+ nothingSelected();
+ }
+ });
+
+ mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ public void onItemClick(AdapterView parent, View v, int position, long id) {
+ positionClicked(position);
+ }
+ });
+
+ // set the fading edge length porportionally to the screen
+ // height for test stability
+ if (params.mFadingEdgeScreenSizeFactor != null) {
+ mListView.setFadingEdgeLength((int) (params.mFadingEdgeScreenSizeFactor * mScreenHeight));
+ } else {
+ mListView.setFadingEdgeLength((int) ((64.0 / 480) * mScreenHeight));
+ }
+
+ if (mIncludeHeader) {
+ mLinearLayout = new LinearLayout(this);
+
+ mHeaderTextView = new TextView(this);
+ mHeaderTextView.setText("hi");
+ mHeaderTextView.setLayoutParams(new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT));
+ mLinearLayout.addView(mHeaderTextView);
+
+ mLinearLayout.setOrientation(LinearLayout.VERTICAL);
+ mLinearLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mListView.setLayoutParams((new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ 0,
+ 1f)));
+
+ mLinearLayout.addView(mListView);
+ setContentView(mLinearLayout);
+ } else {
+ mLinearLayout = new LinearLayout(this);
+ mLinearLayout.setOrientation(LinearLayout.VERTICAL);
+ mLinearLayout.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+ mListView.setLayoutParams((new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ 0,
+ 1f)));
+ mLinearLayout.addView(mListView);
+ setContentView(mLinearLayout);
+ }
+ }
+
+ /**
+ * Returns the LinearLayout containing the ListView in this scenario.
+ *
+ * @return The LinearLayout in which the ListView is held.
+ */
+ protected LinearLayout getListViewContainer() {
+ return mLinearLayout;
+ }
+
+ /**
+ * Attaches a long press listener. You can find out which views were clicked by calling
+ * {@link #getLongClickedPosition()}.
+ */
+ public void enableLongPress() {
+ mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
+ public boolean onItemLongClick(AdapterView parent, View v, int position, long id) {
+ positionLongClicked(position);
+ return true;
+ }
+ });
+ }
+
+ /**
+ * @return The newly created ListView widget.
+ */
+ protected ListView createListView() {
+ return new ListView(this);
+ }
+
+ /**
+ * @return The newly created Params object.
+ */
+ protected Params createParams() {
+ return new Params();
+ }
+
+ /**
+ * Sets an adapter on a ListView.
+ *
+ * @param listView The ListView to set the adapter on.
+ */
+ protected void setAdapter(ListView listView) {
+ listView.setAdapter(new MyAdapter());
+ }
+
+ /**
+ * Read in and validate all of the params passed in by the scenario.
+ * @param params
+ */
+ protected void readAndValidateParams(Params params) {
+ if (params.mMustFillScreen ) {
+ double totalFactor = 0.0;
+ for (int i = 0; i < params.mNumItems; i++) {
+ if (params.mOverrideItemScreenSizeFactors.containsKey(i)) {
+ totalFactor += params.mOverrideItemScreenSizeFactors.get(i);
+ } else {
+ totalFactor += params.mItemScreenSizeFactor;
+ }
+ }
+ if (totalFactor < 1.0) {
+ throw new IllegalArgumentException("list items must combine to be at least " +
+ "the height of the screen. this is not the case with " + params.mNumItems
+ + " items and " + params.mItemScreenSizeFactor + " screen factor and " +
+ "screen height of " + mScreenHeight);
+ }
+ }
+
+ mNumItems = params.mNumItems;
+ mItemsFocusable = params.mItemsFocusable;
+ mStartingSelectionPosition = params.mStartingSelectionPosition;
+ mItemScreenSizeFactor = params.mItemScreenSizeFactor;
+
+ mOverrideItemScreenSizeFactors.putAll(params.mOverrideItemScreenSizeFactors);
+
+ mUnselectableItems.addAll(params.mUnselectableItems);
+ mIncludeHeader = params.mIncludeHeader;
+ mStackFromBottom = params.mStackFromBottom;
+ mHeaderViewCount = params.mHeaderViewCount;
+ mHeadersFocusable = params.mHeaderFocusable;
+ mFooterViewCount = params.mFooterViewCount;
+ }
+
+ public final String getValueAtPosition(int position) {
+ return isItemAtPositionSelectable(position)
+ ?
+ "position " + position:
+ "------- " + position;
+ }
+
+ /**
+ * @return The height that will be set for a particular position.
+ */
+ public int getHeightForPosition(int position) {
+ int desiredHeight = (int) (mScreenHeight * mItemScreenSizeFactor);
+ if (mOverrideItemScreenSizeFactors.containsKey(position)) {
+ desiredHeight = (int) (mScreenHeight * mOverrideItemScreenSizeFactors.get(position));
+ }
+ return desiredHeight;
+ }
+
+
+ /**
+ * @return The contents of the header above the list.
+ * @throws IllegalArgumentException if there is no header.
+ */
+ public final String getHeaderValue() {
+ if (!mIncludeHeader) {
+ throw new IllegalArgumentException("no header above list");
+ }
+ return mHeaderTextView.getText().toString();
+ }
+
+ /**
+ * @param value What to put in the header text view
+ * @throws IllegalArgumentException if there is no header.
+ */
+ protected final void setHeaderValue(String value) {
+ if (!mIncludeHeader) {
+ throw new IllegalArgumentException("no header above list");
+ }
+ mHeaderTextView.setText(value);
+ }
+
+ /**
+ * Create a view for a list item. Override this to create a custom view beyond
+ * the simple focusable / unfocusable text view.
+ * @param position The position.
+ * @param parent The parent
+ * @param desiredHeight The height the view should be to respect the desired item
+ * to screen height ratio.
+ * @return a view for the list.
+ */
+ protected View createView(int position, ViewGroup parent, int desiredHeight) {
+ return ListItemFactory.text(position, parent.getContext(), getValueAtPosition(position),
+ desiredHeight);
+ }
+
+ /**
+ * Convert a non-null view.
+ */
+ public View convertView(int position, View convertView, ViewGroup parent) {
+ return ListItemFactory.convertText(convertView, getValueAtPosition(position), position);
+ }
+
+ public void setClickedPosition(int clickedPosition) {
+ mClickedPosition = clickedPosition;
+ }
+
+ public int getClickedPosition() {
+ return mClickedPosition;
+ }
+
+ public void setLongClickedPosition(int longClickedPosition) {
+ mLongClickedPosition = longClickedPosition;
+ }
+
+ public int getLongClickedPosition() {
+ return mLongClickedPosition;
+ }
+
+ /**
+ * Have a child of the list view call {@link View#requestRectangleOnScreen(android.graphics.Rect)}.
+ * @param childIndex The index into the viewgroup children (i.e the children that are
+ * currently visible).
+ * @param rect The rectangle, in the child's coordinates.
+ */
+ public void requestRectangleOnScreen(int childIndex, final Rect rect) {
+ final View child = getListView().getChildAt(childIndex);
+
+ child.post(new Runnable() {
+ public void run() {
+ child.requestRectangleOnScreen(rect);
+ }
+ });
+ }
+
+ /**
+ * Return an item type for the specified position in the adapter. Override if your
+ * adapter creates more than one type.
+ */
+ public int getItemViewType(int position) {
+ return 0;
+ }
+
+ /**
+ * Return an the number of types created by the adapter. Override if your
+ * adapter creates more than one type.
+ */
+ public int getViewTypeCount() {
+ return 1;
+ }
+
+ /**
+ * @return The number of times convertView failed
+ */
+ public int getConvertMisses() {
+ return mConvertMisses;
+ }
+
+ private class MyAdapter extends BaseAdapter {
+
+ public int getCount() {
+ return mNumItems;
+ }
+
+ public Object getItem(int position) {
+ return getValueAtPosition(position);
+ }
+
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public boolean areAllItemsEnabled() {
+ return mUnselectableItems.isEmpty();
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return isItemAtPositionSelectable(position);
+ }
+
+ public View getView(int position, View convertView, ViewGroup parent) {
+ View result = null;
+ if (position >= mNumItems || position < 0) {
+ throw new IllegalStateException("position out of range for adapter!");
+ }
+
+ if (convertView != null) {
+ result = convertView(position, convertView, parent);
+ if (result == null) {
+ mConvertMisses++;
+ }
+ }
+
+ if (result == null) {
+ int desiredHeight = getHeightForPosition(position);
+ result = createView(position, parent, desiredHeight);
+ }
+ return result;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return ListScenario.this.getItemViewType(position);
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return ListScenario.this.getViewTypeCount();
+ }
+
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/ListUtil.java b/tests/FrameworkTest/src/com/android/frameworktest/util/ListUtil.java
new file mode 100644
index 0000000..1a05fac
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/ListUtil.java
@@ -0,0 +1,103 @@
+/*
+ * 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 com.android.frameworktest.util;
+
+import android.app.Instrumentation;
+import android.view.KeyEvent;
+import android.widget.ListView;
+
+
+/**
+ * Various useful stuff for instrumentation testing listview.
+ */
+public class ListUtil {
+
+
+ private final ListView mListView;
+ private final Instrumentation mInstrumentation;
+
+ /**
+ * @param listView The listview to act on
+ * @param instrumentation The instrumentation to use.
+ */
+ public ListUtil(ListView listView, Instrumentation instrumentation) {
+ mListView = listView;
+ mInstrumentation = instrumentation;
+ }
+
+ /**
+ * Set the selected position of the list view.
+ * @param pos The desired position.
+ */
+ public final void setSelectedPosition(final int pos) {
+ mListView.post(new Runnable() {
+ public void run() {
+ mListView.setSelection(pos);
+ }
+ });
+ mInstrumentation.waitForIdleSync();
+ }
+
+ /**
+ * Get the top of the list.
+ */
+ public final int getListTop() {
+ return mListView.getListPaddingTop();
+ }
+
+ /**
+ * Get the bottom of the list.
+ */
+ public final int getListBottom() {
+ return mListView.getHeight() - mListView.getListPaddingBottom();
+ }
+
+ /**
+ * Arrow (up or down as appropriate) to the desired position in the list.
+ * @param desiredPos The desired position
+ * @throws IllegalStateException if the position can't be reached within 20 presses.
+ */
+ public final void arrowScrollToSelectedPosition(int desiredPos) {
+ if (desiredPos > mListView.getSelectedItemPosition()) {
+ arrowDownToSelectedPosition(desiredPos);
+ } else {
+ arrowUpToSelectedPosition(desiredPos);
+ }
+ }
+
+ private void arrowDownToSelectedPosition(int position) {
+ int maxDowns = 20;
+ while(mListView.getSelectedItemPosition() < position && --maxDowns > 0) {
+ mInstrumentation.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ if (position != mListView.getSelectedItemPosition()) {
+ throw new IllegalStateException("couldn't get to item after 20 downs");
+ }
+
+ }
+
+ private void arrowUpToSelectedPosition(int position) {
+ int maxUps = 20;
+ while(mListView.getSelectedItemPosition() > position && --maxUps > 0) {
+ mInstrumentation.sendCharacterSync(KeyEvent.KEYCODE_DPAD_UP);
+ }
+ if (position != mListView.getSelectedItemPosition()) {
+ throw new IllegalStateException("couldn't get to item after 20 ups");
+ }
+ }
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/ScrollViewScenario.java b/tests/FrameworkTest/src/com/android/frameworktest/util/ScrollViewScenario.java
new file mode 100644
index 0000000..aa17194
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/ScrollViewScenario.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.util;
+
+import com.google.android.collect.Lists;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * Utility base class for creating scroll view scenarios, allowing you to add
+ * a series of different kinds of views arranged vertically, taking up a
+ * specified amount of the screen height.
+ */
+public abstract class ScrollViewScenario extends Activity {
+
+ /**
+ * Holds content of scroll view
+ */
+ private LinearLayout mLinearLayout;
+
+ /**
+ * The actual scroll view
+ */
+ private ScrollView mScrollView;
+
+
+ /**
+ * What we need of each view that the user wants: the view, and the ratio
+ * to the screen height for its desired height.
+ */
+ private interface ViewFactory {
+ View create(final Context context);
+
+ float getHeightRatio();
+ }
+
+ /**
+ * Partially implement ViewFactory given a height ratio.
+ */
+ private static abstract class ViewFactoryBase implements ViewFactory {
+
+ private float mHeightRatio;
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ private ViewFactoryBase() {throw new UnsupportedOperationException("don't call this!");}
+
+ protected ViewFactoryBase(float heightRatio) {
+ mHeightRatio = heightRatio;
+ }
+
+ public float getHeightRatio() {
+ return mHeightRatio;
+ }
+ }
+
+ /**
+ * Builder for selecting the views to be vertically arranged in the scroll
+ * view.
+ */
+ @SuppressWarnings({"JavaDoc"})
+ public static class Params {
+
+ List<ViewFactory> mViewFactories = Lists.newArrayList();
+
+ /**
+ * Add a text view.
+ * @param text The text of the text view.
+ * @param heightRatio The view's height will be this * the screen height.
+ */
+ public Params addTextView(final String text, float heightRatio) {
+ mViewFactories.add(new ViewFactoryBase(heightRatio) {
+ public View create(final Context context) {
+ final TextView tv = new TextView(context);
+ tv.setText(text);
+ return tv;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Add multiple text views.
+ * @param numViews the number of views to add.
+ * @param textPrefix The text to prepend to each text view.
+ * @param heightRatio The view's height will be this * the screen height.
+ */
+ public Params addTextViews(int numViews, String textPrefix, float heightRatio) {
+ for (int i = 0; i < numViews; i++) {
+ addTextView(textPrefix + i, heightRatio);
+ }
+ return this;
+ }
+
+ /**
+ * Add a button.
+ * @param text The text of the button.
+ * @param heightRatio The view's height will be this * the screen height.
+ */
+ public Params addButton(final String text, float heightRatio) {
+ mViewFactories.add(new ViewFactoryBase(heightRatio) {
+ public View create(final Context context) {
+ final Button button = new Button(context);
+ button.setText(text);
+ return button;
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Add multiple buttons.
+ * @param numButtons the number of views to add.
+ * @param textPrefix The text to prepend to each button.
+ * @param heightRatio The view's height will be this * the screen height.
+ */
+ public Params addButtons(int numButtons, String textPrefix, float heightRatio) {
+ for (int i = 0; i < numButtons; i++) {
+ addButton(textPrefix + i, heightRatio);
+ }
+ return this;
+ }
+
+ /**
+ * Add an {@link InternalSelectionView}.
+ * @param numRows The number of rows in the internal selection view.
+ * @param heightRatio The view's height will be this * the screen height.
+ */
+ public Params addInternalSelectionView(final int numRows, float heightRatio) {
+ mViewFactories.add(new ViewFactoryBase(heightRatio) {
+ public View create(final Context context) {
+ return new InternalSelectionView(context, numRows, "isv");
+ }
+ });
+ return this;
+ }
+
+ /**
+ * Add a sublayout of buttons as a single child of the scroll view.
+ * @param numButtons The number of buttons in the sub layout
+ * @param heightRatio The layout's height will be this * the screen height.
+ */
+ public Params addVerticalLLOfButtons(final String prefix, final int numButtons, float heightRatio) {
+ mViewFactories.add(new ViewFactoryBase(heightRatio) {
+
+ public View create(Context context) {
+ final LinearLayout ll = new LinearLayout(context);
+ ll.setOrientation(LinearLayout.VERTICAL);
+
+ // fill width, equally weighted on height
+ final LinearLayout.LayoutParams lp =
+ new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, 0, 1f);
+ for (int i = 0; i < numButtons; i++) {
+ final Button button = new Button(context);
+ button.setText(prefix + i);
+ ll.addView(button, lp);
+ }
+
+ return ll;
+ }
+ });
+ return this;
+ }
+ }
+
+ /**
+ * Override this and initialized the views in the scroll view.
+ * @param params Used to configure the contents of the scroll view.
+ */
+ protected abstract void init(Params params);
+
+ public LinearLayout getLinearLayout() {
+ return mLinearLayout;
+ }
+
+ public ScrollView getScrollView() {
+ return mScrollView;
+ }
+
+ /**
+ * Get the child contained within the vertical linear layout of the
+ * scroll view.
+ * @param index The index within the linear layout.
+ * @return the child within the vertical linear layout of the scroll view
+ * at the specified index.
+ */
+ @SuppressWarnings({"unchecked"})
+ public <T extends View> T getContentChildAt(int index) {
+ return (T) mLinearLayout.getChildAt(index);
+ }
+
+ /**
+ * Hook for changing how scroll view's are created.
+ */
+ @SuppressWarnings({"JavaDoc"})
+ protected ScrollView createScrollView() {
+ return new ScrollView(this);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // for test stability, turn off title bar
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ int screenHeight = getWindowManager().getDefaultDisplay().getHeight()
+ - 25;
+ mLinearLayout = new LinearLayout(this);
+ mLinearLayout.setOrientation(LinearLayout.VERTICAL);
+
+ // initialize params
+ final Params params = new Params();
+ init(params);
+
+ // create views specified by params
+ for (ViewFactory viewFactory : params.mViewFactories) {
+ final LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ (int) (viewFactory.getHeightRatio() * screenHeight));
+ mLinearLayout.addView(viewFactory.create(this), lp);
+ }
+
+ mScrollView = createScrollView();
+ mScrollView.addView(mLinearLayout, new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT,
+ ViewGroup.LayoutParams.FILL_PARENT));
+
+ // no animation to speed up tests
+ mScrollView.setSmoothScrollingEnabled(false);
+
+ setContentView(mScrollView);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/util/TouchModeFlexibleAsserts.java b/tests/FrameworkTest/src/com/android/frameworktest/util/TouchModeFlexibleAsserts.java
new file mode 100644
index 0000000..66adb17
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/util/TouchModeFlexibleAsserts.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.util;
+
+import junit.framework.Assert;
+
+import android.test.InstrumentationTestCase;
+import android.test.TouchUtils;
+import android.view.View;
+
+/**
+ * When entering touch mode via touch, the tests can be flaky. These asserts
+ * are more flexible (allowing up to MAX_ATTEMPTS touches to enter touch mode via touch or
+ * tap) until we can find a way to solve the flakiness.
+ */
+public class TouchModeFlexibleAsserts {
+
+ private static int MAX_ATTEMPTS = 2;
+
+ private static int MAX_DELAY_MILLIS = 2000;
+
+ public static void assertInTouchModeAfterClick(InstrumentationTestCase test, View viewToTouch) {
+ int numAttemptsAtTouchMode = 0;
+ while (numAttemptsAtTouchMode < MAX_ATTEMPTS &&
+ !viewToTouch.isInTouchMode()) {
+ TouchUtils.clickView(test, viewToTouch);
+ numAttemptsAtTouchMode++;
+ }
+ Assert.assertTrue("even after " + MAX_ATTEMPTS + " clicks, did not enter "
+ + "touch mode", viewToTouch.isInTouchMode());
+ //Assert.assertEquals("number of touches to enter touch mode", 1, numAttemptsAtTouchMode);
+ }
+
+ public static void assertInTouchModeAfterTap(InstrumentationTestCase test, View viewToTouch) {
+ int numAttemptsAtTouchMode = 0;
+ while (numAttemptsAtTouchMode < MAX_ATTEMPTS &&
+ !viewToTouch.isInTouchMode()) {
+ TouchUtils.tapView(test, viewToTouch);
+ numAttemptsAtTouchMode++;
+ }
+ Assert.assertTrue("even after " + MAX_ATTEMPTS + " taps, did not enter "
+ + "touch mode", viewToTouch.isInTouchMode());
+ //Assert.assertEquals("number of touches to enter touch mode", 1, numAttemptsAtTouchMode);
+ }
+
+ public static void assertNotInTouchModeAfterKey(InstrumentationTestCase test, int keyCode, View checkForTouchMode) {
+ test.sendKeys(keyCode);
+ int amountLeft = MAX_DELAY_MILLIS;
+
+ while (checkForTouchMode.isInTouchMode() && amountLeft > 0) {
+ amountLeft -= 200;
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ Assert.assertFalse("even after waiting " + MAX_DELAY_MILLIS + " millis after "
+ + "pressing key event, still in touch mode", checkForTouchMode.isInTouchMode());
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/BigCache.java b/tests/FrameworkTest/src/com/android/frameworktest/view/BigCache.java
new file mode 100644
index 0000000..6f5eb00
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/BigCache.java
@@ -0,0 +1,71 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.view.ViewGroup;
+import android.view.View;
+import android.view.Display;
+import android.view.ViewConfiguration;
+
+/**
+ * This activity contains two Views, one as big as the screen, one much larger. The large one
+ * should not be able to activate its drawing cache.
+ */
+public class BigCache extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ final LinearLayout testBed = new LinearLayout(this);
+ testBed.setOrientation(LinearLayout.VERTICAL);
+ testBed.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
+
+ final int cacheSize = ViewConfiguration.getMaximumDrawingCacheSize();
+ final Display display = getWindowManager().getDefaultDisplay();
+ final int screenWidth = display.getWidth();
+ final int screenHeight = display.getHeight();
+
+ final View tiny = new View(this);
+ tiny.setId(R.id.a);
+ tiny.setBackgroundColor(0xFFFF0000);
+ tiny.setLayoutParams(new LinearLayout.LayoutParams(screenWidth, screenHeight));
+
+ final View large = new View(this);
+ large.setId(R.id.b);
+ large.setBackgroundColor(0xFF00FF00);
+ // Compute the height of the view assuming a cache size based on ARGB8888
+ final int height = 2 * (cacheSize / 2) / screenWidth;
+ large.setLayoutParams(new LinearLayout.LayoutParams(screenWidth, height));
+
+ final ScrollView scroller = new ScrollView(this);
+ scroller.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
+
+ testBed.addView(tiny);
+ testBed.addView(large);
+ scroller.addView(testBed);
+
+ setContentView(scroller);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/Disabled.java b/tests/FrameworkTest/src/com/android/frameworktest/view/Disabled.java
new file mode 100644
index 0000000..1f1f4f4
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/Disabled.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.widget.Button;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.app.Activity;
+
+/**
+ * Exercise View's disabled state.
+ */
+public class Disabled extends Activity implements OnClickListener {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.disabled);
+
+ // Find our buttons
+ Button disabledButton = (Button) findViewById(R.id.disabledButton);
+ disabledButton.setEnabled(false);
+
+ // Find our buttons
+ Button disabledButtonA = (Button) findViewById(R.id.disabledButtonA);
+ disabledButtonA.setOnClickListener(this);
+ }
+
+ public void onClick(View v) {
+ Button disabledButtonB = (Button) findViewById(R.id.disabledButtonB);
+ disabledButtonB.setEnabled(!disabledButtonB.isEnabled());
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/GlobalFocusChange.java b/tests/FrameworkTest/src/com/android/frameworktest/view/GlobalFocusChange.java
new file mode 100644
index 0000000..1cbf05a
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/GlobalFocusChange.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.ViewTreeObserver;
+import android.view.View;
+
+public class GlobalFocusChange extends Activity implements ViewTreeObserver.OnGlobalFocusChangeListener {
+ public View mOldFocus;
+ public View mNewFocus;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.focus_listener);
+ findViewById(R.id.left).getViewTreeObserver().addOnGlobalFocusChangeListener(this);
+ }
+
+ public void reset() {
+ mOldFocus = mNewFocus = null;
+ }
+
+ public void onGlobalFocusChanged(View oldFocus, View newFocus) {
+ mOldFocus = oldFocus;
+ mNewFocus = newFocus;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/Include.java b/tests/FrameworkTest/src/com/android/frameworktest/view/Include.java
new file mode 100644
index 0000000..fc36e37
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/Include.java
@@ -0,0 +1,33 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.app.Activity;
+
+/**
+ * Exercise <include /> tag in XML files.
+ */
+public class Include extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.include_tag);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/Longpress.java b/tests/FrameworkTest/src/com/android/frameworktest/view/Longpress.java
new file mode 100644
index 0000000..f3483fc
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/Longpress.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2006 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+public class Longpress extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.longpress);
+ }
+}
+
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/Merge.java b/tests/FrameworkTest/src/com/android/frameworktest/view/Merge.java
new file mode 100644
index 0000000..9596e91
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/Merge.java
@@ -0,0 +1,47 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.widget.LinearLayout;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+
+/**
+ * Exercise <merge /> tag in XML files.
+ */
+public class Merge extends Activity {
+ private LinearLayout mLayout;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ mLayout = new LinearLayout(this);
+ mLayout.setOrientation(LinearLayout.VERTICAL);
+ LayoutInflater.from(this).inflate(R.layout.merge_tag, mLayout);
+
+ setContentView(mLayout);
+ }
+
+ public ViewGroup getLayout() {
+ return mLayout;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/PopupWindowVisibility.java b/tests/FrameworkTest/src/com/android/frameworktest/view/PopupWindowVisibility.java
new file mode 100644
index 0000000..f4d477d4
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/PopupWindowVisibility.java
@@ -0,0 +1,117 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.AutoCompleteTextView;
+import android.widget.Button;
+import android.widget.Spinner;
+
+import com.android.frameworktest.R;
+
+/**
+ * Tests views with popupWindows becoming invisible
+ */
+public class PopupWindowVisibility extends Activity implements OnClickListener {
+
+ private View mFrame;
+ private Button mHide;
+ private Button mShow;
+
+
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.popup_window_visibility);
+
+ mFrame = findViewById(R.id.frame);
+
+ mHide = (Button) findViewById(R.id.hide);
+ mHide.setOnClickListener(this);
+
+ mShow = (Button) findViewById(R.id.show);
+ mShow.setOnClickListener(this);
+
+ Spinner spinner = (Spinner) findViewById(R.id.spinner);
+ ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_spinner_item, mStrings);
+ spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ spinner.setAdapter(spinnerAdapter);
+
+ ArrayAdapter<String> autoAdapter = new ArrayAdapter<String>(this,
+ android.R.layout.simple_dropdown_item_1line, COUNTRIES);
+ AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.auto);
+ textView.setAdapter(autoAdapter);
+ }
+
+
+ public void onClick(View v) {
+ mFrame.setVisibility(v == mHide ? View.INVISIBLE : View.VISIBLE);
+ }
+ private static final String[] mStrings = {
+ "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune"
+ };
+
+ static final String[] COUNTRIES = new String[] {
+ "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+ "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+ "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+ "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+ "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+ "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",
+ "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",
+ "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+ "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+ "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+ "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+ "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+ "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+ "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+ "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+ "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+ "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+ "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+ "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+ "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+ "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+ "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+ "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+ "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+ "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+ "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+ "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+ "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+ "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+ "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+ "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+ "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+ "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+ "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+ "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+ "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+ "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+ "Ukraine", "United Arab Emirates", "United Kingdom",
+ "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+ "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+ "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+ };
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/PreDrawListener.java b/tests/FrameworkTest/src/com/android/frameworktest/view/PreDrawListener.java
new file mode 100644
index 0000000..cb456b2
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/PreDrawListener.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+import com.android.frameworktest.R;
+
+
+/**
+ * Tests views with popupWindows becoming invisible
+ */
+public class PreDrawListener extends Activity implements OnClickListener {
+
+ private MyLinearLayout mFrame;
+
+
+ static public class MyLinearLayout extends LinearLayout implements
+ ViewTreeObserver.OnPreDrawListener {
+
+ public boolean mCancelNextDraw;
+
+ public MyLinearLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public MyLinearLayout(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnPreDrawListener(this);
+ }
+
+ public boolean onPreDraw() {
+ if (mCancelNextDraw) {
+ Button b = new Button(this.getContext());
+ b.setText("Hello");
+ addView(b, new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
+ LayoutParams.WRAP_CONTENT));
+ mCancelNextDraw = false;
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.pre_draw_listener);
+
+ mFrame = (MyLinearLayout) findViewById(R.id.frame);
+
+ Button mGoButton = (Button) findViewById(R.id.go);
+ mGoButton.setOnClickListener(this);
+ }
+
+
+ public void onClick(View v) {
+ mFrame.mCancelNextDraw = true;
+ mFrame.invalidate();
+ }
+
+
+
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/RemoteViewsActivity.java b/tests/FrameworkTest/src/com/android/frameworktest/view/RemoteViewsActivity.java
new file mode 100644
index 0000000..146c0ab
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/RemoteViewsActivity.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+import com.android.frameworktest.R;
+
+/**
+ * Exercise RemoteViews -- especially filtering
+ */
+public class RemoteViewsActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.remote_view_host);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/RunQueue.java b/tests/FrameworkTest/src/com/android/frameworktest/view/RunQueue.java
new file mode 100644
index 0000000..c8c3c28
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/RunQueue.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import com.android.frameworktest.R;
+
+/**
+ * Tests views using post*() and getViewTreeObserver() before onAttachedToWindow().
+ */
+public class RunQueue extends Activity implements ViewTreeObserver.OnGlobalLayoutListener {
+ public boolean runnableRan = false;
+ public boolean runnableCancelled = true;
+ public boolean globalLayout = false;
+ public ViewTreeObserver viewTreeObserver;
+
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+
+ TextView textView = new TextView(this);
+ textView.setText("RunQueue");
+ textView.setId(R.id.simple_view);
+
+ setContentView(textView);
+ final View view = findViewById(R.id.simple_view);
+
+ view.post(new Runnable() {
+ public void run() {
+ runnableRan = true;
+ }
+ });
+
+ final Runnable runnable = new Runnable() {
+ public void run() {
+ runnableCancelled = false;
+ }
+ };
+ view.post(runnable);
+ view.post(runnable);
+ view.post(runnable);
+ view.post(runnable);
+ view.removeCallbacks(runnable);
+
+ viewTreeObserver = view.getViewTreeObserver();
+ viewTreeObserver.addOnGlobalLayoutListener(this);
+ }
+
+ public void onGlobalLayout() {
+ globalLayout = true;
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/StubbedView.java b/tests/FrameworkTest/src/com/android/frameworktest/view/StubbedView.java
new file mode 100644
index 0000000..2b0db9d
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/StubbedView.java
@@ -0,0 +1,43 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.app.Activity;
+import android.view.View;
+
+/**
+ * Exercise <ViewStub /> tag in XML files.
+ */
+public class StubbedView extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.viewstub);
+
+ findViewById(R.id.vis).setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ final View view = findViewById(R.id.viewStub);
+ if (view != null) {
+ view.setVisibility(View.VISIBLE);
+ }
+ }
+ });
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/ViewGroupChildren.java b/tests/FrameworkTest/src/com/android/frameworktest/view/ViewGroupChildren.java
new file mode 100644
index 0000000..163e03c
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/ViewGroupChildren.java
@@ -0,0 +1,35 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.widget.Button;
+import android.view.View;
+import android.app.Activity;
+
+/**
+ * Exercise ViewGroup's ability to add and remove children.
+ */
+public class ViewGroupChildren extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.viewgroupchildren);
+ }
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/Visibility.java b/tests/FrameworkTest/src/com/android/frameworktest/view/Visibility.java
new file mode 100644
index 0000000..e068620
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/Visibility.java
@@ -0,0 +1,70 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.widget.Button;
+import android.view.View;
+import android.app.Activity;
+
+/**
+ * Exercise View's ability to change their visibility: GONE, INVISIBLE and
+ * VISIBLE.
+ */
+public class Visibility extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.visibility);
+
+ // Find the view whose visibility will change
+ mVictim = findViewById(R.id.victim);
+
+ // Find our buttons
+ Button visibleButton = (Button) findViewById(R.id.vis);
+ Button invisibleButton = (Button) findViewById(R.id.invis);
+ Button goneButton = (Button) findViewById(R.id.gone);
+
+ // Wire each button to a click listener
+ visibleButton.setOnClickListener(mVisibleListener);
+ invisibleButton.setOnClickListener(mInvisibleListener);
+ goneButton.setOnClickListener(mGoneListener);
+ }
+
+
+ View.OnClickListener mVisibleListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ mVictim.setVisibility(View.VISIBLE);
+ }
+ };
+
+ View.OnClickListener mInvisibleListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ mVictim.setVisibility(View.INVISIBLE);
+ }
+ };
+
+ View.OnClickListener mGoneListener = new View.OnClickListener() {
+ public void onClick(View v) {
+ mVictim.setVisibility(View.GONE);
+ }
+ };
+
+ private View mVictim;
+}
diff --git a/tests/FrameworkTest/src/com/android/frameworktest/view/ZeroSized.java b/tests/FrameworkTest/src/com/android/frameworktest/view/ZeroSized.java
new file mode 100644
index 0000000..e858fc0
--- /dev/null
+++ b/tests/FrameworkTest/src/com/android/frameworktest/view/ZeroSized.java
@@ -0,0 +1,34 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+
+import android.os.Bundle;
+import android.app.Activity;
+
+/**
+ * This activity contains Views with various widths and heights. The goal is to exercise the
+ * drawing cache when width is null, height is null or both.
+ */
+public class ZeroSized extends Activity {
+ @Override
+ protected void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ setContentView(R.layout.zero_sized);
+ }
+}
diff --git a/tests/FrameworkTest/tests/Android.mk b/tests/FrameworkTest/tests/Android.mk
new file mode 100644
index 0000000..5c54684
--- /dev/null
+++ b/tests/FrameworkTest/tests/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := FrameworkTestTests
+
+LOCAL_INSTRUMENTATION_FOR := FrameworkTest
+
+include $(BUILD_PACKAGE)
+
diff --git a/tests/FrameworkTest/tests/AndroidManifest.xml b/tests/FrameworkTest/tests/AndroidManifest.xml
new file mode 100644
index 0000000..65aaebb
--- /dev/null
+++ b/tests/FrameworkTest/tests/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.frameworktest.tests">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <!--
+ This declares that this app uses the instrumentation test runner targeting
+ the package of com.android.frameworktest. To run the tests use the command:
+ "adb shell am instrument -w com.android.frameworktest.tests/android.test.InstrumentationTestRunner"
+ -->
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.frameworktest"
+ android:label="framework tests"/>
+
+</manifest>
diff --git a/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java b/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
new file mode 100644
index 0000000..aa3d186
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
@@ -0,0 +1,578 @@
+package android.content;
+
+import com.google.android.collect.Lists;
+import com.google.android.collect.Sets;
+
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.test.AndroidTestCase;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.SortedSet;
+
+/** Unit test for {@link android.content.AbstractTableMerger}. */
+public class AbstractTableMergerTest extends AndroidTestCase {
+ MockSyncableContentProvider mRealProvider;
+ MockSyncableContentProvider mTempProvider;
+ MockTableMerger mMerger;
+ MockSyncContext mSyncContext;
+
+ static final String TABLE_NAME = "items";
+ static final String DELETED_TABLE_NAME = "deleted_items";
+ static final Uri CONTENT_URI = Uri.parse("content://testdata");
+ static final Uri TABLE_URI = Uri.withAppendedPath(CONTENT_URI, TABLE_NAME);
+ static final Uri DELETED_TABLE_URI = Uri.withAppendedPath(CONTENT_URI, DELETED_TABLE_NAME);
+
+ private final String ACCOUNT = "account@goo.com";
+
+ private final ArrayList<Expectation> mExpectations = Lists.newArrayList();
+
+ static class Expectation {
+ enum Type {
+ UPDATE,
+ INSERT,
+ DELETE,
+ RESOLVE
+ }
+
+ Type mType;
+ ContentValues mValues;
+ Long mLocalRowId;
+
+ Expectation(Type type, Long localRowId, ContentValues values) {
+ mType = type;
+ mValues = values;
+ mLocalRowId = localRowId;
+ if (type == Type.DELETE) {
+ assertNull(values);
+ } else {
+ assertFalse(values.containsKey("_id"));
+ }
+ }
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mSyncContext = new MockSyncContext();
+ mRealProvider = new MockSyncableContentProvider();
+ mTempProvider = mRealProvider.getTemporaryInstance();
+ mMerger = new MockTableMerger(mRealProvider.getDatabase(),
+ TABLE_NAME, TABLE_URI, DELETED_TABLE_NAME, DELETED_TABLE_URI);
+ mExpectations.clear();
+ }
+
+ ContentValues newValues(String data, String syncId, String syncAccount,
+ String syncTime, String syncVersion, Long syncLocalId) {
+ ContentValues values = new ContentValues();
+ if (data != null) values.put("data", data);
+ if (syncTime != null) values.put("_sync_time", syncTime);
+ if (syncVersion != null) values.put("_sync_version", syncVersion);
+ if (syncId != null) values.put("_sync_id", syncId);
+ if (syncAccount != null) values.put("_sync_account", syncAccount);
+ values.put("_sync_local_id", syncLocalId);
+ values.put("_sync_dirty", 0);
+ return values;
+ }
+
+ ContentValues newDeletedValues(String syncId, String syncAccount, String syncVersion,
+ Long syncLocalId) {
+ ContentValues values = new ContentValues();
+ if (syncVersion != null) values.put("_sync_version", syncVersion);
+ if (syncId != null) values.put("_sync_id", syncId);
+ if (syncAccount != null) values.put("_sync_account", syncAccount);
+ if (syncLocalId != null) values.put("_sync_local_id", syncLocalId);
+ return values;
+ }
+
+ ContentValues newModifyData(String data) {
+ ContentValues values = new ContentValues();
+ values.put("data", data);
+ values.put("_sync_dirty", 1);
+ return values;
+ }
+
+ // Want to test adding, changing, deleting entries to a provider that has extra entries
+ // before and after the entries being changed.
+ public void testInsert() {
+ // add rows to the real provider
+ // add new row to the temp provider
+ final ContentValues row1 = newValues("d1", "si1", ACCOUNT, "st1", "sv1", null);
+ mTempProvider.insert(TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.INSERT, null /* syncLocalId */, row1));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testUpdateWithLocalId() {
+ // add rows to the real provider
+ // add new row to the temp provider that matches an unsynced row in the real provider
+ final ContentValues row1 = newValues("d1", "si1", ACCOUNT, "st1", "sv1", 11L);
+ mTempProvider.insert(TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.UPDATE, 11L, row1));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testUpdateWithoutLocalId() {
+ // add rows to the real provider
+ Uri i1 = mRealProvider.insert(TABLE_URI,
+ newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
+
+ // add new row to the temp provider that matches an unsynced row in the real provider
+ final ContentValues row1 = newValues("d2", "si1", ACCOUNT, "st2", "sv2", null);
+ mTempProvider.insert(TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.UPDATE, ContentUris.parseId(i1), row1));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testResolve() {
+ // add rows to the real provider
+ Uri i1 = mRealProvider.insert(TABLE_URI,
+ newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
+ mRealProvider.update(TABLE_URI, newModifyData("d2"), null, null);
+
+ // add row to the temp provider that matches a dirty, synced row in the real provider
+ final ContentValues row1 = newValues("d3", "si1", ACCOUNT, "st2", "sv2", null);
+ mTempProvider.insert(TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.RESOLVE, ContentUris.parseId(i1), row1));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testResolveWithLocalId() {
+ // add rows to the real provider
+ Uri i1 = mRealProvider.insert(TABLE_URI,
+ newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
+ mRealProvider.update(TABLE_URI, newModifyData("d2"), null, null);
+
+ // add row to the temp provider that matches a dirty, synced row in the real provider
+ ContentValues row1 = newValues("d2", "si1", ACCOUNT, "st2", "sv2", ContentUris.parseId(i1));
+ mTempProvider.insert(TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.UPDATE, ContentUris.parseId(i1), row1));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testDeleteRowAfterDelete() {
+ // add rows to the real provider
+ Uri i1 = mRealProvider.insert(TABLE_URI,
+ newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
+
+ // add a deleted record to the temp provider
+ ContentValues row1 = newDeletedValues(null, null, null, ContentUris.parseId(i1));
+ mTempProvider.insert(DELETED_TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testDeleteRowAfterInsert() {
+ // add rows to the real provider
+ Uri i1 = mRealProvider.insert(TABLE_URI, newModifyData("d1"));
+
+ // add a deleted record to the temp provider
+ ContentValues row1 = newDeletedValues(null, null, null, ContentUris.parseId(i1));
+ mTempProvider.insert(DELETED_TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testDeleteRowAfterUpdate() {
+ // add rows to the real provider
+ Uri i1 = mRealProvider.insert(TABLE_URI,
+ newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
+
+ // add a deleted record to the temp provider
+ ContentValues row1 = newDeletedValues("si1", ACCOUNT, "sv1", ContentUris.parseId(i1));
+ mTempProvider.insert(DELETED_TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ public void testDeleteRowFromServer() {
+ // add rows to the real provider
+ Uri i1 = mRealProvider.insert(TABLE_URI,
+ newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
+
+ // add a deleted record to the temp provider
+ ContentValues row1 = newDeletedValues("si1", ACCOUNT, "sv1", null);
+ mTempProvider.insert(DELETED_TABLE_URI, row1);
+
+ // add expected callbacks to merger
+ mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
+
+ // run merger
+ SyncResult syncResult = new SyncResult();
+ mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
+
+ // check that all expectations were met
+ assertEquals("not all expectations were met", 0, mExpectations.size());
+ }
+
+ class MockTableMerger extends AbstractTableMerger {
+ public MockTableMerger(SQLiteDatabase database, String table, Uri tableURL,
+ String deletedTable, Uri deletedTableURL) {
+ super(database, table, tableURL, deletedTable, deletedTableURL);
+ }
+
+ public void insertRow(ContentProvider diffs, Cursor diffsCursor) {
+ Expectation expectation = mExpectations.remove(0);
+ checkExpectation(expectation,
+ Expectation.Type.INSERT, null /* syncLocalId */, diffsCursor);
+ }
+
+ public void updateRow(long localPersonID, ContentProvider diffs, Cursor diffsCursor) {
+ Expectation expectation = mExpectations.remove(0);
+ checkExpectation(expectation, Expectation.Type.UPDATE, localPersonID, diffsCursor);
+ }
+
+ public void resolveRow(long localPersonID, String syncID, ContentProvider diffs,
+ Cursor diffsCursor) {
+ Expectation expectation = mExpectations.remove(0);
+ checkExpectation(expectation, Expectation.Type.RESOLVE, localPersonID, diffsCursor);
+ }
+
+ @Override
+ public void deleteRow(Cursor cursor) {
+ Expectation expectation = mExpectations.remove(0);
+ assertEquals(expectation.mType, Expectation.Type.DELETE);
+ assertNotNull(expectation.mLocalRowId);
+ final long localRowId = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
+ assertEquals((long)expectation.mLocalRowId, localRowId);
+ cursor.moveToNext();
+ mDb.delete(TABLE_NAME, "_id=" + localRowId, null);
+ }
+
+ protected void notifyChanges() {
+ throw new UnsupportedOperationException();
+ }
+
+ void checkExpectation(Expectation expectation,
+ Expectation.Type actualType, Long localRowId,
+ Cursor cursor) {
+ assertEquals(expectation.mType, actualType);
+ assertEquals(expectation.mLocalRowId, localRowId);
+
+ final SortedSet<String> actualKeys = Sets.newSortedSet(cursor.getColumnNames());
+ final SortedSet<String> expectedKeys = Sets.newSortedSet();
+ for (Map.Entry<String, Object> entry : expectation.mValues.valueSet()) {
+ expectedKeys.add(entry.getKey());
+ }
+ actualKeys.remove("_id");
+ actualKeys.remove("_sync_mark");
+ actualKeys.remove("_sync_local_id");
+ expectedKeys.remove("_sync_local_id");
+ expectedKeys.remove("_id");
+ assertEquals("column mismatch",
+ TextUtils.join(",", expectedKeys), TextUtils.join(",", actualKeys));
+
+// if (localRowId != null) {
+// assertEquals((long) localRowId,
+// cursor.getLong(cursor.getColumnIndexOrThrow("_sync_local_id")));
+// } else {
+// assertTrue("unexpected _sync_local_id, "
+// + cursor.getLong(cursor.getColumnIndexOrThrow("_sync_local_id")),
+// cursor.isNull(cursor.getColumnIndexOrThrow("_sync_local_id")));
+// }
+
+ for (String name : cursor.getColumnNames()) {
+ if ("_id".equals(name)) {
+ continue;
+ }
+ if (cursor.isNull(cursor.getColumnIndexOrThrow(name))) {
+ assertNull(expectation.mValues.getAsString(name));
+ } else {
+ String actualValue =
+ cursor.getString(cursor.getColumnIndexOrThrow(name));
+ assertEquals("mismatch on column " + name,
+ expectation.mValues.getAsString(name), actualValue);
+ }
+ }
+ }
+ }
+
+ class MockSyncableContentProvider extends SyncableContentProvider {
+ SQLiteDatabase mDb;
+ boolean mIsTemporary;
+ boolean mContainsDiffs;
+
+ private final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+
+ private static final int MATCHER_ITEMS = 0;
+ private static final int MATCHER_DELETED_ITEMS = 1;
+
+ public MockSyncableContentProvider() {
+ mIsTemporary = false;
+ setContainsDiffs(false);
+ sURIMatcher.addURI(CONTENT_URI.getAuthority(), "items", MATCHER_ITEMS);
+ sURIMatcher.addURI(CONTENT_URI.getAuthority(), "deleted_items", MATCHER_DELETED_ITEMS);
+
+ mDb = SQLiteDatabase.create(null);
+ mDb.execSQL("CREATE TABLE items ("
+ + "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "data TEXT, "
+ + "_sync_time TEXT, "
+ + "_sync_version TEXT, "
+ + "_sync_id TEXT, "
+ + "_sync_local_id INTEGER, "
+ + "_sync_dirty INTEGER NOT NULL DEFAULT 0, "
+ + "_sync_account TEXT, "
+ + "_sync_mark INTEGER)");
+
+ mDb.execSQL("CREATE TABLE deleted_items ("
+ + "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ + "_sync_version TEXT, "
+ + "_sync_id TEXT, "
+ + "_sync_local_id INTEGER, "
+ + "_sync_account TEXT, "
+ + "_sync_mark INTEGER)");
+ }
+
+ public boolean onCreate() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+ String sortOrder) {
+ int match = sURIMatcher.match(uri);
+ switch (match) {
+ case MATCHER_ITEMS:
+ return mDb.query(TABLE_NAME, projection, selection, selectionArgs,
+ null, null, sortOrder);
+ case MATCHER_DELETED_ITEMS:
+ return mDb.query(DELETED_TABLE_NAME, projection, selection, selectionArgs,
+ null, null, sortOrder);
+ default:
+ throw new UnsupportedOperationException("Cannot query URL: " + uri);
+ }
+ }
+
+ public String getType(Uri uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Uri insert(Uri uri, ContentValues values) {
+ int match = sURIMatcher.match(uri);
+ switch (match) {
+ case MATCHER_ITEMS: {
+ long id = mDb.insert(TABLE_NAME, "_id", values);
+ return CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build();
+ }
+ case MATCHER_DELETED_ITEMS: {
+ long id = mDb.insert(DELETED_TABLE_NAME, "_id", values);
+ return CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build();
+ }
+ default:
+ throw new UnsupportedOperationException("Cannot query URL: " + uri);
+ }
+ }
+
+ public int delete(Uri uri, String selection, String[] selectionArgs) {
+ int match = sURIMatcher.match(uri);
+ switch (match) {
+ case MATCHER_ITEMS:
+ return mDb.delete(TABLE_NAME, selection, selectionArgs);
+ case MATCHER_DELETED_ITEMS:
+ return mDb.delete(DELETED_TABLE_NAME, selection, selectionArgs);
+ default:
+ throw new UnsupportedOperationException("Cannot query URL: " + uri);
+ }
+ }
+
+ public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+ int match = sURIMatcher.match(uri);
+ switch (match) {
+ case MATCHER_ITEMS:
+ return mDb.update(TABLE_NAME, values, selection, selectionArgs);
+ case MATCHER_DELETED_ITEMS:
+ return mDb.update(DELETED_TABLE_NAME, values, selection, selectionArgs);
+ default:
+ throw new UnsupportedOperationException("Cannot query URL: " + uri);
+ }
+ }
+
+ protected boolean isTemporary() {
+ return mIsTemporary;
+ }
+
+ public void close() {
+ throw new UnsupportedOperationException();
+ }
+
+ protected void bootstrapDatabase(SQLiteDatabase db) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected void onDatabaseOpened(SQLiteDatabase db) {
+ throw new UnsupportedOperationException();
+ }
+
+ public MockSyncableContentProvider getTemporaryInstance() {
+ MockSyncableContentProvider temp = new MockSyncableContentProvider();
+ temp.mIsTemporary = true;
+ temp.setContainsDiffs(true);
+ return temp;
+ }
+
+ public SQLiteDatabase getDatabase() {
+ return mDb;
+ }
+
+ public boolean getContainsDiffs() {
+ return mContainsDiffs;
+ }
+
+ public void setContainsDiffs(boolean containsDiffs) {
+ mContainsDiffs = containsDiffs;
+ }
+
+ protected Iterable<? extends AbstractTableMerger> getMergers() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean changeRequiresLocalSync(Uri uri) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void onSyncStart(SyncContext context, String account) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void onSyncStop(SyncContext context, boolean success) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getSyncingAccount() {
+ throw new UnsupportedOperationException();
+ }
+
+ public void merge(SyncContext context, SyncableContentProvider diffs,
+ TempProviderSyncResult result, SyncResult syncResult) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void onSyncCanceled() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isMergeCancelled() {
+ return false;
+ }
+
+ protected int updateInternal(Uri url, ContentValues values, String selection,
+ String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected int deleteInternal(Uri url, String selection, String[] selectionArgs) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected Uri insertInternal(Uri url, ContentValues values) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected Cursor queryInternal(Uri url, String[] projection, String selection,
+ String[] selectionArgs, String sortOrder) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected void onAccountsChanged(String[] accountsArray) {
+ throw new UnsupportedOperationException();
+ }
+
+ protected void deleteRowsForRemovedAccounts(Map<String, Boolean> accounts, String table,
+ String accountColumnName) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void wipeAccount(String account) {
+ throw new UnsupportedOperationException();
+ }
+
+ public byte[] readSyncDataBytes(String account) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeSyncDataBytes(String account, byte[] data) {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ class MockSyncContext extends SyncContext {
+ public MockSyncContext() {
+ super(null);
+ }
+
+ @Override
+ public void setStatusText(String message) {
+ }
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/android/content/SearchRecentSuggestionsProviderTest.java b/tests/FrameworkTest/tests/src/android/content/SearchRecentSuggestionsProviderTest.java
new file mode 100644
index 0000000..a4c33f5
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/android/content/SearchRecentSuggestionsProviderTest.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (C) 2008 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.content;
+
+import android.app.SearchManager;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.SearchRecentSuggestions;
+import android.test.ProviderTestCase2;
+import android.test.suitebuilder.annotation.Suppress;
+
+/**
+ * Very simple provider that I can instantiate right here.
+ */
+class TestProvider extends SearchRecentSuggestionsProvider {
+ final static String AUTHORITY = "android.content.TestProvider";
+ final static int MODE = DATABASE_MODE_QUERIES + DATABASE_MODE_2LINES;
+
+ public TestProvider() {
+ super();
+ setupSuggestions(AUTHORITY, MODE);
+ }
+}
+
+/**
+ * ProviderTestCase that performs unit tests of SearchRecentSuggestionsProvider.
+ *
+ * You can run this test in isolation via the commands:
+ *
+ * $ (cd tests/FrameworkTests/ && mm) && adb sync
+ * $ adb shell am instrument -w \
+ * -e class android.content.SearchRecentSuggestionsProviderTest
+ * com.android.frameworktest.tests/android.test.InstrumentationTestRunner
+ */
+// Suppress these until bug http://b/issue?id=1416586 is fixed.
+@Suppress
+public class SearchRecentSuggestionsProviderTest extends ProviderTestCase2<TestProvider> {
+
+ // Elements prepared by setUp()
+ SearchRecentSuggestions mSearchHelper;
+
+ public SearchRecentSuggestionsProviderTest() {
+ super(TestProvider.class, TestProvider.AUTHORITY);
+ }
+
+ /**
+ * During setup, grab a helper for DB access
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // Use the recent suggestions helper. As long as we pass in our isolated context,
+ // it should correctly access the provider under test.
+ mSearchHelper = new SearchRecentSuggestions(getMockContext(),
+ TestProvider.AUTHORITY, TestProvider.MODE);
+
+ // test for empty database at setup time
+ checkOpenCursorCount(0);
+ }
+
+ /**
+ * Simple test to see if we can instantiate the whole mess.
+ */
+ public void testSetup() {
+ assertTrue(true);
+ }
+
+ /**
+ * Simple test to see if we can write and read back a single query
+ */
+ public void testOneQuery() {
+ final String TEST_LINE1 = "test line 1";
+ final String TEST_LINE2 = "test line 2";
+ mSearchHelper.saveRecentQuery(TEST_LINE1, TEST_LINE2);
+
+ // make sure that there are is exactly one entry returned by a non-filtering cursor
+ checkOpenCursorCount(1);
+
+ // test non-filtering cursor for correct entry
+ checkResultCounts(null, 1, 1, TEST_LINE1, TEST_LINE2);
+
+ // test filtering cursor for correct entry
+ checkResultCounts(TEST_LINE1, 1, 1, TEST_LINE1, TEST_LINE2);
+ checkResultCounts(TEST_LINE2, 1, 1, TEST_LINE1, TEST_LINE2);
+
+ // test that a different filter returns zero results
+ checkResultCounts("bad filter", 0, 0, null, null);
+ }
+
+ /**
+ * Simple test to see if we can write and read back a diverse set of queries
+ */
+ public void testMixedQueries() {
+ // we'll make 10 queries named "query x" and 10 queries named "test x"
+ final String TEST_GROUP_1 = "query ";
+ final String TEST_GROUP_2 = "test ";
+ final String TEST_LINE2 = "line2 ";
+ final int GROUP_COUNT = 10;
+
+ writeEntries(GROUP_COUNT, TEST_GROUP_1, TEST_LINE2);
+ writeEntries(GROUP_COUNT, TEST_GROUP_2, TEST_LINE2);
+
+ // check counts
+ checkOpenCursorCount(2 * GROUP_COUNT);
+
+ // check that each query returns the right result counts
+ checkResultCounts(TEST_GROUP_1, GROUP_COUNT, GROUP_COUNT, null, null);
+ checkResultCounts(TEST_GROUP_2, GROUP_COUNT, GROUP_COUNT, null, null);
+ checkResultCounts(TEST_LINE2, 2 * GROUP_COUNT, 2 * GROUP_COUNT, null, null);
+ }
+
+ /**
+ * Test that the reordering code works properly. The most recently injected queries
+ * should replace existing queries and be sorted to the top of the list.
+ */
+ public void testReordering() {
+ // first we'll make 10 queries named "group1 x"
+ final int GROUP_1_COUNT = 10;
+ final String GROUP_1_QUERY = "group1 ";
+ final String GROUP_1_LINE2 = "line2 ";
+ writeEntries(GROUP_1_COUNT, GROUP_1_QUERY, GROUP_1_LINE2);
+
+ // check totals
+ checkOpenCursorCount(GROUP_1_COUNT);
+
+ // guarantee that group 1 has older timestamps
+ writeDelay();
+
+ // next we'll add 10 entries named "group2 x"
+ final int GROUP_2_COUNT = 10;
+ final String GROUP_2_QUERY = "group2 ";
+ final String GROUP_2_LINE2 = "line2 ";
+ writeEntries(GROUP_2_COUNT, GROUP_2_QUERY, GROUP_2_LINE2);
+
+ // check totals
+ checkOpenCursorCount(GROUP_1_COUNT + GROUP_2_COUNT);
+
+ // guarantee that group 2 has older timestamps
+ writeDelay();
+
+ // now refresh 5 of the 10 from group 1
+ // change line2 so they can be more easily tracked
+ final int GROUP_3_COUNT = 5;
+ final String GROUP_3_QUERY = GROUP_1_QUERY;
+ final String GROUP_3_LINE2 = "refreshed ";
+ writeEntries(GROUP_3_COUNT, GROUP_3_QUERY, GROUP_3_LINE2);
+
+ // confirm that the total didn't change (those were replacements, not adds)
+ checkOpenCursorCount(GROUP_1_COUNT + GROUP_2_COUNT);
+
+ // confirm that the are now 5 in group 1, 10 in group 2, and 5 in group 3
+ int newGroup1Count = GROUP_1_COUNT - GROUP_3_COUNT;
+ checkResultCounts(GROUP_1_QUERY, newGroup1Count, newGroup1Count, null, GROUP_1_LINE2);
+ checkResultCounts(GROUP_2_QUERY, GROUP_2_COUNT, GROUP_2_COUNT, null, null);
+ checkResultCounts(GROUP_3_QUERY, GROUP_3_COUNT, GROUP_3_COUNT, null, GROUP_3_LINE2);
+
+ // finally, spot check that the right groups are in the right places
+ // the ordering should be group 3 (newest), group 2, group 1 (oldest)
+ Cursor c = getQueryCursor(null);
+ int colQuery = c.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_QUERY);
+ int colDisplay1 = c.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1);
+ int colDisplay2 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2);
+
+ // Spot check the first and last expected entries of group 3
+ c.moveToPosition(0);
+ assertTrue("group 3 did not properly reorder to head of list",
+ checkRow(c, colQuery, colDisplay1, colDisplay2, GROUP_3_QUERY, GROUP_3_LINE2));
+ c.move(GROUP_3_COUNT - 1);
+ assertTrue("group 3 did not properly reorder to head of list",
+ checkRow(c, colQuery, colDisplay1, colDisplay2, GROUP_3_QUERY, GROUP_3_LINE2));
+
+ // Spot check the first and last expected entries of group 2
+ c.move(1);
+ assertTrue("group 2 not in expected position after reordering",
+ checkRow(c, colQuery, colDisplay1, colDisplay2, GROUP_2_QUERY, GROUP_2_LINE2));
+ c.move(GROUP_2_COUNT - 1);
+ assertTrue("group 2 not in expected position after reordering",
+ checkRow(c, colQuery, colDisplay1, colDisplay2, GROUP_2_QUERY, GROUP_2_LINE2));
+
+ // Spot check the first and last expected entries of group 1
+ c.move(1);
+ assertTrue("group 1 not in expected position after reordering",
+ checkRow(c, colQuery, colDisplay1, colDisplay2, GROUP_1_QUERY, GROUP_1_LINE2));
+ c.move(newGroup1Count - 1);
+ assertTrue("group 1 not in expected position after reordering",
+ checkRow(c, colQuery, colDisplay1, colDisplay2, GROUP_1_QUERY, GROUP_1_LINE2));
+
+ c.close();
+ }
+
+ /**
+ * Test that the pruning code works properly, The database should not go beyond 250 entries,
+ * and the oldest entries should always be discarded first.
+ *
+ * TODO: This is a slow test, do we have annotation for that?
+ */
+ public void testPruning() {
+ // first we'll make 50 queries named "group1 x"
+ final int GROUP_1_COUNT = 50;
+ final String GROUP_1_QUERY = "group1 ";
+ final String GROUP_1_LINE2 = "line2 ";
+ writeEntries(GROUP_1_COUNT, GROUP_1_QUERY, GROUP_1_LINE2);
+
+ // check totals
+ checkOpenCursorCount(GROUP_1_COUNT);
+
+ // guarantee that group 1 has older timestamps (and will be pruned first)
+ writeDelay();
+
+ // next we'll add 200 entries named "group2 x"
+ final int GROUP_2_COUNT = 200;
+ final String GROUP_2_QUERY = "group2 ";
+ final String GROUP_2_LINE2 = "line2 ";
+ writeEntries(GROUP_2_COUNT, GROUP_2_QUERY, GROUP_2_LINE2);
+
+ // check totals
+ checkOpenCursorCount(GROUP_1_COUNT + GROUP_2_COUNT);
+
+ // Finally we'll add 10 more entries named "group3 x"
+ // These should push out 10 entries from group 1
+ final int GROUP_3_COUNT = 10;
+ final String GROUP_3_QUERY = "group3 ";
+ final String GROUP_3_LINE2 = "line2 ";
+ writeEntries(GROUP_3_COUNT, GROUP_3_QUERY, GROUP_3_LINE2);
+
+ // total should still be 250
+ checkOpenCursorCount(GROUP_1_COUNT + GROUP_2_COUNT);
+
+ // there should be 40 group 1, 200 group 2, and 10 group 3
+ int group1NewCount = GROUP_1_COUNT-GROUP_3_COUNT;
+ checkResultCounts(GROUP_1_QUERY, group1NewCount, group1NewCount, null, null);
+ checkResultCounts(GROUP_2_QUERY, GROUP_2_COUNT, GROUP_2_COUNT, null, null);
+ checkResultCounts(GROUP_3_QUERY, GROUP_3_COUNT, GROUP_3_COUNT, null, null);
+ }
+
+ /**
+ * Test that the clear history code works properly.
+ */
+ public void testClear() {
+ // first we'll make 10 queries named "group1 x"
+ final int GROUP_1_COUNT = 10;
+ final String GROUP_1_QUERY = "group1 ";
+ final String GROUP_1_LINE2 = "line2 ";
+ writeEntries(GROUP_1_COUNT, GROUP_1_QUERY, GROUP_1_LINE2);
+
+ // next we'll add 10 entries named "group2 x"
+ final int GROUP_2_COUNT = 10;
+ final String GROUP_2_QUERY = "group2 ";
+ final String GROUP_2_LINE2 = "line2 ";
+ writeEntries(GROUP_2_COUNT, GROUP_2_QUERY, GROUP_2_LINE2);
+
+ // check totals
+ checkOpenCursorCount(GROUP_1_COUNT + GROUP_2_COUNT);
+
+ // delete all
+ mSearchHelper.clearHistory();
+
+ // check totals
+ checkOpenCursorCount(0);
+ }
+
+ /**
+ * Write a sequence of queries into the database, with incrementing counters in the strings.
+ */
+ private void writeEntries(int groupCount, String line1Base, String line2Base) {
+ for (int i = 0; i < groupCount; i++) {
+ final String line1 = line1Base + i;
+ final String line2 = line2Base + i;
+ mSearchHelper.saveRecentQuery(line1, line2);
+ }
+ }
+
+ /**
+ * A very slight delay to ensure that successive groups of queries in the DB cannot
+ * have the same timestamp.
+ */
+ private void writeDelay() {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ fail("Interrupted sleep.");
+ }
+ }
+
+ /**
+ * Access an "open" (no selection) suggestions cursor and confirm that it has the specified
+ * number of entries.
+ *
+ * @param expectCount The expected number of entries returned by the cursor.
+ */
+ private void checkOpenCursorCount(int expectCount) {
+ Cursor c = getQueryCursor(null);
+ assertEquals(expectCount, c.getCount());
+ c.close();
+ }
+
+ /**
+ * Set up a filter cursor and then scan it for specific results.
+ *
+ * @param queryString The query string to apply.
+ * @param minRows The minimum number of matching rows that must be found.
+ * @param maxRows The maximum number of matching rows that must be found.
+ * @param matchDisplay1 If non-null, must match DISPLAY1 column if row counts as match
+ * @param matchDisplay2 If non-null, must match DISPLAY2 column if row counts as match
+ */
+ private void checkResultCounts(String queryString, int minRows, int maxRows,
+ String matchDisplay1, String matchDisplay2) {
+
+ // get the cursor and apply sanity checks to result
+ Cursor c = getQueryCursor(queryString);
+ assertNotNull(c);
+ assertTrue("Insufficient rows in filtered cursor", c.getCount() >= minRows);
+
+ // look for minimum set of columns (note, display2 is optional)
+ int colQuery = c.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_QUERY);
+ int colDisplay1 = c.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1);
+ int colDisplay2 = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_TEXT_2);
+
+ // now loop through rows and look for desired rows
+ int foundRows = 0;
+ c.moveToFirst();
+ while (!c.isAfterLast()) {
+ if (checkRow(c, colQuery, colDisplay1, colDisplay2, matchDisplay1, matchDisplay2)) {
+ foundRows++;
+ }
+ c.moveToNext();
+ }
+
+ // now check the results
+ assertTrue(minRows <= foundRows);
+ assertTrue(foundRows <= maxRows);
+
+ c.close();
+ }
+
+ /**
+ * Check a single row for equality with target strings.
+ *
+ * @param c The cursor, already moved to the row
+ * @param colQuery The column # containing the query. The query must match display1.
+ * @param colDisp1 The column # containing display line 1.
+ * @param colDisp2 The column # containing display line 2, or -1 if no column
+ * @param matchDisplay1 If non-null, this must be the prefix of display1
+ * @param matchDisplay2 If non-null, this must be the prefix of display2
+ * @return Returns true if the row is a "match"
+ */
+ private boolean checkRow(Cursor c, int colQuery, int colDisp1, int colDisp2,
+ String matchDisplay1, String matchDisplay2) {
+ // Get the data from the row
+ String query = c.getString(colQuery);
+ String display1 = c.getString(colDisp1);
+ String display2 = (colDisp2 >= 0) ? c.getString(colDisp2) : null;
+
+ assertEquals(query, display1);
+ boolean result = true;
+ if (matchDisplay1 != null) {
+ result = result && (display1 != null) && display1.startsWith(matchDisplay1);
+ }
+ if (matchDisplay2 != null) {
+ result = result && (display2 != null) && display2.startsWith(matchDisplay2);
+ }
+
+ return result;
+ }
+
+ /**
+ * Generate a query cursor in a manner like the search dialog would.
+ *
+ * @param queryString The search string, or, null for "all"
+ * @return Returns a cursor, or null if there was some problem. Be sure to close the cursor
+ * when done with it.
+ */
+ private Cursor getQueryCursor(String queryString) {
+ ContentResolver cr = getMockContext().getContentResolver();
+
+ String uriStr = "content://" + TestProvider.AUTHORITY +
+ '/' + SearchManager.SUGGEST_URI_PATH_QUERY;
+ Uri contentUri = Uri.parse(uriStr);
+
+ String[] selArgs = new String[] {queryString};
+
+ Cursor c = cr.query(contentUri, null, null, selArgs, null);
+
+ assertNotNull(c);
+ return c;
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewCallbacks.java b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewCallbacks.java
new file mode 100644
index 0000000..93cb84a
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewCallbacks.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2008 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;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+
+public class AutoCompleteTextViewCallbacks
+ extends ActivityInstrumentationTestCase2<AutoCompleteTextViewSimple> {
+
+ public AutoCompleteTextViewCallbacks() {
+ super("com.android.frameworktest", AutoCompleteTextViewSimple.class);
+ }
+
+ /** Test that the initial popup of the suggestions does not select anything */
+ @MediumTest
+ public void testPopupNoSelection() {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // now check for selection callbacks. Nothing should be clicked or selected.
+ assertFalse("onItemClick should not be called", theActivity.mItemClickCalled);
+ assertFalse("onItemSelected should not be called", theActivity.mItemSelectedCalled);
+
+ // arguably, this should be "false", because we aren't deselecting - we shouldn't
+ // really be calling it. But it's not the end of the world, and we might wind up
+ // breaking something if we change this.
+ assertTrue("onNothingSelected should be called", theActivity.mNothingSelectedCalled);
+ }
+
+ /** Test that arrow-down into the popup calls the onSelected callback */
+ @MediumTest
+ public void testPopupEnterSelection() {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // prepare to move down into the popup
+ theActivity.resetItemListeners();
+ sendKeys("DPAD_DOWN");
+
+ // now check for selection callbacks.
+ assertFalse("onItemClick should not be called", theActivity.mItemClickCalled);
+ assertTrue("onItemSelected should be called", theActivity.mItemSelectedCalled);
+ assertEquals("onItemSelected position", 0, theActivity.mItemSelectedPosition);
+ assertFalse("onNothingSelected should not be called", theActivity.mNothingSelectedCalled);
+
+ // try one more time - should move from 0 to 1
+ theActivity.resetItemListeners();
+ sendKeys("DPAD_DOWN");
+
+ // now check for selection callbacks.
+ assertFalse("onItemClick should not be called", theActivity.mItemClickCalled);
+ assertTrue("onItemSelected should be called", theActivity.mItemSelectedCalled);
+ assertEquals("onItemSelected position", 1, theActivity.mItemSelectedPosition);
+ assertFalse("onNothingSelected should not be called", theActivity.mNothingSelectedCalled);
+ }
+
+ /** Test that arrow-up out of the popup calls the onNothingSelected callback */
+ @MediumTest
+ public void testPopupLeaveSelection() {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // move down into the popup
+ sendKeys("DPAD_DOWN");
+
+ // now move back up out of the popup
+ theActivity.resetItemListeners();
+ sendKeys("DPAD_UP");
+
+ // now check for selection callbacks.
+ assertFalse("onItemClick should not be called", theActivity.mItemClickCalled);
+ assertFalse("onItemSelected should not be called", theActivity.mItemSelectedCalled);
+ assertTrue("onNothingSelected should be called", theActivity.mNothingSelectedCalled);
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
new file mode 100644
index 0000000..663b7a4
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 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;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+
+/**
+ * A collection of tests on aspects of the AutoCompleteTextView's popup
+ */
+public class AutoCompleteTextViewPopup
+ extends ActivityInstrumentationTestCase2<AutoCompleteTextViewSimple> {
+
+ public AutoCompleteTextViewPopup() {
+ super("com.android.frameworktest", AutoCompleteTextViewSimple.class);
+ }
+
+ /** Test that we can move the selection and it responds as expected */
+ @MediumTest
+ public void testPopupSetListSelection() throws Throwable {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ final AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // No initial selection
+ assertEquals("getListSelection(-1)",
+ ListView.INVALID_POSITION, textView.getListSelection());
+
+ // set and check
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ textView.setListSelection(0);
+ }
+ });
+ instrumentation.waitForIdleSync();
+ assertEquals("set selection to (0)", 0, textView.getListSelection());
+
+ // Use movement to cross-check the movement
+ sendKeys("DPAD_DOWN");
+ assertEquals("move selection to (1)", 1, textView.getListSelection());
+ }
+
+ /** Test that we can look at the selection as we move around */
+ @MediumTest
+ public void testPopupGetListSelection() {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // No initial selection
+ assertEquals("getListSelection(-1)",
+ ListView.INVALID_POSITION, textView.getListSelection());
+
+ // check for selection position as expected
+ sendKeys("DPAD_DOWN");
+ assertEquals("move selection to (0)", 0, textView.getListSelection());
+
+ // Repeat for one more movement
+ sendKeys("DPAD_DOWN");
+ assertEquals("move selection to (1)", 1, textView.getListSelection());
+ }
+
+ /** Test that we can clear the selection */
+ @MediumTest
+ public void testPopupClearListSelection() throws Throwable {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ final AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // No initial selection
+ assertEquals("getListSelection(-1)",
+ ListView.INVALID_POSITION, textView.getListSelection());
+
+ // check for selection position as expected
+ sendKeys("DPAD_DOWN");
+ assertEquals("getListSelection(0)", 0, textView.getListSelection());
+
+ // clear it
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ textView.clearListSelection();
+ }
+ });
+ instrumentation.waitForIdleSync();
+ assertEquals("setListSelection(ListView.INVALID_POSITION)",
+ ListView.INVALID_POSITION, textView.getListSelection());
+ }
+
+ /** Make sure we handle an empty adapter properly */
+ @MediumTest
+ public void testPopupNavigateNoAdapter() throws Throwable {
+ AutoCompleteTextViewSimple theActivity = getActivity();
+ final AutoCompleteTextView textView = theActivity.getTextView();
+ final Instrumentation instrumentation = getInstrumentation();
+
+ // focus and type
+ textView.requestFocus();
+ instrumentation.waitForIdleSync();
+ sendKeys("A");
+
+ // No initial selection
+ assertEquals("getListSelection(-1)",
+ ListView.INVALID_POSITION, textView.getListSelection());
+
+ // check for selection position as expected
+ sendKeys("DPAD_DOWN");
+ assertEquals("getListSelection(0)", 0, textView.getListSelection());
+
+ // Now get rid of the adapter
+ runTestOnUiThread(new Runnable() {
+ public void run() {
+ textView.setAdapter((ArrayAdapter<?>) null);
+ }
+ });
+ instrumentation.waitForIdleSync();
+
+ // now try moving "down" - nothing should happen since there's no longer an adapter
+ sendKeys("DPAD_DOWN");
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/android/widget/SimpleCursorAdapterTest.java b/tests/FrameworkTest/tests/src/android/widget/SimpleCursorAdapterTest.java
new file mode 100644
index 0000000..58f4ccb
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/android/widget/SimpleCursorAdapterTest.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2008 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;
+
+import com.android.internal.database.ArrayListCursor;
+import com.google.android.collect.Lists;
+
+import android.content.Context;
+import android.database.Cursor;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+/**
+ * This is a series of tests of basic API contracts for SimpleCursorAdapter. It is
+ * incomplete and can use work.
+ *
+ * NOTE: This contract holds for underlying cursor types too and these should
+ * be extracted into a set of tests that can be run on any descendant of CursorAdapter.
+ */
+public class SimpleCursorAdapterTest extends AndroidTestCase {
+
+ String[] mFrom;
+ int[] mTo;
+ int mLayout;
+ Context mContext;
+
+ ArrayList<ArrayList> mData2x2;
+ Cursor mCursor2x2;
+
+ /**
+ * Set up basic columns and cursor for the tests
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // all the pieces needed for the various tests
+ mFrom = new String[]{"Column1", "Column2"};
+ mTo = new int[]{com.android.internal.R.id.text1, com.android.internal.R.id.text2};
+ mLayout = com.android.internal.R.layout.simple_list_item_2;
+ mContext = getContext();
+
+ // raw data for building a basic test cursor
+ mData2x2 = createTestList(2, 2);
+ mCursor2x2 = new ArrayListCursor(mFrom, mData2x2);
+ }
+
+ /**
+ * Borrowed from CursorWindowTest.java
+ */
+ private ArrayList<ArrayList> createTestList(int rows, int cols) {
+ ArrayList<ArrayList> list = Lists.newArrayList();
+ Random generator = new Random();
+
+ for (int i = 0; i < rows; i++) {
+ ArrayList<Integer> col = Lists.newArrayList();
+ list.add(col);
+ for (int j = 0; j < cols; j++) {
+ // generate random number
+ Integer r = generator.nextInt();
+ col.add(r);
+ }
+ }
+ return list;
+ }
+
+ /**
+ * Test creating with a live cursor
+ */
+ @SmallTest
+ public void testCreateLive() {
+ SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
+
+ // Now see if we can pull 2 rows from the adapter
+ assertEquals(2, ca.getCount());
+ }
+
+ /**
+ * Test creating with a null cursor
+ */
+ @SmallTest
+ public void testCreateNull() {
+ SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, null, mFrom, mTo);
+
+ // The adapter should report zero rows
+ assertEquals(0, ca.getCount());
+ }
+
+ /**
+ * Test changeCursor() with live cursor
+ */
+ @SmallTest
+ public void testChangeCursorLive() {
+ SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
+
+ // Now see if we can pull 2 rows from the adapter
+ assertEquals(2, ca.getCount());
+
+ // now put in a different cursor (5 rows)
+ ArrayList<ArrayList> data2 = createTestList(5, 2);
+ Cursor c2 = new ArrayListCursor(mFrom, data2);
+ ca.changeCursor(c2);
+
+ // Now see if we can pull 5 rows from the adapter
+ assertEquals(5, ca.getCount());
+ }
+
+ /**
+ * Test changeCursor() with null cursor
+ */
+ @SmallTest
+ public void testChangeCursorNull() {
+ SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, mCursor2x2, mFrom, mTo);
+
+ // Now see if we can pull 2 rows from the adapter
+ assertEquals(2, ca.getCount());
+
+ // now put in null
+ ca.changeCursor(null);
+
+ // The adapter should report zero rows
+ assertEquals(0, ca.getCount());
+ }
+
+ /**
+ * Test changeCursor() with differing column layout. This confirms that the Adapter can
+ * deal with cursors that have the same essential data (as defined by the original mFrom
+ * array) but it's OK if the physical structure of the cursor changes (columns rearranged).
+ */
+ @SmallTest
+ public void testChangeCursorColumns() {
+ TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, mCursor2x2,
+ mFrom, mTo);
+
+ // check columns of original - mFrom and mTo should line up
+ int[] columns = ca.getConvertedFrom();
+ assertEquals(columns[0], 0);
+ assertEquals(columns[1], 1);
+
+ // Now make a new cursor with similar data but rearrange the columns
+ String[] swappedFrom = new String[]{"Column2", "Column1"};
+ Cursor c2 = new ArrayListCursor(swappedFrom, mData2x2);
+ ca.changeCursor(c2);
+ assertEquals(2, ca.getCount());
+
+ // check columns to see if rearrangement tracked (should be swapped now)
+ columns = ca.getConvertedFrom();
+ assertEquals(columns[0], 1);
+ assertEquals(columns[1], 0);
+ }
+
+ /**
+ * Test that you can safely construct with a null cursor *and* null to/from arrays.
+ * This is new functionality added in 12/2008.
+ */
+ @SmallTest
+ public void testNullConstructor() {
+ SimpleCursorAdapter ca = new SimpleCursorAdapter(mContext, mLayout, null, null, null);
+ assertEquals(0, ca.getCount());
+ }
+
+ /**
+ * Test going from a null cursor to a non-null cursor *and* setting the to/from arrays
+ * This is new functionality added in 12/2008.
+ */
+ @SmallTest
+ public void testChangeNullToMapped() {
+ TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, null, null, null);
+ assertEquals(0, ca.getCount());
+
+ ca.changeCursorAndColumns(mCursor2x2, mFrom, mTo);
+ assertEquals(2, ca.getCount());
+
+ // check columns of original - mFrom and mTo should line up
+ int[] columns = ca.getConvertedFrom();
+ assertEquals(2, columns.length);
+ assertEquals(0, columns[0]);
+ assertEquals(1, columns[1]);
+ int[] viewIds = ca.getTo();
+ assertEquals(2, viewIds.length);
+ assertEquals(com.android.internal.R.id.text1, viewIds[0]);
+ assertEquals(com.android.internal.R.id.text2, viewIds[1]);
+ }
+
+ /**
+ * Test going from one mapping to a different mapping
+ * This is new functionality added in 12/2008.
+ */
+ @SmallTest
+ public void testChangeMapping() {
+ TestSimpleCursorAdapter ca = new TestSimpleCursorAdapter(mContext, mLayout, mCursor2x2,
+ mFrom, mTo);
+ assertEquals(2, ca.getCount());
+
+ // Now create a new configuration with same cursor and just one column mapped
+ String[] singleFrom = new String[]{"Column1"};
+ int[] singleTo = new int[]{com.android.internal.R.id.text1};
+ ca.changeCursorAndColumns(mCursor2x2, singleFrom, singleTo);
+
+ // And examine the results, make sure they're still consistent
+ int[] columns = ca.getConvertedFrom();
+ assertEquals(1, columns.length);
+ assertEquals(0, columns[0]);
+ int[] viewIds = ca.getTo();
+ assertEquals(1, viewIds.length);
+ assertEquals(com.android.internal.R.id.text1, viewIds[0]);
+
+ // And again, same cursor, different map
+ singleFrom = new String[]{"Column2"};
+ singleTo = new int[]{com.android.internal.R.id.text2};
+ ca.changeCursorAndColumns(mCursor2x2, singleFrom, singleTo);
+
+ // And examine the results, make sure they're still consistent
+ columns = ca.getConvertedFrom();
+ assertEquals(1, columns.length);
+ assertEquals(1, columns[0]);
+ viewIds = ca.getTo();
+ assertEquals(1, viewIds.length);
+ assertEquals(com.android.internal.R.id.text2, viewIds[0]);
+ }
+
+ /**
+ * This is simply a way to sneak a look at the protected mFrom() array. A more API-
+ * friendly way to do this would be to mock out a View and a ViewBinder and exercise
+ * it via those seams.
+ */
+ private static class TestSimpleCursorAdapter extends SimpleCursorAdapter {
+
+ public TestSimpleCursorAdapter(Context context, int layout, Cursor c,
+ String[] from, int[] to) {
+ super(context, layout, c, from, to);
+ }
+
+ int[] getConvertedFrom() {
+ return mFrom;
+ }
+
+ int[] getTo() {
+ return mTo;
+ }
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/AllTests.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/AllTests.java
new file mode 100644
index 0000000..e43ebb8
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/AllTests.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import android.test.suitebuilder.TestSuiteBuilder;
+
+public class AllTests extends TestSuite {
+
+ public static Test suite() {
+ return new TestSuiteBuilder(AllTests.class)
+ .includeAllPackagesUnderHere()
+ .includePackages("android.content")
+ .includePackages("android.widget")
+ .build();
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/drawable/DrawableBgMinSizeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/drawable/DrawableBgMinSizeTest.java
new file mode 100644
index 0000000..ef6297d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/drawable/DrawableBgMinSizeTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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 com.android.frameworktest.drawable;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.drawable.DrawableBgMinSize;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import android.graphics.drawable.Drawable;
+import android.test.ActivityInstrumentationTestCase;
+import android.view.View;
+import android.widget.AbsoluteLayout;
+import android.widget.Button;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+/**
+ * {@link DrawableBgMinSize} exercises Views to obey their background drawable's
+ * minimum sizes.
+ */
+public class DrawableBgMinSizeTest extends
+ ActivityInstrumentationTestCase<DrawableBgMinSize> {
+ private Button mChangeBackgroundsButton;
+
+ private Drawable mBackgroundDrawable;
+ private Drawable mBigBackgroundDrawable;
+
+ private TextView mTextView;
+ private LinearLayout mLinearLayout;
+ private RelativeLayout mRelativeLayout;
+ private FrameLayout mFrameLayout;
+ private AbsoluteLayout mAbsoluteLayout;
+
+ public DrawableBgMinSizeTest() {
+ super("com.android.frameworktest", DrawableBgMinSize.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final DrawableBgMinSize a = getActivity();
+
+ mChangeBackgroundsButton = (Button) a.findViewById(R.id.change_backgrounds);
+ mBackgroundDrawable = a.getResources().getDrawable(R.drawable.drawable_background);
+ mBigBackgroundDrawable = a.getResources().getDrawable(R.drawable.big_drawable_background);
+ mTextView = (TextView) a.findViewById(R.id.text_view);
+ mLinearLayout = (LinearLayout) a.findViewById(R.id.linear_layout);
+ mRelativeLayout = (RelativeLayout) a.findViewById(R.id.relative_layout);
+ mFrameLayout = (FrameLayout) a.findViewById(R.id.frame_layout);
+ mAbsoluteLayout = (AbsoluteLayout) a.findViewById(R.id.absolute_layout);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mChangeBackgroundsButton);
+ assertNotNull(mBackgroundDrawable);
+ assertNotNull(mBigBackgroundDrawable);
+ assertNotNull(mTextView);
+ assertNotNull(mLinearLayout);
+ assertNotNull(mRelativeLayout);
+ assertNotNull(mFrameLayout);
+ assertNotNull(mAbsoluteLayout);
+ }
+
+ public void doMinimumSizeTest(View view) throws Exception {
+ assertTrue(view.getClass().getSimpleName() + " should respect the background Drawable's minimum width",
+ view.getWidth() >= mBackgroundDrawable.getMinimumWidth());
+ assertTrue(view.getClass().getSimpleName() + " should respect the background Drawable's minimum height",
+ view.getHeight() >= mBackgroundDrawable.getMinimumHeight());
+ }
+
+ @MediumTest
+ public void testTextViewMinimumSize() throws Exception {
+ doMinimumSizeTest(mTextView);
+ }
+
+ @MediumTest
+ public void testLinearLayoutMinimumSize() throws Exception {
+ doMinimumSizeTest(mLinearLayout);
+ }
+
+ @MediumTest
+ public void testRelativeLayoutMinimumSize() throws Exception {
+ doMinimumSizeTest(mRelativeLayout);
+ }
+
+ @MediumTest
+ public void testAbsoluteLayoutMinimumSize() throws Exception {
+ doMinimumSizeTest(mAbsoluteLayout);
+ }
+
+ @MediumTest
+ public void testFrameLayoutMinimumSize() throws Exception {
+ doMinimumSizeTest(mFrameLayout);
+ }
+
+ public void doDiffBgMinimumSizeTest(final View view) throws Exception {
+ // Change to the bigger backgrounds
+ TouchUtils.tapView(this, mChangeBackgroundsButton);
+
+ assertTrue(view.getClass().getSimpleName()
+ + " should respect the different bigger background Drawable's minimum width", view
+ .getWidth() >= mBigBackgroundDrawable.getMinimumWidth());
+ assertTrue(view.getClass().getSimpleName()
+ + " should respect the different bigger background Drawable's minimum height", view
+ .getHeight() >= mBigBackgroundDrawable.getMinimumHeight());
+ }
+
+ @MediumTest
+ public void testTextViewDiffBgMinimumSize() throws Exception {
+ doDiffBgMinimumSizeTest(mTextView);
+ }
+
+ @MediumTest
+ public void testLinearLayoutDiffBgMinimumSize() throws Exception {
+ doDiffBgMinimumSizeTest(mLinearLayout);
+ }
+
+ @MediumTest
+ public void testRelativeLayoutDiffBgMinimumSize() throws Exception {
+ doDiffBgMinimumSizeTest(mRelativeLayout);
+ }
+
+ @MediumTest
+ public void testAbsoluteLayoutDiffBgMinimumSize() throws Exception {
+ doDiffBgMinimumSizeTest(mAbsoluteLayout);
+ }
+
+ @MediumTest
+ public void testFrameLayoutDiffBgMinimumSize() throws Exception {
+ doDiffBgMinimumSizeTest(mFrameLayout);
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/drawable/MutateDrawableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/drawable/MutateDrawableTest.java
new file mode 100644
index 0000000..53085ca
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/drawable/MutateDrawableTest.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2009 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 com.android.frameworktest.drawable;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+
+public class MutateDrawableTest extends ActivityInstrumentationTestCase2<MutateDrawable> {
+ private View mFirstButton;
+ private View mSecondButton;
+
+ public MutateDrawableTest() {
+ super("com.android.frameworktest", MutateDrawable.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mFirstButton = getActivity().findViewById(com.android.frameworktest.R.id.a);
+ mSecondButton = getActivity().findViewById(com.android.frameworktest.R.id.b);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mFirstButton);
+ assertNotNull(mSecondButton);
+ assertNotSame(mFirstButton.getBackground(), mSecondButton.getBackground());
+ }
+
+ @MediumTest
+ public void testDrawableCanMutate() throws Exception {
+ assertNotSame(mFirstButton.getBackground().getConstantState(),
+ mSecondButton.getBackground().getConstantState());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListBasicTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListBasicTest.java
new file mode 100644
index 0000000..163e084
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListBasicTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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 com.android.frameworktest.expandablelistview;
+
+import com.android.frameworktest.expandablelistview.ExpandableListSimple;
+import com.android.frameworktest.util.ExpandableListScenario;
+import com.android.frameworktest.util.ListUtil;
+import com.android.frameworktest.util.ExpandableListScenario.MyGroup;
+
+import java.util.List;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.BaseExpandableListAdapter;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+
+public class ExpandableListBasicTest extends ActivityInstrumentationTestCase<ExpandableListSimple> {
+ private ExpandableListScenario mActivity;
+ private ExpandableListView mListView;
+ private ExpandableListAdapter mAdapter;
+ private ListUtil mListUtil;
+
+ public ExpandableListBasicTest() {
+ super("com.android.frameworktest",
+ ExpandableListSimple.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = mActivity.getExpandableListView();
+ mAdapter = mListView.getExpandableListAdapter();
+ mListUtil = new ListUtil(mListView, getInstrumentation());
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ }
+
+ private int expandGroup(int numChildren, boolean atLeastOneChild) {
+ final int groupPos = mActivity.findGroupWithNumChildren(numChildren, atLeastOneChild);
+
+ assertTrue("Could not find group to expand", groupPos >= 0);
+ assertFalse("Group is already expanded", mListView.isGroupExpanded(groupPos));
+ mListUtil.arrowScrollToSelectedPosition(groupPos);
+ getInstrumentation().waitForIdleSync();
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+ assertTrue("Group did not expand", mListView.isGroupExpanded(groupPos));
+
+ return groupPos;
+ }
+
+ @MediumTest
+ public void testExpandGroup() {
+ expandGroup(-1, true);
+ }
+
+ @MediumTest
+ public void testCollapseGroup() {
+ final int groupPos = expandGroup(-1, true);
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+ assertFalse("Group did not collapse", mListView.isGroupExpanded(groupPos));
+ }
+
+ @MediumTest
+ public void testExpandedGroupMovement() {
+
+ // Expand the first group
+ mListUtil.arrowScrollToSelectedPosition(0);
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+
+ // Ensure it expanded
+ assertTrue("Group did not expand", mListView.isGroupExpanded(0));
+
+ // Wait until that's all good
+ getInstrumentation().waitForIdleSync();
+
+ // Make sure it expanded
+ assertTrue("Group did not expand", mListView.isGroupExpanded(0));
+
+ // Insert a collapsed group in front of the one just expanded
+ List<MyGroup> groups = mActivity.getGroups();
+ MyGroup insertedGroup = new MyGroup(1);
+ groups.add(0, insertedGroup);
+
+ // Notify data change
+ assertTrue("Adapter is not an instance of the base adapter",
+ mAdapter instanceof BaseExpandableListAdapter);
+ final BaseExpandableListAdapter adapter = (BaseExpandableListAdapter) mAdapter;
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ adapter.notifyDataSetChanged();
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ // Make sure the right group is expanded
+ assertTrue("The expanded state didn't stay with the proper group",
+ mListView.isGroupExpanded(1));
+ assertFalse("The expanded state was given to the inserted group",
+ mListView.isGroupExpanded(0));
+ }
+
+}
\ No newline at end of file
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeadersTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeadersTest.java
new file mode 100644
index 0000000..49b5106
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/expandablelistview/ExpandableListWithHeadersTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.android.frameworktest.expandablelistview;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.ExpandableListView;
+
+import com.android.frameworktest.expandablelistview.ExpandableListWithHeaders;
+import com.android.frameworktest.util.ListUtil;
+
+public class ExpandableListWithHeadersTest extends ActivityInstrumentationTestCase<ExpandableListWithHeaders> {
+ private ExpandableListView mExpandableListView;
+ private ListUtil mListUtil;
+
+ public ExpandableListWithHeadersTest() {
+ super("com.android.frameworktest",
+ ExpandableListWithHeaders.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mExpandableListView = getActivity().getExpandableListView();
+ mListUtil = new ListUtil(mExpandableListView, getInstrumentation());
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mExpandableListView);
+ }
+
+ @MediumTest
+ public void testExpandOnFirstPosition() {
+ // Should be a header, and hence the first group should NOT have expanded
+ mListUtil.arrowScrollToSelectedPosition(0);
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+ assertFalse(mExpandableListView.isGroupExpanded(0));
+ }
+
+ @LargeTest
+ public void testExpandOnFirstGroup() {
+ mListUtil.arrowScrollToSelectedPosition(getActivity().getNumOfHeadersAndFooters());
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+ assertTrue(mExpandableListView.isGroupExpanded(0));
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/DescendantFocusabilityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/DescendantFocusabilityTest.java
new file mode 100644
index 0000000..6bdd416
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/DescendantFocusabilityTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.DescendantFocusability;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.UiThreadTest;
+import android.test.TouchUtils;
+import android.view.ViewGroup;
+
+public class DescendantFocusabilityTest extends ActivityInstrumentationTestCase<DescendantFocusability> {
+
+ private DescendantFocusability a;
+
+ public DescendantFocusabilityTest() {
+ super("com.android.frameworktest", DescendantFocusability.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ a = getActivity();
+
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals(ViewGroup.FOCUS_BEFORE_DESCENDANTS,
+ a.beforeDescendants.getDescendantFocusability());
+ assertEquals(ViewGroup.FOCUS_AFTER_DESCENDANTS,
+ a.afterDescendants.getDescendantFocusability());
+ assertEquals(ViewGroup.FOCUS_BLOCK_DESCENDANTS,
+ a.blocksDescendants.getDescendantFocusability());
+
+ assertTrue(a.beforeDescendantsChild.isFocusable());
+ assertTrue(a.afterDescendantsChild.isFocusable());
+ assertTrue(a.blocksDescendantsChild.isFocusable());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testBeforeDescendants() {
+ a.beforeDescendants.setFocusable(true);
+
+ assertTrue(a.beforeDescendants.requestFocus());
+ assertTrue(a.beforeDescendants.isFocused());
+
+ a.beforeDescendants.setFocusable(false);
+ a.beforeDescendants.requestFocus();
+ assertTrue(a.beforeDescendantsChild.isFocused());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testAfterDescendants() {
+ a.afterDescendants.setFocusable(true);
+
+ assertTrue(a.afterDescendants.requestFocus());
+ assertTrue(a.afterDescendantsChild.isFocused());
+
+ a.afterDescendants.setFocusable(false);
+ assertTrue(a.afterDescendants.requestFocus());
+ assertTrue(a.afterDescendantsChild.isFocused());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testBlocksDescendants() {
+ a.blocksDescendants.setFocusable(true);
+ assertTrue(a.blocksDescendants.requestFocus());
+ assertTrue(a.blocksDescendants.isFocused());
+ assertFalse(a.blocksDescendantsChild.isFocused());
+
+ a.blocksDescendants.setFocusable(false);
+ assertFalse(a.blocksDescendants.requestFocus());
+ assertFalse(a.blocksDescendants.isFocused());
+ assertFalse(a.blocksDescendantsChild.isFocused());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testChildOfDescendantBlockerRequestFocusFails() {
+ assertFalse(a.blocksDescendantsChild.requestFocus());
+ }
+
+ @LargeTest
+ public void testBeforeDescendantsEnterTouchMode() {
+ a.runOnUiThread(new Runnable() {
+ public void run() {
+ a.beforeDescendants.setFocusableInTouchMode(true);
+ a.beforeDescendantsChild.requestFocus();
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ assertTrue(a.beforeDescendantsChild.isFocused());
+ assertFalse(a.beforeDescendantsChild.isInTouchMode());
+
+ TouchUtils.clickView(this, a.beforeDescendantsChild);
+ assertTrue(a.beforeDescendantsChild.isInTouchMode());
+ assertFalse(a.beforeDescendants.isFocused());
+ }
+
+ @LargeTest
+ public void testAfterDescendantsEnterTouchMode() {
+ a.runOnUiThread(new Runnable() {
+ public void run() {
+ a.afterDescendants.setFocusableInTouchMode(true);
+ a.afterDescendantsChild.requestFocus();
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ assertTrue(a.afterDescendantsChild.isFocused());
+ assertFalse(a.afterDescendantsChild.isInTouchMode());
+
+ TouchUtils.clickView(this, a.afterDescendantsChild);
+ assertTrue(a.afterDescendantsChild.isInTouchMode());
+ assertTrue(a.afterDescendants.isFocused());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/FocusAfterRemovalTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/FocusAfterRemovalTest.java
new file mode 100644
index 0000000..8fb9b01
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/FocusAfterRemovalTest.java
@@ -0,0 +1,131 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.FocusAfterRemoval;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.view.KeyEvent;
+import android.view.View;
+
+/**
+ * {@link FocusAfterRemoval} is set up to exercise cases where the views that
+ * have focus become invisible or GONE.
+ */
+public class FocusAfterRemovalTest extends ActivityInstrumentationTestCase<FocusAfterRemoval> {
+
+ private LinearLayout mLeftLayout;
+ private Button mTopLeftButton;
+ private Button mBottomLeftButton;
+ private Button mTopRightButton;
+ private Button mBottomRightButton;
+
+ public FocusAfterRemovalTest() {
+ super("com.android.frameworktest", FocusAfterRemoval.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final FocusAfterRemoval a = getActivity();
+ mLeftLayout = (LinearLayout) a.findViewById(R.id.leftLayout);
+ mTopLeftButton = (Button) a.findViewById(R.id.topLeftButton);
+ mBottomLeftButton = (Button) a.findViewById(R.id.bottomLeftButton);
+ mTopRightButton = (Button) a.findViewById(R.id.topRightButton);
+ mBottomRightButton = (Button) a.findViewById(R.id.bottomRightButton);
+ }
+
+ // Test that setUp did what we expect it to do. These asserts
+ // can't go in SetUp, or the test will hang.
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mLeftLayout);
+ assertNotNull(mTopLeftButton);
+ assertNotNull(mTopRightButton);
+ assertNotNull(mBottomLeftButton);
+ assertNotNull(mBottomRightButton);
+
+ assertTrue(mTopLeftButton.hasFocus());
+ }
+
+ // if a parent layout becomes GONE when one of its children has focus,
+ // make sure the focus moves to something visible (bug 827087)
+ @MediumTest
+ public void testFocusLeavesWhenParentLayoutIsGone() throws Exception {
+
+ // clicking on this button makes its parent linear layout GONE
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ assertEquals(View.GONE, mLeftLayout.getVisibility());
+
+ assertTrue("focus should jump to visible button",
+ mTopRightButton.hasFocus());
+
+ }
+
+ @MediumTest
+ public void testFocusLeavesWhenParentLayoutInvisible() throws Exception {
+
+ // move down to bottom left button
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertTrue(mBottomLeftButton.hasFocus());
+
+ // clicking on this button makes its parent linear layout INVISIBLE
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ assertEquals(View.INVISIBLE,
+ getActivity().findViewById(R.id.leftLayout).getVisibility());
+
+ assertTrue("focus should jump to visible button",
+ mTopRightButton.hasFocus());
+ }
+
+ @MediumTest
+ public void testFocusLeavesWhenFocusedViewBecomesGone() throws Exception {
+
+ // move to top right
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+ assertTrue(mTopRightButton.hasFocus());
+
+ // click making it GONE
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ assertEquals(View.GONE, mTopRightButton.getVisibility());
+
+ assertTrue("focus should jump to visible button",
+ mTopLeftButton.hasFocus());
+ }
+
+ @MediumTest
+ public void testFocusLeavesWhenFocusedViewBecomesInvisible() throws Exception {
+
+ // move to bottom right
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertTrue(mBottomRightButton.hasFocus());
+
+ // click making it INVISIBLE
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ assertEquals(View.INVISIBLE, mBottomRightButton.getVisibility());
+
+ assertTrue("focus should jump to visible button",
+ mTopLeftButton.hasFocus());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/FocusChangeWithInterestingRectHintTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/FocusChangeWithInterestingRectHintTest.java
new file mode 100644
index 0000000..6bdb1ca
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/FocusChangeWithInterestingRectHintTest.java
@@ -0,0 +1,114 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.AdjacentVerticalRectLists;
+import com.android.frameworktest.util.InternalSelectionView;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+
+/**
+ * {@link android.view.FocusFinder#findNextFocus(android.view.ViewGroup, android.view.View, int)}
+ * and
+ * {@link android.view.View#requestFocus(int, android.graphics.Rect)}
+ * work together to give a newly focused item a hint about the most interesting
+ * rectangle of the previously focused view. The view taking focus can use this
+ * to set an internal selection more appropriate using this rect.
+ *
+ * This tests that behavior using three adjacent {@link com.android.frameworktest.util.InternalSelectionView}
+ * that report interesting rects when giving up focus, and use interesting rects
+ * when taking focus to best select the internal row to show as selected.
+ *
+ */
+public class FocusChangeWithInterestingRectHintTest extends ActivityInstrumentationTestCase<AdjacentVerticalRectLists> {
+
+ private InternalSelectionView mLeftColumn;
+ private InternalSelectionView mMiddleColumn;
+ private InternalSelectionView mRightColumn;
+
+ public FocusChangeWithInterestingRectHintTest() {
+ super("com.android.frameworktest", AdjacentVerticalRectLists.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mLeftColumn = getActivity().getLeftColumn();
+ mMiddleColumn = getActivity().getMiddleColumn();
+ mRightColumn = getActivity().getRightColumn();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mLeftColumn);
+ assertNotNull(mMiddleColumn);
+ assertNotNull(mRightColumn);
+ assertTrue(mLeftColumn.hasFocus());
+ assertTrue("need at least 3 rows", mLeftColumn.getNumRows() > 2);
+ assertEquals(mLeftColumn.getNumRows(), mMiddleColumn.getNumRows());
+ assertEquals(mMiddleColumn.getNumRows(), mRightColumn.getNumRows());
+ }
+
+
+ @LargeTest
+ public void testSnakeBackAndForth() {
+ final int numRows = mLeftColumn.getNumRows();
+ for (int row = 0; row < numRows; row++) {
+
+ if ((row % 2) == 0) {
+ assertEquals("row " + row + ": should be at left column",
+ row, mLeftColumn.getSelectedRow());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+ assertTrue("row " + row + ": should be at middle column",
+ mMiddleColumn.hasFocus());
+ assertEquals(row, mMiddleColumn.getSelectedRow());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+ assertTrue("row " + row + ": should be at right column",
+ mRightColumn.hasFocus());
+ assertEquals(row, mRightColumn.getSelectedRow());
+
+ if (row < numRows - 1) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(row + 1, mRightColumn.getSelectedRow());
+ }
+ } else {
+ assertTrue("row " + row + ": should be at right column",
+ mRightColumn.hasFocus());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
+ assertTrue("row " + row + ": should be at middle column",
+ mMiddleColumn.hasFocus());
+ assertEquals(row, mMiddleColumn.getSelectedRow());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
+ assertEquals("row " + row + ": should be at left column",
+ row, mLeftColumn.getSelectedRow());
+
+ if (row < numRows - 1) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(row + 1, mLeftColumn.getSelectedRow());
+ }
+ }
+ }
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/GoneParentFocusedChildTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/GoneParentFocusedChildTest.java
new file mode 100644
index 0000000..a490322
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/GoneParentFocusedChildTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import com.android.frameworktest.focus.GoneParentFocusedChild;
+
+/**
+ * When a parent is GONE, key events shouldn't go to its children, even if they
+ * have focus. (part of investigation into issue 945150).
+ */
+public class GoneParentFocusedChildTest
+ extends ActivityInstrumentationTestCase<GoneParentFocusedChild> {
+
+
+ public GoneParentFocusedChildTest() {
+ super("com.android.frameworktest", GoneParentFocusedChild.class);
+ }
+
+ @MediumTest
+ public void testPreconditinos() {
+ assertNotNull(getActivity().getLayout());
+ assertNotNull(getActivity().getGoneGroup());
+ assertNotNull(getActivity().getButton());
+ assertTrue("button should have focus",
+ getActivity().getButton().hasFocus());
+ assertEquals("gone group should be, well, gone!",
+ View.GONE,
+ getActivity().getGoneGroup().getVisibility());
+ assertFalse("the activity should have received no key events",
+ getActivity().isUnhandledKeyEvent());
+ }
+
+ @MediumTest
+ public void testKeyEventGoesToActivity() {
+ sendKeys(KeyEvent.KEYCODE_J);
+ assertTrue(getActivity().isUnhandledKeyEvent());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/HorizontalFocusSearchTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/HorizontalFocusSearchTest.java
new file mode 100644
index 0000000..ca7cd7e
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/HorizontalFocusSearchTest.java
@@ -0,0 +1,124 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.HorizontalFocusSearch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.Suppress;
+import android.widget.LinearLayout;
+import android.widget.Button;
+import android.view.View;
+
+import static com.android.frameworktest.focus.VerticalFocusSearchTest.FocusSearchAlg;
+import static com.android.frameworktest.focus.VerticalFocusSearchTest.NewFocusSearchAlg;
+
+/**
+ * Tests that focus searching works on a horizontal linear layout of buttons of
+ * various widths and vertical placements.
+ */
+// Suppress until bug http://b/issue?id=1416545 is fixed.
+@Suppress
+public class HorizontalFocusSearchTest extends ActivityInstrumentationTestCase<HorizontalFocusSearch> {
+
+ private FocusSearchAlg mFocusFinder;
+
+ private LinearLayout mLayout;
+ private Button mLeftTall;
+ private Button mMidShort1Top;
+ private Button mMidShort2Bottom;
+ private Button mRightTall;
+
+
+ public HorizontalFocusSearchTest() {
+ super("com.android.frameworktest", HorizontalFocusSearch.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mFocusFinder = new NewFocusSearchAlg();
+
+ mLayout = getActivity().getLayout();
+ mLeftTall = getActivity().getLeftTall();
+ mMidShort1Top = getActivity().getMidShort1Top();
+ mMidShort2Bottom = getActivity().getMidShort2Bottom();
+ mRightTall = getActivity().getRightTall();
+ }
+
+ public void testPreconditions() {
+ assertNotNull(mLayout);
+ assertNotNull(mLeftTall);
+ assertNotNull(mMidShort1Top);
+ assertNotNull(mMidShort2Bottom);
+ assertNotNull(mRightTall);
+ }
+
+ public void testSearchFromLeftButton() {
+ assertNull("going up from mLeftTall",
+ mFocusFinder.findNextFocus(mLayout, mLeftTall, View.FOCUS_UP));
+ assertNull("going down from mLeftTall",
+ mFocusFinder.findNextFocus(mLayout, mLeftTall, View.FOCUS_DOWN));
+ assertNull("going left from mLeftTall",
+ mFocusFinder.findNextFocus(mLayout, mLeftTall, View.FOCUS_LEFT));
+
+ assertEquals("going right from mLeftTall",
+ mMidShort1Top,
+ mFocusFinder.findNextFocus(mLayout, mLeftTall, View.FOCUS_RIGHT));
+ }
+
+ public void TODO_testSearchFromMiddleLeftButton() {
+ assertNull("going up from mMidShort1Top",
+ mFocusFinder.findNextFocus(mLayout, mMidShort1Top, View.FOCUS_UP));
+ assertEquals("going down from mMidShort1Top",
+ mMidShort2Bottom,
+ mFocusFinder.findNextFocus(mLayout, mMidShort1Top, View.FOCUS_DOWN));
+ assertEquals("going left from mMidShort1Top",
+ mLeftTall,
+ mFocusFinder.findNextFocus(mLayout, mMidShort1Top, View.FOCUS_LEFT));
+ assertEquals("going right from mMidShort1Top",
+ mMidShort2Bottom,
+ mFocusFinder.findNextFocus(mLayout, mMidShort1Top, View.FOCUS_RIGHT));
+ }
+
+ public void TODO_testSearchFromMiddleRightButton() {
+ assertEquals("going up from mMidShort2Bottom",
+ mMidShort1Top,
+ mFocusFinder.findNextFocus(mLayout, mMidShort2Bottom, View.FOCUS_UP));
+ assertNull("going down from mMidShort2Bottom",
+ mFocusFinder.findNextFocus(mLayout, mMidShort2Bottom, View.FOCUS_DOWN));
+ assertEquals("going left from mMidShort2Bottom",
+ mMidShort1Top,
+ mFocusFinder.findNextFocus(mLayout, mMidShort2Bottom, View.FOCUS_LEFT));
+ assertEquals("goind right from mMidShort2Bottom",
+ mRightTall,
+ mFocusFinder.findNextFocus(mLayout, mMidShort2Bottom, View.FOCUS_RIGHT));
+ }
+
+ public void testSearchFromRightButton() {
+ assertNull("going up from mRightTall",
+ mFocusFinder.findNextFocus(mLayout, mRightTall, View.FOCUS_UP));
+ assertNull("going down from mRightTall",
+ mFocusFinder.findNextFocus(mLayout, mRightTall, View.FOCUS_DOWN));
+ assertEquals("going left from mRightTall",
+ mMidShort2Bottom,
+ mFocusFinder.findNextFocus(mLayout, mRightTall, View.FOCUS_LEFT));
+ assertNull("going right from mRightTall",
+ mFocusFinder.findNextFocus(mLayout, mRightTall, View.FOCUS_RIGHT));
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/LinearLayoutGridTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/LinearLayoutGridTest.java
new file mode 100644
index 0000000..c26c331
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/LinearLayoutGridTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.test.SingleLaunchActivityTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.FocusFinder;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.frameworktest.focus.LinearLayoutGrid;
+
+/**
+ * Tests focus searching between buttons within a grid that are touching, for example,
+ * two buttons next two each other would have the left button's right equal to the
+ * right button's left. Same goes for top and bottom edges.
+ *
+ * This exercises some edge cases of {@link android.view.FocusFinder}.
+ */
+public class LinearLayoutGridTest extends SingleLaunchActivityTestCase<LinearLayoutGrid> {
+ private ViewGroup mRootView;
+
+ public LinearLayoutGridTest() {
+ super("com.android.frameworktest", LinearLayoutGrid.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mRootView = getActivity().getRootView();
+ }
+
+ @MediumTest
+ public void testGoDownFromMiddle() {
+ assertEquals(getActivity().getButtonAt(2, 1),
+ FocusFinder.getInstance().findNextFocus(
+ mRootView,
+ getActivity().getButtonAt(1, 1),
+ View.FOCUS_DOWN));
+ }
+
+ @MediumTest
+ public void testGoUpFromMiddle() {
+ assertEquals(getActivity().getButtonAt(0, 1),
+ FocusFinder.getInstance().findNextFocus(
+ mRootView,
+ getActivity().getButtonAt(1, 1),
+ View.FOCUS_UP));
+ }
+
+ @MediumTest
+ public void testGoRightFromMiddle() {
+ assertEquals(getActivity().getButtonAt(1, 2),
+ FocusFinder.getInstance().findNextFocus(
+ mRootView,
+ getActivity().getButtonAt(1, 1),
+ View.FOCUS_RIGHT));
+ }
+
+ @MediumTest
+ public void testGoLeftFromMiddle() {
+ assertEquals(getActivity().getButtonAt(1, 0),
+ FocusFinder.getInstance().findNextFocus(
+ mRootView,
+ getActivity().getButtonAt(1, 1),
+ View.FOCUS_LEFT));
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ListOfButtonsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ListOfButtonsTest.java
new file mode 100644
index 0000000..902fc1c
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ListOfButtonsTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.ListOfButtons;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListAdapter;
+import android.widget.Button;
+import android.widget.ListView;
+import android.view.KeyEvent;
+import android.view.View;
+
+/**
+ * Tests that focus works as expected when navigating into and out of
+ * a {@link ListView} that has buttons in it.
+ */
+public class ListOfButtonsTest extends ActivityInstrumentationTestCase<ListOfButtons> {
+
+ private ListAdapter mListAdapter;
+ private Button mButtonAtTop;
+
+ private ListView mListView;
+
+ public ListOfButtonsTest() {
+ super("com.android.frameworktest", ListOfButtons.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ ListOfButtons a = getActivity();
+ mListAdapter = a.getListAdapter();
+ mButtonAtTop = (Button) a.findViewById(R.id.button);
+ mListView = a.getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mListAdapter);
+ assertNotNull(mButtonAtTop);
+ assertNotNull(mListView);
+
+ assertFalse(mButtonAtTop.hasFocus());
+ assertTrue(mListView.hasFocus());
+ assertEquals("expecting 0 index to be selected",
+ 0, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testNavigateToButtonAbove() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+ assertTrue(mButtonAtTop.hasFocus());
+ assertFalse(mListView.hasFocus());
+ }
+
+ @MediumTest
+ public void testNavigateToSecondItem() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertTrue(mListView.hasFocus());
+
+ View childOne = mListView.getChildAt(1);
+ assertNotNull(childOne);
+ assertEquals(childOne, mListView.getFocusedChild());
+ assertTrue(childOne.hasFocus());
+ }
+
+ @MediumTest
+ public void testNavigateUpAboveAndBackOut() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertFalse("button at top should have focus back",
+ mButtonAtTop.hasFocus());
+ assertTrue(mListView.hasFocus());
+ }
+
+ // TODO: this reproduces bug 981791
+ public void TODO_testNavigateThroughAllButtonsAndBack() {
+
+ String[] labels = getActivity().getLabels();
+ for (int i = 0; i < labels.length; i++) {
+ String label = labels[i];
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+
+ String indexInfo = "index: " + i + ", label: " + label;
+
+ assertTrue(indexInfo, mListView.hasFocus());
+
+ Button button = (Button) mListView.getSelectedView();
+ assertNotNull(indexInfo, button);
+ assertEquals(indexInfo, label, button.getText().toString());
+ assertTrue(indexInfo, button.hasFocus());
+ }
+
+ // pressing down again shouldn't matter; make sure last item keeps focus
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+
+ for (int i = labels.length - 1; i >= 0; i--) {
+ String label = labels[i];
+
+ String indexInfo = "index: " + i + ", label: " + label;
+
+ assertTrue(indexInfo, mListView.hasFocus());
+
+ Button button = (Button) mListView.getSelectedView();
+ assertNotNull(indexInfo, button);
+ assertEquals(indexInfo, label, button.getText().toString());
+ assertTrue(indexInfo, button.hasFocus());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ getInstrumentation().waitForIdleSync();
+ }
+
+ assertTrue("button at top should have focus back",
+ mButtonAtTop.hasFocus());
+ assertFalse(mListView.hasFocus());
+ }
+
+ @MediumTest
+ public void testGoInAndOutOfListWithItemsFocusable() {
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+ assertTrue(mButtonAtTop.hasFocus());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ final String firstButtonLabel = getActivity().getLabels()[0];
+ final Button firstButton = (Button) mListView.getSelectedView();
+
+ assertTrue(firstButton.isFocused());
+ assertEquals(firstButtonLabel, firstButton.getText());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertTrue(mButtonAtTop.isFocused());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertTrue(firstButton.isFocused());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertTrue(mButtonAtTop.isFocused());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertTrue(firstButton.isFocused());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ListWithFooterViewAndNewLabelsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ListWithFooterViewAndNewLabelsTest.java
new file mode 100644
index 0000000..c094882
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ListWithFooterViewAndNewLabelsTest.java
@@ -0,0 +1,72 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.ListWithFooterViewAndNewLabels;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.widget.Button;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+public class ListWithFooterViewAndNewLabelsTest
+ extends ActivityInstrumentationTestCase<ListWithFooterViewAndNewLabels> {
+
+ private Button mButton;
+
+ private ListAdapter mAdapter;
+
+ private ListView mListView;
+
+
+ public ListWithFooterViewAndNewLabelsTest() {
+ super("com.android.frameworktest",
+ ListWithFooterViewAndNewLabels.class);
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ ListWithFooterViewAndNewLabels a = getActivity();
+ mButton = (Button) a.findViewById(R.id.button);
+ mAdapter = a.getListAdapter();
+ mListView = a.getListView();
+ }
+
+ // bug 900885
+ public void FAILING_testPreconditions() {
+ assertNotNull(mButton);
+ assertNotNull(mAdapter);
+ assertNotNull(mListView);
+
+ assertTrue(mButton.hasFocus());
+ assertEquals("expected list adapter to have 1 item",
+ 1, mAdapter.getCount());
+ assertEquals("expected list view to have 2 items (1 in adapter, plus "
+ + "the footer view).",
+ 2, mListView.getCount());
+
+ // fails here!!!
+ assertEquals("Expecting the selected index to be 0, the first non footer "
+ + "view item.",
+ 0, mListView.getSelectedItemPosition());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/RequestFocusTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/RequestFocusTest.java
new file mode 100644
index 0000000..5fb3a29
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/RequestFocusTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.RequestFocus;
+import com.android.frameworktest.R;
+
+import android.os.Handler;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+import android.util.AndroidRuntimeException;
+
+/**
+ * {@link RequestFocusTest} is set up to exercise cases where the views that
+ * have focus become invisible or GONE.
+ */
+public class RequestFocusTest extends ActivityInstrumentationTestCase<RequestFocus> {
+
+ private Button mTopLeftButton;
+ private Button mBottomLeftButton;
+ private Button mTopRightButton;
+ private Button mBottomRightButton;
+ private Handler mHandler;
+
+ public RequestFocusTest() {
+ super("com.android.frameworktest", RequestFocus.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final RequestFocus a = getActivity();
+ mHandler = a.getHandler();
+ mTopLeftButton = (Button) a.findViewById(R.id.topLeftButton);
+ mBottomLeftButton = (Button) a.findViewById(R.id.bottomLeftButton);
+ mTopRightButton = (Button) a.findViewById(R.id.topRightButton);
+ mBottomRightButton = (Button) a.findViewById(R.id.bottomRightButton);
+ }
+
+ // Test that setUp did what we expect it to do. These asserts
+ // can't go in SetUp, or the test will hang.
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mHandler);
+ assertNotNull(mTopLeftButton);
+ assertNotNull(mTopRightButton);
+ assertNotNull(mBottomLeftButton);
+ assertNotNull(mBottomRightButton);
+ assertTrue("requestFocus() should work from onCreate.", mBottomRightButton.hasFocus());
+ }
+
+ // Test that a posted requestFocus works.
+ @LargeTest
+ public void testPostedRequestFocus() throws Exception {
+ mHandler.post(new Runnable() { public void run() {
+ mBottomLeftButton.requestFocus();
+ }});
+ synchronized(this) {
+ try {
+ wait(500);
+ } catch (InterruptedException e) {
+ // Don't care.
+ }
+ }
+ assertTrue("Focus should move to bottom left", mBottomLeftButton.hasFocus());
+ }
+
+ // Test that a requestFocus from the wrong thread fails.
+ @MediumTest
+ public void testWrongThreadRequestFocusFails() throws Exception {
+ try {
+ mTopRightButton.requestFocus();
+ fail("requestFocus from wrong thread should raise exception.");
+ } catch (AndroidRuntimeException e) {
+ // Expected. The actual exception is not public, so we can't catch it.
+ assertEquals("android.view.ViewRoot$CalledFromWrongThreadException",
+ e.getClass().getName());
+ }
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java
new file mode 100644
index 0000000..07916ee
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/ScrollingThroughListOfFocusablesTest.java
@@ -0,0 +1,225 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import android.graphics.Rect;
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.ListView;
+import com.android.frameworktest.focus.ListOfInternalSelectionViews;
+import com.android.frameworktest.util.InternalSelectionView;
+
+
+/**
+ * TODO: extract base test case that launches {@link ListOfInternalSelectionViews} with
+ * bundle params.
+ */
+public class ScrollingThroughListOfFocusablesTest extends InstrumentationTestCase {
+
+ Rect mTempRect = new Rect();
+
+ private ListOfInternalSelectionViews mActivity;
+ private ListView mListView;
+
+ private int mNumItems = 4;
+ private int mNumRowsPerItem = 5;
+ private double mScreenHeightFactor = 5 /4;
+
+ @Override
+ protected void setUp() throws Exception {
+ mActivity = launchActivity(
+ "com.android.frameworktest",
+ ListOfInternalSelectionViews.class,
+ ListOfInternalSelectionViews.getBundleFor(
+ mNumItems, // 4 items
+ mNumRowsPerItem, // 5 internally selectable rows per item
+ mScreenHeightFactor)); // each item is 5 / 4 screen height tall
+ mListView = mActivity.getListView();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mActivity.finish();
+ super.tearDown();
+ }
+
+ @MediumTest
+ public void testPreconditions() throws Exception {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ assertEquals(mNumItems, mActivity.getNumItems());
+ assertEquals(mNumRowsPerItem, mActivity.getNumRowsPerItem());
+ }
+
+ @MediumTest
+ public void testScrollingDownInFirstItem() throws Exception {
+
+ for (int i = 0; i < mNumRowsPerItem; i++) {
+ assertEquals(0, mListView.getSelectedItemPosition());
+ InternalSelectionView view = mActivity.getSelectedView();
+
+ assertInternallySelectedRowOnScreen(view, i);
+
+ // move to next row
+ if (i < mNumRowsPerItem - 1) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+ }
+ }
+
+ {
+ assertEquals(0, mListView.getSelectedItemPosition());
+ InternalSelectionView view = (InternalSelectionView)
+ mListView.getSelectedView();
+
+ // 1 pixel tolerance in case height / 4 is not an even number
+ final int fadingEdge = mListView.getBottom() - mListView.getVerticalFadingEdgeLength();
+ assertTrue("bottom of view should be just above fading edge",
+ view.getBottom() >= fadingEdge - 1 &&
+ view.getBottom() <= fadingEdge);
+ }
+
+
+ // make sure fading edge is the expected view
+ {
+ assertEquals("should be a second view visible due to the fading edge",
+ 2, mListView.getChildCount());
+ InternalSelectionView peekingChild = (InternalSelectionView)
+ mListView.getChildAt(1);
+ assertNotNull(peekingChild);
+ assertEquals("wrong value for peeking list item",
+ mActivity.getLabelForPosition(1), peekingChild.getLabel());
+ }
+ }
+
+
+ @MediumTest
+ public void testScrollingToSecondItem() throws Exception {
+
+ for (int i = 0; i < mNumRowsPerItem; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+ }
+
+ assertEquals("should have moved to second item",
+ 1, mListView.getSelectedItemPosition());
+ }
+
+ @LargeTest
+ public void testNoFadingEdgeAtBottomOfLastItem() {
+
+ // move down to last item
+ for (int i = 0; i < mNumItems; i++) {
+ for (int j = 0; j < mNumRowsPerItem; j++) {
+ if (i < mNumItems - 1 || j < mNumRowsPerItem - 1) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+ }
+ }
+ }
+
+ assertEquals(mNumItems - 1, mListView.getSelectedItemPosition());
+ InternalSelectionView view = mActivity.getSelectedView();
+ assertEquals(mNumRowsPerItem - 1, view.getSelectedRow());
+
+ view.getRectForRow(mTempRect, mNumRowsPerItem - 1);
+ mListView.offsetDescendantRectToMyCoords(view, mTempRect);
+
+ assertTrue("bottom of last row of last item should be at " +
+ "the bottom of the list view (no fading edge)",
+ mListView.getBottom() - mListView.getVerticalFadingEdgeLength() < mTempRect.bottom);
+ }
+
+ @LargeTest
+ public void testNavigatingUpThroughInternalSelection() throws Exception {
+
+ // get to bottom of second item
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < mNumRowsPerItem; j++) {
+ if (i < 1 || j < mNumRowsPerItem - 1) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+ }
+ }
+ }
+
+
+ // (make sure we are at last row of second item)
+ {
+ assertEquals(1, mListView.getSelectedItemPosition());
+ InternalSelectionView view = mActivity.getSelectedView();
+ assertEquals(mNumRowsPerItem - 1, view.getSelectedRow());
+ }
+
+ // go back up to the top of the second item
+ for (int i = mNumRowsPerItem - 1; i >= 0; i--) {
+ assertEquals(1, mListView.getSelectedItemPosition());
+ InternalSelectionView view = mActivity.getSelectedView();
+
+ assertInternallySelectedRowOnScreen(view, i);
+
+ // move up to next row
+ if (i > 0) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ getInstrumentation().waitForIdleSync();
+ }
+ }
+
+ // now we are at top row, should have caused scrolling, and fading edge...
+ {
+ assertEquals(1, mListView.getSelectedItemPosition());
+ InternalSelectionView view = mActivity.getSelectedView();
+ assertEquals(0, view.getSelectedRow());
+
+ view.getDrawingRect(mTempRect);
+ mListView.offsetDescendantRectToMyCoords(view, mTempRect);
+ assertEquals("top of selected row should be just below top vertical fading edge",
+ mListView.getVerticalFadingEdgeLength(),
+ view.getTop());
+ }
+
+ // make sure fading edge is the view we expect
+ {
+ final InternalSelectionView view =
+ (InternalSelectionView) mListView.getChildAt(0);
+ assertEquals(mActivity.getLabelForPosition(0), view.getLabel());
+ }
+
+
+ }
+
+ /**
+ * @param internalFocused The view to check
+ * @param row
+ */
+ private void assertInternallySelectedRowOnScreen(
+ InternalSelectionView internalFocused,
+ int row) {
+ assertEquals("expecting selected row",
+ row, internalFocused.getSelectedRow());
+
+ internalFocused.getRectForRow(mTempRect, row);
+ mListView.offsetDescendantRectToMyCoords(internalFocused, mTempRect);
+
+ assertTrue("top of row " + row + " should be on sreen",
+ mTempRect.top >= 0);
+ assertTrue("bottom of row " + row + " should be on sreen",
+ mTempRect.bottom < mActivity.getScreenHeight());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/VerticalFocusSearchTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/VerticalFocusSearchTest.java
new file mode 100644
index 0000000..47a81fb
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/focus/VerticalFocusSearchTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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 com.android.frameworktest.focus;
+
+import com.android.frameworktest.focus.VerticalFocusSearch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.Suppress;
+import android.view.FocusFinder;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+/**
+ * Tests that focus searching works on a vertical linear layout of buttons of
+ * various widths and horizontal placements.
+ */
+// Suppress until bug http://b/issue?id=1416545 is fixed
+@Suppress
+public class VerticalFocusSearchTest extends ActivityInstrumentationTestCase<VerticalFocusSearch> {
+
+ private LinearLayout mLayout;
+
+ private Button mTopWide;
+ private Button mMidSkinny1Left;
+ private Button mMidSkinny2Right;
+ private Button mBottomWide;
+
+ private FocusSearchAlg mFocusFinder;
+
+ // helps test old and new impls when figuring out why something that used
+ // to work doesn't anymore (or verifying that new works as well as old).
+ interface FocusSearchAlg {
+ View findNextFocus(ViewGroup root, View focused, int direction);
+ }
+
+ // calls new impl
+ static class NewFocusSearchAlg implements FocusSearchAlg {
+
+ public View findNextFocus(ViewGroup root, View focused, int direction) {
+ return FocusFinder.getInstance()
+ .findNextFocus(root, focused, direction);
+ }
+ }
+
+ public VerticalFocusSearchTest() {
+ super("com.android.frameworktest", VerticalFocusSearch.class);
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mLayout = getActivity().getLayout();
+ mTopWide = getActivity().getTopWide();
+ mMidSkinny1Left = getActivity().getMidSkinny1Left();
+ mMidSkinny2Right = getActivity().getMidSkinny2Right();
+ mBottomWide = getActivity().getBottomWide();
+
+ mFocusFinder = new NewFocusSearchAlg();
+ }
+
+ public void testPreconditions() {
+ assertNotNull(mLayout);
+ assertNotNull(mTopWide);
+ assertNotNull(mMidSkinny1Left);
+ assertNotNull(mMidSkinny2Right);
+ assertNotNull(mBottomWide);
+ }
+
+ public void testSearchFromTopButton() {
+ assertNull("going up from mTopWide.",
+ mFocusFinder.findNextFocus(mLayout, mTopWide, View.FOCUS_UP));
+
+ assertNull("going left from mTopWide.",
+ mFocusFinder.findNextFocus(mLayout, mTopWide, View.FOCUS_LEFT));
+
+ assertNull("going right from mTopWide.",
+ mFocusFinder.findNextFocus(mLayout, mTopWide, View.FOCUS_RIGHT));
+
+ assertEquals("going down from mTopWide.",
+ mMidSkinny1Left,
+ mFocusFinder
+ .findNextFocus(mLayout, mTopWide, View.FOCUS_DOWN));
+ }
+
+ public void testSearchFromMidLeft() {
+ assertNull("going left should have no next focus",
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny1Left, View.FOCUS_LEFT));
+
+ assertEquals("going right from mMidSkinny1Left should go to mMidSkinny2Right",
+ mMidSkinny2Right,
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny1Left, View.FOCUS_RIGHT));
+
+ assertEquals("going up from mMidSkinny1Left should go to mTopWide",
+ mTopWide,
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny1Left, View.FOCUS_UP));
+
+ assertEquals("going down from mMidSkinny1Left should go to mMidSkinny2Right",
+ mMidSkinny2Right,
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny1Left, View.FOCUS_DOWN));
+ }
+
+ public void testSearchFromMidRight() {
+ assertEquals("going left from mMidSkinny2Right should go to mMidSkinny1Left",
+ mMidSkinny1Left,
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny2Right, View.FOCUS_LEFT));
+
+ assertNull("going right should have no next focus",
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny2Right, View.FOCUS_RIGHT));
+
+ assertEquals("going up from mMidSkinny2Right should go to mMidSkinny1Left",
+ mMidSkinny1Left,
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny2Right, View.FOCUS_UP));
+
+ assertEquals("going down from mMidSkinny2Right should go to mBottomWide",
+ mBottomWide,
+ mFocusFinder.findNextFocus(mLayout, mMidSkinny2Right, View.FOCUS_DOWN));
+
+ }
+
+ public void testSearchFromFromBottom() {
+ assertNull("going down from bottom button should have no next focus.",
+ mFocusFinder.findNextFocus(mLayout, mBottomWide, View.FOCUS_DOWN));
+
+ assertNull("going left from bottom button should have no next focus.",
+ mFocusFinder.findNextFocus(mLayout, mBottomWide, View.FOCUS_LEFT));
+
+ assertNull("going right from bottom button should have no next focus.",
+ mFocusFinder.findNextFocus(mLayout, mBottomWide, View.FOCUS_RIGHT));
+
+ assertEquals("going up from bottom button should go to mMidSkinny2Right.",
+ mMidSkinny2Right,
+ mFocusFinder.findNextFocus(mLayout, mBottomWide, View.FOCUS_UP));
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridInHorizontalTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridInHorizontalTest.java
new file mode 100644
index 0000000..8af6214
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridInHorizontalTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.GridView;
+
+import com.android.frameworktest.gridview.GridInHorizontal;
+
+public class GridInHorizontalTest extends ActivityInstrumentationTestCase<GridInHorizontal> {
+
+ private GridInHorizontal mActivity;
+ private GridView mGridView;
+
+ public GridInHorizontalTest() {
+ super("com.android.frameworktest", GridInHorizontal.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+ assertTrue("Grid has 0 width", mGridView.getMeasuredWidth() > 0);
+ assertTrue("Grid has 0 height", mGridView.getMeasuredHeight() > 0);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridInVerticalTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridInVerticalTest.java
new file mode 100644
index 0000000..61e1c8b
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridInVerticalTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.GridView;
+
+import com.android.frameworktest.gridview.GridInVertical;
+
+public class GridInVerticalTest extends ActivityInstrumentationTestCase<GridInVertical> {
+
+ private GridInVertical mActivity;
+ private GridView mGridView;
+
+ public GridInVerticalTest() {
+ super("com.android.frameworktest", GridInVertical.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+ assertTrue("Grid has 0 width", mGridView.getMeasuredWidth() > 0);
+ assertTrue("Grid has 0 height", mGridView.getMeasuredHeight() > 0);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridPaddingTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridPaddingTest.java
new file mode 100644
index 0000000..43581c6
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridPaddingTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.GridView;
+
+public class GridPaddingTest extends ActivityInstrumentationTestCase2<GridPadding> {
+ private GridView mGridView;
+
+ public GridPaddingTest() {
+ super("com.android.frameworktest", GridPadding.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ setActivityInitialTouchMode(true);
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mGridView);
+ assertTrue("Not in touch mode", mGridView.isInTouchMode());
+ }
+
+ @MediumTest
+ public void testResurrectSelection() {
+ sendKeys("DPAD_DOWN");
+ assertEquals("The first item should be selected", mGridView.getSelectedItemPosition(), 0);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridScrollListenerTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridScrollListenerTest.java
new file mode 100644
index 0000000..f939f16
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridScrollListenerTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.KeyEvent;
+import android.widget.AbsListView;
+import android.widget.GridView;
+
+import com.android.frameworktest.gridview.GridScrollListener;
+
+public class GridScrollListenerTest extends ActivityInstrumentationTestCase<GridScrollListener> implements
+ AbsListView.OnScrollListener {
+ private GridScrollListener mActivity;
+ private GridView mGridView;
+ private int mFirstVisibleItem = -1;
+ private int mVisibleItemCount = -1;
+ private int mTotalItemCount = -1;
+
+ public GridScrollListenerTest() {
+ super("com.android.frameworktest", GridScrollListener.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ mGridView.setOnScrollListener(this);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ assertEquals(0, mFirstVisibleItem);
+ }
+
+ @LargeTest
+ public void testKeyScrolling() {
+ Instrumentation inst = getInstrumentation();
+
+ int firstVisibleItem = mFirstVisibleItem;
+ for (int i = 0; i < mVisibleItemCount * 2; i++) {
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ inst.waitForIdleSync();
+
+ assertTrue("Arrow scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+
+ firstVisibleItem = mFirstVisibleItem;
+ inst.sendCharacterSync(KeyEvent.KEYCODE_SPACE);
+ inst.waitForIdleSync();
+
+ assertTrue("Page scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+
+ firstVisibleItem = mFirstVisibleItem;
+ KeyEvent down = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_ALT_ON);
+ KeyEvent up = new KeyEvent(0, 0, KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_ALT_ON);
+ inst.sendKeySync(down);
+ inst.sendKeySync(up);
+ inst.waitForIdleSync();
+
+ assertTrue("Full scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+ assertEquals("Full scroll did not happen", mTotalItemCount,
+ mFirstVisibleItem + mVisibleItemCount);
+ }
+
+ @LargeTest
+ public void testTouchScrolling() {
+ Instrumentation inst = getInstrumentation();
+
+ int firstVisibleItem = mFirstVisibleItem;
+ TouchUtils.dragQuarterScreenUp(this);
+ TouchUtils.dragQuarterScreenUp(this);
+ assertTrue("Touch scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+ }
+
+
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ mFirstVisibleItem = firstVisibleItem;
+ mVisibleItemCount = visibleItemCount;
+ mTotalItemCount = totalItemCount;
+ }
+
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionBaseTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionBaseTest.java
new file mode 100644
index 0000000..3ca9b09
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionBaseTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.util.GridScenario;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.widget.GridView;
+
+public class GridSetSelectionBaseTest<T extends GridScenario> extends ActivityInstrumentationTestCase<T> {
+ private T mActivity;
+ private GridView mGridView;
+
+ protected GridSetSelectionBaseTest(Class<T> klass) {
+ super("com.android.frameworktest", klass);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ // First item should be selected
+ if (mGridView.isStackFromBottom()) {
+ assertEquals(mGridView.getAdapter().getCount() - 1,
+ mGridView.getSelectedItemPosition());
+ } else {
+ assertEquals(0, mGridView.getSelectedItemPosition());
+ }
+ }
+
+ @MediumTest
+ public void testSetSelectionToTheEnd() {
+ final int target = mGridView.getAdapter().getCount() - 1;
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setSelection(target);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals(mGridView.getSelectedItemPosition(), target);
+ assertNotNull(mGridView.getSelectedView());
+
+ ViewAsserts.assertOnScreen(mGridView, mGridView.getSelectedView());
+ }
+
+ @MediumTest
+ public void testSetSelectionToMiddle() {
+ final int target = mGridView.getAdapter().getCount() / 2;
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setSelection(target);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals(mGridView.getSelectedItemPosition(), target);
+ assertNotNull(mGridView.getSelectedView());
+
+ ViewAsserts.assertOnScreen(mGridView, mGridView.getSelectedView());
+ }
+
+ @MediumTest
+ public void testSetSelectionToTheTop() {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setSelection(0);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals(mGridView.getSelectedItemPosition(), 0);
+ assertNotNull(mGridView.getSelectedView());
+
+ ViewAsserts.assertOnScreen(mGridView, mGridView.getSelectedView());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionManyTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionManyTest.java
new file mode 100644
index 0000000..aadc185
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionManyTest.java
@@ -0,0 +1,25 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.gridview.GridSetSelectionMany;
+
+public class GridSetSelectionManyTest extends GridSetSelectionBaseTest<GridSetSelectionMany> {
+ public GridSetSelectionManyTest() {
+ super(GridSetSelectionMany.class);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomManyTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomManyTest.java
new file mode 100644
index 0000000..831ba85
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomManyTest.java
@@ -0,0 +1,25 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.gridview.GridSetSelectionStackFromBottomMany;
+
+public class GridSetSelectionStackFromBottomManyTest extends GridSetSelectionBaseTest<GridSetSelectionStackFromBottomMany> {
+ public GridSetSelectionStackFromBottomManyTest() {
+ super(GridSetSelectionStackFromBottomMany.class);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomTest.java
new file mode 100644
index 0000000..c4d0513
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionStackFromBottomTest.java
@@ -0,0 +1,25 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.gridview.GridSetSelectionStackFromBottom;
+
+public class GridSetSelectionStackFromBottomTest extends GridSetSelectionBaseTest<GridSetSelectionStackFromBottom> {
+ public GridSetSelectionStackFromBottomTest() {
+ super(GridSetSelectionStackFromBottom.class);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionTest.java
new file mode 100644
index 0000000..5a584a5
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSetSelectionTest.java
@@ -0,0 +1,25 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.gridview.GridSetSelection;
+
+public class GridSetSelectionTest extends GridSetSelectionBaseTest<GridSetSelection> {
+ public GridSetSelectionTest() {
+ super(GridSetSelection.class);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSingleColumnTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSingleColumnTest.java
new file mode 100644
index 0000000..b72a2e0
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridSingleColumnTest.java
@@ -0,0 +1,47 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.GridView;
+
+import com.android.frameworktest.gridview.GridSingleColumn;
+
+public class GridSingleColumnTest extends ActivityInstrumentationTestCase<GridSingleColumn> {
+ private GridSingleColumn mActivity;
+ private GridView mGridView;
+
+ public GridSingleColumnTest() {
+ super("com.android.frameworktest", GridSingleColumn.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+ assertEquals(0, mGridView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridStackFromBottomManyTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridStackFromBottomManyTest.java
new file mode 100644
index 0000000..a0b819e
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridStackFromBottomManyTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.gridview.GridStackFromBottomMany;
+
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.GridView;
+import android.test.ActivityInstrumentationTestCase;
+
+public class GridStackFromBottomManyTest extends ActivityInstrumentationTestCase<GridStackFromBottomMany> {
+ private GridStackFromBottomMany mActivity;
+ private GridView mGridView;
+
+ public GridStackFromBottomManyTest() {
+ super("com.android.frameworktest", GridStackFromBottomMany.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ // Last item should be selected
+ assertEquals(mGridView.getAdapter().getCount() - 1, mGridView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridStackFromBottomTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridStackFromBottomTest.java
new file mode 100644
index 0000000..821c7a5
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/GridStackFromBottomTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.gridview;
+
+import com.android.frameworktest.gridview.GridStackFromBottom;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.GridView;
+
+public class GridStackFromBottomTest extends ActivityInstrumentationTestCase<GridStackFromBottom> {
+ private GridStackFromBottom mActivity;
+ private GridView mGridView;
+
+ public GridStackFromBottomTest() {
+ super("com.android.frameworktest", GridStackFromBottom.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ // Last item should be selected
+ assertEquals(mGridView.getAdapter().getCount() - 1, mGridView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchSetSelectionTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchSetSelectionTest.java
new file mode 100644
index 0000000..926d662
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchSetSelectionTest.java
@@ -0,0 +1,82 @@
+/*
+ * 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 com.android.frameworktest.gridview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.View;
+import android.widget.GridView;
+
+import com.android.frameworktest.gridview.GridSimple;
+
+/**
+ * Tests setting the selection in touch mode
+ */
+public class GridTouchSetSelectionTest extends ActivityInstrumentationTestCase<GridSimple> {
+ private GridSimple mActivity;
+ private GridView mGridView;
+
+ public GridTouchSetSelectionTest() {
+ super("com.android.frameworktest", GridSimple.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+ }
+
+ @LargeTest
+ public void testSetSelection() {
+ TouchUtils.dragQuarterScreenDown(this);
+ TouchUtils.dragQuarterScreenUp(this);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mGridView.getSelectedItemPosition());
+
+ final int targetPosition = mGridView.getAdapter().getCount() / 2;
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mGridView.setSelection(targetPosition);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ boolean found = false;
+ int childCount = mGridView.getChildCount();
+ for (int i=0; i<childCount; i++) {
+ View child = mGridView.getChildAt(i);
+ if (child.getId() == targetPosition) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue("Selected item not visible in list", found);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchStackFromBottomManyTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchStackFromBottomManyTest.java
new file mode 100644
index 0000000..710617e
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchStackFromBottomManyTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 com.android.frameworktest.gridview.touch;
+
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import com.android.frameworktest.gridview.GridStackFromBottomMany;
+
+import android.widget.GridView;
+import android.view.View;
+import android.test.ActivityInstrumentationTestCase;
+
+public class GridTouchStackFromBottomManyTest extends ActivityInstrumentationTestCase<GridStackFromBottomMany> {
+ private GridStackFromBottomMany mActivity;
+ private GridView mGridView;
+
+ public GridTouchStackFromBottomManyTest() {
+ super("com.android.frameworktest", GridStackFromBottomMany.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ // Last item should be selected
+ assertEquals(mGridView.getAdapter().getCount() - 1, mGridView.getSelectedItemPosition());
+ }
+
+ @LargeTest
+ public void testScrollToTop() {
+ View firstChild;
+ TouchUtils.scrollToTop(this, mGridView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mGridView.getSelectedItemPosition());
+
+ firstChild = mGridView.getChildAt(0);
+
+ assertEquals("Item zero not the first child in the grid", 0, firstChild.getId());
+
+ assertEquals("Item zero not at the top of the grid",
+ mGridView.getListPaddingTop(), firstChild.getTop());
+ }
+
+ @MediumTest
+ public void testScrollToBottom() {
+ TouchUtils.scrollToBottom(this, mGridView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mGridView.getSelectedItemPosition());
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ assertEquals("Grid is not scrolled to the bottom", mGridView.getAdapter().getCount() - 1,
+ lastChild.getId());
+
+ assertEquals("Last item is not touching the bottom edge",
+ mGridView.getHeight() - mGridView.getListPaddingBottom(), lastChild.getBottom());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchStackFromBottomTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchStackFromBottomTest.java
new file mode 100644
index 0000000..e085105
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchStackFromBottomTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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 com.android.frameworktest.gridview.touch;
+
+import com.android.frameworktest.gridview.GridStackFromBottom;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.widget.GridView;
+import android.view.View;
+
+public class GridTouchStackFromBottomTest extends ActivityInstrumentationTestCase<GridStackFromBottom> {
+ private GridStackFromBottom mActivity;
+ private GridView mGridView;
+
+ public GridTouchStackFromBottomTest() {
+ super("com.android.frameworktest", GridStackFromBottom.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ // First item should be selected
+ assertEquals(mGridView.getAdapter().getCount() - 1, mGridView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testPushUp() {
+ TouchUtils.scrollToBottom(this, mGridView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mGridView.getSelectedItemPosition());
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ assertEquals("Last item not the last child in the grid",
+ mGridView.getAdapter().getCount() - 1, lastChild.getId());
+
+ assertEquals("Last item not at the bottom of the grid",
+ mGridView.getHeight() - mGridView.getListPaddingBottom(), lastChild.getBottom());
+ }
+
+ @MediumTest
+ public void testPullDown() {
+ TouchUtils.scrollToTop(this, mGridView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mGridView.getSelectedItemPosition());
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ assertEquals("Last item not the last child in the grid",
+ mGridView.getAdapter().getCount() - 1, lastChild.getId());
+
+ assertEquals("Last item not at the bottom of the grid",
+ mGridView.getHeight() - mGridView.getListPaddingBottom(), lastChild.getBottom());
+ }
+
+ @MediumTest
+ public void testPushUpFast() {
+ TouchUtils.dragViewToTop(this, mGridView.getChildAt(mGridView.getChildCount() - 1), 2);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mGridView.getSelectedItemPosition());
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ assertEquals("Last item not the last child in the grid",
+ mGridView.getAdapter().getCount() - 1, lastChild.getId());
+
+ assertEquals("Last item not at the bottom of the grid",
+ mGridView.getHeight() - mGridView.getListPaddingBottom(), lastChild.getBottom());
+ }
+
+ @MediumTest
+ public void testPullDownFast() {
+ TouchUtils.dragViewToBottom(this, mGridView.getChildAt(0), 2);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mGridView.getSelectedItemPosition());
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ assertEquals("Last item not the last child in the grid",
+ mGridView.getAdapter().getCount() - 1, lastChild.getId());
+
+ assertEquals("Last item not at the bottom of the grid",
+ mGridView.getHeight() - mGridView.getListPaddingBottom(), lastChild.getBottom());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchVerticalSpacingStackFromBottomTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchVerticalSpacingStackFromBottomTest.java
new file mode 100644
index 0000000..3937c43
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchVerticalSpacingStackFromBottomTest.java
@@ -0,0 +1,154 @@
+/*
+ * 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 com.android.frameworktest.gridview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.GridView;
+
+import com.android.frameworktest.gridview.GridVerticalSpacingStackFromBottom;
+
+public class GridTouchVerticalSpacingStackFromBottomTest extends ActivityInstrumentationTestCase<GridVerticalSpacingStackFromBottom> {
+ private GridVerticalSpacingStackFromBottom mActivity;
+ private GridView mGridView;
+
+ public GridTouchVerticalSpacingStackFromBottomTest() {
+ super("com.android.frameworktest", GridVerticalSpacingStackFromBottom.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ // Last item should be selected
+ assertEquals(mGridView.getAdapter().getCount() - 1, mGridView.getSelectedItemPosition());
+
+ }
+
+ @MediumTest
+ public void testNoScroll() {
+ View firstChild = mGridView.getChildAt(0);
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ int lastTop = lastChild.getTop();
+
+ TouchUtils.dragViewBy(this, firstChild, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
+ ViewConfiguration.getTouchSlop());
+
+ View newLastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ assertEquals("View scrolled too early", lastTop, newLastChild.getTop());
+ assertEquals("Wrong view in last position", mGridView.getAdapter().getCount() - 1,
+ newLastChild.getId());
+ }
+
+ @LargeTest
+ public void testShortScroll() {
+ View firstChild = mGridView.getChildAt(0);
+ if (firstChild.getTop() < this.mGridView.getListPaddingTop()) {
+ firstChild = mGridView.getChildAt(1);
+ }
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ int lastTop = lastChild.getTop();
+
+ TouchUtils.dragViewBy(this, firstChild, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
+ ViewConfiguration.getTouchSlop() + 1 + 10);
+
+ View newLastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ assertEquals("View scrolled to wrong position", lastTop, newLastChild.getTop() - 10);
+ assertEquals("Wrong view in last position", mGridView.getAdapter().getCount() - 1,
+ newLastChild.getId());
+ }
+
+ @LargeTest
+ public void testLongScroll() {
+ View firstChild = mGridView.getChildAt(0);
+ if (firstChild.getTop() < mGridView.getListPaddingTop()) {
+ firstChild = mGridView.getChildAt(1);
+ }
+
+ int firstTop = firstChild.getTop();
+
+ int distance = TouchUtils.dragViewBy(this, firstChild,
+ Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
+ (int) (mActivity.getWindowManager().getDefaultDisplay().getHeight() * 0.75f));
+
+ assertEquals("View scrolled to wrong position", firstTop
+ + (distance - ViewConfiguration.getTouchSlop() - 1), firstChild.getTop());
+ }
+
+ @LargeTest
+ public void testManyScrolls() {
+ int originalCount = mGridView.getChildCount();
+
+ View firstChild;
+ int firstId = Integer.MIN_VALUE;
+ int firstTop = Integer.MIN_VALUE;
+ int prevId;
+ int prevTop;
+ do {
+ prevId = firstId;
+ prevTop = firstTop;
+ TouchUtils.dragQuarterScreenDown(this);
+ assertTrue(String.format("Too many children created: %d expected no more than %d",
+ mGridView.getChildCount(), originalCount + 4),
+ mGridView.getChildCount() <= originalCount + 4);
+ firstChild = mGridView.getChildAt(0);
+ firstId = firstChild.getId();
+ firstTop = firstChild.getTop();
+ } while ((prevId != firstId) || (prevTop != firstTop));
+
+
+ firstChild = mGridView.getChildAt(0);
+ assertEquals("View scrolled to wrong position", 0, firstChild.getId());
+
+ firstId = Integer.MIN_VALUE;
+ firstTop = Integer.MIN_VALUE;
+ do {
+ prevId = firstId;
+ prevTop = firstTop;
+ TouchUtils.dragQuarterScreenUp(this);
+ assertTrue(String.format("Too many children created: %d expected no more than %d",
+ mGridView.getChildCount(), originalCount + 4),
+ mGridView.getChildCount() <= originalCount + 4);
+ firstChild = mGridView.getChildAt(0);
+ firstId = firstChild.getId();
+ firstTop = firstChild.getTop();
+ } while ((prevId != firstId) || (prevTop != firstTop));
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+ assertEquals("Grid is not scrolled to the bottom", mGridView.getAdapter().getCount() - 1,
+ lastChild.getId());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchVerticalSpacingTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchVerticalSpacingTest.java
new file mode 100644
index 0000000..0b39909
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/gridview/touch/GridTouchVerticalSpacingTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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 com.android.frameworktest.gridview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.GridView;
+
+import com.android.frameworktest.gridview.GridVerticalSpacing;
+
+public class GridTouchVerticalSpacingTest extends ActivityInstrumentationTestCase<GridVerticalSpacing> {
+ private GridVerticalSpacing mActivity;
+ private GridView mGridView;
+
+ public GridTouchVerticalSpacingTest() {
+ super("com.android.frameworktest", GridVerticalSpacing.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mGridView = getActivity().getGridView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mGridView);
+
+ assertEquals(0, mGridView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testNoScroll() {
+ View firstChild = mGridView.getChildAt(0);
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ int firstTop = firstChild.getTop();
+
+ TouchUtils.dragViewBy(this, lastChild, Gravity.TOP | Gravity.LEFT,
+ 0, -(ViewConfiguration.getTouchSlop()));
+
+ View newFirstChild = mGridView.getChildAt(0);
+
+ assertEquals("View scrolled too early", firstTop, newFirstChild.getTop());
+ assertEquals("Wrong view in first position", 0, newFirstChild.getId());
+ }
+
+ @LargeTest
+ public void testShortScroll() {
+ View firstChild = mGridView.getChildAt(0);
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ int firstTop = firstChild.getTop();
+
+ TouchUtils.dragViewBy(this, lastChild, Gravity.TOP | Gravity.LEFT,
+ 0, -(ViewConfiguration.getTouchSlop() + 1 + 10));
+
+ View newFirstChild = mGridView.getChildAt(0);
+
+ assertEquals("View scrolled to wrong position", firstTop, newFirstChild.getTop() + 10);
+ assertEquals("Wrong view in first position", 0, newFirstChild.getId());
+ }
+
+ @LargeTest
+ public void testLongScroll() {
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+
+ int lastTop = lastChild.getTop();
+
+ int distance = TouchUtils.dragViewToY(this, lastChild, Gravity.TOP | Gravity.LEFT,
+ mGridView.getTop());
+
+ assertEquals("View scrolled to wrong position",
+ lastTop - (distance - ViewConfiguration.getTouchSlop() - 1), lastChild.getTop());
+ }
+
+ @LargeTest
+ public void testManyScrolls() {
+ int originalCount = mGridView.getChildCount();
+
+ View firstChild;
+ int firstId = Integer.MIN_VALUE;
+ int firstTop = Integer.MIN_VALUE;
+ int prevId;
+ int prevTop;
+ do {
+ prevId = firstId;
+ prevTop = firstTop;
+ TouchUtils.dragQuarterScreenUp(this);
+ assertTrue(String.format("Too many children created: %d expected no more than %d",
+ mGridView.getChildCount(), originalCount + 4),
+ mGridView.getChildCount() <= originalCount + 4);
+ firstChild = mGridView.getChildAt(0);
+ firstId = firstChild.getId();
+ firstTop = firstChild.getTop();
+ } while ((prevId != firstId) || (prevTop != firstTop));
+
+
+ View lastChild = mGridView.getChildAt(mGridView.getChildCount() - 1);
+ assertEquals("Grid is not scrolled to the bottom", mGridView.getAdapter().getCount() - 1,
+ lastChild.getId());
+
+ firstId = Integer.MIN_VALUE;
+ firstTop = Integer.MIN_VALUE;
+ do {
+ prevId = firstId;
+ prevTop = firstTop;
+ TouchUtils.dragQuarterScreenDown(this);
+ assertTrue(String.format("Too many children created: %d expected no more than %d",
+ mGridView.getChildCount(), originalCount + 4),
+ mGridView.getChildCount() <= originalCount + 4);
+ firstChild = mGridView.getChildAt(0);
+ firstId = firstChild.getId();
+ firstTop = firstChild.getTop();
+ } while ((prevId != firstId) || (prevTop != firstTop));
+
+ firstChild = mGridView.getChildAt(0);
+ assertEquals("Grid is not scrolled to the top", 0, firstChild.getId());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/frame/FrameLayoutGravityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/frame/FrameLayoutGravityTest.java
new file mode 100644
index 0000000..239bd7d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/frame/FrameLayoutGravityTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.frame;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.app.Activity;
+import android.view.View;
+import com.android.frameworktest.layout.frame.FrameLayoutGravity;
+import com.android.frameworktest.R;
+
+public class FrameLayoutGravityTest extends ActivityInstrumentationTestCase<FrameLayoutGravity> {
+ private View mLeftView;
+ private View mRightView;
+ private View mCenterHorizontalView;
+ private View mLeftCenterVerticalView;
+ private View mRighCenterVerticalView;
+ private View mCenterView;
+ private View mLeftBottomView;
+ private View mRightBottomView;
+ private View mCenterHorizontalBottomView;
+ private View mParent;
+
+ public FrameLayoutGravityTest() {
+ super("com.android.frameworktest", FrameLayoutGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+
+ mParent = activity.findViewById(R.id.parent);
+
+ mLeftView = activity.findViewById(R.id.left);
+ mRightView = activity.findViewById(R.id.right);
+ mCenterHorizontalView = activity.findViewById(R.id.center_horizontal);
+
+ mLeftCenterVerticalView = activity.findViewById(R.id.left_center_vertical);
+ mRighCenterVerticalView = activity.findViewById(R.id.right_center_vertical);
+ mCenterView = activity.findViewById(R.id.center);
+
+ mLeftBottomView = activity.findViewById(R.id.left_bottom);
+ mRightBottomView = activity.findViewById(R.id.right_bottom);
+ mCenterHorizontalBottomView = activity.findViewById(R.id.center_horizontal_bottom);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mParent);
+ assertNotNull(mLeftView);
+ assertNotNull(mRightView);
+ assertNotNull(mCenterHorizontalView);
+ assertNotNull(mLeftCenterVerticalView);
+ assertNotNull(mRighCenterVerticalView);
+ assertNotNull(mCenterView);
+ assertNotNull(mLeftBottomView);
+ assertNotNull(mRightBottomView);
+ assertNotNull(mCenterHorizontalBottomView);
+ }
+
+ @MediumTest
+ public void testLeftTopAligned() throws Exception {
+ ViewAsserts.assertLeftAligned(mParent, mLeftView);
+ ViewAsserts.assertTopAligned(mParent, mLeftView);
+ }
+
+ @MediumTest
+ public void testRightTopAligned() throws Exception {
+ ViewAsserts.assertRightAligned(mParent, mRightView);
+ ViewAsserts.assertTopAligned(mParent, mRightView);
+ }
+
+ @MediumTest
+ public void testCenterHorizontalTopAligned() throws Exception {
+ ViewAsserts.assertHorizontalCenterAligned(mParent, mCenterHorizontalView);
+ ViewAsserts.assertTopAligned(mParent, mCenterHorizontalView);
+ }
+
+ @MediumTest
+ public void testLeftCenterVerticalAligned() throws Exception {
+ ViewAsserts.assertLeftAligned(mParent, mLeftCenterVerticalView);
+ ViewAsserts.assertVerticalCenterAligned(mParent, mLeftCenterVerticalView);
+ }
+
+ @MediumTest
+ public void testRightCenterVerticalAligned() throws Exception {
+ ViewAsserts.assertRightAligned(mParent, mRighCenterVerticalView);
+ ViewAsserts.assertVerticalCenterAligned(mParent, mRighCenterVerticalView);
+ }
+
+ @MediumTest
+ public void testCenterAligned() throws Exception {
+ ViewAsserts.assertHorizontalCenterAligned(mParent, mCenterView);
+ ViewAsserts.assertVerticalCenterAligned(mParent, mCenterView);
+ }
+
+ @MediumTest
+ public void testLeftBottomAligned() throws Exception {
+ ViewAsserts.assertLeftAligned(mParent, mLeftBottomView);
+ ViewAsserts.assertBottomAligned(mParent, mLeftBottomView);
+ }
+
+ @MediumTest
+ public void testRightBottomAligned() throws Exception {
+ ViewAsserts.assertRightAligned(mParent, mRightBottomView);
+ ViewAsserts.assertBottomAligned(mParent, mRightBottomView);
+ }
+
+ @MediumTest
+ public void testCenterHorizontalBottomAligned() throws Exception {
+ ViewAsserts.assertHorizontalCenterAligned(mParent, mCenterHorizontalBottomView);
+ ViewAsserts.assertBottomAligned(mParent, mCenterHorizontalBottomView);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/frame/FrameLayoutMarginTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/frame/FrameLayoutMarginTest.java
new file mode 100644
index 0000000..4df4805
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/frame/FrameLayoutMarginTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.frame;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.app.Activity;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.frameworktest.layout.frame.FrameLayoutMargin;
+import com.android.frameworktest.R;
+
+public class FrameLayoutMarginTest extends ActivityInstrumentationTestCase<FrameLayoutMargin> {
+ private View mLeftView;
+ private View mRightView;
+ private View mTopView;
+ private View mBottomView;
+ private View mParent;
+
+ public FrameLayoutMarginTest() {
+ super("com.android.frameworktest", FrameLayoutMargin.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+
+ mParent = activity.findViewById(R.id.parent);
+
+ mLeftView = activity.findViewById(R.id.left);
+ mRightView = activity.findViewById(R.id.right);
+ mTopView = activity.findViewById(R.id.top);
+ mBottomView = activity.findViewById(R.id.bottom);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mParent);
+ assertNotNull(mLeftView);
+ assertNotNull(mRightView);
+ assertNotNull(mTopView);
+ assertNotNull(mBottomView);
+ }
+
+ @MediumTest
+ public void testLeftMarginAligned() throws Exception {
+ ViewAsserts.assertLeftAligned(mParent, mLeftView,
+ ((ViewGroup.MarginLayoutParams) mLeftView.getLayoutParams()).leftMargin);
+ }
+
+ @MediumTest
+ public void testRightMarginAligned() throws Exception {
+ ViewAsserts.assertRightAligned(mParent, mRightView,
+ ((ViewGroup.MarginLayoutParams) mRightView.getLayoutParams()).rightMargin);
+ }
+
+ @MediumTest
+ public void testTopMarginAligned() throws Exception {
+ ViewAsserts.assertTopAligned(mParent, mTopView,
+ ((ViewGroup.MarginLayoutParams) mTopView.getLayoutParams()).topMargin);
+ }
+
+ @MediumTest
+ public void testBottomMarginAligned() throws Exception {
+ ViewAsserts.assertBottomAligned(mParent, mBottomView,
+ ((ViewGroup.MarginLayoutParams) mBottomView.getLayoutParams()).bottomMargin);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentCenterGravityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentCenterGravityTest.java
new file mode 100644
index 0000000..0b6360e
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentCenterGravityTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.view.View;
+import android.widget.Button;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.layout.linear.BaselineAlignmentCenterGravity;
+
+public class BaselineAlignmentCenterGravityTest extends ActivityInstrumentationTestCase<BaselineAlignmentCenterGravity> {
+ private Button mButton1;
+ private Button mButton2;
+ private Button mButton3;
+
+ public BaselineAlignmentCenterGravityTest() {
+ super("com.android.frameworktest", BaselineAlignmentCenterGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mButton1 = (Button) activity.findViewById(R.id.button1);
+ mButton2 = (Button) activity.findViewById(R.id.button2);
+ mButton3 = (Button) activity.findViewById(R.id.button3);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mButton1);
+ assertNotNull(mButton2);
+ assertNotNull(mButton3);
+ }
+
+ @MediumTest
+ public void testChildrenAligned() throws Exception {
+ final View parent = (View) mButton1.getParent();
+ ViewAsserts.assertTopAligned(mButton1, parent);
+ ViewAsserts.assertTopAligned(mButton2, parent);
+ ViewAsserts.assertTopAligned(mButton3, parent);
+ ViewAsserts.assertBottomAligned(mButton1, parent);
+ ViewAsserts.assertBottomAligned(mButton2, parent);
+ ViewAsserts.assertBottomAligned(mButton3, parent);
+ ViewAsserts.assertTopAligned(mButton1, mButton2);
+ ViewAsserts.assertTopAligned(mButton2, mButton3);
+ ViewAsserts.assertBottomAligned(mButton1, mButton2);
+ ViewAsserts.assertBottomAligned(mButton2, mButton3);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentSpinnerButton.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentSpinnerButton.java
new file mode 100644
index 0000000..050e053
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentSpinnerButton.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.view.View;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.layout.linear.HorizontalOrientationVerticalAlignment;
+
+public class BaselineAlignmentSpinnerButton extends ActivityInstrumentationTestCase<HorizontalOrientationVerticalAlignment> {
+ private View mSpinner;
+ private View mButton;
+
+ public BaselineAlignmentSpinnerButton() {
+ super("com.android.frameworktest", HorizontalOrientationVerticalAlignment.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mSpinner = activity.findViewById(R.id.reminder_value);
+ mButton = activity.findViewById(R.id.reminder_remove);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mSpinner);
+ assertNotNull(mButton);
+ }
+
+ @MediumTest
+ public void testChildrenAligned() throws Exception {
+ ViewAsserts.assertBaselineAligned(mSpinner, mButton);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentZeroWidthAndWeightTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentZeroWidthAndWeightTest.java
new file mode 100644
index 0000000..a315d81
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineAlignmentZeroWidthAndWeightTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.layout.linear.BaselineAlignmentZeroWidthAndWeight;
+import com.android.frameworktest.layout.linear.ExceptionTextView;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+
+public class BaselineAlignmentZeroWidthAndWeightTest extends ActivityInstrumentationTestCase<BaselineAlignmentZeroWidthAndWeight> {
+ private Button mShowButton;
+
+ public BaselineAlignmentZeroWidthAndWeightTest() {
+ super("com.android.frameworktest", BaselineAlignmentZeroWidthAndWeight.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mShowButton = (Button) activity.findViewById(R.id.show);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mShowButton);
+ }
+
+ @MediumTest
+ public void testComputeTexViewWithoutIllegalArgumentException() throws Exception {
+ assertTrue(mShowButton.hasFocus());
+
+ // Pressing the button will show an ExceptionTextView that might set a failed bit if
+ // the test fails.
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+
+ final ExceptionTextView etv = (ExceptionTextView) getActivity()
+ .findViewById(R.id.routeToField);
+ assertFalse("exception test view should not fail", etv.isFailed());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineButtonsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineButtonsTest.java
new file mode 100644
index 0000000..9f2e138
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/BaselineButtonsTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.widget.ImageButton;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.layout.linear.BaselineButtons;
+
+public class BaselineButtonsTest extends ActivityInstrumentationTestCase<BaselineButtons> {
+ private View mCurrentTime;
+ private View mTotalTime;
+ private ImageButton mPrev;
+ private ImageButton mNext;
+ private ImageButton mPause;
+ private View mLayout;
+
+ public BaselineButtonsTest() {
+ super("com.android.frameworktest", BaselineButtons.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mCurrentTime = activity.findViewById(R.id.currenttime);
+ mTotalTime = activity.findViewById(R.id.totaltime);
+ mPrev = (ImageButton) activity.findViewById(R.id.prev);
+ mNext = (ImageButton) activity.findViewById(R.id.next);
+ mPause = (ImageButton) activity.findViewById(R.id.pause);
+ mLayout = activity.findViewById(R.id.layout);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mCurrentTime);
+ assertNotNull(mTotalTime);
+ assertNotNull(mPrev);
+ assertNotNull(mNext);
+ assertNotNull(mPause);
+ assertNotNull(mLayout);
+ }
+
+ @MediumTest
+ public void testLayout() {
+ int pauseHeight = Math.max(mPause.getDrawable().getIntrinsicHeight()
+ + mPause.getPaddingTop() + mPause.getPaddingBottom(),
+ mPause.getBackground().getMinimumHeight());
+ int prevHeight = Math.max(mPrev.getDrawable().getIntrinsicHeight() + mPrev.getPaddingTop()
+ + mPrev.getPaddingBottom(),
+ mPrev.getBackground().getMinimumHeight());
+ int nextHeight = Math.max(mNext.getDrawable().getIntrinsicHeight() + mNext.getPaddingTop()
+ + mNext.getPaddingBottom(),
+ mNext.getBackground().getMinimumHeight());
+ assertEquals("Layout incorrect height", pauseHeight, mLayout.getHeight());
+ assertEquals("Pause incorrect height", pauseHeight, mPause.getHeight());
+ assertEquals("Prev incorrect height", prevHeight, mPrev.getHeight());
+ assertEquals("Next incorrect height", nextHeight, mNext.getHeight());
+ assertEquals("Pause wrong top", 0, mPause.getTop());
+ assertEquals("Prev wrong top", (pauseHeight - prevHeight) / 2, mPrev.getTop());
+ assertEquals("Next wrong top", (pauseHeight - nextHeight) / 2, mNext.getTop());
+ assertEquals("CurrentTime wrong bottom", pauseHeight, mCurrentTime.getBottom());
+ assertEquals("TotalTime wrong bottom", pauseHeight, mTotalTime.getBottom());
+ assertTrue("CurrentTime too tall", mCurrentTime.getTop() > 0);
+ assertTrue("TotalTime too tall", mTotalTime.getTop() > 0);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/FillInWrapTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/FillInWrapTest.java
new file mode 100644
index 0000000..0e7a4a0
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/FillInWrapTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+
+import com.android.frameworktest.R;
+
+public class FillInWrapTest extends ActivityInstrumentationTestCase<FillInWrap> {
+ private View mChild;
+ private View mContainer;
+
+ public FillInWrapTest() {
+ super("com.android.frameworktest", FillInWrap.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mChild = activity.findViewById(R.id.data);
+ mContainer = activity.findViewById(R.id.layout);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mChild);
+ assertNotNull(mContainer);
+ }
+
+ @MediumTest
+ public void testLayout() {
+ assertTrue("the child's height should be less than the parent's",
+ mChild.getMeasuredHeight() < mContainer.getMeasuredHeight());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/LinearLayoutEditTextsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/LinearLayoutEditTextsTest.java
new file mode 100644
index 0000000..9dde62c
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/LinearLayoutEditTextsTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.layout.linear;
+
+import com.android.frameworktest.layout.linear.LinearLayoutEditTexts;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.app.Activity;
+
+public class LinearLayoutEditTextsTest extends ActivityInstrumentationTestCase<LinearLayoutEditTexts> {
+ private View mChild;
+ private View mContainer;
+
+ public LinearLayoutEditTextsTest() {
+ super("com.android.frameworktest", LinearLayoutEditTexts.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mChild = activity.findViewById(R.id.editText1);
+ mContainer = activity.findViewById(R.id.layout);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mChild);
+ assertNotNull(mContainer);
+ }
+
+ @MediumTest
+ public void testLayout() {
+ final int childHeight = mChild.getHeight();
+ final int containerHeight = mContainer.getHeight();
+
+ assertEquals(containerHeight, childHeight);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/WeightSumTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/WeightSumTest.java
new file mode 100644
index 0000000..a51743b
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/WeightSumTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.layout.linear.WeightSum;
+
+public class WeightSumTest extends ActivityInstrumentationTestCase<WeightSum> {
+ private View mChild;
+ private View mContainer;
+
+ public WeightSumTest() {
+ super("com.android.frameworktest", WeightSum.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mChild = activity.findViewById(R.id.child);
+ mContainer = activity.findViewById(R.id.container);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mChild);
+ assertNotNull(mContainer);
+ }
+
+ @MediumTest
+ public void testLayout() {
+ final int childWidth = mChild.getWidth();
+ final int containerWidth = mContainer.getWidth();
+
+ assertEquals(containerWidth / 2, childWidth);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/WeightTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/WeightTest.java
new file mode 100644
index 0000000..f7fec78
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/linear/WeightTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.frameworktest.layout.linear;
+
+import android.app.Activity;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.view.View;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.layout.linear.Weight;
+
+public class WeightTest extends ActivityInstrumentationTestCase<Weight> {
+ private View mChild;
+ private View mContainer;
+
+ public WeightTest() {
+ super("com.android.frameworktest", Weight.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Activity activity = getActivity();
+ mChild = activity.findViewById(R.id.child4);
+ mContainer = activity.findViewById(R.id.layout);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mChild);
+ assertNotNull(mContainer);
+ }
+
+ @MediumTest
+ public void testLayout() {
+ ViewAsserts.assertRightAligned(mChild, mContainer);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/AddColumnTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/AddColumnTest.java
new file mode 100644
index 0000000..9d713c8
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/AddColumnTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.layout.table.AddColumn;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+import android.widget.TableLayout;
+import android.widget.TableRow;
+
+/**
+ * {@link com.android.frameworktest.layout.table.AddColumn} is
+ * setup to exercise the case of adding row programmatically in a table.
+ */
+public class AddColumnTest extends ActivityInstrumentationTestCase<AddColumn> {
+ private Button mAddRow;
+ private TableLayout mTable;
+
+ public AddColumnTest() {
+ super("com.android.frameworktest", AddColumn.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final AddColumn activity = getActivity();
+ mAddRow = (Button) activity.findViewById(R.id.add_row_button);
+ mTable = (TableLayout) activity.findViewById(R.id.table);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mAddRow);
+ assertNotNull(mTable);
+ assertTrue(mAddRow.hasFocus());
+ }
+
+ @MediumTest
+ public void testWidths() throws Exception {
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+
+ TableRow row1 = (TableRow) mTable.getChildAt(0);
+ TableRow row2 = (TableRow) mTable.getChildAt(1);
+
+ assertTrue(row1.getChildCount() < row2.getChildCount());
+
+ for (int i = 0; i < row1.getChildCount(); i++) {
+ assertEquals(row2.getChildAt(i).getWidth(), row1.getChildAt(i).getWidth());
+ }
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/CellSpanTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/CellSpanTest.java
new file mode 100644
index 0000000..85f9c2c
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/CellSpanTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.layout.table.CellSpan;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+
+/**
+ * {@link com.android.frameworktest.layout.table.CellSpan} is
+ * setup to exercise tables in which cells use spanning.
+ */
+public class CellSpanTest extends ActivityInstrumentationTestCase<CellSpan> {
+ private View mA;
+ private View mB;
+ private View mC;
+ private View mSpanThenCell;
+ private View mCellThenSpan;
+ private View mSpan;
+
+ public CellSpanTest() {
+ super("com.android.frameworktest", CellSpan.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final CellSpan activity = getActivity();
+ mA = activity.findViewById(R.id.a);
+ mB = activity.findViewById(R.id.b);
+ mC = activity.findViewById(R.id.c);
+ mSpanThenCell = activity.findViewById(R.id.spanThenCell);
+ mCellThenSpan = activity.findViewById(R.id.cellThenSpan);
+ mSpan = activity.findViewById(R.id.span);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mA);
+ assertNotNull(mB);
+ assertNotNull(mC);
+ assertNotNull(mSpanThenCell);
+ assertNotNull(mCellThenSpan);
+ assertNotNull(mSpan);
+ }
+
+ @MediumTest
+ public void testSpanThenCell() throws Exception {
+ int spanWidth = mA.getMeasuredWidth() + mB.getMeasuredWidth();
+ assertEquals("span followed by cell is broken", spanWidth,
+ mSpanThenCell.getMeasuredWidth());
+ }
+
+ @MediumTest
+ public void testCellThenSpan() throws Exception {
+ int spanWidth = mB.getMeasuredWidth() + mC.getMeasuredWidth();
+ assertEquals("cell followed by span is broken", spanWidth,
+ mCellThenSpan.getMeasuredWidth());
+ }
+
+ @MediumTest
+ public void testSpan() throws Exception {
+ int spanWidth = mA.getMeasuredWidth() + mB.getMeasuredWidth() +
+ mC.getMeasuredWidth();
+ assertEquals("span is broken", spanWidth, mSpan.getMeasuredWidth());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/FixedWidthTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/FixedWidthTest.java
new file mode 100644
index 0000000..a54d503
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/FixedWidthTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.layout.table.FixedWidth;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+
+/**
+ * {@link com.android.frameworktest.layout.table.FixedWidth} is
+ * setup to exercise tables in which cells use fixed width and height.
+ */
+public class FixedWidthTest extends ActivityInstrumentationTestCase<FixedWidth> {
+ private View mFixedWidth;
+ private View mFixedHeight;
+ private View mNonFixedWidth;
+
+ public FixedWidthTest() {
+ super("com.android.frameworktest", FixedWidth.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final FixedWidth activity = getActivity();
+ mFixedWidth = activity.findViewById(R.id.fixed_width);
+ mNonFixedWidth = activity.findViewById(R.id.non_fixed_width);
+ mFixedHeight = activity.findViewById(R.id.fixed_height);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mFixedWidth);
+ assertNotNull(mFixedHeight);
+ assertNotNull(mNonFixedWidth);
+ }
+
+ @MediumTest
+ public void testFixedWidth() throws Exception {
+ assertEquals(150, mFixedWidth.getWidth());
+ assertEquals(mFixedWidth.getWidth(), mNonFixedWidth.getWidth());
+ }
+
+ @MediumTest
+ public void testFixedHeight() throws Exception {
+ assertEquals(48, mFixedHeight.getHeight());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/HorizontalGravityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/HorizontalGravityTest.java
new file mode 100644
index 0000000..1355cb3
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/HorizontalGravityTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.layout.table.HorizontalGravity;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.view.View;
+
+/**
+ * {@link com.android.frameworktest.layout.table.HorizontalGravity} is
+ * setup to exercise tables in which cells use horizontal gravity.
+ */
+public class HorizontalGravityTest extends ActivityInstrumentationTestCase<HorizontalGravity> {
+ private View mReference;
+ private View mCenter;
+ private View mBottomRight;
+ private View mLeft;
+
+ public HorizontalGravityTest() {
+ super("com.android.frameworktest", HorizontalGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final HorizontalGravity activity = getActivity();
+ mReference = activity.findViewById(R.id.reference);
+ mCenter = activity.findViewById(R.id.center);
+ mBottomRight = activity.findViewById(R.id.bottomRight);
+ mLeft = activity.findViewById(R.id.left);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mReference);
+ assertNotNull(mCenter);
+ assertNotNull(mBottomRight);
+ assertNotNull(mLeft);
+ }
+
+ @MediumTest
+ public void testCenterGravity() throws Exception {
+ ViewAsserts.assertHorizontalCenterAligned(mReference, mCenter);
+ }
+
+ @MediumTest
+ public void testLeftGravity() throws Exception {
+ ViewAsserts.assertLeftAligned(mReference, mLeft);
+ }
+
+ @MediumTest
+ public void testRightGravity() throws Exception {
+ ViewAsserts.assertRightAligned(mReference, mBottomRight);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/VerticalGravityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/VerticalGravityTest.java
new file mode 100644
index 0000000..de3e68b
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/VerticalGravityTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.layout.table.VerticalGravity;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.view.View;
+
+/**
+ * {@link com.android.frameworktest.layout.table.VerticalGravity} is
+ * setup to exercise tables in which cells use vertical gravity.
+ */
+public class VerticalGravityTest extends ActivityInstrumentationTestCase<VerticalGravity> {
+ private View mReference1;
+ private View mReference2;
+ private View mReference3;
+ private View mTop;
+ private View mCenter;
+ private View mBottom;
+
+ public VerticalGravityTest() {
+ super("com.android.frameworktest", VerticalGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final VerticalGravity activity = getActivity();
+ mReference1 = activity.findViewById(R.id.reference1);
+ mReference2 = activity.findViewById(R.id.reference2);
+ mReference3 = activity.findViewById(R.id.reference3);
+ mTop = activity.findViewById(R.id.cell_top);
+ mCenter = activity.findViewById(R.id.cell_center);
+ mBottom = activity.findViewById(R.id.cell_bottom);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mReference1);
+ assertNotNull(mReference2);
+ assertNotNull(mReference3);
+ assertNotNull(mTop);
+ assertNotNull(mCenter);
+ assertNotNull(mBottom);
+ }
+
+ @MediumTest
+ public void testTopGravity() throws Exception {
+ ViewAsserts.assertTopAligned(mReference1, mTop);
+ }
+
+ @MediumTest
+ public void testCenterGravity() throws Exception {
+ ViewAsserts.assertVerticalCenterAligned(mReference2, mCenter);
+ }
+
+ @MediumTest
+ public void testBottomGravity() throws Exception {
+ ViewAsserts.assertBottomAligned(mReference3, mBottom);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/WeightTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/WeightTest.java
new file mode 100644
index 0000000..9e20686
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/layout/table/WeightTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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 com.android.frameworktest.layout.table;
+
+import com.android.frameworktest.layout.table.Weight;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+
+/**
+ * {@link com.android.frameworktest.layout.table.Weight} is
+ * setup to exercise tables in which cells use a weight.
+ */
+public class WeightTest extends ActivityInstrumentationTestCase<Weight> {
+ private View mCell1;
+ private View mCell2;
+ private View mCell3;
+ private View mRow;
+
+ public WeightTest() {
+ super("com.android.frameworktest", Weight.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ final Weight activity = getActivity();
+ mCell1 = activity.findViewById(R.id.cell1);
+ mCell3 = activity.findViewById(R.id.cell2);
+ mCell2 = activity.findViewById(R.id.cell3);
+ mRow = activity.findViewById(R.id.row);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mCell1);
+ assertNotNull(mCell2);
+ assertNotNull(mCell3);
+ assertNotNull(mRow);
+ }
+
+ @MediumTest
+ public void testAllCellsFillParent() throws Exception {
+ assertEquals(mCell1.getWidth() + mCell2.getWidth() + mCell3.getWidth(), mRow.getWidth());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListBottomGravityManyTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListBottomGravityManyTest.java
new file mode 100644
index 0000000..d36e343
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListBottomGravityManyTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListBottomGravityMany;
+
+public class ListBottomGravityManyTest extends ActivityInstrumentationTestCase<ListBottomGravityMany> {
+ private ListBottomGravityMany mActivity;
+ private ListView mListView;
+
+ public ListBottomGravityManyTest() {
+ super("com.android.frameworktest", ListBottomGravityMany.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ // Last item should be selected
+ assertEquals(mListView.getAdapter().getCount() - 1, mListView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListBottomGravityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListBottomGravityTest.java
new file mode 100644
index 0000000..79556cf
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListBottomGravityTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListBottomGravity;
+
+public class ListBottomGravityTest extends ActivityInstrumentationTestCase<ListBottomGravity> {
+ private ListBottomGravity mActivity;
+ private ListView mListView;
+
+ public ListBottomGravityTest() {
+ super("com.android.frameworktest", ListBottomGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ // Last item should be selected
+ assertEquals(mListView.getAdapter().getCount() - 1, mListView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListEmptyViewTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListEmptyViewTest.java
new file mode 100644
index 0000000..ca12154
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListEmptyViewTest.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import android.app.Instrumentation;
+import android.content.Intent;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ListView;
+
+public class ListEmptyViewTest extends ActivityInstrumentationTestCase<ListWithEmptyView> {
+ private ListWithEmptyView mActivity;
+ private ListView mListView;
+
+
+ public ListEmptyViewTest() {
+ super("com.android.frameworktest", ListWithEmptyView.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ assertTrue("Empty view not shown", mListView.getVisibility() == View.GONE);
+ }
+
+ @MediumTest
+ public void testZeroToOne() {
+ Instrumentation inst = getInstrumentation();
+
+ inst.invokeMenuActionSync(mActivity, mActivity.MENU_ADD, 0);
+ inst.waitForIdleSync();
+ assertTrue("Empty view still shown", mActivity.getEmptyView().getVisibility() == View.GONE);
+ assertTrue("List not shown", mActivity.getListView().getVisibility() == View.VISIBLE);
+ }
+
+ @MediumTest
+ public void testZeroToOneForwardBack() {
+ Instrumentation inst = getInstrumentation();
+
+ inst.invokeMenuActionSync(mActivity, mActivity.MENU_ADD, 0);
+ inst.waitForIdleSync();
+ assertTrue("Empty view still shown", mActivity.getEmptyView().getVisibility() == View.GONE);
+ assertTrue("List not shown", mActivity.getListView().getVisibility() == View.VISIBLE);
+
+ // Navigate forward
+ Intent intent = new Intent();
+ intent.setClass(mActivity, ListWithEmptyView.class);
+ mActivity.startActivity(intent);
+
+ // Navigate backward
+ inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
+ inst.waitForIdleSync();
+ assertTrue("Empty view still shown", mActivity.getEmptyView().getVisibility() == View.GONE);
+ assertTrue("List not shown", mActivity.getListView().getVisibility() == View.VISIBLE);
+
+ }
+
+ @LargeTest
+ public void testZeroToManyToZero() {
+ Instrumentation inst = getInstrumentation();
+
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ inst.invokeMenuActionSync(mActivity, mActivity.MENU_ADD, 0);
+ inst.waitForIdleSync();
+ assertTrue("Empty view still shown",
+ mActivity.getEmptyView().getVisibility() == View.GONE);
+ assertTrue("List not shown", mActivity.getListView().getVisibility() == View.VISIBLE);
+ }
+
+ for (i = 0; i < 10; i++) {
+ inst.invokeMenuActionSync(mActivity, mActivity.MENU_REMOVE, 0);
+ inst.waitForIdleSync();
+ if (i < 9) {
+ assertTrue("Empty view still shown",
+ mActivity.getEmptyView().getVisibility() == View.GONE);
+ assertTrue("List not shown",
+ mActivity.getListView().getVisibility() == View.VISIBLE);
+ } else {
+ assertTrue("Empty view not shown",
+ mActivity.getEmptyView().getVisibility() == View.VISIBLE);
+ assertTrue("List still shown",
+ mActivity.getListView().getVisibility() == View.GONE);
+ }
+ }
+
+ // Navigate forward
+ Intent intent = new Intent();
+ intent.setClass(mActivity, ListWithEmptyView.class);
+ mActivity.startActivity(intent);
+
+ // Navigate backward
+ inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
+ inst.waitForIdleSync();
+ assertTrue("Empty view not shown", mActivity.getEmptyView().getVisibility() == View.VISIBLE);
+ assertTrue("List still shown", mActivity.getListView().getVisibility() == View.GONE);
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListFocusableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListFocusableTest.java
new file mode 100644
index 0000000..1bb1f1c
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListFocusableTest.java
@@ -0,0 +1,232 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.widget.ListAdapter;
+import android.widget.ArrayAdapter;
+
+public class ListFocusableTest extends ActivityInstrumentationTestCase<ListTopGravity> {
+ private ListTopGravity mActivity;
+ private ListView mListView;
+
+ public ListFocusableTest() {
+ super("com.android.frameworktest", ListTopGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ // First item should be selected
+ assertEquals(0, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testAdapterFull() {
+ setFullAdapter();
+ assertTrue(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterEmpty() {
+ setEmptyAdapter();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterNull() {
+ setNullAdapter();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterFullSetFocusable() {
+ assertTrue(mListView.isFocusable());
+
+ setFocusable();
+ assertTrue(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterFullSetNonFocusable() {
+ assertTrue(mListView.isFocusable());
+
+ setNonFocusable();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterEmptySetFocusable() {
+ setEmptyAdapter();
+ assertFalse(mListView.isFocusable());
+
+ setFocusable();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterEmptySetNonFocusable() {
+ setEmptyAdapter();
+ assertFalse(mListView.isFocusable());
+
+ setNonFocusable();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterNullSetFocusable() {
+ setNullAdapter();
+ assertFalse(mListView.isFocusable());
+
+ setFocusable();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testAdapterNullSetNonFocusable() {
+ setNullAdapter();
+ assertFalse(mListView.isFocusable());
+
+ setNonFocusable();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testFocusableSetAdapterFull() {
+ assertTrue(mListView.isFocusable());
+
+ setFullAdapter();
+ assertTrue(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testNonFocusableSetAdapterFull() {
+ assertTrue(mListView.isFocusable());
+
+ setNonFocusable();
+ assertFalse(mListView.isFocusable());
+
+ setFullAdapter();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testFocusableSetAdapterEmpty() {
+ assertTrue(mListView.isFocusable());
+
+ setEmptyAdapter();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testNonFocusableSetAdapterEmpty() {
+ assertTrue(mListView.isFocusable());
+
+ setNonFocusable();
+ assertFalse(mListView.isFocusable());
+
+ setEmptyAdapter();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testFocusableSetAdapterNull() {
+ assertTrue(mListView.isFocusable());
+
+ setNullAdapter();
+ assertFalse(mListView.isFocusable());
+ }
+
+ @MediumTest
+ public void testNonFocusableSetAdapterNull() {
+ assertTrue(mListView.isFocusable());
+
+ setNonFocusable();
+ assertFalse(mListView.isFocusable());
+
+ setNullAdapter();
+ assertFalse(mListView.isFocusable());
+ }
+
+ private ListAdapter createFullAdapter() {
+ return new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_1,
+ new String[] { "Android", "Robot" });
+ }
+
+ private ListAdapter createEmptyAdapter() {
+ return new ArrayAdapter<String>(mActivity, android.R.layout.simple_list_item_1,
+ new String[] { });
+ }
+
+
+ private void setFullAdapter() {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setAdapter(createFullAdapter());
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ }
+
+ private void setEmptyAdapter() {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setAdapter(createEmptyAdapter());
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ }
+
+ private void setNullAdapter() {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setAdapter(null);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ }
+
+ private void setFocusable() {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setFocusable(true);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ }
+
+ private void setNonFocusable() {
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setFocusable(false);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListHeterogeneousTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListHeterogeneousTest.java
new file mode 100644
index 0000000..0e48993
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListHeterogeneousTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListHeterogeneous;
+
+public class ListHeterogeneousTest extends ActivityInstrumentationTestCase<ListHeterogeneous> {
+ private ListHeterogeneous mActivity;
+ private ListView mListView;
+
+
+ public ListHeterogeneousTest() {
+ super("com.android.frameworktest", ListHeterogeneous.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ }
+
+ @LargeTest
+ public void testKeyScrolling() {
+ Instrumentation inst = getInstrumentation();
+
+ int count = mListView.getAdapter().getCount();
+
+
+ for (int i = 0; i < count - 1; i++) {
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ inst.waitForIdleSync();
+ int convertMissesBefore = mActivity.getConvertMisses();
+
+ assertEquals("Unexpected convert misses", 0, convertMissesBefore);
+
+ for (int i = 0; i < count - 1; i++) {
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_UP);
+ }
+ inst.waitForIdleSync();
+ int convertMissesAfter = mActivity.getConvertMisses();
+
+ assertEquals("Unexpected convert misses", 0, convertMissesAfter);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListInHorizontalTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListInHorizontalTest.java
new file mode 100644
index 0000000..1432576
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListInHorizontalTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.listview.ListInHorizontal;
+
+public class ListInHorizontalTest extends ListUnspecifiedMeasure<ListInHorizontal> {
+ public ListInHorizontalTest() {
+ super(ListInHorizontal.class);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListInVerticalTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListInVerticalTest.java
new file mode 100644
index 0000000..73078b9
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListInVerticalTest.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.listview.ListInVertical;
+
+public class ListInVerticalTest extends ListUnspecifiedMeasure<ListInVertical> {
+ public ListInVerticalTest() {
+ super(ListInVertical.class);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListItemRequestRectAboveThinFirstItemTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListItemRequestRectAboveThinFirstItemTest.java
new file mode 100644
index 0000000..16c4d39
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListItemRequestRectAboveThinFirstItemTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.graphics.Rect;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.KeyEvent;
+import android.widget.ListView;
+import com.android.frameworktest.listview.ListOfThinItems;
+
+public class ListItemRequestRectAboveThinFirstItemTest
+ extends ActivityInstrumentationTestCase<ListOfThinItems> {
+ private ListView mListView;
+
+ public ListItemRequestRectAboveThinFirstItemTest() {
+ super("com.android.frameworktest", ListOfThinItems.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+
+ assertTrue("first child needs to be within fading edge height",
+ mListView.getChildAt(0).getBottom() < mListView.getVerticalFadingEdgeLength());
+ assertTrue("should be at least two visible children",
+ mListView.getChildCount() >= 2);
+ }
+
+ // reproduce bug 998501: when first item fits within fading edge,
+ // having the second item call requestRectangleOnScreen with a rect above
+ // the bounds of the list, it was scrolling too far
+ @MediumTest
+ public void testSecondItemRequestRectAboveTop() throws Exception {
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("selected position", 1, mListView.getSelectedItemPosition());
+
+ final View second = mListView.getChildAt(1);
+ final Rect rect = new Rect();
+ second.getDrawingRect(rect);
+ rect.offset(0, -2 * second.getBottom());
+
+ getActivity().requestRectangleOnScreen(1, rect);
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals("top of first item",
+ mListView.getListPaddingTop(), mListView.getChildAt(0).getTop());
+
+ }
+
+ // same thing, but at bottom
+ @LargeTest
+ public void testSecondToLastItemRequestRectBelowBottom() throws Exception {
+
+ final int secondToLastPos = mListView.getCount() - 2;
+
+ while (mListView.getSelectedItemPosition() < secondToLastPos) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals("selected position", secondToLastPos,
+ mListView.getSelectedItemPosition());
+
+ final View secondToLast = mListView.getSelectedView();
+ final Rect rect = new Rect();
+ secondToLast.getDrawingRect(rect);
+ rect.offset(0,
+ 2 * (mListView.getBottom() - secondToLast.getTop()));
+
+ final int secondToLastIndex = mListView.getChildCount() - 2;
+ getActivity().requestRectangleOnScreen(secondToLastIndex, rect);
+ getInstrumentation().waitForIdleSync();
+
+ int listBottom = mListView.getHeight() - mListView.getPaddingBottom();
+ assertEquals("bottom of last item should be at bottom of list",
+ listBottom,
+ mListView.getChildAt(mListView.getChildCount() - 1).getBottom());
+ }
+
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListManagedCursorTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListManagedCursorTest.java
new file mode 100644
index 0000000..0251dfb
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListManagedCursorTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.FlakyTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.ListView;
+import android.test.TouchUtils;
+
+/**
+ * Tests restoring the scroll position in a list with a managed cursor.
+ */
+public class ListManagedCursorTest extends ActivityInstrumentationTestCase<ListManagedCursor> {
+ private ListManagedCursor mActivity;
+ private ListView mListView;
+
+ public ListManagedCursorTest() {
+ super("com.android.frameworktest", ListManagedCursor.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ assertEquals(0, mListView.getFirstVisiblePosition());
+ }
+
+ /**
+ * Scroll the list using arrows, launch new activity, hit back, make sure we're still scrolled.
+ */
+ @LargeTest
+ public void testKeyScrolling() {
+ Instrumentation inst = getInstrumentation();
+
+ int firstVisiblePosition = arrowScroll(inst);
+
+ inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
+ inst.waitForIdleSync();
+
+ assertTrue("List changed to touch mode", !mListView.isInTouchMode());
+ assertTrue("List did not preserve scroll position",
+ firstVisiblePosition == mListView.getFirstVisiblePosition());
+ }
+
+ /**
+ * Scroll the list using touch, launch new activity, hit back, make sure we're still scrolled.
+ */
+ @LargeTest
+ public void testTouchScrolling() {
+ Instrumentation inst = getInstrumentation();
+
+ int firstVisiblePosition = touchScroll(inst);
+
+ inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
+ inst.waitForIdleSync();
+
+ assertTrue("List not in touch mode", mListView.isInTouchMode());
+ assertTrue("List did not preserve scroll position",
+ firstVisiblePosition == mListView.getFirstVisiblePosition());
+ }
+
+ /**
+ * Scroll the list using arrows, launch new activity, change to touch mode, hit back, make sure
+ * we're still scrolled.
+ */
+ @LargeTest
+ public void testKeyScrollingToTouchMode() {
+ Instrumentation inst = getInstrumentation();
+
+ int firstVisiblePosition = arrowScroll(inst);
+
+ TouchUtils.dragQuarterScreenUp(this);
+ inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
+ inst.waitForIdleSync();
+
+ assertTrue("List did not change to touch mode", mListView.isInTouchMode());
+ assertTrue("List did not preserve scroll position",
+ firstVisiblePosition == mListView.getFirstVisiblePosition());
+ }
+
+
+ /**
+ * Scroll the list using touch, launch new activity, change to trackball mode, hit back, make
+ * sure we're still scrolled.
+ */
+ @FlakyTest(tolerance=3)
+ @LargeTest
+ public void testTouchScrollingToTrackballMode() {
+ Instrumentation inst = getInstrumentation();
+
+ int firstVisiblePosition = touchScroll(inst);
+
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ inst.waitForIdleSync();
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ inst.waitForIdleSync();
+ inst.sendCharacterSync(KeyEvent.KEYCODE_BACK);
+ inst.waitForIdleSync();
+ assertTrue("List not in trackball mode", !mListView.isInTouchMode());
+ assertTrue("List did not preserve scroll position", firstVisiblePosition == mListView
+ .getFirstVisiblePosition());
+ }
+
+ public int arrowScroll(Instrumentation inst) {
+ int count = mListView.getChildCount();
+
+ for (int i = 0; i < count * 2; i++) {
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ inst.waitForIdleSync();
+
+ int firstVisiblePosition = mListView.getFirstVisiblePosition();
+ assertTrue("Arrow scroll did not happen", firstVisiblePosition > 0);
+ assertTrue("List still in touch mode", !mListView.isInTouchMode());
+
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_CENTER);
+ inst.waitForIdleSync();
+
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ return firstVisiblePosition;
+ }
+
+ public int touchScroll(Instrumentation inst) {
+ TouchUtils.dragQuarterScreenUp(this);
+ inst.waitForIdleSync();
+ TouchUtils.dragQuarterScreenUp(this);
+ inst.waitForIdleSync();
+ TouchUtils.dragQuarterScreenUp(this);
+ inst.waitForIdleSync();
+ TouchUtils.dragQuarterScreenUp(this);
+ inst.waitForIdleSync();
+
+ int firstVisiblePosition = mListView.getFirstVisiblePosition();
+ assertTrue("Touch scroll did not happen", firstVisiblePosition > 0);
+ assertTrue("List not in touch mode", mListView.isInTouchMode());
+
+ TouchUtils.clickView(this, mListView.getChildAt(mListView.getChildCount() - 1));
+ inst.waitForIdleSync();
+
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ return firstVisiblePosition;
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListRetainsFocusAcrossLayoutsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListRetainsFocusAcrossLayoutsTest.java
new file mode 100644
index 0000000..02a8beb
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListRetainsFocusAcrossLayoutsTest.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.listview.ListItemFocusablesClose;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+
+public class ListRetainsFocusAcrossLayoutsTest extends ActivityInstrumentationTestCase<ListItemFocusablesClose> {
+
+ public ListRetainsFocusAcrossLayoutsTest() {
+ super("com.android.frameworktest", ListItemFocusablesClose.class);
+ }
+
+ private void requestLayoutOnList() {
+ getActivity().runOnUiThread(new Runnable() {
+ public void run() {
+ getActivity().getListView().requestLayout();
+ }
+ });
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("top button at position 0 should be focused",
+ getActivity().getChildOfItem(0, 0).isFocused());
+ }
+
+ @MediumTest
+ public void testBottomButtonRetainsFocusAfterLayout() throws Exception {
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertTrue("bottom botton at position 0 should be focused",
+ getActivity().getChildOfItem(0, 2).isFocused());
+
+ requestLayoutOnList();
+ getInstrumentation().waitForIdleSync();
+
+ assertTrue("bottom botton at position 0 should be focused after layout",
+ getActivity().getChildOfItem(0, 2).isFocused());
+ }
+
+ @MediumTest
+ public void testTopButtonOfSecondPositionRetainsFocusAfterLayout() {
+ sendRepeatedKeys(2, KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertTrue("top botton at position 1 should be focused",
+ getActivity().getChildOfItem(1, 0).isFocused());
+
+ requestLayoutOnList();
+ getInstrumentation().waitForIdleSync();
+
+ assertTrue("top botton at position 1 should be focused after layout",
+ getActivity().getChildOfItem(1, 0).isFocused());
+
+ }
+
+ @MediumTest
+ public void testBottomButtonOfSecondPositionRetainsFocusAfterLayout() {
+ sendRepeatedKeys(3, KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertTrue("bottom botton at position 1 should be focused",
+ getActivity().getChildOfItem(1, 2).isFocused());
+
+ requestLayoutOnList();
+ getInstrumentation().waitForIdleSync();
+
+ assertTrue("bottom botton at position 1 should be focused after layout",
+ getActivity().getChildOfItem(1, 2).isFocused());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListScrollListenerTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListScrollListenerTest.java
new file mode 100644
index 0000000..44958d9
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListScrollListenerTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.AbsListView;
+import android.widget.ListView;
+
+import android.test.TouchUtils;
+
+public class ListScrollListenerTest extends ActivityInstrumentationTestCase<ListScrollListener> implements
+ AbsListView.OnScrollListener {
+ private ListScrollListener mActivity;
+ private ListView mListView;
+ private int mFirstVisibleItem = -1;
+ private int mVisibleItemCount = -1;
+ private int mTotalItemCount = -1;
+
+ public ListScrollListenerTest() {
+ super("com.android.frameworktest", ListScrollListener.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ mListView.setOnScrollListener(this);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ assertEquals(0, mFirstVisibleItem);
+ }
+
+ @LargeTest
+ public void testKeyScrolling() {
+ Instrumentation inst = getInstrumentation();
+
+ int firstVisibleItem = mFirstVisibleItem;
+ for (int i = 0; i < mVisibleItemCount * 2; i++) {
+ inst.sendCharacterSync(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ inst.waitForIdleSync();
+ assertTrue("Arrow scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+
+ firstVisibleItem = mFirstVisibleItem;
+ inst.sendCharacterSync(KeyEvent.KEYCODE_SPACE);
+ inst.waitForIdleSync();
+ assertTrue("Page scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+
+ firstVisibleItem = mFirstVisibleItem;
+ KeyEvent down = new KeyEvent(0, 0, KeyEvent.ACTION_DOWN,
+ KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_ALT_ON);
+ KeyEvent up = new KeyEvent(0, 0, KeyEvent.ACTION_UP,
+ KeyEvent.KEYCODE_DPAD_DOWN, 0, KeyEvent.META_ALT_ON);
+ inst.sendKeySync(down);
+ inst.sendKeySync(up);
+ inst.waitForIdleSync();
+
+ assertTrue("Full scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+ assertEquals("Full scroll did not happen", mTotalItemCount,
+ mFirstVisibleItem + mVisibleItemCount);
+ }
+
+ @LargeTest
+ public void testTouchScrolling() {
+ int firstVisibleItem = mFirstVisibleItem;
+ TouchUtils.dragQuarterScreenUp(this);
+ TouchUtils.dragQuarterScreenUp(this);
+ assertTrue("Touch scroll did not happen", mFirstVisibleItem > firstVisibleItem);
+ }
+
+
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
+ mFirstVisibleItem = firstVisibleItem;
+ mVisibleItemCount = visibleItemCount;
+ mTotalItemCount = totalItemCount;
+ }
+
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListSetSelectionTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListSetSelectionTest.java
new file mode 100644
index 0000000..e35d894
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListSetSelectionTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.UiThreadTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+
+/**
+ * Basic tests of setting & clearing the selection
+ */
+public class ListSetSelectionTest extends ActivityInstrumentationTestCase2<ListSimple> {
+ private ListSimple mActivity;
+ private ListView mListView;
+
+ public ListSetSelectionTest() {
+ super("com.android.frameworktest", ListSimple.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ }
+
+ /** Confirm that we can set the selection to each specific position */
+ @MediumTest
+ @UiThreadTest
+ public void testSetSelection() {
+ // Set the selection to each position
+ int childCount = mListView.getChildCount();
+ for (int i=0; i<childCount; i++) {
+ mListView.setSelection(i);
+ assertEquals("Set selection", i, mListView.getSelectedItemPosition());
+ }
+ }
+
+ /** Confirm that you cannot unset the selection using the same API */
+ @MediumTest
+ @UiThreadTest
+ public void testClearSelection() {
+ // Set the selection to first position
+ mListView.setSelection(0);
+ assertEquals("Set selection", 0, mListView.getSelectedItemPosition());
+
+ // Clear the selection
+ mListView.setSelection(ListView.INVALID_POSITION);
+ assertEquals("Set selection", 0, mListView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListUnspecifiedMeasure.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListUnspecifiedMeasure.java
new file mode 100644
index 0000000..55a57ef
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListUnspecifiedMeasure.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview;
+
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.app.Activity;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+
+public class ListUnspecifiedMeasure<T extends Activity> extends ActivityInstrumentationTestCase<T> {
+ private T mActivity;
+ private ListView mListView;
+
+ protected ListUnspecifiedMeasure(Class<T> klass) {
+ super("com.android.frameworktest", klass);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = (ListView) mActivity.findViewById(R.id.list);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ }
+
+ @MediumTest
+ public void testWasMeasured() {
+ assertTrue(mListView.getMeasuredWidth() > 0);
+ assertTrue(mListView.getWidth() > 0);
+ assertTrue(mListView.getMeasuredHeight() > 0);
+ assertTrue(mListView.getHeight() > 0);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListViewHeightTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListViewHeightTest.java
new file mode 100644
index 0000000..d5bdf8b
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/ListViewHeightTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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 com.android.frameworktest.listview;
+
+import android.app.Instrumentation;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+import android.widget.ListView;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.listview.ListViewHeight;
+
+public class ListViewHeightTest extends ActivityInstrumentationTestCase<ListViewHeight> {
+ private ListViewHeight mActivity;
+
+
+ public ListViewHeightTest() {
+ super("com.android.frameworktest", ListViewHeight.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ }
+
+ @MediumTest
+ public void testButtons() {
+ Instrumentation inst = getInstrumentation();
+ final Button button1 = (Button) mActivity.findViewById(R.id.button1);
+ final Button button2 = (Button) mActivity.findViewById(R.id.button2);
+ final Button button3 = (Button) mActivity.findViewById(R.id.button3);
+
+
+ ListView list = (ListView) mActivity.findViewById(R.id.inner_list);
+ assertEquals("Unexpected items in adapter", 0, list.getCount());
+ assertEquals("Unexpected children in list view", 0, list.getChildCount());
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ button1.performClick();
+ }
+ });
+ inst.waitForIdleSync();
+ assertTrue("List not be visible after clicking button1", list.isShown());
+ assertTrue("List incorrect height", list.getHeight() == 200);
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ button2.performClick();
+ }
+ });
+ inst.waitForIdleSync();
+ assertTrue("List not be visible after clicking button2", list.isShown());
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ button3.performClick();
+ }
+ });
+ inst.waitForIdleSync();
+ assertFalse("List should not be visible clicking button3", list.isShown());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListInterleaveFocusablesTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListInterleaveFocusablesTest.java
new file mode 100644
index 0000000..1fe75c4
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListInterleaveFocusablesTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.KeyEvent;
+import android.view.View;
+
+import com.android.frameworktest.listview.ListInterleaveFocusables;
+import com.android.frameworktest.util.ListUtil;
+
+public class ListInterleaveFocusablesTest extends ActivityInstrumentationTestCase<ListInterleaveFocusables> {
+ private ListView mListView;
+ private ListUtil mListUtil;
+
+ public ListInterleaveFocusablesTest() {
+ super("com.android.frameworktest", ListInterleaveFocusables.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mListView = getActivity().getListView();
+ mListUtil = new ListUtil(mListView, getInstrumentation());
+ }
+
+ @LargeTest
+ public void testPreconditions() {
+ assertEquals(7, mListView.getChildCount());
+ assertTrue(mListView.getChildAt(1).isFocusable());
+ assertTrue(mListView.getChildAt(3).isFocusable());
+ assertTrue(mListView.getChildAt(6).isFocusable());
+ }
+
+ @MediumTest
+ public void testGoingFromUnFocusableSelectedToFocusable() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals("selected item position", 1, mListView.getSelectedItemPosition());
+ assertSelectedViewFocus(true);
+ }
+
+ // go down from an item that isn't focusable, make sure it finds the focusable
+ // below (instead of above). this exposes a (now fixed) bug where the focus search
+ // was not starting from the right spot
+ @MediumTest
+ public void testGoingDownFromUnFocusableSelectedToFocusableWithOtherFocusableAbove() {
+ mListUtil.setSelectedPosition(2);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("selected item position", 3, mListView.getSelectedItemPosition());
+ assertSelectedViewFocus(true);
+ }
+
+ // same, but going up
+ @MediumTest
+ public void testGoingUpFromUnFocusableSelectedToFocusableWithOtherFocusableAbove() {
+ mListUtil.setSelectedPosition(2);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("selected item position", 1, mListView.getSelectedItemPosition());
+ assertSelectedViewFocus(true);
+ }
+
+ /**
+ * Go down from a focusable when there is a focusable below, but it is more than
+ * one item away; make sure it won't give that item focus because it is too far away.
+ */
+ @MediumTest
+ public void testGoingDownFromFocusableToUnfocusableWhenFocusableIsBelow() {
+ mListUtil.setSelectedPosition(3);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("selected item position", 4, mListView.getSelectedItemPosition());
+ assertSelectedViewFocus(false);
+ }
+
+ // same but going up
+ @MediumTest
+ public void testGoingUpFromFocusableToUnfocusableWhenFocusableIsBelow() {
+ mListUtil.setSelectedPosition(6);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("selected item position", 5, mListView.getSelectedItemPosition());
+ assertSelectedViewFocus(false);
+ }
+
+ public void assertSelectedViewFocus(boolean isFocused) {
+ final View view = mListView.getSelectedView();
+ assertEquals("selected view focused", isFocused, view.isFocused());
+ assertEquals("selected position's isSelected should be the inverse "
+ + "of it having focus", !isFocused, view.isSelected());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusableAboveUnfocusableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusableAboveUnfocusableTest.java
new file mode 100644
index 0000000..6ff9181
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusableAboveUnfocusableTest.java
@@ -0,0 +1,55 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.KeyEvent;
+import com.android.frameworktest.listview.ListItemFocusableAboveUnfocusable;
+
+public class ListItemFocusableAboveUnfocusableTest extends ActivityInstrumentationTestCase<ListItemFocusableAboveUnfocusable> {
+ private ListView mListView;
+
+ public ListItemFocusableAboveUnfocusableTest() {
+ super("com.android.frameworktest", ListItemFocusableAboveUnfocusable.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mListView = getActivity().getListView();
+ }
+
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals("selected position", 0, mListView.getSelectedItemPosition());
+ assertTrue(mListView.getChildAt(0).isFocused());
+ assertFalse(mListView.getChildAt(1).isFocusable());
+ }
+
+ @MediumTest
+ public void testMovingToUnFocusableTakesFocusAway() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertFalse("focused item should have lost focus",
+ mListView.getChildAt(0).isFocused());
+ assertEquals("selected position", 1, mListView.getSelectedItemPosition());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusablesCloseTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusablesCloseTest.java
new file mode 100644
index 0000000..07356ba
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusablesCloseTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import com.android.frameworktest.listview.ListItemFocusablesClose;
+
+public class ListItemFocusablesCloseTest extends ActivityInstrumentationTestCase<ListItemFocusablesClose> {
+ private ListView mListView;
+ private int mListTop;
+ private int mListBottom;
+
+ public ListItemFocusablesCloseTest() {
+ super("com.android.frameworktest", ListItemFocusablesClose.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception{
+ super.setUp();
+ mListView = getActivity().getListView();
+ mListTop = mListView.getListPaddingTop();
+ mListBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mListView);
+ assertTrue(mListView.getAdapter().areAllItemsEnabled());
+ assertTrue(mListView.getItemsCanFocus());
+ assertEquals(0, mListView.getSelectedItemPosition());
+ final LinearLayout first = (LinearLayout) mListView.getSelectedView();
+ getInstrumentation().waitForIdleSync();
+ assertEquals("first item should be at top of screen",
+ mListView.getListPaddingTop(),
+ first.getTop());
+ assertTrue("first button of first list item should have focus",
+ first.getChildAt(0).isFocused());
+ assertTrue("item should be shorter than list for this test to make sense",
+ first.getHeight() < mListView.getHeight());
+ assertEquals("two items should be on screen",
+ 2, mListView.getChildCount());
+ assertTrue("first button of second item should be on screen",
+ getActivity().getChildOfItem(1, 0).getBottom() < mListBottom);
+ }
+
+
+ @MediumTest
+ public void testChangeFocusWithinItem() {
+ final LinearLayout first = (LinearLayout) mListView.getSelectedView();
+ final int topOfFirstItemBefore = first.getTop();
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertTrue("focus should have moved to second button of first item",
+ first.getChildAt(2).isFocused());
+ assertEquals("selection should not have changed",
+ 0, mListView.getSelectedItemPosition());
+ assertEquals("list item should not have been shifted",
+ topOfFirstItemBefore, first.getTop());
+
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertTrue("focus should have moved back to first button of first item",
+ first.getChildAt(0).isFocused());
+ assertEquals("list item should not have been shifted",
+ topOfFirstItemBefore, first.getTop());
+ }
+
+ @MediumTest
+ public void testMoveDownToButtonInDifferentSelection() {
+ final LinearLayout first = (LinearLayout) mListView.getSelectedView();
+ final int topOfFirstItemBefore = first.getTop();
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals("selection should have moved to second item",
+ 1, mListView.getSelectedItemPosition());
+ final LinearLayout selectedItem = (LinearLayout) mListView.getSelectedView();
+ assertTrue("first button of second item should have focus",
+ selectedItem.getChildAt(0).isFocused());
+ assertEquals("list item should not have been shifted",
+ topOfFirstItemBefore, first.getTop());
+ }
+
+ @MediumTest
+ public void testMoveUpToButtonInDifferentSelection() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(1, mListView.getSelectedItemPosition());
+ assertTrue("first button of second item should have focus",
+ getActivity().getChildOfItem(1, 0).hasFocus());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("first list item should have selection", 0,
+ mListView.getSelectedItemPosition());
+ assertTrue("second button of first item should have focus",
+ getActivity().getChildOfItem(0, 2).hasFocus());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusablesFarApartTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusablesFarApartTest.java
new file mode 100644
index 0000000..951e021
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemFocusablesFarApartTest.java
@@ -0,0 +1,116 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ListView;
+import com.android.frameworktest.listview.ListItemFocusablesFarApart;
+
+public class ListItemFocusablesFarApartTest extends ActivityInstrumentationTestCase<ListItemFocusablesFarApart> {
+ private ListView mListView;
+ private int mListTop;
+ private int mListBottom;
+
+ public ListItemFocusablesFarApartTest() {
+ super("com.android.frameworktest", ListItemFocusablesFarApart.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ mListTop = mListView.getListPaddingTop();
+ mListBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+ }
+
+ /**
+ * Get the child of a list item.
+ * @param listIndex The index of the currently visible items
+ * @param index The index of the child.
+ */
+ public View getChildOfItem(int listIndex, int index) {
+ return ((ViewGroup) mListView.getChildAt(listIndex)).getChildAt(index);
+
+ }
+
+ public int getTopOfChildOfItem(int listIndex, int index) {
+ ViewGroup listItem = (ViewGroup) mListView.getChildAt(listIndex);
+ View child = listItem.getChildAt(index);
+ return child.getTop() + listItem.getTop();
+ }
+
+ public int getBottomOfChildOfItem(int listIndex, int index) {
+ ViewGroup listItem = (ViewGroup) mListView.getChildAt(listIndex);
+ View child = listItem.getChildAt(index);
+ return child.getBottom() + listItem.getTop();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mListView);
+ assertEquals("should only be one visible list item",
+ 1, mListView.getChildCount());
+ int topOfFirstButton = getTopOfChildOfItem(0, 0);
+ int topOfSecondButton = getTopOfChildOfItem(0, 2);
+ assertTrue("second button should be more than max scroll away from first",
+ topOfSecondButton - topOfFirstButton > mListView.getMaxScrollAmount());
+ }
+
+
+ @MediumTest
+ public void testPanWhenNextFocusableTooFarDown() {
+
+ int expectedTop = mListView.getChildAt(0).getTop();
+
+ final Button topButton = (Button) getChildOfItem(0, 0);
+
+ int counter = 0;
+ while(getTopOfChildOfItem(0, 2) > mListBottom) {
+ // just to make sure we never end up with an infinite loop
+ if (counter > 5) fail("couldn't reach next button within " + counter + " downs");
+
+ if (getBottomOfChildOfItem(0, 0) < mListTop) {
+ assertFalse("after " + counter + " downs, top button not visible, should not have focus",
+ topButton.isFocused());
+ assertFalse("after " + counter + " downs, neither top button nor botom button visible, nothng within first list " +
+ "item should have focus", mListView.getChildAt(0).hasFocus());
+ } else {
+ assertTrue("after " + counter + " downs, top button still visible, should have focus",
+ topButton.isFocused());
+ }
+
+ assertEquals("after " + counter + " downs, " +
+ "should have panned by max scroll amount",
+ expectedTop, mListView.getChildAt(0).getTop());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ expectedTop -= mListView.getMaxScrollAmount();
+ counter++;
+ }
+
+ // at this point, the second button is visible on screen.
+ // it should have focus
+ assertTrue("second button should have focus",
+ getChildOfItem(0, 2).isFocused());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemsExpandOnSelectionTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemsExpandOnSelectionTest.java
new file mode 100644
index 0000000..f61ce7b
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListItemsExpandOnSelectionTest.java
@@ -0,0 +1,118 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.KeyEvent;
+import com.android.frameworktest.listview.ListItemsExpandOnSelection;
+
+public class ListItemsExpandOnSelectionTest extends ActivityInstrumentationTestCase<ListItemsExpandOnSelection> {
+ private ListView mListView;
+ private int mListTop;
+ private int mListBottom;
+ private int mExpandedHeight;
+ private int mNormalHeight;
+
+ public ListItemsExpandOnSelectionTest() {
+ super("com.android.frameworktest",
+ ListItemsExpandOnSelection.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ mListTop = mListView.getListPaddingTop();
+ mListBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+ mExpandedHeight = mListView.getChildAt(0).getHeight();
+ mNormalHeight = mListView.getChildAt(1).getHeight();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals(0, mListView.getSelectedItemPosition());
+ assertEquals("selected item should be 1.5 times taller than the others",
+ mExpandedHeight, (int) (mNormalHeight * 1.5));
+ }
+
+ @MediumTest
+ public void testMoveSelectionDownNotRequiringScroll() {
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals(1, mListView.getSelectedItemPosition());
+ assertEquals("first item's top should not have shifted",
+ mListTop, mListView.getChildAt(0).getTop());
+
+ }
+
+ @MediumTest
+ public void testMoveSelectionUpNotRequiringScroll() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals(1, mListView.getSelectedItemPosition());
+ final int oldBottom = mListView.getSelectedView().getBottom();
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+ assertEquals("bottom of 2nd itme should have stayed the same when " +
+ "moving back up",
+ oldBottom,
+ mListView.getChildAt(1).getBottom());
+ }
+
+ @MediumTest
+ public void testMoveSelectionDownRequiringScroll() {
+ int lastItemIndex = mListView.getChildCount() - 1;
+
+ for(int i = 0; i < lastItemIndex; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals("list position", lastItemIndex, mListView.getSelectedItemPosition());
+ assertEquals("expanded height", mExpandedHeight, mListView.getSelectedView().getHeight());
+ assertEquals("should be above bottom fading edge",
+ mListBottom - mListView.getVerticalFadingEdgeLength(),
+ mListView.getSelectedView().getBottom());
+ }
+
+ @LargeTest
+ public void testMoveSelectionUpRequiringScroll() {
+ int childrenPerScreen = mListView.getChildCount();
+
+ // go down past last child on screen
+ for(int i = 0; i < childrenPerScreen; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+
+ // go back up to second to last
+ for(int i = 0; i < childrenPerScreen - 1; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ }
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals("list position", 1, mListView.getSelectedItemPosition());
+ assertEquals("expanded height", mExpandedHeight, mListView.getSelectedView().getHeight());
+ assertEquals("should be below top fading edge",
+ mListTop + mListView.getVerticalFadingEdgeLength(),
+ mListView.getSelectedView().getTop());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListLastItemPartiallyVisibleTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListLastItemPartiallyVisibleTest.java
new file mode 100644
index 0000000..38f4b0e
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListLastItemPartiallyVisibleTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.View;
+import android.view.KeyEvent;
+import com.android.frameworktest.listview.ListLastItemPartiallyVisible;
+
+public class ListLastItemPartiallyVisibleTest extends ActivityInstrumentationTestCase<ListLastItemPartiallyVisible> {
+ private ListView mListView;
+ private int mListBottom;
+
+
+ public ListLastItemPartiallyVisibleTest() {
+ super("com.android.frameworktest", ListLastItemPartiallyVisible.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ mListBottom = mListView.getHeight() - mListView.getPaddingBottom();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals("number of elements visible should be the same as number of items " +
+ "in adapter", mListView.getCount(), mListView.getChildCount());
+
+ final View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+ assertTrue("last item should be partially off screen",
+ lastChild.getBottom() > mListBottom);
+ assertEquals("selected position", 0, mListView.getSelectedItemPosition());
+ }
+
+ // reproduce bug 998094
+ @MediumTest
+ public void testMovingDownToFullyVisibleNoScroll() {
+ final View firstChild = mListView.getChildAt(0);
+ final int firstBottom = firstChild.getBottom();
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("shouldn't have scrolled: bottom of first child changed.",
+ firstBottom, firstChild.getBottom());
+ }
+
+ // reproduce bug 998094
+ @MediumTest
+ public void testMovingUpToFullyVisibleNoScroll() {
+ int numMovesToLast = mListView.getCount() - 1;
+ for (int i = 0; i < numMovesToLast; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals("should have moved to last position",
+ mListView.getChildCount() - 1, mListView.getSelectedItemPosition());
+
+ final View lastChild = mListView.getSelectedView();
+ final int lastTop = lastChild.getTop();
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("shouldn't have scrolled: top of last child changed.",
+ lastTop, lastChild.getTop());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfItemsShorterThanScreenTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfItemsShorterThanScreenTest.java
new file mode 100644
index 0000000..126eea2
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfItemsShorterThanScreenTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TextView;
+import com.android.frameworktest.listview.ListOfItemsShorterThanScreen;
+
+public class ListOfItemsShorterThanScreenTest
+ extends ActivityInstrumentationTestCase<ListOfItemsShorterThanScreen> {
+ private ListView mListView;
+ private ListOfItemsShorterThanScreen mActivity;
+
+
+ public ListOfItemsShorterThanScreenTest() {
+ super("com.android.frameworktest", ListOfItemsShorterThanScreen.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals(0, mListView.getSelectedItemPosition());
+ assertTrue(mListView.getChildAt(0).isSelected());
+ assertEquals(mListView.getListPaddingTop(), mListView.getSelectedView().getTop());
+ }
+
+ @MediumTest
+ public void testMoveDownToOnScreenNextItem() {
+ final View next = mListView.getChildAt(1);
+ assertFalse(next.isSelected());
+ final int secondPosition = mListView.getSelectedView().getBottom();
+ assertEquals("second item should be positioned item height pixels from top.",
+ secondPosition,
+ next.getTop());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(1, mListView.getSelectedItemPosition());
+ assertTrue(next.isSelected());
+ assertEquals("next selected item shouldn't have moved",
+ secondPosition,
+ next.getTop());
+ }
+
+ @MediumTest
+ public void testMoveUpToOnScreenItem() {
+ // move down one, then back up
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals(0, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testMoveDownToItemRequiringScrolling() {
+ final int lastOnScreenItemIndex = mListView.getChildCount() - 1;
+ final View lastItem = mListView.getChildAt(lastOnScreenItemIndex);
+ assertTrue("last item should be partially off screen",
+ lastItem.getBottom() > mListView.getBottom());
+ assertEquals(mListView.getListPaddingTop(), mListView.getSelectedView().getTop());
+
+ for (int i = 0; i < lastOnScreenItemIndex; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+
+ assertEquals(lastOnScreenItemIndex, mListView.getSelectedItemPosition());
+ assertEquals(
+ getTopOfBottomFadingEdge(),
+ mListView.getSelectedView().getBottom());
+
+ // there should be a peeking view
+
+ // the current view isn't the last anymore...
+ assertEquals(mListView.getSelectedView(), mListView.getChildAt(mListView.getChildCount() - 2));
+
+ // peeking view is now last
+ final TextView view = (TextView) mListView.getChildAt(mListView.getChildCount() - 1);
+ assertEquals(mActivity.getValueAtPosition(lastOnScreenItemIndex + 1), view.getText());
+ assertFalse(view.isSelected());
+ }
+
+ @MediumTest
+ public void testMoveUpToItemRequiringScrolling() {
+ // go down to one past last item, then back up to the second item. this will
+ // require scrolling to get it back on screen, and will need a peeking edge
+
+ int numItemsOnScreen = mListView.getChildCount();
+ for (int i = 0; i < numItemsOnScreen; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ for (int i = 0; i < numItemsOnScreen - 1; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ }
+
+ assertEquals(1, mListView.getSelectedItemPosition());
+ assertEquals("top should be just below vertical fading edge",
+ mListView.getVerticalFadingEdgeLength() + mListView.getListPaddingTop(),
+ mListView.getSelectedView().getTop());
+ }
+
+ @MediumTest
+ public void testPressUpWhenAlreadyAtTop() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+ assertEquals(0, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testPressDownWhenAlreadyAtBottom() {
+ final int lastItemPosition = mListView.getAdapter().getCount() - 1;
+ for (int i = 0; i < lastItemPosition; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals(lastItemPosition, mListView.getSelectedItemPosition());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(lastItemPosition, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testNoVerticalFadingEdgeWhenMovingToBottom() {
+ final int lastItemPosition = mListView.getAdapter().getCount() - 1;
+ for (int i = 0; i < lastItemPosition; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals(lastItemPosition, mListView.getSelectedItemPosition());
+
+ assertEquals("bottom of last item should be just above padding; no fading edge.",
+ mListView.getHeight() - mListView.getListPaddingBottom(),
+ mListView.getSelectedView().getBottom());
+
+ }
+
+ // the top of the bottom fading edge takes into account the list padding at the bottom,
+ // and the fading edge size
+ private int getTopOfBottomFadingEdge() {
+ return mListView.getHeight() - (mListView.getVerticalFadingEdgeLength() + mListView.getListPaddingBottom());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
new file mode 100644
index 0000000..ec3a15c
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfItemsTallerThanScreenTest.java
@@ -0,0 +1,195 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.View;
+import android.view.KeyEvent;
+import com.android.frameworktest.listview.ListOfItemsTallerThanScreen;
+
+public class ListOfItemsTallerThanScreenTest
+ extends ActivityInstrumentationTestCase<ListOfItemsTallerThanScreen> {
+
+ private ListView mListView;
+ private ListOfItemsTallerThanScreen mActivity;
+
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ public ListOfItemsTallerThanScreenTest() {
+ super("com.android.frameworktest", ListOfItemsTallerThanScreen.class);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mListView);
+ assertEquals("should only be one visible child", 1, mListView.getChildCount());
+ final int amountOffScreen = mListView.getChildAt(0).getBottom() - (mListView.getBottom() - mListView.getListPaddingBottom());
+ assertTrue("must be more than max scroll off screen for this test to work",
+ amountOffScreen > mListView.getMaxScrollAmount());
+ }
+
+ @MediumTest
+ public void testScrollDownAcrossItem() {
+ final View view = mListView.getSelectedView();
+ assertTrue(view.isSelected());
+
+ assertEquals(mListView.getListPaddingTop(),
+ view.getTop());
+
+ assertTrue("view must be taller than screen for this test to be worth anything",
+ view.getBottom() > mListView.getBottom());
+
+ // scroll down until next view is peeking ahead
+ int numScrollsUntilNextViewVisible = getNumDownPressesToScrollDownAcrossSelected();
+
+ for (int i = 0; i < numScrollsUntilNextViewVisible; i++) {
+ assertEquals("after " + i + " down scrolls across tall item",
+ mListView.getListPaddingTop() - mListView.getMaxScrollAmount() * i,
+ view.getTop());
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+
+ // at this point, next view should be on screen peeking ahead, but we haven't given
+ // it selection yet
+ assertEquals("child count", 2, mListView.getChildCount());
+ assertEquals("selected position", 0, mListView.getSelectedItemPosition());
+ assertTrue("same view should be selected", view.isSelected());
+ final View peekingView = mListView.getChildAt(1);
+ assertEquals(view.getBottom(), peekingView.getTop());
+ }
+
+ @MediumTest
+ public void testScrollDownToNextItem() {
+ final int numPresses = getNumDownPressesToScrollDownAcrossSelected();
+ assertEquals(1, mListView.getChildCount());
+
+ for (int i = 0; i < numPresses; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ // remember top of peeking child
+ final int topOfPeekingNext = mListView.getChildAt(1).getTop();
+
+ // next view is peeking, now press one more time
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ // old view should not have selection
+ assertFalse(mListView.getChildAt(0).isSelected());
+
+ // next view should now have selection, and be scrolled another a third of the list
+ // height
+ assertEquals(2, mListView.getChildCount());
+ final View next = mListView.getChildAt(1);
+ assertTrue("has selection", next.isSelected());
+ assertEquals(topOfPeekingNext - (mListView.getMaxScrollAmount()), next.getTop());
+ }
+
+ @MediumTest
+ public void testScrollFirstItemOffScreen() {
+ int numDownsToGetFirstItemOffScreen =
+ (mListView.getSelectedView().getHeight() / mListView.getMaxScrollAmount()) + 1;
+
+ for (int i = 0; i < numDownsToGetFirstItemOffScreen; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals("should be at next item",
+ 1, mListView.getSelectedItemPosition());
+
+ final int listTop = mListView.getTop() + mListView.getListPaddingTop();
+ assertTrue("top of selected view should be above top of list",
+ mListView.getSelectedView().getTop() < listTop);
+
+ assertEquals("off screen item shouldn't be a child of list view",
+ 1, mListView.getChildCount());
+ }
+
+ @LargeTest
+ public void testScrollDownToLastItem() {
+ final int numItems = mListView.getAdapter().getCount();
+
+ int maxDowns = 20;
+ while (mListView.getSelectedItemPosition() < (numItems - 1)) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ if (--maxDowns <= 0) {
+ fail("couldn't get to last item within 20 down arrows");
+ }
+ }
+ getInstrumentation().waitForIdleSync();
+
+ // press down enough times to get to bottom of last item
+ final int numDownsLeft = getNumDownPressesToScrollDownAcrossSelected();
+ assertTrue(numDownsLeft > 0);
+ for (int i = 0; i < numDownsLeft; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ // one more time to get across last item
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+
+ assertEquals(numItems - 1, mListView.getSelectedItemPosition());
+ final int realBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+ assertEquals(realBottom, mListView.getSelectedView().getBottom());
+
+ assertEquals("views scrolled off screen should be removed from view group",
+ 1, mListView.getChildCount());
+ }
+
+ @MediumTest
+ public void testScrollUpAcrossFirstItem() {
+ final int listTop = mListView.getListPaddingTop();
+ assertEquals(listTop, mListView.getSelectedView().getTop());
+ final int numPresses = getNumDownPressesToScrollDownAcrossSelected();
+ for (int i = 0; i < numPresses; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals(2, mListView.getChildCount());
+ for (int i = 0; i < numPresses; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals(1, mListView.getChildCount());
+ }
+ assertEquals(listTop, mListView.getSelectedView().getTop());
+ }
+
+ /**
+ * Assuming the selected view is overlapping the bottom edge, how many times
+ * do I have to press down to get beyond it so that either:
+ * a) the next view is peeking in
+ * b) the selected view is the last item in the list, and we are scrolled to the bottom
+ * @return
+ */
+ private int getNumDownPressesToScrollDownAcrossSelected() {
+ View selected = mListView.getSelectedView();
+ int realBottom = mListView.getBottom() - mListView.getListPaddingBottom();
+ assertTrue("view should be overlapping bottom",
+ selected.getBottom() > realBottom);
+ assertTrue("view should be overlapping bottom",
+ selected.getTop() < realBottom);
+
+ int pixelsOffScreen = selected.getBottom() - realBottom;
+ return (pixelsOffScreen / mListView.getMaxScrollAmount()) + 1;
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfShortShortTallShortShortTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
new file mode 100644
index 0000000..e218099
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfShortShortTallShortShortTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.ListView;
+import com.android.frameworktest.listview.ListOfShortShortTallShortShort;
+import com.android.frameworktest.util.ListUtil;
+
+public class ListOfShortShortTallShortShortTest extends ActivityInstrumentationTestCase<ListOfShortShortTallShortShort> {
+ private ListView mListView;
+ private ListUtil mListUtil;
+
+ public ListOfShortShortTallShortShortTest() {
+ super("com.android.frameworktest", ListOfShortShortTallShortShort.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ mListUtil = new ListUtil(mListView, getInstrumentation());
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals("list item count", 5, mListView.getCount());
+ assertEquals("list visible child count", 3, mListView.getChildCount());
+ int firstTwoHeight = mListView.getChildAt(0).getHeight() + mListView.getChildAt(1).getHeight();
+ assertTrue("first two items should fit within fading edge",
+ firstTwoHeight <= mListView.getVerticalFadingEdgeLength());
+ assertTrue("first two items should fit within list max scroll",
+ firstTwoHeight <= mListView.getMaxScrollAmount());
+ }
+
+ @MediumTest
+ public void testFadeTopTwoItemsOut() {
+ // put 2nd item selected
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ // one more to get two items scrolled off
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals("selected item position", 2, mListView.getSelectedItemPosition());
+ assertTrue("selected item top should be above list top",
+ mListView.getSelectedView().getTop() < mListUtil.getListTop());
+ assertTrue("selected item bottom should be below list bottom",
+ mListView.getSelectedView().getBottom() > mListUtil.getListBottom());
+ assertEquals("should only be 1 child of list (2 should have been scrolled off and removed",
+ 1, mListView.getChildCount());
+ }
+
+ @LargeTest
+ public void testFadeInTwoBottomItems() {
+ // put 2nd item selected
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ // one more to get two items scrolled off
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("number of list children", 1, mListView.getChildCount());
+
+ // last down brings bottom two items into view
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("should have scrolled two extra views onto screen",
+ 3, mListView.getChildCount());
+ assertEquals("new view position", 3, mListView.getChildAt(1).getId());
+ assertEquals("new view position", 4, mListView.getChildAt(2).getId());
+
+ assertTrue("bottom most view shouldn't be above list bottom",
+ mListView.getChildAt(2).getBottom() >= mListUtil.getListBottom());
+ }
+
+ @LargeTest
+ public void testFadeOutBottomTwoItems() throws Exception {
+ mListUtil.arrowScrollToSelectedPosition(4);
+
+ // go up to tall item
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+ // one more time to scroll off bottom two items
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+
+ assertEquals("selected item position", 2, mListView.getSelectedItemPosition());
+ assertTrue("selected item top should be at or above list top",
+ mListView.getSelectedView().getTop() <= mListUtil.getListTop());
+ assertTrue("selected item bottom should be below list bottom",
+ mListView.getSelectedView().getBottom() > mListUtil.getListBottom());
+ assertEquals("should only be 1 child of list (2 should have been scrolled off and removed",
+ 1, mListView.getChildCount());
+ }
+
+ @LargeTest
+ public void testFadeInTopTwoItems() throws Exception {
+ mListUtil.arrowScrollToSelectedPosition(4);
+
+ // put 2nd item selected
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+ // one more to get two items scrolled off
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("number of list children", 1, mListView.getChildCount());
+
+ // last down brings top two items into view
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("should have scrolled two extra views onto screen",
+ 3, mListView.getChildCount());
+ assertEquals("new view position", 0, mListView.getChildAt(0).getId());
+ assertEquals("new view position", 1, mListView.getChildAt(1).getId());
+
+ assertTrue("top most view shouldn't be above list top",
+ mListView.getChildAt(0).getTop() <= mListUtil.getListTop());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfShortTallShortTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfShortTallShortTest.java
new file mode 100644
index 0000000..6a83ada
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfShortTallShortTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.KeyEvent;
+import com.android.frameworktest.listview.ListOfShortTallShort;
+
+public class ListOfShortTallShortTest extends ActivityInstrumentationTestCase<ListOfShortTallShort> {
+ private ListView mListView;
+
+ public ListOfShortTallShortTest() {
+ super("com.android.frameworktest", ListOfShortTallShort.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("second item should be taller than screen",
+ mListView.getChildAt(1).getHeight() > mListView.getHeight());
+ }
+
+ @MediumTest
+ public void testGoDownFromShortToTall() {
+ int topBeforeMove = mListView.getChildAt(1).getTop();
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals("selection should have moved to tall item below",
+ 1, mListView.getSelectedItemPosition());
+ assertEquals("should not have scrolled; top should be the same.",
+ topBeforeMove,
+ mListView.getSelectedView().getTop());
+ }
+
+ @MediumTest
+ public void testGoUpFromShortToTall() {
+ int maxMoves = 8;
+ while (mListView.getSelectedItemPosition() != 2 && maxMoves > 0) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals("couldn't get to 3rd item",
+ 2,
+ mListView.getSelectedItemPosition());
+
+ assertEquals("should only be two items on screen",
+ 2, mListView.getChildCount());
+ assertEquals("selected item should be last item on screen",
+ mListView.getChildAt(1), mListView.getSelectedView());
+
+ final int bottomBeforeMove = mListView.getChildAt(0).getBottom();
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("should have moved selection to tall item above",
+ 1, mListView.getSelectedItemPosition());
+ assertEquals("should not have scrolled, top should be the same",
+ bottomBeforeMove,
+ mListView.getChildAt(0).getBottom());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfThinItemsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfThinItemsTest.java
new file mode 100644
index 0000000..e8dbbec
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListOfThinItemsTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ListView;
+import com.android.frameworktest.listview.ListOfThinItems;
+
+public class ListOfThinItemsTest extends ActivityInstrumentationTestCase<ListOfThinItems> {
+ private ListView mListView;
+
+ public ListOfThinItemsTest() {
+ super("com.android.frameworktest", ListOfThinItems.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception{
+ super.setUp();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mListView);
+ assertTrue("need item height less than fading edge length",
+ mListView.getSelectedView().getHeight() < mListView.getVerticalFadingEdgeLength());
+ assertTrue("need items off screen",
+ mListView.getChildCount() < mListView.getAdapter().getCount());
+ }
+
+ @LargeTest
+ public void testScrollToBottom() {
+ final int numItems = mListView.getAdapter().getCount();
+ final int listBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+ for (int i = 0; i < numItems; i++) {
+ assertEquals("wrong selection at position " + i,
+ i, mListView.getSelectedItemPosition());
+ final int bottomFadingEdge = listBottom - mListView.getVerticalFadingEdgeLength();
+ final View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+ final int lastVisiblePosition = lastChild.getId();
+
+
+ int bottomThreshold = (lastVisiblePosition < mListView.getAdapter().getCount() - 1) ?
+ bottomFadingEdge : listBottom;
+
+ String prefix = "after " + i + " down presses, ";
+
+ assertTrue(prefix + "selected item is below bottom threshold (fading edge or bottom as " +
+ "appropriate)",
+ mListView.getSelectedView().getBottom() <= bottomThreshold);
+ assertTrue(prefix + "first item in list must be at very top or just above",
+ mListView.getChildAt(0).getTop() <= 0);
+ assertTrue(prefix + "last item in list should be at very bottom or just below",
+ lastChild.getBottom() >= listBottom);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ }
+
+ @LargeTest
+ public void testScrollToTop() {
+ final int numItems = mListView.getAdapter().getCount();
+
+ for (int i = 0; i < numItems - 1; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals("should have moved to last position",
+ numItems - 1, mListView.getSelectedItemPosition());
+
+ int listTop = mListView.getListPaddingTop();
+ final int listBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+
+ for (int i = 0; i < numItems; i++) {
+ int expectedPostion = numItems - (i + 1);
+ assertEquals("wrong selection at position " + expectedPostion,
+ expectedPostion, mListView.getSelectedItemPosition());
+ final int topFadingEdge = listTop + mListView.getVerticalFadingEdgeLength();
+ final View firstChild = mListView.getChildAt(0);
+ final View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+ final int firstVisiblePosition = firstChild.getId();
+
+
+ int topThreshold = (firstVisiblePosition > 0) ?
+ topFadingEdge : listTop;
+
+ String prefix = "after " + i + " up presses, ";
+
+ assertTrue(prefix + "selected item is above top threshold (fading edge or top as " +
+ "appropriate)",
+ mListView.getSelectedView().getTop() >= topThreshold);
+ assertTrue(prefix + "first item in list must be at very top or just above",
+ firstChild.getTop() <= 0);
+ assertTrue(prefix + "last item in list should be at very bottom or just below",
+ lastChild.getBottom() >= listBottom);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ }
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithFirstScreenUnSelectableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithFirstScreenUnSelectableTest.java
new file mode 100644
index 0000000..307c39d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithFirstScreenUnSelectableTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Google Inc.
+ *
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import com.android.frameworktest.listview.ListWithFirstScreenUnSelectable;
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.KeyEvent;
+import android.widget.ListView;
+import android.widget.AdapterView;
+
+public class ListWithFirstScreenUnSelectableTest
+ extends ActivityInstrumentationTestCase2<ListWithFirstScreenUnSelectable> {
+ private ListView mListView;
+
+ public ListWithFirstScreenUnSelectableTest() {
+ super("com.android.frameworktest", ListWithFirstScreenUnSelectable.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ setActivityInitialTouchMode(true);
+
+ mListView = getActivity().getListView();
+ }
+
+ public void testPreconditions() {
+ assertTrue(mListView.isInTouchMode());
+ assertEquals(1, mListView.getChildCount());
+ assertFalse(mListView.getAdapter().isEnabled(0));
+ assertEquals(AdapterView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ }
+
+ public void testRessurectSelection() {
+ sendKeys(KeyEvent.KEYCODE_SPACE);
+ assertEquals(AdapterView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ }
+
+ public void testScrollUpDoesNothing() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals(AdapterView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ assertEquals(1, mListView.getChildCount());
+ assertEquals(0, mListView.getFirstVisiblePosition());
+ }
+
+ public void testScrollDownPansNextItemOn() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(2, mListView.getChildCount());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithNoFadingEdgeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithNoFadingEdgeTest.java
new file mode 100644
index 0000000..449e048
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithNoFadingEdgeTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview.arrowscroll;
+
+import com.android.frameworktest.listview.ListWithNoFadingEdge;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.KeyEvent;
+
+public class ListWithNoFadingEdgeTest extends ActivityInstrumentationTestCase<ListWithNoFadingEdge> {
+
+ private ListView mListView;
+
+ public ListWithNoFadingEdgeTest() {
+ super("com.android.frameworktest", ListWithNoFadingEdge.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mListView);
+ assertEquals("listview vertical fading edge", 0, mListView.getVerticalFadingEdgeLength());
+ assertTrue("expecting that not all views fit on screen",
+ mListView.getChildCount() < mListView.getCount());
+ }
+
+ @MediumTest
+ public void testScrollDownToBottom() {
+ final int numItems = mListView.getCount();
+
+ for (int i = 0; i < numItems; i++) {
+ assertEquals("selected position", i, mListView.getSelectedItemPosition());
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals("selected position", numItems - 1, mListView.getSelectedItemPosition());
+ }
+
+ @LargeTest
+ public void testScrollFromBottomToTop() {
+ final int numItems = mListView.getCount();
+
+ getActivity().runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setSelection(numItems - 1);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ for (int i = numItems - 1; i >=0; i--) {
+ assertEquals(i, mListView.getSelectedItemPosition());
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ }
+
+ assertEquals("selected position", 0, mListView.getSelectedItemPosition());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithOffScreenNextSelectableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithOffScreenNextSelectableTest.java
new file mode 100644
index 0000000..6e62ccb
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithOffScreenNextSelectableTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.TextView;
+import com.android.frameworktest.listview.ListWithOffScreenNextSelectable;
+
+public class ListWithOffScreenNextSelectableTest
+ extends ActivityInstrumentationTestCase<ListWithOffScreenNextSelectable> {
+ private ListView mListView;
+
+ public ListWithOffScreenNextSelectableTest() {
+ super("com.android.frameworktest", ListWithOffScreenNextSelectable.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mListView);
+ assertEquals(5, mListView.getAdapter().getCount());
+ assertFalse(mListView.getAdapter().areAllItemsEnabled());
+ assertFalse(mListView.getAdapter().isEnabled(1));
+ assertFalse(mListView.getAdapter().isEnabled(2));
+ assertFalse(mListView.getAdapter().isEnabled(3));
+ assertEquals("only 4 children should be on screen (so that next selectable is off " +
+ "screen) for this test to be meaningful.",
+ 4, mListView.getChildCount());
+ assertEquals(0, mListView.getSelectedItemPosition());
+ }
+
+ // when the next items on screen are not selectable, we pan until the next selectable item
+ // is (partially visible), then we jump to it
+ @MediumTest
+ public void testGoDownToOffScreenSelectable() {
+
+ final int listBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+
+ final View lastVisibleView = mListView.getChildAt(mListView.getChildCount() - 1);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("expecting view to be panned to just above fading edge",
+ listBottom - mListView.getVerticalFadingEdgeLength(), lastVisibleView.getBottom());
+ assertEquals("selection should not have moved yet",
+ 0, mListView.getSelectedItemPosition());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("selection should have moved",
+ 4, mListView.getSelectedItemPosition());
+ assertEquals("wrong view created when scrolling",
+ getActivity().getValueAtPosition(4), ((TextView) mListView.getSelectedView()).getText());
+ assertEquals(listBottom, mListView.getSelectedView().getBottom());
+ }
+
+ @MediumTest
+ public void testGoUpToOffScreenSelectable() {
+ final int listBottom = mListView.getHeight() - mListView.getListPaddingBottom();
+ final int listTop = mListView.getListPaddingTop();
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals(4, mListView.getSelectedItemPosition());
+ assertEquals(listBottom, mListView.getSelectedView().getBottom());
+
+ // now we have the reverse situation: the next selectable position upward is off screen
+ final View firstVisibleView = mListView.getChildAt(0);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("should have panned top view just below vertical fading edge",
+ listTop + mListView.getVerticalFadingEdgeLength(), firstVisibleView.getTop());
+ assertEquals("selection should not have moved yet",
+ 4, mListView.getSelectedItemPosition());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("selection should have moved",
+ 0, mListView.getSelectedItemPosition());
+ assertEquals(getActivity().getValueAtPosition(0),((TextView) mListView.getSelectedView()).getText());
+ assertEquals(listTop, mListView.getSelectedView().getTop());
+
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithOnItemSelectedActionTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithOnItemSelectedActionTest.java
new file mode 100644
index 0000000..0a8af45
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithOnItemSelectedActionTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.widget.TextView;
+import android.view.KeyEvent;
+import com.android.frameworktest.listview.ListWithOnItemSelectedAction;
+
+public class ListWithOnItemSelectedActionTest extends ActivityInstrumentationTestCase<ListWithOnItemSelectedAction> {
+ private ListView mListView;
+
+ public ListWithOnItemSelectedActionTest() {
+ super("com.android.frameworktest", ListWithOnItemSelectedAction.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ }
+
+ private String getValueOfSelectedTextView() {
+ return ((TextView) mListView.getSelectedView()).getText().toString();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals(0, mListView.getSelectedItemPosition());
+ assertEquals("header text field should be echoing contents of selected item",
+ getValueOfSelectedTextView(),
+ getActivity().getHeaderValue());
+ }
+
+ @MediumTest
+ public void testHeaderEchoesSelectionAfterMove() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals(1, mListView.getSelectedItemPosition());
+ assertEquals("header text field should be echoing contents of selected item",
+ getValueOfSelectedTextView(),
+ getActivity().getHeaderValue());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
new file mode 100644
index 0000000..0c0084e
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithScreenOfNoSelectablesTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview.arrowscroll;
+
+import com.android.frameworktest.listview.ListWithScreenOfNoSelectables;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.ListView;
+
+public class ListWithScreenOfNoSelectablesTest extends ActivityInstrumentationTestCase<ListWithScreenOfNoSelectables> {
+
+ private ListView mListView;
+
+ public ListWithScreenOfNoSelectablesTest() {
+ super("com.android.frameworktest", ListWithScreenOfNoSelectables.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("expecting first position to be selectable",
+ mListView.getAdapter().isEnabled(0));
+ final int numItems = mListView.getCount();
+ for (int i = 1; i < numItems; i++) {
+ assertFalse("expecting item to be unselectable (index " + i +")",
+ mListView.getAdapter().isEnabled(i));
+ }
+ assertTrue("expecting that not all views fit on screen",
+ mListView.getChildCount() < mListView.getCount());
+ }
+
+
+ @MediumTest
+ public void testGoFromSelectedViewExistsToNoSelectedViewExists() {
+
+ // go down untile first (and only selectable) item is off screen
+ View first = mListView.getChildAt(0);
+ while (first.getParent() != null) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+
+ // nothing should be selected
+ assertEquals("selected position", ListView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ assertNull("selected view", mListView.getSelectedView());
+ }
+
+ @LargeTest
+ public void testPanDownAcrossUnselectableChildrenToBottom() {
+ final int lastPosition = mListView.getCount() - 1;
+ final int maxDowns = 20;
+ for(int count = 0; count < maxDowns && mListView.getLastVisiblePosition() <= lastPosition; count++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ assertEquals("last visible position not the last position in the list even "
+ + "after " + maxDowns + " downs", lastPosition, mListView.getLastVisiblePosition());
+ }
+
+ @MediumTest
+ public void testGoFromNoSelectionToSelectionExists() {
+ // go down untile first (and only selectable) item is off screen
+ View first = mListView.getChildAt(0);
+ while (first.getParent() != null) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+
+ // nothing should be selected
+ assertEquals("selected position", ListView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ assertNull("selected view", mListView.getSelectedView());
+
+ // go up once to bring the selectable back on screen
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("first visible position", 0, mListView.getFirstVisiblePosition());
+ assertEquals("selected position", ListView.INVALID_POSITION, mListView.getSelectedItemPosition());
+
+
+ // up once more should give it selection
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("selected position", 0, mListView.getSelectedItemPosition());
+
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithSeparatorsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithSeparatorsTest.java
new file mode 100644
index 0000000..fdeaa4a
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/arrowscroll/ListWithSeparatorsTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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 com.android.frameworktest.listview.arrowscroll;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.ListView;
+import android.view.KeyEvent;
+import com.android.frameworktest.listview.ListWithSeparators;
+
+public class ListWithSeparatorsTest extends ActivityInstrumentationTestCase<ListWithSeparators> {
+ private ListWithSeparators mActivity;
+ private ListView mListView;
+
+ public ListWithSeparatorsTest() {
+ super("com.android.frameworktest", ListWithSeparators.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ assertFalse(mListView.getAdapter().areAllItemsEnabled());
+ assertFalse(mListView.getAdapter().isEnabled(0));
+ assertFalse(mListView.getAdapter().isEnabled(2));
+ assertEquals(1, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testGoingUpDoesnNotHitUnselectableItem() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals("selected position should remain the same",
+ 1, mListView.getSelectedItemPosition());
+
+ assertEquals("seperator should be scrolled flush with top",
+ mListView.getListPaddingTop(), mListView.getChildAt(0).getTop());
+ }
+
+ @MediumTest
+ public void testGoingDownSkipsOverUnselectable() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("should have skipped to next selectable ",
+ 3,
+ mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testGoingUpSkippingOverUnselectable() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertEquals(1, mListView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java
new file mode 100644
index 0000000..2c0c2d8
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/AdjacentListsWithAdjacentISVsInsideTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview.focus;
+
+import com.android.frameworktest.listview.AdjacentListsWithAdjacentISVsInside;
+import com.android.frameworktest.util.InternalSelectionView;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.ListView;
+
+public class AdjacentListsWithAdjacentISVsInsideTest extends ActivityInstrumentationTestCase<AdjacentListsWithAdjacentISVsInside> {
+
+ private ListView mLeftListView;
+ private InternalSelectionView mLeftIsv;
+ private InternalSelectionView mLeftMiddleIsv;
+ private ListView mRightListView;
+ private InternalSelectionView mRightMiddleIsv;
+ private InternalSelectionView mRightIsv;
+
+ public AdjacentListsWithAdjacentISVsInsideTest() {
+ super("com.android.frameworktest", AdjacentListsWithAdjacentISVsInside.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ final AdjacentListsWithAdjacentISVsInside a = getActivity();
+ mLeftListView = a.getLeftListView();
+ mLeftIsv = a.getLeftIsv();
+ mLeftMiddleIsv = a.getLeftMiddleIsv();
+ mRightListView = a.getRightListView();
+ mRightMiddleIsv = a.getRightMiddleIsv();
+ mRightIsv = a.getRightIsv();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue(mLeftListView.hasFocus());
+ assertTrue(mLeftIsv.isFocused());
+ assertEquals(0, mLeftIsv.getSelectedRow());
+ }
+
+ /**
+ * rockinist test name to date!
+ */
+ @MediumTest
+ public void testFocusedRectAndFocusHintWorkWithinListItemHorizontal() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals(1, mLeftIsv.getSelectedRow());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+ assertTrue(mLeftListView.hasFocus());
+ assertTrue(mLeftMiddleIsv.isFocused());
+ assertEquals("mLeftMiddleIsv.getSelectedRow()", 1, mLeftMiddleIsv.getSelectedRow());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
+ assertTrue(mLeftIsv.isFocused());
+ assertEquals("mLeftIsv.getSelectedRow()", 1, mLeftIsv.getSelectedRow());
+ }
+
+ @MediumTest
+ public void testFocusTransfersOutsideOfListWhenNoCandidateInsideHorizontal() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_RIGHT);
+
+ assertTrue(mLeftListView.hasFocus());
+ assertTrue(mLeftMiddleIsv.isFocused());
+ assertEquals(2, mLeftMiddleIsv.getSelectedRow());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+ assertTrue("mRightListView.hasFocus()", mRightListView.hasFocus());
+ assertTrue("mRightMiddleIsv.isFocused()", mRightMiddleIsv.isFocused());
+ assertEquals("mRightMiddleIsv.getSelectedRow()", 2, mRightMiddleIsv.getSelectedRow());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListButtonsDiagonalAcrossItemsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListButtonsDiagonalAcrossItemsTest.java
new file mode 100644
index 0000000..c54add3
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListButtonsDiagonalAcrossItemsTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview.focus;
+
+import com.android.frameworktest.listview.ListButtonsDiagonalAcrossItems;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.FocusFinder;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ListView;
+
+/**
+ * Test that ListView will override default behavior of focus searching to
+ * make sure going right and left doesn't change selection
+ */
+public class ListButtonsDiagonalAcrossItemsTest extends ActivityInstrumentationTestCase<ListButtonsDiagonalAcrossItems> {
+
+ private Button mLeftButton;
+ private Button mCenterButton;
+ private Button mRightButton;
+ private ListView mListView;
+
+ public ListButtonsDiagonalAcrossItemsTest() {
+ super("com.android.frameworktest", ListButtonsDiagonalAcrossItems.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mLeftButton = getActivity().getLeftButton();
+ mCenterButton = getActivity().getCenterButton();
+ mRightButton = getActivity().getRightButton();
+
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ final ListView lv = mListView;
+ assertEquals("num children", 3, lv.getChildCount());
+
+ assertEquals("selected position", 0, lv.getSelectedItemPosition());
+ assertTrue("left button focused", mLeftButton.isFocused());
+
+ assertTrue("left left of center",
+ mLeftButton.getRight()
+ < mCenterButton.getLeft());
+
+ assertTrue("center left of right",
+ mCenterButton.getRight()
+ < mRightButton.getLeft());
+
+ assertEquals("focus search right from left button should be center button",
+ mCenterButton,
+ FocusFinder.getInstance().findNextFocus(mListView, mLeftButton, View.FOCUS_RIGHT));
+ assertEquals("focus search right from center button should be right button",
+ mRightButton,
+ FocusFinder.getInstance().findNextFocus(mListView, mCenterButton, View.FOCUS_RIGHT));
+ assertEquals("focus search left from centr button should be left button",
+ mLeftButton,
+ FocusFinder.getInstance().findNextFocus(mListView, mCenterButton, View.FOCUS_LEFT));
+ }
+
+ @MediumTest
+ public void testGoingRightDoesNotChangeSelection() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+
+ assertEquals("selected position shouldn't have changed",
+ 0,
+ mListView.getSelectedItemPosition());
+ assertTrue("left should still be focused", mLeftButton.isFocused());
+ }
+
+ @MediumTest
+ public void testGoingLeftDoesNotChangeSelection() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("list view postion", 1, mListView.getSelectedItemPosition());
+ assertTrue("mCenterButton.isFocused()", mCenterButton.isFocused());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
+ assertEquals("selected position shouldn't have changed",
+ 1,
+ mListView.getSelectedItemPosition());
+ assertTrue("center should still be focused", mCenterButton.isFocused());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListHorizontalFocusWithinItemWinsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListHorizontalFocusWithinItemWinsTest.java
new file mode 100644
index 0000000..35f9b06
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListHorizontalFocusWithinItemWinsTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview.focus;
+
+import com.android.frameworktest.listview.ListHorizontalFocusWithinItemWins;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.FocusFinder;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ListView;
+
+public class ListHorizontalFocusWithinItemWinsTest extends ActivityInstrumentationTestCase<ListHorizontalFocusWithinItemWins> {
+
+ private ListView mListView;
+ private Button mTopLeftButton;
+ private Button mTopRightButton;
+ private Button mBottomMiddleButton;
+
+ public ListHorizontalFocusWithinItemWinsTest() {
+ super("com.android.frameworktest", ListHorizontalFocusWithinItemWins.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mListView = getActivity().getListView();
+ mTopLeftButton = getActivity().getTopLeftButton();
+ mTopRightButton = getActivity().getTopRightButton();
+ mBottomMiddleButton = getActivity().getBottomMiddleButton();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertEquals("list position", 0, mListView.getSelectedItemPosition());
+ assertTrue("mTopLeftButton.isFocused()", mTopLeftButton.isFocused());
+ assertEquals("global focus search to right from top left is bottom middle",
+ mBottomMiddleButton,
+ FocusFinder.getInstance().findNextFocus(mListView, mTopLeftButton, View.FOCUS_RIGHT));
+ assertEquals("global focus search to left from top right is bottom middle",
+ mBottomMiddleButton,
+ FocusFinder.getInstance().findNextFocus(mListView, mTopRightButton, View.FOCUS_LEFT));
+ }
+
+ @MediumTest
+ public void testOptionWithinItemTrumpsGlobal() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+
+ assertEquals("list position", 0, mListView.getSelectedItemPosition());
+ assertTrue("mTopRightButton.isFocused()", mTopRightButton.isFocused());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT);
+ assertEquals("list position", 0, mListView.getSelectedItemPosition());
+ assertTrue("mTopLeftButton.isFocused()", mTopLeftButton.isFocused());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListWithEditTextHeaderTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListWithEditTextHeaderTest.java
new file mode 100644
index 0000000..dea689f
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/focus/ListWithEditTextHeaderTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.listview.focus;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.FlakyTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.KeyEvent;
+import android.widget.AbsListView;
+import android.widget.ListView;
+import com.android.frameworktest.listview.ListWithEditTextHeader;
+
+public class ListWithEditTextHeaderTest extends ActivityInstrumentationTestCase<ListWithEditTextHeader> {
+ private ListView mListView;
+
+ public ListWithEditTextHeaderTest() {
+ super("com.android.frameworktest", ListWithEditTextHeader.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("listview.getItemsCanFocus()", mListView.getItemsCanFocus());
+ assertFalse("out of touch-mode", mListView.isInTouchMode());
+ assertEquals("header view count", 1, mListView.getHeaderViewsCount());
+ assertTrue("header has focus", mListView.getChildAt(0).isFocused());
+ }
+
+ @FlakyTest(tolerance=2)
+ @LargeTest
+ public void testClickingHeaderKeepsFocus() {
+ TouchUtils.clickView(this, mListView.getChildAt(0));
+ assertTrue("header has focus", mListView.getChildAt(0).isFocused());
+ assertEquals("nothing selected", AbsListView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ }
+
+ @LargeTest
+ public void testClickingHeaderWhenOtherItemHasFocusGivesHeaderFocus() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertEquals("selected position", 1, mListView.getSelectedItemPosition());
+ TouchUtils.clickView(this, mListView.getChildAt(0));
+ assertTrue("header has focus", mListView.getChildAt(0).isFocused());
+ assertEquals("nothing selected", AbsListView.INVALID_POSITION, mListView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListGetSelectedViewTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListGetSelectedViewTest.java
new file mode 100644
index 0000000..3a75f93
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListGetSelectedViewTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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 com.android.frameworktest.listview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.widget.ListView;
+import android.view.View;
+
+import com.android.frameworktest.listview.ListGetSelectedView;
+
+/**
+ * This test is made to check that getSelectedView() will return
+ * null in touch mode.
+ */
+public class ListGetSelectedViewTest extends ActivityInstrumentationTestCase<ListGetSelectedView> {
+ private ListGetSelectedView mActivity;
+ private ListView mListView;
+
+ public ListGetSelectedViewTest() {
+ super("com.android.frameworktest", ListGetSelectedView.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ assertEquals(0, mListView.getSelectedItemPosition());
+ }
+
+ @LargeTest
+ public void testGetSelectedView() {
+ View last = mListView.getChildAt(1);
+ TouchUtils.clickView(this, last);
+
+ assertNull(mListView.getSelectedItem());
+ assertNull(mListView.getSelectedView());
+ assertEquals(-1, mListView.getSelectedItemPosition());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListOfTouchablesTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListOfTouchablesTest.java
new file mode 100644
index 0000000..f8b384d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListOfTouchablesTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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 com.android.frameworktest.listview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListOfTouchables;
+import android.test.TouchUtils;
+
+/**
+ * Touch tests for a list where all of the items fit on the screen.
+ */
+public class ListOfTouchablesTest extends ActivityInstrumentationTestCase<ListOfTouchables> {
+ private ListOfTouchables mActivity;
+ private ListView mListView;
+
+ public ListOfTouchablesTest() {
+ super("com.android.frameworktest", ListOfTouchables.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ }
+
+ @LargeTest
+ public void testShortScroll() {
+ View firstChild = mListView.getChildAt(0);
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ int firstTop = firstChild.getTop();
+
+ TouchUtils.dragViewBy(this, lastChild, Gravity.TOP | Gravity.LEFT,
+ 0, -(ViewConfiguration.getTouchSlop() + 1 + 10));
+
+ View newFirstChild = mListView.getChildAt(0);
+
+ assertEquals("View scrolled too early", firstTop, newFirstChild.getTop() + 10);
+ assertEquals("Wrong view in first position", 0, newFirstChild.getId());
+ }
+
+ @LargeTest
+ public void testLongScroll() {
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ int lastTop = lastChild.getTop();
+
+ int distance = TouchUtils.dragViewToY(this, lastChild,
+ Gravity.TOP | Gravity.LEFT, mListView.getTop());
+
+ assertEquals("View scrolled to wrong position",
+ lastTop - (distance - ViewConfiguration.getTouchSlop() - 1), lastChild.getTop());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListSetSelectionTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListSetSelectionTest.java
new file mode 100644
index 0000000..c3d7264
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListSetSelectionTest.java
@@ -0,0 +1,148 @@
+/*
+ * 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 com.android.frameworktest.listview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.View;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListSimple;
+
+/**
+ * Tests setting the selection in touch mode
+ */
+public class ListSetSelectionTest extends ActivityInstrumentationTestCase<ListSimple> {
+ private ListSimple mActivity;
+ private ListView mListView;
+
+ public ListSetSelectionTest() {
+ super("com.android.frameworktest", ListSimple.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+ }
+
+ @LargeTest
+ public void testSetSelection() {
+ TouchUtils.dragQuarterScreenDown(this);
+ TouchUtils.dragQuarterScreenUp(this);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ final int targetPosition = mListView.getAdapter().getCount() / 2;
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setSelection(targetPosition);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ boolean found = false;
+ int childCount = mListView.getChildCount();
+ for (int i=0; i<childCount; i++) {
+ View child = mListView.getChildAt(i);
+ if (child.getId() == targetPosition) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue("Selected item not visible in list", found);
+ }
+
+ @LargeTest
+ public void testSetSelectionFromTop() {
+ TouchUtils.dragQuarterScreenDown(this);
+ TouchUtils.dragQuarterScreenUp(this);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ final int targetPosition = mListView.getAdapter().getCount() / 2;
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setSelectionFromTop(targetPosition, 100);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ View target = null;
+ boolean found = false;
+ int childCount = mListView.getChildCount();
+ for (int i=0; i<childCount; i++) {
+ View child = mListView.getChildAt(i);
+ if (child.getId() == targetPosition) {
+ target = child;
+ found = true;
+ break;
+ }
+ }
+ assertTrue("Selected item not visible in list", found);
+
+ if (target != null) {
+ assertEquals("Selection not at correct location", 100 + mListView.getPaddingTop(),
+ target.getTop());
+ }
+ }
+
+ @LargeTest
+ public void testSetSelection0() {
+ TouchUtils.dragQuarterScreenDown(this);
+ TouchUtils.dragQuarterScreenDown(this);
+ TouchUtils.dragQuarterScreenDown(this);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ mActivity.runOnUiThread(new Runnable() {
+ public void run() {
+ mListView.setSelection(0);
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+
+ boolean found = false;
+ int childCount = mListView.getChildCount();
+ for (int i=0; i<childCount; i++) {
+ View child = mListView.getChildAt(i);
+ if (child.getId() == 0 && i == 0) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue("Selected item not visible in list", found);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchBottomGravityManyTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchBottomGravityManyTest.java
new file mode 100644
index 0000000..d271564
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchBottomGravityManyTest.java
@@ -0,0 +1,153 @@
+/*
+ * 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 com.android.frameworktest.listview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListBottomGravityMany;
+
+/**
+ * Touch tests for a list where all of the items do not fit on the screen, and the list
+ * stacks from the bottom.
+ */
+public class ListTouchBottomGravityManyTest extends ActivityInstrumentationTestCase<ListBottomGravityMany> {
+ private ListBottomGravityMany mActivity;
+ private ListView mListView;
+
+ public ListTouchBottomGravityManyTest() {
+ super("com.android.frameworktest", ListBottomGravityMany.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ // Last item should be selected
+ assertEquals(mListView.getAdapter().getCount() - 1, mListView.getSelectedItemPosition());
+ }
+
+ @LargeTest
+ public void testPullDown() {
+ int originalCount = mListView.getChildCount();
+
+ TouchUtils.scrollToTop(this, mListView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ View firstChild = mListView.getChildAt(0);
+
+ assertEquals("Item zero not the first child in the list", 0, firstChild.getId());
+
+ assertEquals("Item zero not at the top of the list", mListView.getListPaddingTop(),
+ firstChild.getTop());
+
+ assertTrue(String.format("Too many children created: %d expected no more than %d",
+ mListView.getChildCount(), originalCount + 1),
+ mListView.getChildCount() <= originalCount + 1);
+ }
+
+ @MediumTest
+ public void testPushUp() {
+ TouchUtils.scrollToBottom(this, mListView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ assertEquals("List is not scrolled to the bottom", mListView.getAdapter().getCount() - 1,
+ lastChild.getId());
+
+ assertEquals("Last item is not touching the bottom edge",
+ mListView.getHeight() - mListView.getListPaddingBottom(), lastChild.getBottom());
+ }
+
+ @MediumTest
+ public void testNoScroll() {
+ View firstChild = mListView.getChildAt(0);
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ int lastTop = lastChild.getTop();
+
+ TouchUtils.dragViewBy(this, firstChild, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL,
+ 0, ViewConfiguration.getTouchSlop());
+
+ View newLastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ assertEquals("View scrolled too early", lastTop, newLastChild.getTop());
+ assertEquals("Wrong view in last position", mListView.getAdapter().getCount() - 1,
+ newLastChild.getId());
+ }
+
+ @LargeTest
+ public void testShortScroll() {
+ View firstChild = mListView.getChildAt(0);
+ if (firstChild.getTop() < this.mListView.getListPaddingTop()) {
+ firstChild = mListView.getChildAt(1);
+ }
+
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ int lastTop = lastChild.getTop();
+
+ TouchUtils.dragViewBy(this, firstChild, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL,
+ 0, ViewConfiguration.getTouchSlop() + 1 + 10);
+
+ View newLastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ assertEquals("View scrolled to wrong position", lastTop, newLastChild.getTop() - 10);
+ assertEquals("Wrong view in last position", mListView.getAdapter().getCount() - 1,
+ newLastChild.getId());
+ }
+
+ @LargeTest
+ public void testLongScroll() {
+ View firstChild = mListView.getChildAt(0);
+ if (firstChild.getTop() < mListView.getListPaddingTop()) {
+ firstChild = mListView.getChildAt(1);
+ }
+
+ int firstTop = firstChild.getTop();
+
+ int distance = TouchUtils.dragViewBy(this, firstChild,
+ Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0,
+ (int)(mActivity.getWindowManager().getDefaultDisplay().getHeight() * 0.75f));
+
+ assertEquals("View scrolled to wrong position", firstTop
+ + (distance - ViewConfiguration.getTouchSlop() - 1), firstChild.getTop());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchBottomGravityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchBottomGravityTest.java
new file mode 100644
index 0000000..78d39fb
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchBottomGravityTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 com.android.frameworktest.listview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.View;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListBottomGravity;
+
+/**
+ * Touch tests for a list where all of the items fit on the screen, and the list
+ * stacks from the bottom.
+ */
+public class ListTouchBottomGravityTest extends ActivityInstrumentationTestCase<ListBottomGravity> {
+ private ListBottomGravity mActivity;
+ private ListView mListView;
+
+ public ListTouchBottomGravityTest() {
+ super("com.android.frameworktest", ListBottomGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ // First item should be selected
+ assertEquals(mListView.getAdapter().getCount() - 1, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testPullDown() {
+ View firstChild = mListView.getChildAt(0);
+
+ TouchUtils.dragViewToBottom(this, firstChild);
+
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ assertEquals("List is not scrolled to the bottom", mListView.getAdapter().getCount() - 1,
+ lastChild.getId());
+
+ assertEquals("Last item is not touching the bottom edge",
+ mListView.getHeight() - mListView.getListPaddingBottom(), lastChild.getBottom());
+ }
+
+ @MediumTest
+ public void testPushUp() {
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ TouchUtils.dragViewToTop(this, lastChild);
+
+ lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ assertEquals("List is not scrolled to the bottom", mListView.getAdapter().getCount() - 1,
+ lastChild.getId());
+
+ assertEquals("Last item is not touching the bottom edge",
+ mListView.getHeight() - mListView.getListPaddingBottom(), lastChild.getBottom());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchManyTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchManyTest.java
new file mode 100644
index 0000000..ef085f84
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchManyTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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 com.android.frameworktest.listview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListTopGravityMany;
+
+/**
+ * Touch tests for a list where all of the items do not fit on the screen.
+ */
+public class ListTouchManyTest extends ActivityInstrumentationTestCase<ListTopGravityMany> {
+ private ListTopGravityMany mActivity;
+ private ListView mListView;
+
+ public ListTouchManyTest() {
+ super("com.android.frameworktest", ListTopGravityMany.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ // First item should be selected
+ assertEquals(0, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testPullDown() {
+ TouchUtils.scrollToTop(this, mListView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ View firstChild = mListView.getChildAt(0);
+
+ assertEquals("Item zero not the first child in the list", 0, firstChild.getId());
+
+ assertEquals("Item zero not at the top of the list", mListView.getListPaddingTop(),
+ firstChild.getTop());
+ }
+
+ @LargeTest
+ public void testPushUp() {
+ int originalCount = mListView.getChildCount();
+
+ TouchUtils.scrollToBottom(this, mListView);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ assertEquals("List is not scrolled to the bottom", mListView.getAdapter().getCount() - 1,
+ lastChild.getId());
+
+ assertEquals("Last item is not touching the bottom edge",
+ mListView.getHeight() - mListView.getListPaddingBottom(), lastChild.getBottom());
+
+ assertTrue(String.format("Too many children created: %d expected no more than %d",
+ mListView.getChildCount(), originalCount + 1),
+ mListView.getChildCount() <= originalCount + 1);
+ }
+
+ @LargeTest
+ public void testPress() {
+ int i;
+ int count = mListView.getChildCount();
+ mActivity.setClickedPosition(-1);
+ mActivity.setLongClickedPosition(-1);
+
+ for (i = 0; i < count; i++) {
+ View child = mListView.getChildAt(i);
+ if ((child.getTop() >= mListView.getListPaddingTop())
+ && (child.getBottom() <=
+ mListView.getHeight() - mListView.getListPaddingBottom())) {
+ TouchUtils.clickView(this, child);
+
+ assertEquals("Incorrect view position reported being clicked", i,
+ mActivity.getClickedPosition());
+ assertEquals("View falsely reported being long clicked", -1,
+ mActivity.getLongClickedPosition());
+ try {
+ Thread.sleep((long)(ViewConfiguration.getLongPressTimeout() * 1.25f));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ @LargeTest
+ public void testLongPress() {
+ int i;
+ int count = mListView.getChildCount();
+ mActivity.enableLongPress();
+ mActivity.setClickedPosition(-1);
+ mActivity.setLongClickedPosition(-1);
+
+ for (i = 0; i < count; i++) {
+ View child = mListView.getChildAt(i);
+ if ((child.getTop() >= mListView.getListPaddingTop())
+ && (child.getBottom() <=
+ mListView.getHeight() - mListView.getListPaddingBottom())) {
+ TouchUtils.longClickView(this, child);
+ assertEquals("Incorrect view position reported being long clicked", i,
+ mActivity.getLongClickedPosition());
+ assertEquals("View falsely reported being clicked", -1,
+ mActivity.getClickedPosition());
+ }
+ }
+ }
+
+ @MediumTest
+ public void testNoScroll() {
+ View firstChild = mListView.getChildAt(0);
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ int firstTop = firstChild.getTop();
+
+ TouchUtils.dragViewBy(this, lastChild, Gravity.TOP | Gravity.LEFT,
+ 0, -(ViewConfiguration.getTouchSlop()));
+
+ View newFirstChild = mListView.getChildAt(0);
+
+ assertEquals("View scrolled too early", firstTop, newFirstChild.getTop());
+ assertEquals("Wrong view in first position", 0, newFirstChild.getId());
+ }
+
+ @LargeTest
+ public void testShortScroll() {
+ View firstChild = mListView.getChildAt(0);
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ int firstTop = firstChild.getTop();
+
+ TouchUtils.dragViewBy(this, lastChild, Gravity.TOP | Gravity.LEFT,
+ 0, -(ViewConfiguration.getTouchSlop() + 1 + 10));
+
+ View newFirstChild = mListView.getChildAt(0);
+
+ assertEquals("View scrolled too early", firstTop, newFirstChild.getTop() + 10);
+ assertEquals("Wrong view in first position", 0, newFirstChild.getId());
+ }
+
+ @LargeTest
+ public void testLongScroll() {
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ int lastTop = lastChild.getTop();
+
+ int distance = TouchUtils.dragViewToY(this, lastChild,
+ Gravity.TOP | Gravity.LEFT, mListView.getTop());
+
+ assertEquals("View scrolled to wrong position",
+ lastTop - (distance - ViewConfiguration.getTouchSlop() - 1), lastChild.getTop());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchTest.java
new file mode 100644
index 0000000..4e5c423
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/listview/touch/ListTouchTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.android.frameworktest.listview.touch;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.View;
+import android.widget.ListView;
+
+import com.android.frameworktest.listview.ListTopGravity;
+
+/**
+ * Touch tests for a list where all of the items fit on the screen.
+ */
+public class ListTouchTest extends ActivityInstrumentationTestCase<ListTopGravity> {
+ private ListTopGravity mActivity;
+ private ListView mListView;
+
+ public ListTouchTest() {
+ super("com.android.frameworktest", ListTopGravity.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mListView = getActivity().getListView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertNotNull(mListView);
+
+ // First item should be selected
+ assertEquals(0, mListView.getSelectedItemPosition());
+ }
+
+ @MediumTest
+ public void testPullDown() {
+ View firstChild = mListView.getChildAt(0);
+
+ TouchUtils.dragViewToBottom(this, firstChild);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ firstChild = mListView.getChildAt(0);
+
+ assertEquals("Item zero not the first child in the list", 0, firstChild.getId());
+
+ assertEquals("Item zero not at the top of the list", mListView.getListPaddingTop(),
+ firstChild.getTop());
+ }
+
+ @MediumTest
+ public void testPushUp() {
+ View lastChild = mListView.getChildAt(mListView.getChildCount() - 1);
+
+ TouchUtils.dragViewToTop(this, lastChild);
+
+ // Nothing should be selected
+ assertEquals("Selection still available after touch", -1,
+ mListView.getSelectedItemPosition());
+
+ View firstChild = mListView.getChildAt(0);
+
+ assertEquals("Item zero not the first child in the list", 0, firstChild.getId());
+
+ assertEquals("Item zero not at the top of the list", mListView.getListPaddingTop(),
+ firstChild.getTop());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuLayoutLandscapeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuLayoutLandscapeTest.java
new file mode 100644
index 0000000..38cb6a1
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuLayoutLandscapeTest.java
@@ -0,0 +1,230 @@
+/**
+ * Copyright (C) 2008 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 com.android.frameworktest.menus;
+
+import com.android.frameworktest.util.KeyUtils;
+import com.android.internal.view.menu.IconMenuView;
+import com.android.internal.view.menu.MenuBuilder;
+
+import android.content.pm.ActivityInfo;
+import android.test.ActivityInstrumentationTestCase;
+
+public class MenuLayoutLandscapeTest extends ActivityInstrumentationTestCase<MenuLayoutLandscape> {
+ private static final String LONG_TITLE = "Really really really really really really really really really really long title";
+ private static final String SHORT_TITLE = "Item";
+
+ private MenuLayout mActivity;
+
+ public MenuLayoutLandscapeTest() {
+ super("com.android.frameworktest", MenuLayoutLandscape.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ }
+
+ private void toggleMenu() {
+ getInstrumentation().waitForIdleSync();
+ KeyUtils.tapMenuKey(this);
+ getInstrumentation().waitForIdleSync();
+ }
+
+ /**
+ * Asserts the layout of the menu.
+ *
+ * @param expectedLayout The number of parameters is the number of rows, and
+ * each parameter is how many items on that row (the first
+ * parameter is the top-most row).
+ */
+ private void assertLayout(Integer... expectedLayout) {
+ toggleMenu();
+
+ IconMenuView iconMenuView = ((IconMenuView) mActivity.getMenuView(MenuBuilder.TYPE_ICON));
+ int[] layout = iconMenuView.getLayout();
+ int layoutNumRows = iconMenuView.getLayoutNumRows();
+
+ int expectedRows = expectedLayout.length;
+ assertEquals("Row mismatch", expectedRows, layoutNumRows);
+
+ for (int row = 0; row < expectedRows; row++) {
+ assertEquals("Col mismatch on row " + row, expectedLayout[row].intValue(),
+ layout[row]);
+ }
+ }
+
+ public void test1ShortItem() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(1)
+ .setItemTitle(0, SHORT_TITLE));
+ assertLayout(1);
+ }
+
+ public void test1LongItem() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(1)
+ .setItemTitle(0, LONG_TITLE));
+ assertLayout(1);
+ }
+
+ public void test2LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(2)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE));
+ assertLayout(1, 1);
+ }
+
+ public void test2ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(2)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE));
+ assertLayout(2);
+ }
+
+ public void test3ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(3)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE));
+ assertLayout(3);
+ }
+
+ public void test3VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(3)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, SHORT_TITLE));
+ assertLayout(1, 2);
+ }
+
+ public void test3VarietyItems2() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(3)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE));
+ assertLayout(1, 2);
+ }
+
+ public void test4LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(4)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, LONG_TITLE));
+ assertLayout(2, 2);
+ }
+
+ public void test4ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(4)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE));
+ assertLayout(4);
+ }
+
+ public void test4VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(4)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE));
+ assertLayout(2, 2);
+ }
+
+ public void test5ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(5)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE)
+ .setItemTitle(4, SHORT_TITLE));
+ assertLayout(5);
+ }
+
+ public void test5LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(5)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, LONG_TITLE)
+ .setItemTitle(4, LONG_TITLE));
+ assertLayout(2, 3);
+ }
+
+ public void test5VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(5)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, SHORT_TITLE)
+ .setItemTitle(4, LONG_TITLE));
+ assertLayout(2, 3);
+ }
+
+ public void test6LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(6)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, LONG_TITLE)
+ .setItemTitle(4, LONG_TITLE)
+ .setItemTitle(5, LONG_TITLE));
+ assertLayout(3, 3);
+ }
+
+ public void test6ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(6)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE)
+ .setItemTitle(4, SHORT_TITLE)
+ .setItemTitle(5, SHORT_TITLE));
+ assertLayout(6);
+ }
+
+ public void test6VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(6)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, LONG_TITLE)
+ .setItemTitle(4, SHORT_TITLE)
+ .setItemTitle(5, SHORT_TITLE));
+ assertLayout(3, 3);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuLayoutPortraitTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuLayoutPortraitTest.java
new file mode 100644
index 0000000..a04ec62
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuLayoutPortraitTest.java
@@ -0,0 +1,231 @@
+/**
+ * Copyright (C) 2008 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 com.android.frameworktest.menus;
+
+import com.android.frameworktest.util.KeyUtils;
+import com.android.internal.view.menu.IconMenuView;
+import com.android.internal.view.menu.MenuBuilder;
+
+import android.content.pm.ActivityInfo;
+import android.test.ActivityInstrumentationTestCase;
+
+public class MenuLayoutPortraitTest extends ActivityInstrumentationTestCase<MenuLayoutPortrait> {
+ private static final String LONG_TITLE = "Really really really really really really really really really really long title";
+ private static final String SHORT_TITLE = "Item";
+
+ private MenuLayout mActivity;
+
+ public MenuLayoutPortraitTest() {
+ super("com.android.frameworktest", MenuLayoutPortrait.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ }
+
+ private void toggleMenu() {
+ getInstrumentation().waitForIdleSync();
+ KeyUtils.tapMenuKey(this);
+ getInstrumentation().waitForIdleSync();
+ }
+
+ /**
+ * Asserts the layout of the menu.
+ *
+ * @param expectedLayout The number of parameters is the number of rows, and
+ * each parameter is how many items on that row.
+ */
+ private void assertLayout(Integer... expectedLayout) {
+ toggleMenu();
+
+ IconMenuView iconMenuView = ((IconMenuView) mActivity.getMenuView(MenuBuilder.TYPE_ICON));
+ int[] layout = iconMenuView.getLayout();
+ int layoutNumRows = iconMenuView.getLayoutNumRows();
+
+ int expectedRows = expectedLayout.length;
+ assertEquals("Row mismatch", expectedRows, layoutNumRows);
+
+ for (int row = 0; row < expectedRows; row++) {
+ assertEquals("Col mismatch on row " + row, expectedLayout[row].intValue(),
+ layout[row]);
+ }
+ }
+
+ public void test1ShortItem() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(1)
+ .setItemTitle(0, SHORT_TITLE));
+ assertLayout(1);
+ }
+
+ public void test1LongItem() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(1)
+ .setItemTitle(0, LONG_TITLE));
+ assertLayout(1);
+ }
+
+ public void test2LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(2)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE));
+ assertLayout(1, 1);
+ }
+
+ public void test2ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(2)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE));
+ assertLayout(2);
+ }
+
+ public void test3ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(3)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE));
+ assertLayout(3);
+ }
+
+ public void test3VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(3)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, SHORT_TITLE));
+ // We maintain the order added, so there must be 3 rows
+ assertLayout(1, 1, 1);
+ }
+
+ public void test3VarietyItems2() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(3)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE));
+ // The long can fit in first row, and two shorts in second
+ assertLayout(1, 2);
+ }
+
+ public void test4LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(4)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, LONG_TITLE));
+ assertLayout(1, 1, 2);
+ }
+
+ public void test4ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(4)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE));
+ assertLayout(2, 2);
+ }
+
+ public void test4VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(4)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE));
+ assertLayout(1, 1, 2);
+ }
+
+ public void test5ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(5)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE)
+ .setItemTitle(4, SHORT_TITLE));
+ assertLayout(2, 3);
+ }
+
+ public void test5LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(5)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, LONG_TITLE)
+ .setItemTitle(4, LONG_TITLE));
+ assertLayout(1, 2, 2);
+ }
+
+ public void test5VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(5)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, SHORT_TITLE)
+ .setItemTitle(4, LONG_TITLE));
+ assertLayout(1, 2, 2);
+ }
+
+ public void test6LongItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(6)
+ .setItemTitle(0, LONG_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, LONG_TITLE)
+ .setItemTitle(3, LONG_TITLE)
+ .setItemTitle(4, LONG_TITLE)
+ .setItemTitle(5, LONG_TITLE));
+ assertLayout(2, 2, 2);
+ }
+
+ public void test6ShortItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(6)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, SHORT_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, SHORT_TITLE)
+ .setItemTitle(4, SHORT_TITLE)
+ .setItemTitle(5, SHORT_TITLE));
+ assertLayout(3, 3);
+ }
+
+ public void test6VarietyItems() {
+ mActivity.setParams(new MenuScenario.Params()
+ .setNumItems(6)
+ .setItemTitle(0, SHORT_TITLE)
+ .setItemTitle(1, LONG_TITLE)
+ .setItemTitle(2, SHORT_TITLE)
+ .setItemTitle(3, LONG_TITLE)
+ .setItemTitle(4, SHORT_TITLE)
+ .setItemTitle(5, SHORT_TITLE));
+ assertLayout(2, 2, 2);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuWith1ItemTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuWith1ItemTest.java
new file mode 100644
index 0000000..286533c
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/menus/MenuWith1ItemTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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 com.android.frameworktest.menus;
+
+import com.android.frameworktest.menus.MenuWith1Item;
+import com.android.frameworktest.util.KeyUtils;
+import com.android.internal.view.menu.MenuBuilder;
+
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.view.KeyEvent;
+import android.view.View;
+
+public class MenuWith1ItemTest extends ActivityInstrumentationTestCase<MenuWith1Item> {
+ private MenuWith1Item mActivity;
+
+ public MenuWith1ItemTest() {
+ super("com.android.frameworktest", MenuWith1Item.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertNotNull(mActivity);
+ assertFalse(mActivity.getButton().isInTouchMode());
+ }
+
+ @MediumTest
+ public void testItemClick() {
+
+ // Open menu, click on an item
+ KeyUtils.tapMenuKey(this);
+ getInstrumentation().waitForIdleSync();
+ assertFalse("Item seems to have been clicked before we clicked on it", mActivity
+ .wasItemClicked(0));
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ assertTrue("Item doesn't seem to have registered our click", mActivity.wasItemClicked(0));
+ }
+
+ @LargeTest
+ public void testTouchModeTransfersRemovesFocus() throws Exception {
+ // open menu, move around to give it focus
+ sendKeys(KeyEvent.KEYCODE_MENU, KeyEvent.KEYCODE_DPAD_LEFT);
+ final View menuItem = mActivity.getItemView(MenuBuilder.TYPE_ICON, 0);
+ assertTrue("menuItem.isFocused()", menuItem.isFocused());
+
+ // close the menu
+ sendKeys(KeyEvent.KEYCODE_MENU);
+ Thread.sleep(500);
+
+ // touch the screen
+ TouchUtils.clickView(this, mActivity.getButton());
+ assertTrue("should be in touch mode after touching button",
+ mActivity.getButton().isInTouchMode());
+
+ // open the menu, menu item shouldn't be focused, because we are not
+ // in touch mode
+ sendKeys(KeyEvent.KEYCODE_MENU);
+ assertTrue("menuItem.isInTouchMode()", menuItem.isInTouchMode());
+ assertFalse("menuItem.isFocused()", menuItem.isFocused());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/ButtonAboveTallInternalSelectionViewTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/ButtonAboveTallInternalSelectionViewTest.java
new file mode 100644
index 0000000..e4dd2b8
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/ButtonAboveTallInternalSelectionViewTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.scroll.ButtonAboveTallInternalSelectionView;
+import com.android.frameworktest.util.InternalSelectionView;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+
+public class ButtonAboveTallInternalSelectionViewTest extends
+ ActivityInstrumentationTestCase<ButtonAboveTallInternalSelectionView> {
+
+ public ButtonAboveTallInternalSelectionViewTest() {
+ super("com.android.frameworktest", ButtonAboveTallInternalSelectionView.class);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("expecting the top button to have focus",
+ getActivity().getButtonAbove().isFocused());
+ assertEquals("scrollview scroll y",
+ 0,
+ getActivity().getScrollView().getScrollY());
+ assertTrue("internal selection view should be taller than screen",
+ getActivity().getIsv().getHeight() > getActivity().getScrollView().getHeight());
+
+ assertTrue("top of ISV should be on screen",
+ getActivity().getIsv().getTop() >
+ getActivity().getScrollView().getScrollY());
+
+ }
+
+ @MediumTest
+ public void testMovingFocusDownToItemTallerThanScreenStillOnScreen() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ getInstrumentation().waitForIdleSync();
+
+ final InternalSelectionView isv = getActivity().getIsv();
+ assertTrue("internal selection view should have taken focus",
+ isv.isFocused());
+ assertEquals("internal selection view selected row",
+ 0, isv.getSelectedRow());
+ assertTrue("top of ISV should still be on screen",
+ getActivity().getIsv().getTop() >
+ getActivity().getScrollView().getScrollY());
+ }
+
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/RequestRectangleVisibleTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/RequestRectangleVisibleTest.java
new file mode 100644
index 0000000..3eec37b
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/RequestRectangleVisibleTest.java
@@ -0,0 +1,237 @@
+/*
+ * 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.scroll.RequestRectangleVisible;
+import com.android.frameworktest.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.frameworktest", 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]);
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/RequestRectangleVisibleWithInternalScrollTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/RequestRectangleVisibleWithInternalScrollTest.java
new file mode 100644
index 0000000..5d71466
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/RequestRectangleVisibleWithInternalScrollTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.ViewAsserts;
+import android.test.suitebuilder.annotation.Suppress;
+import android.view.KeyEvent;
+import android.widget.Button;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+/**
+ * This is suppressed because {@link TextView#scrollBy} isn't working.
+ */
+@Suppress
+public class RequestRectangleVisibleWithInternalScrollTest
+ extends ActivityInstrumentationTestCase<RequestRectangleVisibleWithInternalScroll> {
+
+ private TextView mTextBlob;
+ private Button mScrollToBlob;
+
+ private ScrollView mScrollView;
+
+
+ public RequestRectangleVisibleWithInternalScrollTest() {
+ super("com.android.frameworktest",
+ RequestRectangleVisibleWithInternalScroll.class);
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mTextBlob = getActivity().getTextBlob();
+ mScrollToBlob = getActivity().getScrollToBlob();
+
+ mScrollView = (ScrollView) getActivity().findViewById(R.id.scrollView);
+ }
+
+ public void testPreconditions() {
+ assertNotNull(mTextBlob);
+ assertNotNull(mScrollToBlob);
+ assertEquals(getActivity().getScrollYofBlob(), mTextBlob.getScrollY());
+ }
+
+ public void testMoveToChildWithScrollYBelow() {
+ assertTrue(mScrollToBlob.hasFocus());
+
+ ViewAsserts.assertOffScreenBelow(mScrollView, mTextBlob);
+
+ // click
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync(); // wait for scrolling to finish
+
+ // should be on screen, positioned at the bottom (with enough room for
+ // fading edge)
+ ViewAsserts.assertOnScreen(mScrollView, mTextBlob);
+ ViewAsserts.assertHasScreenCoordinates(
+ mScrollView, mTextBlob,
+ 0,
+ mScrollView.getHeight()
+ - mTextBlob.getHeight()
+ - mScrollView.getVerticalFadingEdgeLength());
+
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/ScrollViewButtonsAndLabelsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/ScrollViewButtonsAndLabelsTest.java
new file mode 100644
index 0000000..b23b567
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/ScrollViewButtonsAndLabelsTest.java
@@ -0,0 +1,214 @@
+/*
+ * 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 com.android.frameworktest.scroll;
+
+import com.android.frameworktest.scroll.ScrollViewButtonsAndLabels;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.ScrollView;
+import android.view.KeyEvent;
+
+
+public class ScrollViewButtonsAndLabelsTest
+ extends ActivityInstrumentationTestCase<ScrollViewButtonsAndLabels> {
+
+ private ScrollView mScrollView;
+ private LinearLayout mLinearLayout;
+ private int mScreenBottom;
+ private int mScreenTop;
+
+ public ScrollViewButtonsAndLabelsTest() {
+ super("com.android.frameworktest",
+ ScrollViewButtonsAndLabels.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mScrollView = getActivity().getScrollView();
+ mLinearLayout = getActivity().getLinearLayout();
+
+ int origin[] = {0, 0};
+ mScrollView.getLocationOnScreen(origin);
+ mScreenTop = origin[1];
+ mScreenBottom = origin[1] + mScrollView.getHeight();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("vertical fading edge width needs to be non-zero for this "
+ + "test to be worth anything",
+ mScrollView.getVerticalFadingEdgeLength() > 0);
+ }
+
+ // moving down to something off screen should move the element
+ // onto the screen just above the vertical fading edge
+ @LargeTest
+ public void testArrowScrollDownOffScreenVerticalFadingEdge() {
+
+ int offScreenIndex = findFirstButtonOffScreenTop2Bottom();
+ Button firstButtonOffScreen = getActivity().getButton(offScreenIndex);
+
+ for (int i = 0; i < offScreenIndex; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ getInstrumentation().waitForIdleSync();
+ assertTrue(firstButtonOffScreen.hasFocus());
+
+ assertTrue("the button we've moved to off screen must not be the last "
+ + "button in the scroll view for this test to work (since we "
+ + "are expecting the fading edge to be there).",
+ offScreenIndex < getActivity().getNumButtons());
+
+ // now we are at the first button off screen
+ int buttonLoc[] = {0, 0};
+ firstButtonOffScreen.getLocationOnScreen(buttonLoc);
+ int buttonBottom = buttonLoc[1] + firstButtonOffScreen.getHeight();
+
+ int verticalFadingEdgeLength = mScrollView
+ .getVerticalFadingEdgeLength();
+ assertEquals("bottom of button should be verticalFadingEdgeLength "
+ + "above the bottom of the screen",
+ buttonBottom, mScreenBottom - verticalFadingEdgeLength);
+ }
+
+ // there should be no offset for vertical fading edge
+ // if the item is the last one on screen
+ @LargeTest
+ public void testArrowScrollDownToBottomElementOnScreen() {
+
+ int numGroups = getActivity().getNumButtons();
+ Button lastButton = getActivity().getButton(numGroups - 1);
+
+ assertEquals("button needs to be at the very bottom of the layout for "
+ + "this test to work",
+ mLinearLayout.getHeight(), lastButton.getBottom());
+
+ // move down to last button
+ for (int i = 0; i < numGroups; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ getInstrumentation().waitForIdleSync();
+ assertTrue("last button should have focus", lastButton.hasFocus());
+
+ int buttonLoc[] = {0, 0};
+ lastButton.getLocationOnScreen(buttonLoc);
+ int buttonBottom = buttonLoc[1] + lastButton.getHeight();
+ assertEquals("button should be at very bottom of screen",
+ mScreenBottom, buttonBottom);
+ }
+
+ @LargeTest
+ public void testArrowScrollUpOffScreenVerticalFadingEdge() {
+ // get to bottom button
+ int numGroups = goToBottomButton();
+
+ // go up to first off screen button
+ int offScreenIndex = findFirstButtonOffScreenBottom2Top();
+ Button offScreenButton = getActivity().getButton(offScreenIndex);
+ int clicksToOffScreenIndex = numGroups - offScreenIndex - 1;
+ for (int i = 0; i < clicksToOffScreenIndex; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ }
+ getInstrumentation().waitForIdleSync();
+ assertTrue("we want to be at offScreenButton", offScreenButton.hasFocus());
+
+ // top should take into account fading edge
+ int buttonLoc[] = {0, 0};
+ offScreenButton.getLocationOnScreen(buttonLoc);
+ assertEquals("top should take into account fading edge",
+ mScreenTop + mScrollView.getVerticalFadingEdgeLength(), buttonLoc[1]);
+ }
+
+
+ @LargeTest
+ public void testArrowScrollUpToTopElementOnScreen() {
+ // get to bottom button
+ int numButtons = goToBottomButton();
+
+ // go back to the top
+ for (int i = 0; i < numButtons; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ }
+ getInstrumentation().waitForIdleSync();
+
+ Button topButton = getActivity().getButton(0);
+ assertTrue("should be back at top button", topButton.hasFocus());
+
+
+ int buttonLoc[] = {0, 0};
+ topButton.getLocationOnScreen(buttonLoc);
+ assertEquals("top of top button should be at top of screen; no need to take"
+ + " into account vertical fading edge.",
+ mScreenTop, buttonLoc[1]);
+ }
+
+ private int goToBottomButton() {
+ int numButtons = getActivity().getNumButtons();
+ Button lastButton = getActivity().getButton(numButtons - 1);
+
+ for (int i = 0; i < numButtons; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ getInstrumentation().waitForIdleSync();
+ assertTrue("we want to be at the last button", lastButton.hasFocus());
+ return numButtons;
+ }
+
+ // search from top to bottom for the first button off screen
+ private int findFirstButtonOffScreenTop2Bottom() {
+ int origin[] = {0, 0};
+ mScrollView.getLocationOnScreen(origin);
+ int screenHeight = mScrollView.getHeight();
+
+ for (int i = 0; i < getActivity().getNumButtons(); i++) {
+
+ int buttonLoc[] = {0, 0};
+ Button button = getActivity().getButton(i);
+ button.getLocationOnScreen(buttonLoc);
+
+ if (buttonLoc[1] - origin[1] > screenHeight) {
+ return i;
+ }
+ }
+ fail("couldn't find first button off screen");
+ return -1; // this won't execute, but the compiler needs it
+ }
+
+ private int findFirstButtonOffScreenBottom2Top() {
+ int origin[] = {0, 0};
+ mScrollView.getLocationOnScreen(origin);
+
+ for (int i = getActivity().getNumButtons() - 1; i >= 0; i--) {
+
+ int buttonLoc[] = {0, 0};
+ Button button = getActivity().getButton(i);
+ button.getLocationOnScreen(buttonLoc);
+
+ if (buttonLoc[1] < 0) {
+ return i;
+ }
+ }
+ fail("couldn't find first button off screen");
+ return -1; // this won't execute, but the compiler needs it
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/ButtonsWithTallTextViewInBetweenTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/ButtonsWithTallTextViewInBetweenTest.java
new file mode 100644
index 0000000..6b78560
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/ButtonsWithTallTextViewInBetweenTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll.arrowscroll;
+
+import com.android.frameworktest.scroll.ButtonsWithTallTextViewInBetween;
+
+import android.graphics.Rect;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+public class ButtonsWithTallTextViewInBetweenTest
+ extends ActivityInstrumentationTestCase<ButtonsWithTallTextViewInBetween> {
+
+ private ScrollView mScrollView;
+ private Button mTopButton;
+ private TextView mMiddleFiller;
+ private TextView mBottomButton;
+
+ public ButtonsWithTallTextViewInBetweenTest() {
+ super("com.android.frameworktest", ButtonsWithTallTextViewInBetween.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mScrollView = getActivity().getScrollView();
+ mTopButton = getActivity().getTopButton();
+ mMiddleFiller = getActivity().getMiddleFiller();
+ mBottomButton = getActivity().getBottomButton();
+ }
+
+ private Rect mTempRect = new Rect();
+
+ private int getTopWithinScrollView(View descendant) {
+ descendant.getDrawingRect(mTempRect);
+ mScrollView.offsetDescendantRectToMyCoords(descendant, mTempRect);
+ return mTempRect.top;
+ }
+
+ private int getBottomWithinScrollView(View descendant) {
+ descendant.getDrawingRect(mTempRect);
+ mScrollView.offsetDescendantRectToMyCoords(descendant, mTempRect);
+ return mTempRect.bottom;
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("top button should be shorter than max scroll amount",
+ mTopButton.getHeight() <
+ mScrollView.getMaxScrollAmount());
+ assertTrue("bottom button should be further than max scroll amount off screen",
+ getTopWithinScrollView(mBottomButton)- mScrollView.getBottom() > mScrollView.getMaxScrollAmount());
+ }
+
+ @MediumTest
+ public void testPanTopButtonOffScreenLosesFocus() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertEquals("scroll view should be scrolled by the max amount for one "
+ + "arrow navigation",
+ mScrollView.getMaxScrollAmount(),
+ mScrollView.getScrollY());
+
+ assertTrue("top button should be off screen",
+ getBottomWithinScrollView(mTopButton) < mScrollView.getScrollY());
+
+ assertFalse("top button should have lost focus",
+ mTopButton.isFocused());
+
+ assertTrue("scroll view should be focused", mScrollView.isFocused());
+ }
+
+ @MediumTest
+ public void testScrollDownToBottomButton() throws Exception {
+ final int screenBottom = mScrollView.getScrollY() + mScrollView.getHeight();
+ final int numDownsToButtonButton =
+ ((getBottomWithinScrollView(mBottomButton) - screenBottom)) / mScrollView.getMaxScrollAmount() + 1;
+
+ for (int i = 0; i < numDownsToButtonButton; i++) {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+
+ assertTrue("bottombutton.isFocused", mBottomButton.isFocused());
+
+ assertEquals("should be fully scrolled to bottom",
+ getActivity().getLinearLayout().getHeight() - mScrollView.getHeight(),
+ mScrollView.getScrollY());
+ }
+
+ @MediumTest
+ public void testPanBottomButtonOffScreenLosesFocus() throws Exception {
+ mBottomButton.post(new Runnable() {
+ public void run() {
+ mBottomButton.requestFocus();
+ }
+ });
+
+ getInstrumentation().waitForIdleSync();
+
+ assertTrue("bottombutton.isFocused", mBottomButton.isFocused());
+ final int maxScroll = getActivity().getLinearLayout().getHeight()
+ - mScrollView.getHeight();
+ assertEquals("should be fully scrolled to bottom",
+ maxScroll,
+ mScrollView.getScrollY());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+
+ assertEquals("scroll view should have scrolled by the max amount for one "
+ + "arrow navigation",
+ maxScroll - mScrollView.getMaxScrollAmount(),
+ mScrollView.getScrollY());
+
+ assertTrue("bottom button should be off screen",
+ getTopWithinScrollView(mBottomButton) > mScrollView.getScrollY() + mScrollView.getHeight());
+
+ assertFalse("bottom button should have lost focus",
+ mBottomButton.isFocused());
+
+ assertTrue("scroll view should be focused", mScrollView.isFocused());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/ShortButtonsTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/ShortButtonsTest.java
new file mode 100644
index 0000000..689eb19
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/ShortButtonsTest.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll.arrowscroll;
+
+import com.android.frameworktest.scroll.ShortButtons;
+
+import android.graphics.Rect;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+import android.widget.ScrollView;
+
+public class ShortButtonsTest extends ActivityInstrumentationTestCase<ShortButtons> {
+
+ private ScrollView mScrollView;
+
+ public ShortButtonsTest() {
+ super("com.android.frameworktest", ShortButtons.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mScrollView = getActivity().getScrollView();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("buttons should be shorter than screen",
+ getActivity().getButtonAt(0).getHeight()
+ < mScrollView.getHeight());
+
+ assertTrue("should be enough buttons to have some scrolled off screen",
+ getActivity().getLinearLayout().getHeight()
+ > getActivity().getScrollView().getHeight());
+ }
+
+ @LargeTest
+ public void testScrollDownToBottomThroughButtons() throws Exception {
+ final int numButtons = getActivity().getNumButtons();
+
+ for (int i = 0; i < numButtons; i++) {
+ String prefix = "after " + i + " downs expected button " + i;
+ final Button button = getActivity().getButtonAt(i);
+ assertTrue(prefix + " to have focus", button.isFocused());
+ assertTrue(prefix + " to be on screen", isButtonOnScreen(button));
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+
+ assertEquals("should be fully scrolled to bottom",
+ getActivity().getLinearLayout().getHeight() - mScrollView.getHeight(),
+ mScrollView.getScrollY());
+ }
+
+ @LargeTest
+ public void testScrollFromBottomToTopThroughButtons() throws Exception {
+ final int numButtons = getActivity().getNumButtons();
+
+ final Button lastButton = getActivity().getButtonAt(numButtons - 1);
+
+ lastButton.post(new Runnable() {
+ public void run() {
+ lastButton.requestFocus();
+ }
+ });
+
+ getInstrumentation().waitForIdleSync();
+
+ assertTrue("lastButton.isFocused()", lastButton.isFocused());
+
+ for (int i = numButtons - 1; i >= 0; i--) {
+ String prefix = "after " + i + " ups expected button " + i;
+ final Button button = getActivity().getButtonAt(i);
+ assertTrue(prefix + " to have focus", button.isFocused());
+ assertTrue(prefix + " to be on screen", isButtonOnScreen(button));
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ }
+
+ assertEquals("should be fully scrolled to top",
+ 0,
+ mScrollView.getScrollY());
+ }
+
+ private Rect mTempRect = new Rect();
+ protected boolean isButtonOnScreen(Button b) {
+ b.getDrawingRect(mTempRect);
+ mScrollView.offsetDescendantRectToMyCoords(b, mTempRect);
+ return mTempRect.bottom >= mScrollView.getScrollY()
+ && mTempRect.top <= (mScrollView.getScrollY() + mScrollView.getHeight());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/TallTextAboveButtonTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/TallTextAboveButtonTest.java
new file mode 100644
index 0000000..573045d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/scroll/arrowscroll/TallTextAboveButtonTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.scroll.arrowscroll;
+
+import com.android.frameworktest.scroll.TallTextAboveButton;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.ScrollView;
+import android.widget.TextView;
+
+public class TallTextAboveButtonTest extends ActivityInstrumentationTestCase<TallTextAboveButton> {
+ private ScrollView mScrollView;
+ private TextView mTopText;
+ private TextView mBottomButton;
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mScrollView = getActivity().getScrollView();
+ mTopText = getActivity().getContentChildAt(0);
+ mBottomButton = getActivity().getContentChildAt(1);
+ }
+
+ public TallTextAboveButtonTest() {
+ super("com.android.frameworktest", TallTextAboveButton.class);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("top text should be larger than screen",
+ mTopText.getHeight() > mScrollView.getHeight());
+ assertTrue("scroll view should have focus (because nothing else focusable "
+ + "is on screen), but " + getActivity().getScrollView().findFocus() + " does instead",
+ getActivity().getScrollView().isFocused());
+ }
+
+ @MediumTest
+ public void testGainFocusAsScrolledOntoScreen() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertTrue("button should have scrolled onto screen",
+ mBottomButton.getBottom() >= mScrollView.getBottom());
+ assertTrue("button should have gained focus as it was scrolled completely "
+ + "into view", mBottomButton.isFocused());
+
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertTrue("scroll view should have focus, but " + getActivity().getScrollView().findFocus() + " does instead",
+ getActivity().getScrollView().isFocused());
+ }
+
+ @MediumTest
+ public void testScrollingButtonOffScreenLosesFocus() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertTrue("button should have focus", mBottomButton.isFocused());
+ sendKeys(KeyEvent.KEYCODE_DPAD_UP);
+ assertTrue("scroll view should have focus, but " + getActivity().getScrollView().findFocus() + " does instead",
+ getActivity().getScrollView().isFocused());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/settings/RingtonePickerActivityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/settings/RingtonePickerActivityTest.java
new file mode 100644
index 0000000..42888ff
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/settings/RingtonePickerActivityTest.java
@@ -0,0 +1,227 @@
+/*
+ * 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 com.android.frameworktest.settings;
+
+import com.android.frameworktest.settings.RingtonePickerActivityLauncher;
+
+import android.app.Instrumentation;
+import android.database.Cursor;
+import android.media.RingtoneManager;
+import android.net.Uri;
+import android.provider.MediaStore;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.Suppress;
+import android.view.KeyEvent;
+
+/**
+ * Tests the RingtonePickerActivity.
+ * <p>
+ * There is a launcher for launching the RingtonePickerActivity (RPA) since the RPA needs
+ * to be a subactivity. We don't have a reference to the actual RPA.
+ * <p>
+ * This relies heavily on keypresses getting to the right widget. It depends on:
+ * <li> Less than NUM_RINGTONES_AND_SOME ringtones on the system
+ * <li> Pressing arrow-down a ton will eventually end up on the 'Cancel' button
+ * <li> From the 'Cancel' button, pressing arrow-left will end up on 'OK' button
+ */
+@Suppress
+public class RingtonePickerActivityTest extends ActivityInstrumentationTestCase<RingtonePickerActivityLauncher> {
+
+ private static final int NUM_RINGTONES_AND_SOME = 20;
+ private RingtonePickerActivityLauncher mActivity;
+ private Instrumentation mInstrumentation;
+
+ public RingtonePickerActivityTest() {
+ super("com.android.frameworktest", RingtonePickerActivityLauncher.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mInstrumentation = getInstrumentation();
+ assertNotNull(mActivity);
+ assertFalse(mActivity.resultReceived);
+ assertNotNull(mInstrumentation);
+ }
+
+ public void testDefault() {
+ mActivity.launchRingtonePickerActivity(true, null, RingtoneManager.TYPE_ALL);
+ mInstrumentation.waitForIdleSync();
+
+ // Go to top
+ goTo(true);
+ // Select default ringtone
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ // Go to bottom/cancel button
+ goTo(false);
+ // Select OK button
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_CENTER);
+
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue(mActivity.resultReceived);
+ assertNotNull(mActivity.result);
+ assertTrue(RingtoneManager.isDefault(mActivity.pickedUri));
+ }
+
+ public void testFirst() {
+ mActivity.launchRingtonePickerActivity(true, null, RingtoneManager.TYPE_ALL);
+ mInstrumentation.waitForIdleSync();
+
+ // Go to top
+ goTo(true);
+ // Select first (non-default) ringtone
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_CENTER);
+ // Go to bottom/cancel button
+ goTo(false);
+ // Select OK button
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_CENTER);
+
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue(mActivity.resultReceived);
+ assertNotNull(mActivity.result);
+ assertNotNull(mActivity.pickedUri);
+ assertFalse(RingtoneManager.isDefault(mActivity.pickedUri));
+ }
+
+ public void testExisting() {
+ // We need to get an existing ringtone first, so launch it, pick first,
+ // and keep that URI
+ testFirst();
+ Uri firstUri = mActivity.pickedUri;
+
+ mActivity.launchRingtonePickerActivity(true, firstUri, RingtoneManager.TYPE_ALL);
+ mInstrumentation.waitForIdleSync();
+
+ //// Hit cancel:
+
+ // Go to bottom
+ goTo(false);
+ // Select Cancel button
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue(mActivity.resultReceived);
+ assertEquals(mActivity.pickedUri, firstUri);
+ }
+
+ public void testExistingButDifferent() {
+ // We need to get an existing ringtone first, so launch it, pick first,
+ // and keep that URI
+ testFirst();
+ Uri firstUri = mActivity.pickedUri;
+
+ mActivity.launchRingtonePickerActivity(true, firstUri, RingtoneManager.TYPE_ALL);
+ mInstrumentation.waitForIdleSync();
+
+ //// Pick second:
+
+ // Go to top
+ goTo(true);
+ // Select second (non-default) ringtone
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN, KeyEvent.KEYCODE_DPAD_DOWN,
+ KeyEvent.KEYCODE_DPAD_CENTER);
+ // Go to bottom/cancel button
+ goTo(false);
+ // Select OK button
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_CENTER);
+
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue(mActivity.resultReceived);
+ assertNotNull(mActivity.result);
+ assertTrue(!firstUri.equals(mActivity.pickedUri));
+ }
+
+ public void testCancel() {
+ mActivity.launchRingtonePickerActivity(true, null, RingtoneManager.TYPE_ALL);
+ mInstrumentation.waitForIdleSync();
+
+ // Go to bottom
+ goTo(false);
+ // Select Cancel button
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue(mActivity.resultReceived);
+ assertNull(mActivity.result);
+ }
+
+ public void testNoDefault() {
+ mActivity.launchRingtonePickerActivity(false, null, RingtoneManager.TYPE_ALL);
+ mInstrumentation.waitForIdleSync();
+
+ // Go to top
+ goTo(true);
+ // Select first (non-default) ringtone
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ // Go to bottom/cancel button
+ goTo(false);
+ // Select OK button
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_CENTER);
+
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue(mActivity.resultReceived);
+ assertNotNull(mActivity.result);
+ assertNotNull(mActivity.pickedUri);
+ assertFalse(RingtoneManager.isDefault(mActivity.pickedUri));
+ }
+
+ public void testNotifications() {
+ mActivity.launchRingtonePickerActivity(false, null, RingtoneManager.TYPE_NOTIFICATION);
+ mInstrumentation.waitForIdleSync();
+
+ // Move to top of list
+ goTo(true);
+ // Select first ringtone in list
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ // Move all the way down (will focus 'Cancel')
+ goTo(false);
+ // Move left and click (will click 'Ok')
+ sendKeys(KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_DPAD_CENTER);
+
+ // Wait until main thread is idle
+ mInstrumentation.waitForIdleSync();
+
+ assertTrue(mActivity.resultReceived);
+ assertNotNull(mActivity.result);
+ assertNotNull(mActivity.pickedUri);
+
+ // Get the path of the picked ringtone
+ Uri uri = mActivity.pickedUri;
+ Cursor c = mActivity.getContentResolver().query(uri, new String[] { "_data" },
+ null, null, null);
+ assertTrue("Query for selected ringtone URI does not have a result", c.moveToFirst());
+ String path = c.getString(0);
+ // Quick check to see if the ringtone is a notification
+ assertTrue("The path of the selected ringtone did not contain \"notification\"",
+ path.contains("notifications"));
+ }
+
+ private void goTo(boolean top) {
+ // Get to the buttons at the bottom (top == false), or the top (top == true)
+ for (int i = 0; i < NUM_RINGTONES_AND_SOME; i++) {
+ sendKeys(top ? KeyEvent.KEYCODE_DPAD_UP : KeyEvent.KEYCODE_DPAD_DOWN);
+ }
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/text/HtmlTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/HtmlTest.java
new file mode 100644
index 0000000..9b309c4
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/HtmlTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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 com.android.frameworktest.text;
+
+import android.test.InstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.text.Html;
+import android.text.Spanned;
+import android.text.style.StyleSpan;
+import android.graphics.Typeface;
+
+public class HtmlTest extends InstrumentationTestCase {
+
+ @MediumTest
+ public void testSingleTagOnWhileString() {
+ Spanned spanned = Html.fromHtml("<b>hello</b>");
+ Object[] spans = spanned.getSpans(-1, 100, Object.class);
+ assertEquals(1, spans.length);
+ Object span = spans[0];
+ assertEquals(0, spanned.getSpanStart(span));
+ assertEquals(5, spanned.getSpanEnd(span));
+ }
+
+ @MediumTest
+ public void testEmptyFontTag() {
+ Spanned spanned = Html.fromHtml("Hello <font color=\"#ff00ff00\"></font>");
+ Object[] spans = spanned.getSpans(0, 100, Object.class);
+ // TODO: figure out what the spans should be after the crashes are fixed and assert them.
+ }
+
+ /** Tests that the parser can handle mal-formed HTML. */
+ @MediumTest
+ public void testBadHtml() {
+ Spanned spanned = Html.fromHtml("Hello <b>b<i>bi</b>i</i>");
+ Object[] spans = spanned.getSpans(0, 100, Object.class);
+ assertEquals(Typeface.ITALIC, ((StyleSpan) spans[0]).getStyle());
+ assertEquals(7, spanned.getSpanStart(spans[0]));
+ assertEquals(9, spanned.getSpanEnd(spans[0]));
+ assertEquals(Typeface.BOLD, ((StyleSpan) spans[1]).getStyle());
+ assertEquals(6, spanned.getSpanStart(spans[1]));
+ assertEquals(9, spanned.getSpanEnd(spans[1]));
+ assertEquals(Typeface.ITALIC, ((StyleSpan) spans[2]).getStyle());
+ assertEquals(9, spanned.getSpanStart(spans[2]));
+ assertEquals(10, spanned.getSpanEnd(spans[2]));
+ }
+
+ @MediumTest
+ public void testSymbols() {
+ String spanned = Html.fromHtml("© > <").toString();
+ assertEquals("\u00a9 > <", spanned);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableStringBuilderTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableStringBuilderTest.java
new file mode 100644
index 0000000..a807977
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableStringBuilderTest.java
@@ -0,0 +1,11 @@
+package com.android.frameworktest.text;
+
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+
+public class SpannableStringBuilderTest extends SpannableTest {
+
+ protected Spannable newSpannableWithText(String text) {
+ return new SpannableStringBuilder(text);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableStringTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableStringTest.java
new file mode 100644
index 0000000..311df23
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableStringTest.java
@@ -0,0 +1,11 @@
+package com.android.frameworktest.text;
+
+import android.text.Spannable;
+import android.text.SpannableString;
+
+public class SpannableStringTest extends SpannableTest {
+
+ protected Spannable newSpannableWithText(String text) {
+ return new SpannableString(text);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableTest.java
new file mode 100644
index 0000000..a5f6836
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/text/SpannableTest.java
@@ -0,0 +1,34 @@
+package com.android.frameworktest.text;
+
+import android.test.InstrumentationTestCase;
+import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.text.Spannable;
+
+public abstract class SpannableTest extends InstrumentationTestCase {
+
+ protected abstract Spannable newSpannableWithText(String text);
+
+ @MediumTest
+ public void testGetSpans() {
+ Spannable spannable = newSpannableWithText("abcdef");
+ Object emptySpan = new Object();
+ spannable.setSpan(emptySpan, 1, 1, 0);
+ Object unemptySpan = new Object();
+ spannable.setSpan(unemptySpan, 1, 2, 0);
+
+ Object[] spans;
+
+ // Empty spans are included when they merely abut the query region
+ // but other spans are not, unless the query region is empty, in
+ // in which case any abutting spans are returned.
+ spans = spannable.getSpans(0, 1, Object.class);
+ MoreAsserts.assertEquals(new Object[]{emptySpan}, spans);
+ spans = spannable.getSpans(0, 2, Object.class);
+ MoreAsserts.assertEquals(new Object[]{emptySpan, unemptySpan}, spans);
+ spans = spannable.getSpans(1, 2, Object.class);
+ MoreAsserts.assertEquals(new Object[]{emptySpan, unemptySpan}, spans);
+ spans = spannable.getSpans(2, 2, Object.class);
+ MoreAsserts.assertEquals(new Object[]{unemptySpan}, spans);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/ChangeTouchModeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/ChangeTouchModeTest.java
new file mode 100644
index 0000000..d274d0d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/ChangeTouchModeTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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 com.android.frameworktest.touchmode;
+
+import com.android.frameworktest.layout.linear.LLOfButtons1;
+import com.android.frameworktest.layout.linear.LLOfButtons2;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertInTouchModeAfterClick;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertNotInTouchModeAfterKey;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertInTouchModeAfterTap;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+
+/**
+ * Tests that the touch mode changes from various events, and that the state
+ * persists across activities.
+ */
+public class ChangeTouchModeTest extends ActivityInstrumentationTestCase<LLOfButtons1> {
+
+ public ChangeTouchModeTest() {
+ super("com.android.frameworktest", LLOfButtons1.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @MediumTest
+ public void testPreconditions() throws Exception {
+ assertFalse("touch mode", getActivity().isInTouchMode());
+ }
+
+ @MediumTest
+ public void testTouchingScreenEntersTouchMode() throws Exception {
+ assertInTouchModeAfterTap(this, getActivity().getFirstButton());
+ assertTrue("touch mode", getActivity().isInTouchMode());
+ }
+
+ // TODO: reenable when more reliable
+ public void DISABLE_testDpadDirectionLeavesTouchMode() throws Exception {
+ assertInTouchModeAfterClick(this, getActivity().getFirstButton());
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+ assertNotInTouchModeAfterKey(this, KeyEvent.KEYCODE_DPAD_RIGHT, getActivity().getFirstButton());
+ assertFalse("touch mode", getActivity().isInTouchMode());
+ }
+
+ public void TODO_touchTrackBallMovementLeavesTouchMode() throws Exception {
+
+ }
+
+ @MediumTest
+ public void testTouchModeFalseAcrossActivites() throws Exception {
+
+ getInstrumentation().waitForIdleSync();
+
+ LLOfButtons2 otherActivity = null;
+ try {
+ otherActivity =
+ launchActivity("com.android.frameworktest", LLOfButtons2.class, null);
+ assertNotNull(otherActivity);
+ assertFalse(otherActivity.isInTouchMode());
+ } finally {
+ if (otherActivity != null) {
+ otherActivity.finish();
+ }
+ }
+ }
+
+ @LargeTest
+ public void testTouchModeTrueAcrossActivites() throws Exception {
+ assertInTouchModeAfterClick(this, getActivity().getFirstButton());
+ LLOfButtons2 otherActivity = null;
+ try {
+ otherActivity =
+ launchActivity("com.android.frameworktest", LLOfButtons2.class, null);
+ assertNotNull(otherActivity);
+ assertTrue(otherActivity.isInTouchMode());
+ } finally {
+ if (otherActivity != null) {
+ otherActivity.finish();
+ }
+ }
+ }
+
+ @LargeTest
+ public void testTouchModeChangedInOtherActivity() throws Exception {
+
+ assertFalse("touch mode", getActivity().isInTouchMode());
+
+ LLOfButtons2 otherActivity = null;
+ try {
+ otherActivity =
+ launchActivity("com.android.frameworktest", LLOfButtons2.class, null);
+ assertNotNull(otherActivity);
+ assertFalse(otherActivity.isInTouchMode());
+ assertInTouchModeAfterClick(this, otherActivity.getFirstButton());
+ assertTrue(otherActivity.isInTouchMode());
+ } finally {
+ if (otherActivity != null) {
+ otherActivity.finish();
+ }
+ }
+
+ // need to wait for async update back to window to occur
+ Thread.sleep(200);
+
+ assertTrue("touch mode", getActivity().isInTouchMode());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/FocusableInTouchModeClickTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/FocusableInTouchModeClickTest.java
new file mode 100644
index 0000000..7cd6444
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/FocusableInTouchModeClickTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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 com.android.frameworktest.touchmode;
+
+import com.android.frameworktest.layout.linear.LLOfTwoFocusableInTouchMode;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+
+public class FocusableInTouchModeClickTest extends ActivityInstrumentationTestCase2<LLOfTwoFocusableInTouchMode> {
+
+ public FocusableInTouchModeClickTest() {
+ super("com.android.frameworktest", LLOfTwoFocusableInTouchMode.class);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ setActivityInitialTouchMode(true);
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("should start in touch mode", getActivity().getButton1().isInTouchMode());
+ assertTrue(getActivity().getButton1().isFocused());
+ }
+
+ @LargeTest
+ public void testClickGivesFocusNoClickFired() {
+ TouchUtils.clickView(this, getActivity().getButton2());
+ assertTrue("click should give focusable in touch mode focus",
+ getActivity().getButton2().isFocused());
+ assertFalse("getting focus should result in no on click",
+ getActivity().isB2Fired());
+
+ TouchUtils.clickView(this, getActivity().getButton2());
+ assertTrue("subsequent click while focused should fire on click",
+ getActivity().isB2Fired());
+ }
+
+ @MediumTest
+ public void testTapGivesFocusNoClickFired() {
+ TouchUtils.touchAndCancelView(this, getActivity().getButton2());
+ assertFalse("button shouldn't have fired click", getActivity().isB2Fired());
+ assertFalse("button shouldn't have focus", getActivity().getButton2().isFocused());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/StartInTouchWithViewInFocusTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/StartInTouchWithViewInFocusTest.java
new file mode 100644
index 0000000..6403435
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/StartInTouchWithViewInFocusTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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 com.android.frameworktest.touchmode;
+
+import com.android.frameworktest.layout.linear.LLEditTextThenButton;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertNotInTouchModeAfterKey;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+import android.widget.EditText;
+
+public class StartInTouchWithViewInFocusTest extends
+ ActivityInstrumentationTestCase2<LLEditTextThenButton> {
+
+ private EditText mEditText;
+
+ private Button mButton;
+
+ public StartInTouchWithViewInFocusTest() {
+ super("com.android.frameworktest", LLEditTextThenButton.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.setActivityInitialTouchMode(true);
+ mEditText = getActivity().getEditText();
+ mButton = getActivity().getButton();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertTrue("should start in touch mode", mEditText.isInTouchMode());
+ assertTrue("edit text is focusable in touch mode, should have focus", mEditText.isFocused());
+ }
+
+ // TODO: reenable when more reliable
+ public void DISABLE_testKeyDownLeavesTouchModeAndGoesToNextView() {
+ assertNotInTouchModeAfterKey(this, KeyEvent.KEYCODE_DPAD_DOWN, mEditText);
+ assertFalse("should have left touch mode", mEditText.isInTouchMode());
+ assertTrue("should have given focus to next view", mButton.isFocused());
+ }
+
+ // TODO: reenable when more reliable
+ public void DISABLE_testNonDirectionalKeyExitsTouchMode() {
+ assertNotInTouchModeAfterKey(this, KeyEvent.KEYCODE_A, mEditText);
+ assertFalse("should have left touch mode", mEditText.isInTouchMode());
+ assertTrue("edit text should still have focus", mEditText.isFocused());
+ }
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/TouchModeFocusChangeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/TouchModeFocusChangeTest.java
new file mode 100644
index 0000000..1a0c833
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/TouchModeFocusChangeTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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 com.android.frameworktest.touchmode;
+
+import com.android.frameworktest.layout.linear.LLOfButtons1;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertInTouchModeAfterClick;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertInTouchModeAfterTap;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertNotInTouchModeAfterKey;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+
+/**
+ * Make sure focus isn't kept by buttons when entering touch mode.
+ *
+ * When in touch mode and hitting the d-pad, we should leave touch mode and the
+ * top most focusable gets focus.
+ */
+public class TouchModeFocusChangeTest extends ActivityInstrumentationTestCase<LLOfButtons1> {
+ private LLOfButtons1 mActivity;
+ private Button mFirstButton;
+
+ public TouchModeFocusChangeTest() {
+ super("com.android.frameworktest", LLOfButtons1.class);
+ }
+
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mActivity = getActivity();
+ mFirstButton = mActivity.getFirstButton();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertFalse("we should not be in touch mode", mActivity.isInTouchMode());
+ assertTrue("top button should have focus", mFirstButton.isFocused());
+ }
+
+ @MediumTest
+ public void testTouchButtonNotTakeFocus() {
+ assertInTouchModeAfterTap(this, mFirstButton);
+
+ assertTrue("should be in touch mode", mActivity.isInTouchMode());
+ assertFalse("button.isFocused",
+ mFirstButton.isFocused());
+ assertFalse("button.hasFocus",
+ mFirstButton.hasFocus());
+ assertNull("activity shouldn't have focus", mActivity.getCurrentFocus());
+ assertFalse("linear layout should not have focus",
+ mActivity.getLayout().hasFocus());
+
+ assertTrue("button's onClickListener should have fired",
+ mActivity.buttonClickListenerFired());
+ }
+
+ // TODO: reenable when more reliable
+ public void DISABLE_testLeaveTouchModeWithDpadEvent() {
+ assertInTouchModeAfterClick(this, mFirstButton);
+
+ assertTrue("should be in touch mode", mActivity.isInTouchMode());
+ assertFalse("button should not have focus when touched",
+ mFirstButton.isFocused());
+
+ assertNotInTouchModeAfterKey(this, KeyEvent.KEYCODE_DPAD_RIGHT, mFirstButton);
+ assertFalse("should be out of touch mode", mActivity.isInTouchMode());
+ assertTrue("first button (the top most focusable) should have gained focus",
+ mFirstButton.isFocused());
+ }
+
+
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/TouchModeFocusableTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/TouchModeFocusableTest.java
new file mode 100644
index 0000000..86925b5
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/touchmode/TouchModeFocusableTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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 com.android.frameworktest.touchmode;
+
+import com.android.frameworktest.layout.linear.LLEditTextThenButton;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertInTouchModeAfterTap;
+import static com.android.frameworktest.util.TouchModeFlexibleAsserts.assertInTouchModeAfterClick;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.KeyEvent;
+import android.widget.Button;
+import android.widget.EditText;
+
+/**
+ * Some views, like edit texts, can keep and gain focus even when in touch mode.
+ */
+public class TouchModeFocusableTest extends ActivityInstrumentationTestCase<LLEditTextThenButton> {
+ private EditText mEditText;
+ private Button mButton;
+
+
+ public TouchModeFocusableTest() {
+ super("com.android.frameworktest", LLEditTextThenButton.class);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mEditText = getActivity().getEditText();
+ mButton = getActivity().getButton();
+ }
+
+ @MediumTest
+ public void testPreconditions() {
+ assertFalse("should not be in touch mode to start off", mButton.isInTouchMode());
+ assertTrue("edit text should have focus", mEditText.isFocused());
+ assertTrue("edit text should be focusable in touch mode", mEditText.isFocusableInTouchMode());
+ }
+
+ @MediumTest
+ public void testClickButtonEditTextKeepsFocus() {
+ assertInTouchModeAfterTap(this, mButton);
+ assertTrue("should be in touch mode", mButton.isInTouchMode());
+ assertTrue("edit text should still have focus", mEditText.isFocused());
+ }
+
+ @LargeTest
+ public void testClickEditTextGivesItFocus() {
+ // go down to button
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+ assertTrue("button should have focus", mButton.isFocused());
+
+ assertInTouchModeAfterClick(this, mEditText);
+ assertTrue("clicking edit text should have entered touch mode", mButton.isInTouchMode());
+ assertTrue("clicking edit text should have given it focus", mEditText.isFocused());
+ }
+
+
+ // entering touch mode takes focus away from the currently focused item if it
+ // isn't focusable in touch mode.
+ @LargeTest
+ public void testEnterTouchModeGivesFocusBackToFocusableInTouchMode() {
+ sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
+
+ assertTrue("button should have focus",
+ mButton.isFocused());
+
+ assertInTouchModeAfterClick(this, mButton);
+ assertTrue("should be in touch mode", mButton.isInTouchMode());
+ assertNull("nothing should have focus", getActivity().getCurrentFocus());
+ assertFalse("layout should not have focus",
+ getActivity().getLayout().hasFocus());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/BigCacheTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/BigCacheTest.java
new file mode 100644
index 0000000..b5e7473
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/BigCacheTest.java
@@ -0,0 +1,83 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.BigCache;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.graphics.Bitmap;
+
+/**
+ * Builds the drawing cache of two Views, one smaller than the maximum cache size,
+ * one larger than the maximum cache size. The latter should always have a null
+ * drawing cache.
+ */
+public class BigCacheTest extends ActivityInstrumentationTestCase<BigCache> {
+ private View mTiny;
+ private View mLarge;
+
+ public BigCacheTest() {
+ super("com.android.frameworktest", BigCache.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final BigCache activity = getActivity();
+ mTiny = activity.findViewById(R.id.a);
+ mLarge = activity.findViewById(R.id.b);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mTiny);
+ assertNotNull(mLarge);
+ }
+
+ @MediumTest
+ public void testDrawingCacheBelowMaximumSize() throws Exception {
+ final int max = ViewConfiguration.getMaximumDrawingCacheSize();
+ assertTrue(mTiny.getWidth() * mTiny.getHeight() * 2 < max);
+ assertNotNull(createCacheForView(mTiny));
+ }
+
+ @MediumTest
+ public void testDrawingCacheAboveMaximumSize() throws Exception {
+ final int max = ViewConfiguration.getMaximumDrawingCacheSize();
+ assertTrue(mLarge.getWidth() * mLarge.getHeight() * 2 > max);
+ assertNull(createCacheForView(mLarge));
+ }
+
+ private Bitmap createCacheForView(final View view) {
+ final Bitmap[] cache = new Bitmap[1];
+ getActivity().runOnUiThread(new Runnable() {
+ public void run() {
+ view.setDrawingCacheEnabled(true);
+ view.invalidate();
+ view.buildDrawingCache();
+ cache[0] = view.getDrawingCache();
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ return cache[0];
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/DisabledLongpressTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/DisabledLongpressTest.java
new file mode 100644
index 0000000..ef3ecee
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/DisabledLongpressTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.Longpress;
+import com.android.frameworktest.R;
+import com.android.frameworktest.util.KeyUtils;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+
+/**
+ * Exercises {@link android.view.View}'s longpress plumbing by testing the
+ * disabled case.
+ */
+public class DisabledLongpressTest extends ActivityInstrumentationTestCase<Longpress> {
+ private View mSimpleView;
+ private boolean mLongClicked;
+
+ public DisabledLongpressTest() {
+ super("com.android.frameworktest", Longpress.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final Longpress a = getActivity();
+ mSimpleView = a.findViewById(R.id.simple_view);
+ mSimpleView.setOnLongClickListener(new OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ mLongClicked = true;
+ return true;
+ }
+ });
+ // The View#setOnLongClickListener will ensure the View is long
+ // clickable, we reverse that here
+ mSimpleView.setLongClickable(false);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ mLongClicked = false;
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mSimpleView);
+ assertTrue(mSimpleView.hasFocus());
+ assertFalse(mLongClicked);
+ }
+
+ @LargeTest
+ public void testKeypadLongClick() throws Exception {
+ mSimpleView.requestFocus();
+ getInstrumentation().waitForIdleSync();
+ KeyUtils.longClick(this);
+
+ getInstrumentation().waitForIdleSync();
+ assertFalse(mLongClicked);
+ }
+
+ @LargeTest
+ public void testTouchLongClick() throws Exception {
+ TouchUtils.longClickView(this, mSimpleView);
+ getInstrumentation().waitForIdleSync();
+ assertFalse(mLongClicked);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/DisabledTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/DisabledTest.java
new file mode 100644
index 0000000..d9ed033
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/DisabledTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.widget.Button;
+import android.view.KeyEvent;
+import android.view.View;
+
+/**
+ * Exercises {@link android.view.View}'s disabled property.
+ */
+public class DisabledTest extends ActivityInstrumentationTestCase<Disabled> {
+ private Button mDisabled;
+ private View mDisabledParent;
+ private boolean mClicked;
+ private boolean mParentClicked;
+
+ public DisabledTest() {
+ super("com.android.frameworktest", Disabled.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final Disabled a = getActivity();
+ mDisabled = (Button) a.findViewById(R.id.disabledButton);
+ mDisabled.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mClicked = true;
+ }
+ });
+
+ mDisabledParent = a.findViewById(R.id.clickableParent);
+ mDisabledParent.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ mParentClicked = true;
+ }
+ });
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ mClicked = false;
+ mParentClicked = false;
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mDisabled);
+ assertNotNull(mDisabledParent);
+ assertFalse(mDisabled.isEnabled());
+ assertTrue(mDisabledParent.isEnabled());
+ assertTrue(mDisabled.hasFocus());
+ }
+
+ @MediumTest
+ public void testKeypadClick() throws Exception {
+ sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
+ getInstrumentation().waitForIdleSync();
+ assertFalse(mClicked);
+ assertFalse(mParentClicked);
+ }
+
+ @LargeTest
+ public void testTouchClick() throws Exception {
+ TouchUtils.clickView(this, mDisabled);
+ getInstrumentation().waitForIdleSync();
+ assertFalse(mClicked);
+ assertFalse(mParentClicked);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/GlobalFocusChangeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/GlobalFocusChangeTest.java
new file mode 100644
index 0000000..8a8d728
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/GlobalFocusChangeTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.FlakyTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.TouchUtils;
+import android.view.View;
+import android.view.KeyEvent;
+import com.android.frameworktest.R;
+
+public class GlobalFocusChangeTest extends ActivityInstrumentationTestCase<GlobalFocusChange> {
+ private GlobalFocusChange mActivity;
+ private View mLeft;
+ private View mRight;
+
+ public GlobalFocusChangeTest() {
+ super("com.android.frameworktest", GlobalFocusChange.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ mActivity = getActivity();
+ mLeft = mActivity.findViewById(R.id.left);
+ mRight = mActivity.findViewById(R.id.right);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mActivity.reset();
+ super.tearDown();
+ }
+
+ @FlakyTest(tolerance = 4)
+ @LargeTest
+ public void testFocusChange() throws Exception {
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+
+ assertFalse(mLeft.isFocused());
+ assertTrue(mRight.isFocused());
+
+ assertSame(mLeft, mActivity.mOldFocus);
+ assertSame(mRight, mActivity.mNewFocus);
+ }
+
+ @FlakyTest(tolerance = 4)
+ @MediumTest
+ public void testEnterTouchMode() throws Exception {
+ assertTrue(mLeft.isFocused());
+
+ TouchUtils.tapView(this, mLeft);
+
+ assertSame(mLeft, mActivity.mOldFocus);
+ assertSame(null, mActivity.mNewFocus);
+ }
+
+ @FlakyTest(tolerance = 4)
+ @MediumTest
+ public void testLeaveTouchMode() throws Exception {
+ assertTrue(mLeft.isFocused());
+
+ TouchUtils.tapView(this, mLeft);
+ sendKeys(KeyEvent.KEYCODE_DPAD_RIGHT);
+
+ assertTrue(mLeft.isFocused());
+
+ assertSame(null, mActivity.mOldFocus);
+ assertSame(mLeft, mActivity.mNewFocus);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/IncludeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/IncludeTest.java
new file mode 100644
index 0000000..dd1382d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/IncludeTest.java
@@ -0,0 +1,78 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.Include;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class IncludeTest extends ActivityInstrumentationTestCase<Include> {
+ public IncludeTest() {
+ super("com.android.frameworktest", Include.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @MediumTest
+ public void testIncluded() throws Exception {
+ final Include activity = getActivity();
+
+ final View button1 = activity.findViewById(R.id.included_button);
+ assertNotNull("The layout include_button was not included", button1);
+
+ final View button2 = activity.findViewById(R.id.included_button_overriden);
+ assertNotNull("The layout include_button was not included with overriden id", button2);
+ }
+
+ @MediumTest
+ public void testIncludedWithLayoutParams() throws Exception {
+ final Include activity = getActivity();
+
+ final View button1 = activity.findViewById(R.id.included_button);
+ final View button2 = activity.findViewById(R.id.included_button_overriden);
+
+ assertTrue("Both buttons should have different width",
+ button1.getLayoutParams().width != button2.getLayoutParams().width);
+ assertTrue("Both buttons should have different height",
+ button1.getLayoutParams().height != button2.getLayoutParams().height);
+ }
+
+ @MediumTest
+ public void testIncludedWithVisibility() throws Exception {
+ final Include activity = getActivity();
+ final View button1 = activity.findViewById(R.id.included_button_visibility);
+
+ assertEquals("Included button should be invisible", View.INVISIBLE, button1.getVisibility());
+ }
+
+ @MediumTest
+ public void testIncludedWithSize() throws Exception {
+ final Include activity = getActivity();
+ final View button1 = activity.findViewById(R.id.included_button_with_size);
+
+ final ViewGroup.LayoutParams lp = button1.getLayoutParams();
+ assertEquals("Included button should be 23dip x 23dip", 23, lp.width);
+ assertEquals("Included button should be 23dip x 23dip", 23, lp.height);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/LongpressTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/LongpressTest.java
new file mode 100644
index 0000000..37106f6
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/LongpressTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.Longpress;
+import com.android.frameworktest.R;
+import com.android.frameworktest.util.KeyUtils;
+import android.test.TouchUtils;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.view.View;
+import android.view.View.OnLongClickListener;
+
+/**
+ * Exercises {@link android.view.View}'s longpress plumbing.
+ */
+public class LongpressTest extends ActivityInstrumentationTestCase<Longpress> {
+ private View mSimpleView;
+ private boolean mLongClicked;
+
+ public LongpressTest() {
+ super("com.android.frameworktest", Longpress.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final Longpress a = getActivity();
+ mSimpleView = a.findViewById(R.id.simple_view);
+ mSimpleView.setOnLongClickListener(new OnLongClickListener() {
+ public boolean onLongClick(View v) {
+ mLongClicked = true;
+ return true;
+ }
+ });
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ mLongClicked = false;
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mSimpleView);
+ assertTrue(mSimpleView.hasFocus());
+ assertFalse(mLongClicked);
+ }
+
+ @LargeTest
+ public void testKeypadLongClick() throws Exception {
+ mSimpleView.requestFocus();
+ getInstrumentation().waitForIdleSync();
+ KeyUtils.longClick(this);
+
+ getInstrumentation().waitForIdleSync();
+ assertTrue(mLongClicked);
+ }
+
+ @LargeTest
+ public void testTouchLongClick() throws Exception {
+ TouchUtils.longClickView(this, mSimpleView);
+ getInstrumentation().waitForIdleSync();
+ assertTrue(mLongClicked);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/MergeTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/MergeTest.java
new file mode 100644
index 0000000..612ebd4
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/MergeTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.Merge;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.ViewGroup;
+
+public class MergeTest extends ActivityInstrumentationTestCase<Merge> {
+ public MergeTest() {
+ super("com.android.frameworktest", Merge.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @MediumTest
+ public void testMerged() throws Exception {
+ final Merge activity = getActivity();
+ final ViewGroup layout = activity.getLayout();
+
+ assertEquals("The layout wasn't merged", 7, layout.getChildCount());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java
new file mode 100644
index 0000000..3dcb252
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RemoteViewsActivityTest.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2008 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 com.android.frameworktest.view;
+
+import android.os.Parcel;
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.InflateException;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.RemoteViews;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.view.RemoteViewsActivity;
+
+public class RemoteViewsActivityTest extends ActivityInstrumentationTestCase<RemoteViewsActivity> {
+ public RemoteViewsActivityTest() {
+ super("com.android.frameworktest", RemoteViewsActivity.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @MediumTest
+ public void testGood() throws Exception {
+ final RemoteViewsActivity activity = getActivity();
+
+ RemoteViews orig = new RemoteViews("com.android.frameworktest",
+ R.layout.remote_view_test_good);
+ Parcel p = Parcel.obtain();
+ orig.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ RemoteViews r = RemoteViews.CREATOR.createFromParcel(p);
+
+ ViewGroup parent = (ViewGroup) activity.findViewById(R.id.parent);
+
+ View result = r.apply(activity, parent);
+
+ p.recycle();
+
+ assertTrue("LinearLayout not inflated", result.findViewById(R.id.linear) != null);
+ assertTrue("TextView not inflated", result.findViewById(R.id.text) != null);
+ assertTrue("ImageView not inflated", result.findViewById(R.id.image) != null);
+ assertTrue("FrameLayout not inflated", result.findViewById(R.id.frame) != null);
+ assertTrue("RelateiveLayout not inflated", result.findViewById(R.id.relative) != null);
+ assertTrue("AbsoluteLayout not inflated", result.findViewById(R.id.absolute) != null);
+ assertTrue("ProgressBar not inflated", result.findViewById(R.id.progress) != null);
+ assertTrue("ImageButton not inflated", result.findViewById(R.id.image_button) != null);
+ assertTrue("Button not inflated", result.findViewById(R.id.button) != null);
+ }
+
+ @MediumTest
+ public void testDerivedClass() throws Exception {
+ final RemoteViewsActivity activity = getActivity();
+
+ RemoteViews orig = new RemoteViews("com.android.frameworktest",
+ R.layout.remote_view_test_bad_1);
+ Parcel p = Parcel.obtain();
+ orig.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ RemoteViews r = RemoteViews.CREATOR.createFromParcel(p);
+
+ ViewGroup parent = (ViewGroup) activity.findViewById(R.id.parent);
+
+ boolean exceptionThrown = false;
+ View result = null;
+
+ try {
+ result = r.apply(activity, parent);
+ } catch (InflateException e) {
+ exceptionThrown = true;
+ }
+
+ p.recycle();
+
+ assertTrue("Derived class (EditText) allowed to be inflated", exceptionThrown);
+ assertNull("Derived class (EditText) allowed to be inflated", result);
+ }
+
+ @MediumTest
+ public void testWebView() throws Exception {
+ final RemoteViewsActivity activity = getActivity();
+
+ RemoteViews orig = new RemoteViews("com.android.frameworktest",
+ R.layout.remote_view_test_bad_2);
+ Parcel p = Parcel.obtain();
+ orig.writeToParcel(p, 0);
+ p.setDataPosition(0);
+
+ RemoteViews r = RemoteViews.CREATOR.createFromParcel(p);
+
+ ViewGroup parent = (ViewGroup) activity.findViewById(R.id.parent);
+
+ boolean exceptionThrown = false;
+ View result = null;
+
+ try {
+ result = r.apply(activity, parent);
+ } catch (InflateException e) {
+ exceptionThrown = true;
+ }
+
+ p.recycle();
+
+ assertTrue("WebView allowed to be inflated", exceptionThrown);
+ assertNull("WebView allowed to be inflated", result);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RunQueueTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RunQueueTest.java
new file mode 100644
index 0000000..dc8fcd8
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/RunQueueTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+
+public class RunQueueTest extends ActivityInstrumentationTestCase<RunQueue> {
+ public RunQueueTest() {
+ super("com.android.frameworktest", RunQueue.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @MediumTest
+ public void testRunnableRan() throws Exception {
+ final RunQueue activity = getActivity();
+ getInstrumentation().waitForIdleSync();
+ assertTrue("The runnable did not run", activity.runnableRan);
+ }
+
+ @MediumTest
+ public void testRunnableCancelled() throws Exception {
+ final RunQueue activity = getActivity();
+ getInstrumentation().waitForIdleSync();
+ assertTrue("The runnable was not cancelled", activity.runnableCancelled);
+ }
+
+ @MediumTest
+ public void testListenerFired() throws Exception {
+ final RunQueue activity = getActivity();
+ getInstrumentation().waitForIdleSync();
+ assertTrue("The global layout listener did not fire", activity.globalLayout);
+ }
+
+ @MediumTest
+ public void testTreeObserverKilled() throws Exception {
+ final RunQueue activity = getActivity();
+ getInstrumentation().waitForIdleSync();
+ assertFalse("The view tree observer is still alive", activity.viewTreeObserver.isAlive());
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ViewGroupChildrenTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ViewGroupChildrenTest.java
new file mode 100644
index 0000000..fceec51
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ViewGroupChildrenTest.java
@@ -0,0 +1,268 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.R;
+import com.android.frameworktest.view.ViewGroupChildren;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.ViewAsserts;
+import android.test.UiThreadTest;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ * Exercises {@link android.view.ViewGroup}'s ability to add/remove children.
+ */
+public class ViewGroupChildrenTest extends ActivityInstrumentationTestCase<ViewGroupChildren> {
+ private ViewGroup mGroup;
+
+ public ViewGroupChildrenTest() {
+ super("com.android.frameworktest", ViewGroupChildren.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final ViewGroupChildren a = getActivity();
+ mGroup = (ViewGroup) a.findViewById(R.id.group);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mGroup);
+ }
+
+ @MediumTest
+ public void testStartsEmpty() throws Exception {
+ assertEquals("A ViewGroup should have no child by default", 0, mGroup.getChildCount());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testAddChild() throws Exception {
+ View view = createView("1");
+ mGroup.addView(view);
+
+ assertEquals(1, mGroup.getChildCount());
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ ViewAsserts.assertGroupContains(mGroup, view);
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testAddChildAtFront() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ for (int i = 0; i < 24; i++) {
+ View view = createView(String.valueOf(i + 1));
+ mGroup.addView(view);
+ }
+
+ View view = createView("X");
+ mGroup.addView(view, 0);
+
+ assertEquals(25, mGroup.getChildCount());
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ ViewAsserts.assertGroupContains(mGroup, view);
+ assertSame(view, mGroup.getChildAt(0));
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testAddChildInMiddle() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ for (int i = 0; i < 24; i++) {
+ View view = createView(String.valueOf(i + 1));
+ mGroup.addView(view);
+ }
+
+ View view = createView("X");
+ mGroup.addView(view, 12);
+
+ assertEquals(25, mGroup.getChildCount());
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ ViewAsserts.assertGroupContains(mGroup, view);
+ assertSame(view, mGroup.getChildAt(12));
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testAddChildren() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ for (int i = 0; i < 24; i++) {
+ View view = createView(String.valueOf(i + 1));
+ mGroup.addView(view);
+
+ ViewAsserts.assertGroupContains(mGroup, view);
+ }
+ assertEquals(24, mGroup.getChildCount());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testRemoveChild() throws Exception {
+ View view = createView("1");
+ mGroup.addView(view);
+
+ ViewAsserts.assertGroupIntegrity(mGroup);
+
+ mGroup.removeView(view);
+
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ ViewAsserts.assertGroupNotContains(mGroup, view);
+
+ assertEquals(0, mGroup.getChildCount());
+ assertNull(view.getParent());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testRemoveChildren() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ final View[] views = new View[24];
+
+ for (int i = 0; i < views.length; i++) {
+ views[i] = createView(String.valueOf(i + 1));
+ mGroup.addView(views[i]);
+ }
+
+ for (int i = views.length - 1; i >= 0; i--) {
+ mGroup.removeViewAt(i);
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ ViewAsserts.assertGroupNotContains(mGroup, views[i]);
+ assertNull(views[i].getParent());
+ }
+
+ assertEquals(0, mGroup.getChildCount());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testRemoveChildrenBulk() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ final View[] views = new View[24];
+
+ for (int i = 0; i < views.length; i++) {
+ views[i] = createView(String.valueOf(i + 1));
+ mGroup.addView(views[i]);
+ }
+
+ mGroup.removeViews(6, 7);
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ for (int i = 6; i < 13; i++) {
+ ViewAsserts.assertGroupNotContains(mGroup, views[i]);
+ assertNull(views[i].getParent());
+ }
+
+ assertEquals(17, mGroup.getChildCount());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testRemoveChildrenBulkAtFront() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ final View[] views = new View[24];
+
+ for (int i = 0; i < views.length; i++) {
+ views[i] = createView(String.valueOf(i + 1));
+ mGroup.addView(views[i]);
+ }
+
+ mGroup.removeViews(0, 7);
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ for (int i = 0; i < 7; i++) {
+ ViewAsserts.assertGroupNotContains(mGroup, views[i]);
+ assertNull(views[i].getParent());
+ }
+
+ assertEquals("8", ((TextView) mGroup.getChildAt(0)).getText());
+ assertEquals(17, mGroup.getChildCount());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testRemoveChildrenBulkAtEnd() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ final View[] views = new View[24];
+
+ for (int i = 0; i < views.length; i++) {
+ views[i] = createView(String.valueOf(i + 1));
+ mGroup.addView(views[i]);
+ }
+
+ mGroup.removeViews(17, 7);
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ for (int i = 17; i < 24; i++) {
+ ViewAsserts.assertGroupNotContains(mGroup, views[i]);
+ assertNull(views[i].getParent());
+ }
+ assertEquals("17", ((TextView) mGroup.getChildAt(mGroup.getChildCount() - 1)).getText());
+ assertEquals(17, mGroup.getChildCount());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testRemoveChildAtFront() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ final View[] views = new View[24];
+
+ for (int i = 0; i < views.length; i++) {
+ views[i] = createView(String.valueOf(i + 1));
+ mGroup.addView(views[i]);
+ }
+
+ mGroup.removeViewAt(0);
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ ViewAsserts.assertGroupNotContains(mGroup, views[0]);
+ assertNull(views[0].getParent());
+
+ assertEquals(views.length - 1, mGroup.getChildCount());
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testRemoveChildInMiddle() throws Exception {
+ // 24 should be greater than ViewGroup.ARRAY_CAPACITY_INCREMENT
+ final View[] views = new View[24];
+
+ for (int i = 0; i < views.length; i++) {
+ views[i] = createView(String.valueOf(i + 1));
+ mGroup.addView(views[i]);
+ }
+
+ mGroup.removeViewAt(12);
+ ViewAsserts.assertGroupIntegrity(mGroup);
+ ViewAsserts.assertGroupNotContains(mGroup, views[12]);
+ assertNull(views[12].getParent());
+
+ assertEquals(views.length - 1, mGroup.getChildCount());
+ }
+
+ private TextView createView(String text) {
+ TextView view = new TextView(getActivity());
+ view.setText(text);
+ view.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.FILL_PARENT,
+ LinearLayout.LayoutParams.WRAP_CONTENT
+ ));
+ return view;
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ViewStubTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ViewStubTest.java
new file mode 100644
index 0000000..89bd646
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ViewStubTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.StubbedView;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.test.UiThreadTest;
+import android.view.View;
+import android.view.ViewStub;
+
+public class ViewStubTest extends ActivityInstrumentationTestCase<StubbedView> {
+ public ViewStubTest() {
+ super("com.android.frameworktest", StubbedView.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @MediumTest
+ public void testStubbed() throws Exception {
+ final StubbedView activity = getActivity();
+
+ final View stub = activity.findViewById(R.id.viewStub);
+ assertNotNull("The ViewStub does not exist", stub);
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testInflated() throws Exception {
+ final StubbedView activity = getActivity();
+
+ final ViewStub stub = (ViewStub) activity.findViewById(R.id.viewStub);
+ final View swapped = stub.inflate();
+
+ assertNotNull("The inflated view is null", swapped);
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testInflatedId() throws Exception {
+ final StubbedView activity = getActivity();
+
+ final ViewStub stub = (ViewStub) activity.findViewById(R.id.viewStubWithId);
+ final View swapped = stub.inflate();
+
+ assertNotNull("The inflated view is null", swapped);
+ assertTrue("The inflated view has no id", swapped.getId() != View.NO_ID);
+ assertTrue("The inflated view has the wrong id", swapped.getId() == R.id.stub_inflated);
+ }
+
+ @UiThreadTest
+ @MediumTest
+ public void testInflatedLayoutParams() throws Exception {
+ final StubbedView activity = getActivity();
+
+ final ViewStub stub = (ViewStub) activity.findViewById(R.id.viewStubWithId);
+ final View swapped = stub.inflate();
+
+ assertNotNull("The inflated view is null", swapped);
+
+ assertEquals("Both stub and inflated should same width",
+ stub.getLayoutParams().width, swapped.getLayoutParams().width);
+ assertEquals("Both stub and inflated should same height",
+ stub.getLayoutParams().height, swapped.getLayoutParams().height);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VisibilityTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VisibilityTest.java
new file mode 100644
index 0000000..77b281d
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/VisibilityTest.java
@@ -0,0 +1,179 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.Visibility;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.LargeTest;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.Button;
+import android.widget.TextView;
+import android.view.View;
+import static android.view.KeyEvent.*;
+
+/**
+ * Exercises {@link android.view.View}'s ability to change visibility between
+ * GONE, VISIBLE and INVISIBLE.
+ */
+public class VisibilityTest extends ActivityInstrumentationTestCase<Visibility> {
+ private TextView mRefUp;
+ private TextView mRefDown;
+ private TextView mVictim;
+ private Button mVisible;
+ private Button mInvisible;
+ private Button mGone;
+
+ public VisibilityTest() {
+ super("com.android.frameworktest", Visibility.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final Visibility a = getActivity();
+ mRefUp = (TextView) a.findViewById(R.id.refUp);
+ mRefDown = (TextView) a.findViewById(R.id.refDown);
+ mVictim = (TextView) a.findViewById(R.id.victim);
+ mVisible = (Button) a.findViewById(R.id.vis);
+ mInvisible = (Button) a.findViewById(R.id.invis);
+ mGone = (Button) a.findViewById(R.id.gone);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mRefUp);
+ assertNotNull(mRefDown);
+ assertNotNull(mVictim);
+ assertNotNull(mVisible);
+ assertNotNull(mInvisible);
+ assertNotNull(mGone);
+
+ assertTrue(mVisible.hasFocus());
+ }
+
+ @MediumTest
+ public void testVisibleToInvisible() throws Exception {
+ sendKeys("DPAD_RIGHT");
+ assertTrue(mInvisible.hasFocus());
+
+ int oldTop = mVictim.getTop();
+
+ sendKeys("DPAD_CENTER");
+ assertEquals(View.INVISIBLE, mVictim.getVisibility());
+
+ int newTop = mVictim.getTop();
+ assertEquals(oldTop, newTop);
+ }
+
+ @MediumTest
+ public void testVisibleToGone() throws Exception {
+ //sendKeys("2*DPAD_RIGHT");
+ sendRepeatedKeys(2, KEYCODE_DPAD_RIGHT);
+ assertTrue(mGone.hasFocus());
+
+ int oldTop = mVictim.getTop();
+
+ sendKeys("DPAD_CENTER");
+ assertEquals(View.GONE, mVictim.getVisibility());
+
+ int refDownTop = mRefDown.getTop();
+ assertEquals(oldTop, refDownTop);
+ }
+
+ @LargeTest
+ public void testGoneToVisible() throws Exception {
+ sendKeys("2*DPAD_RIGHT");
+ assertTrue(mGone.hasFocus());
+
+ int oldTop = mVictim.getTop();
+
+ sendKeys("DPAD_CENTER");
+ assertEquals(View.GONE, mVictim.getVisibility());
+
+ int refDownTop = mRefDown.getTop();
+ assertEquals(oldTop, refDownTop);
+
+ sendKeys("2*DPAD_LEFT DPAD_CENTER");
+ assertEquals(View.VISIBLE, mVictim.getVisibility());
+
+ int newTop = mVictim.getTop();
+ assertEquals(oldTop, newTop);
+ }
+
+ @MediumTest
+ public void testGoneToInvisible() throws Exception {
+ sendKeys("2*DPAD_RIGHT");
+ assertTrue(mGone.hasFocus());
+
+ int oldTop = mVictim.getTop();
+
+ sendKeys("DPAD_CENTER");
+ assertEquals(View.GONE, mVictim.getVisibility());
+
+ int refDownTop = mRefDown.getTop();
+ assertEquals(oldTop, refDownTop);
+
+ sendKeys(KEYCODE_DPAD_LEFT, KEYCODE_DPAD_CENTER);
+ assertEquals(View.INVISIBLE, mVictim.getVisibility());
+
+ int newTop = mVictim.getTop();
+ assertEquals(oldTop, newTop);
+ }
+
+ @MediumTest
+ public void testInvisibleToVisible() throws Exception {
+ sendKeys("DPAD_RIGHT");
+ assertTrue(mInvisible.hasFocus());
+
+ int oldTop = mVictim.getTop();
+
+ sendKeys("DPAD_CENTER");
+ assertEquals(View.INVISIBLE, mVictim.getVisibility());
+
+ int newTop = mVictim.getTop();
+ assertEquals(oldTop, newTop);
+
+ sendKeys("DPAD_LEFT DPAD_CENTER");
+ assertEquals(View.VISIBLE, mVictim.getVisibility());
+
+ newTop = mVictim.getTop();
+ assertEquals(oldTop, newTop);
+ }
+
+ @MediumTest
+ public void testInvisibleToGone() throws Exception {
+ sendKeys("DPAD_RIGHT");
+ assertTrue(mInvisible.hasFocus());
+
+ int oldTop = mVictim.getTop();
+
+ sendKeys("DPAD_CENTER");
+ assertEquals(View.INVISIBLE, mVictim.getVisibility());
+
+ int newTop = mVictim.getTop();
+ assertEquals(oldTop, newTop);
+
+ sendKeys("DPAD_RIGHT DPAD_CENTER");
+ assertEquals(View.GONE, mVictim.getVisibility());
+
+ int refDownTop = mRefDown.getTop();
+ assertEquals(oldTop, refDownTop);
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ZeroSizedTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ZeroSizedTest.java
new file mode 100644
index 0000000..cd646e4
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/view/ZeroSizedTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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 com.android.frameworktest.view;
+
+import com.android.frameworktest.view.ZeroSized;
+import com.android.frameworktest.R;
+
+import android.test.ActivityInstrumentationTestCase;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.graphics.Bitmap;
+
+/**
+ * Builds the drawing cache of Views of various dimension. The assumption is that
+ * a View with a 0-sized dimension (width or height) will always have a null
+ * drawing cache.
+ */
+public class ZeroSizedTest extends ActivityInstrumentationTestCase<ZeroSized> {
+ private View mWithDimension;
+ private View mWithNoWdith;
+ private View mWithNoHeight;
+ private View mWithNoDimension;
+
+ public ZeroSizedTest() {
+ super("com.android.frameworktest", ZeroSized.class);
+ }
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ final ZeroSized activity = getActivity();
+ mWithDimension = activity.findViewById(R.id.dimension);
+ mWithNoWdith = activity.findViewById(R.id.noWidth);
+ mWithNoHeight = activity.findViewById(R.id.noHeight);
+ mWithNoDimension = activity.findViewById(R.id.noDimension);
+ }
+
+ @MediumTest
+ public void testSetUpConditions() throws Exception {
+ assertNotNull(mWithDimension);
+ assertNotNull(mWithNoWdith);
+ assertNotNull(mWithNoHeight);
+ assertNotNull(mWithNoDimension);
+ }
+
+ @MediumTest
+ public void testDrawingCacheWithDimension() throws Exception {
+ assertTrue(mWithDimension.getWidth() > 0);
+ assertTrue(mWithDimension.getHeight() > 0);
+ assertNotNull(createCacheForView(mWithDimension));
+ }
+
+ @MediumTest
+ public void testDrawingCacheWithNoWidth() throws Exception {
+ assertTrue(mWithNoWdith.getWidth() == 0);
+ assertTrue(mWithNoWdith.getHeight() > 0);
+ assertNull(createCacheForView(mWithNoWdith));
+ }
+
+ @MediumTest
+ public void testDrawingCacheWithNoHeight() throws Exception {
+ assertTrue(mWithNoHeight.getWidth() > 0);
+ assertTrue(mWithNoHeight.getHeight() == 0);
+ assertNull(createCacheForView(mWithNoHeight));
+ }
+
+ @MediumTest
+ public void testDrawingCacheWithNoDimension() throws Exception {
+ assertTrue(mWithNoDimension.getWidth() == 0);
+ assertTrue(mWithNoDimension.getHeight() == 0);
+ assertNull(createCacheForView(mWithNoDimension));
+ }
+
+ private Bitmap createCacheForView(final View view) {
+ final Bitmap[] cache = new Bitmap[1];
+ getActivity().runOnUiThread(new Runnable() {
+ public void run() {
+ view.setDrawingCacheEnabled(true);
+ view.invalidate();
+ view.buildDrawingCache();
+ cache[0] = view.getDrawingCache();
+ }
+ });
+ getInstrumentation().waitForIdleSync();
+ return cache[0];
+ }
+}
diff --git a/tests/FrameworkTest/tests/src/com/android/frameworktest/widget/ListViewTest.java b/tests/FrameworkTest/tests/src/com/android/frameworktest/widget/ListViewTest.java
new file mode 100644
index 0000000..ecb7d3a
--- /dev/null
+++ b/tests/FrameworkTest/tests/src/com/android/frameworktest/widget/ListViewTest.java
@@ -0,0 +1,139 @@
+package com.android.frameworktest.widget;
+
+import com.google.android.collect.Lists;
+
+import junit.framework.Assert;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.test.InstrumentationTestCase;
+import android.test.mock.MockContext;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+
+import java.util.List;
+
+/**
+ * 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.
+ */
+
+public class ListViewTest extends InstrumentationTestCase {
+
+ /**
+ * If a view in a ListView requests a layout it should be remeasured.
+ */
+ @MediumTest
+ public void testRequestLayout() throws Exception {
+ MockContext context = new MockContext2();
+ ListView listView = new ListView(context);
+ List<String> items = Lists.newArrayList("hello");
+ Adapter<String> adapter = new Adapter<String>(context, 0, items);
+ listView.setAdapter(adapter);
+
+ int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
+
+ adapter.notifyDataSetChanged();
+ listView.measure(measureSpec, measureSpec);
+ listView.layout(0, 0, 100, 100);
+
+ MockView childView = (MockView) listView.getChildAt(0);
+
+ childView.requestLayout();
+ childView.onMeasureCalled = false;
+ listView.measure(measureSpec, measureSpec);
+ listView.layout(0, 0, 100, 100);
+ Assert.assertTrue(childView.onMeasureCalled);
+ }
+
+ /**
+ * The list view should handle the disappearance of the only selected item, even when that item
+ * was selected before its disappearance.
+ *
+ */
+ @MediumTest
+ public void testNoSelectableItems() throws Exception {
+ MockContext context = new MockContext2();
+ ListView listView = new ListView(context);
+ // We use a header as the unselectable item to remain after the selectable one is removed.
+ listView.addHeaderView(new View(context), null, false);
+ List<String> items = Lists.newArrayList("hello");
+ Adapter<String> adapter = new Adapter<String>(context, 0, items);
+ listView.setAdapter(adapter);
+
+ listView.setSelection(1);
+
+ int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
+
+ adapter.notifyDataSetChanged();
+ listView.measure(measureSpec, measureSpec);
+ listView.layout(0, 0, 100, 100);
+
+ items.remove(0);
+
+ adapter.notifyDataSetChanged();
+ listView.measure(measureSpec, measureSpec);
+ listView.layout(0, 0, 100, 100);
+ }
+
+ private class MockContext2 extends MockContext {
+
+ @Override
+ public Resources getResources() {
+ return getInstrumentation().getTargetContext().getResources();
+ }
+
+ @Override
+ public Resources.Theme getTheme() {
+ return getInstrumentation().getTargetContext().getTheme();
+ }
+
+ @Override
+ public Object getSystemService(String name) {
+ if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) {
+ return getInstrumentation().getTargetContext().getSystemService(name);
+ }
+ return super.getSystemService(name);
+ }
+ }
+
+ private class MockView extends View {
+
+ public boolean onMeasureCalled = false;
+
+ public MockView(Context context) {
+ super(context);
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ onMeasureCalled = true;
+ }
+ }
+
+ private class Adapter<T> extends ArrayAdapter<T> {
+
+ public Adapter(Context context, int resource, List<T> objects) {
+ super(context, resource, objects);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ return new MockView(getContext());
+ }
+ }
+
+}