auto import from //depot/cupcake/@135843
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);
+ }
+}