Automated import from //branches/master/...@142670,142670
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 6bee0f0..aff3529 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -225,6 +225,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.widget.cts.StubActivity"
+            android:label="StubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
         <activity android:name="android.widget.cts.ExpandableListWithHeaders"
             android:label="ExpandableListWithHeaders">
             <intent-filter>
@@ -251,6 +259,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name="android.text.method.cts.StubActivity"
+            android:label="StubActivity">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
+            </intent-filter>
+        </activity>
+
     </application>
 
 </manifest>
diff --git a/tests/src/android/widget/cts/StubActivity.java b/tests/src/android/widget/cts/StubActivity.java
new file mode 100644
index 0000000..fe4002c
--- /dev/null
+++ b/tests/src/android/widget/cts/StubActivity.java
@@ -0,0 +1,26 @@
+/*
+ * 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 android.widget.cts;
+
+import android.app.Activity;
+
+/**
+ * Stub activity for helping test. It's an empty activity.
+ */
+public class StubActivity extends Activity {
+
+}
diff --git a/tests/tests/widget/src/android/widget/cts/FilterTest.java b/tests/tests/widget/src/android/widget/cts/FilterTest.java
new file mode 100644
index 0000000..862cb03
--- /dev/null
+++ b/tests/tests/widget/src/android/widget/cts/FilterTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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 android.widget.cts;
+
+import dalvik.annotation.TestLevel;
+import dalvik.annotation.TestTargetClass;
+import dalvik.annotation.TestTargetNew;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.view.animation.cts.DelayedCheck;
+import android.widget.Filter;
+import android.widget.Filter.FilterListener;
+
+@TestTargetClass(Filter.class)
+public class FilterTest extends ActivityInstrumentationTestCase2<StubActivity> {
+    private static final long TIME_OUT = 10000;
+    private static final String TEST_CONSTRAINT = "filter test";
+    private MockFilter mMockFilter;
+
+    public FilterTest() {
+        super("com.android.cts.stub", StubActivity.class);
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "Filter",
+        args = {}
+    )
+    public void testConstructor() {
+        new MockFilter();
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "convertResultToString",
+        args = {java.lang.Object.class}
+    )
+    public void testConvertResultToString() {
+        final MockFilter filter = new MockFilter();
+        assertEquals("", filter.convertResultToString(null));
+
+        final String testStr = "Test";
+        assertEquals(testStr, filter.convertResultToString(testStr));
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "filter",
+        args = {java.lang.CharSequence.class}
+    )
+    public void testFilter1() {
+        getActivity().runOnUiThread(new Runnable() {
+            public void run() {
+                mMockFilter = new MockFilter();
+                mMockFilter.filter(TEST_CONSTRAINT);
+            }
+        });
+
+        new DelayedCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mMockFilter.hadPerformedFiltering();
+            }
+        }.run();
+        assertEquals(TEST_CONSTRAINT, mMockFilter.getPerformFilteringConstraint());
+
+        new DelayedCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mMockFilter.hadPublishedResults();
+            }
+        }.run();
+        assertEquals(TEST_CONSTRAINT, mMockFilter.getPublishResultsConstraint());
+        assertSame(mMockFilter.getExpectResults(), mMockFilter.getResults());
+    }
+
+    @TestTargetNew(
+        level = TestLevel.COMPLETE,
+        method = "filter",
+        args = {java.lang.CharSequence.class, android.widget.Filter.FilterListener.class}
+    )
+    public void testFilter2() {
+        final MockFilterListener mockFilterListener = new MockFilterListener();
+        getActivity().runOnUiThread(new Runnable() {
+            public void run() {
+                mMockFilter = new MockFilter();
+                mMockFilter.filter(TEST_CONSTRAINT, mockFilterListener);
+            }
+        });
+
+        new DelayedCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mMockFilter.hadPerformedFiltering();
+            }
+        }.run();
+        assertEquals(TEST_CONSTRAINT, mMockFilter.getPerformFilteringConstraint());
+
+        new DelayedCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mMockFilter.hadPublishedResults();
+            }
+        }.run();
+        assertEquals(TEST_CONSTRAINT, mMockFilter.getPublishResultsConstraint());
+        assertSame(mMockFilter.getExpectResults(), mMockFilter.getResults());
+
+        new DelayedCheck(TIME_OUT) {
+            @Override
+            protected boolean check() {
+                return mockFilterListener.hasCalledOnFilterComplete();
+            }
+        }.run();
+    }
+
+    private static class MockFilter extends Filter {
+        private boolean mHadPublishedResults = false;
+        private boolean mHadPerformedFiltering = false;
+        private CharSequence mPerformFilteringConstraint;
+        private CharSequence mPublishResultsConstraint;
+        private FilterResults mResults;
+        private FilterResults mExpectResults = new FilterResults();
+
+        public MockFilter() {
+            super();
+        }
+
+        public boolean hadPublishedResults() {
+            return mHadPublishedResults;
+        }
+
+        public boolean hadPerformedFiltering() {
+            return mHadPerformedFiltering;
+        }
+
+        public CharSequence getPerformFilteringConstraint() {
+            return mPerformFilteringConstraint;
+        }
+
+        public CharSequence getPublishResultsConstraint() {
+            return mPublishResultsConstraint;
+        }
+
+        public FilterResults getResults() {
+            return mResults;
+        }
+
+        public FilterResults getExpectResults() {
+            return mExpectResults;
+        }
+
+        @Override
+        protected FilterResults performFiltering(CharSequence constraint) {
+            mHadPerformedFiltering = true;
+            mPerformFilteringConstraint = constraint;
+            return mExpectResults;
+        }
+
+        @Override
+        protected void publishResults(CharSequence constraint, FilterResults results) {
+            mPublishResultsConstraint = constraint;
+            mResults = results;
+            mHadPublishedResults = true;
+        }
+    }
+
+    private static class MockFilterListener implements FilterListener {
+        private boolean mCalledOnFilterComplete = false;
+
+        public void onFilterComplete(int count) {
+            mCalledOnFilterComplete = true;
+        }
+
+        public boolean hasCalledOnFilterComplete() {
+            return mCalledOnFilterComplete;
+        }
+    }
+}