diff options
author | Karl Rosaen <> | 2009-04-23 19:00:21 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-04-23 19:00:21 -0700 |
commit | 875d50a4b9294b2be33cff6493cae7acd1d07ea7 (patch) | |
tree | 48cc044c4719e53d214e5fa6c273d1ecd9078356 /tests | |
parent | b08971b876801d9cb878f3f0ca0ebfde7c9bea8e (diff) | |
download | frameworks_base-875d50a4b9294b2be33cff6493cae7acd1d07ea7.zip frameworks_base-875d50a4b9294b2be33cff6493cae7acd1d07ea7.tar.gz frameworks_base-875d50a4b9294b2be33cff6493cae7acd1d07ea7.tar.bz2 |
AI 147564: Merge back from search branch to donut. Notes:
- all public apis and framework changes have been reviewed by relevant folks in our branch (e.g romainguy)
- all new public apis are @hidden; they will still get reviewed by api council once we're in git
- other than that, it's mostly GlobalSearch and search dialog stuff, a new apps provider, and some tweaks
to the contacts provider that was reviewed by jham
Automated import of CL 147564
Diffstat (limited to 'tests')
3 files changed, 465 insertions, 372 deletions
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java index 09e3b02..f3c1542 100644 --- a/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java +++ b/tests/AndroidTests/src/com/android/unit_tests/SearchManagerTest.java @@ -23,27 +23,11 @@ import android.app.ISearchManager; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; -import android.content.Intent; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; -import android.content.res.XmlResourceParser; import android.os.ServiceManager; -import android.server.search.SearchableInfo; -import android.server.search.SearchableInfo.ActionKeyInfo; -import android.test.ActivityInstrumentationTestCase; -import android.test.MoreAsserts; -import android.test.mock.MockContext; -import android.test.mock.MockPackageManager; +import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.MediumTest; import android.util.AndroidRuntimeException; -import android.view.KeyEvent; - -import java.util.ArrayList; -import java.util.List; /** * To launch this test from the command line: @@ -52,7 +36,7 @@ import java.util.List; * -e class com.android.unit_tests.SearchManagerTest \ * com.android.unit_tests/android.test.InstrumentationTestRunner */ -public class SearchManagerTest extends ActivityInstrumentationTestCase<LocalActivity> { +public class SearchManagerTest extends ActivityInstrumentationTestCase2<LocalActivity> { // If non-zero, enable a set of tests that start and stop the search manager. // This is currently disabled because it's causing an unwanted jump from the unit test @@ -71,18 +55,6 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase<LocalActi * testSearchManagerInvocations() * FIX - make it work again * stress test with a very long string - * - * SearchableInfo tests - * Mock the context so I can provide very specific input data - * Confirm OK with "zero" searchables - * Confirm "good" metadata read properly - * Confirm "bad" metadata skipped properly - * Confirm ordering of searchables - * Confirm "good" actionkeys - * confirm "bad" actionkeys are rejected - * confirm XML ordering enforced (will fail today - bug in SearchableInfo) - * findActionKey works - * getIcon works * * SearchManager tests * confirm proper identification of "default" activity based on policy, not hardcoded contacts @@ -195,348 +167,6 @@ public class SearchManagerTest extends ActivityInstrumentationTestCase<LocalActi searchManager.stopSearch(); } } - - /** - * The goal of this test is to confirm proper operation of the - * SearchableInfo helper class. - * - * TODO: The metadata source needs to be mocked out because adding - * searchability metadata via this test is causing it to leak into the - * real system. So for now I'm just going to test for existence of the - * GoogleSearch app (which is searchable). - */ - @LargeTest - public void testSearchableGoogleSearch() { - // test basic array & hashmap - SearchableInfo.buildSearchableList(mContext); - - // test linkage from another activity - // TODO inject this via mocking into the package manager. - // TODO for now, just check for searchable GoogleSearch app (this isn't really a unit test) - ComponentName thisActivity = new ComponentName( - "com.android.googlesearch", - "com.android.googlesearch.GoogleSearch"); - - SearchableInfo si = SearchableInfo.getSearchableInfo(mContext, thisActivity); - assertNotNull(si); - assertTrue(si.mSearchable); - assertEquals(thisActivity, si.mSearchActivity); - - Context appContext = si.getActivityContext(mContext); - assertNotNull(appContext); - MoreAsserts.assertNotEqual(appContext, mContext); - assertEquals("Google Search", appContext.getString(si.getHintId())); - assertEquals("Google", appContext.getString(si.getLabelId())); - } - - /** - * Test that non-searchable activities return no searchable info (this would typically - * trigger the use of the default searchable e.g. contacts) - */ - @LargeTest - public void testNonSearchable() { - // test basic array & hashmap - SearchableInfo.buildSearchableList(mContext); - - // confirm that we return null for non-searchy activities - ComponentName nonActivity = new ComponentName( - "com.android.unit_tests", - "com.android.unit_tests.NO_SEARCH_ACTIVITY"); - SearchableInfo si = SearchableInfo.getSearchableInfo(mContext, nonActivity); - assertNull(si); - } - - /** - * This is an attempt to run the searchable info list with a mocked context. Here are some - * things I'd like to test. - * - * Confirm OK with "zero" searchables - * Confirm "good" metadata read properly - * Confirm "bad" metadata skipped properly - * Confirm ordering of searchables - * Confirm "good" actionkeys - * confirm "bad" actionkeys are rejected - * confirm XML ordering enforced (will fail today - bug in SearchableInfo) - * findActionKey works - * getIcon works - */ - @LargeTest - public void testSearchableMocked() { - MyMockPackageManager mockPM = new MyMockPackageManager(mContext.getPackageManager()); - MyMockContext mockContext = new MyMockContext(mContext, mockPM); - ArrayList<SearchableInfo> searchables; - int count; - - // build item list with real-world source data - mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_PASSTHROUGH); - SearchableInfo.buildSearchableList(mockContext); - // tests with "real" searchables (deprecate, this should be a unit test) - searchables = SearchableInfo.getSearchablesList(); - count = searchables.size(); - assertTrue(count >= 1); // this isn't really a unit test - checkSearchables(searchables); - - // build item list with mocked search data - // this round of tests confirms good operations with "zero" searchables found - // This should return either a null pointer or an empty list - mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_MOCK_ZERO); - SearchableInfo.buildSearchableList(mockContext); - searchables = SearchableInfo.getSearchablesList(); - if (searchables != null) { - count = searchables.size(); - assertTrue(count == 0); - } - } - - /** - * Generic health checker for an array of searchables. - * - * This is designed to pass for any semi-legal searchable, without knowing much about - * the format of the underlying data. It's fairly easy for a non-compliant application - * to provide meta-data that will pass here (e.g. a non-existent suggestions authority). - * - * @param searchables The list of searchables to examine. - */ - private void checkSearchables(ArrayList<SearchableInfo> searchablesList) { - assertNotNull(searchablesList); - int count = searchablesList.size(); - for (int ii = 0; ii < count; ii++) { - SearchableInfo si = searchablesList.get(ii); - assertNotNull(si); - assertTrue(si.mSearchable); - assertTrue(si.getLabelId() != 0); // This must be a useable string - assertNotEmpty(si.mSearchActivity.getClassName()); - assertNotEmpty(si.mSearchActivity.getPackageName()); - if (si.getSuggestAuthority() != null) { - // The suggestion fields are largely optional, so we'll just confirm basic health - assertNotEmpty(si.getSuggestAuthority()); - assertNullOrNotEmpty(si.getSuggestPath()); - assertNullOrNotEmpty(si.getSuggestSelection()); - assertNullOrNotEmpty(si.getSuggestIntentAction()); - assertNullOrNotEmpty(si.getSuggestIntentData()); - } - /* Add a way to get the entire action key list, then explicitly test its elements */ - /* For now, test the most common action key (CALL) */ - ActionKeyInfo ai = si.findActionKey(KeyEvent.KEYCODE_CALL); - if (ai != null) { - assertEquals(ai.mKeyCode, KeyEvent.KEYCODE_CALL); - // one of these three fields must be non-null & non-empty - boolean m1 = (ai.mQueryActionMsg != null) && (ai.mQueryActionMsg.length() > 0); - boolean m2 = (ai.mSuggestActionMsg != null) && (ai.mSuggestActionMsg.length() > 0); - boolean m3 = (ai.mSuggestActionMsgColumn != null) && - (ai.mSuggestActionMsgColumn.length() > 0); - assertTrue(m1 || m2 || m3); - } - - /* - * Find ways to test these: - * - * private int mSearchMode - * private Drawable mIcon - */ - - /* - * Explicitly not tested here: - * - * Can be null, so not much to see: - * public String mSearchHint - * private String mZeroQueryBanner - * - * To be deprecated/removed, so don't bother: - * public boolean mFilterMode - * public boolean mQuickStart - * private boolean mIconResized - * private int mIconResizeWidth - * private int mIconResizeHeight - * - * All of these are "internal" working variables, not part of any contract - * private ActivityInfo mActivityInfo - * private Rect mTempRect - * private String mSuggestProviderPackage - * private String mCacheActivityContext - */ - } - } - - /** - * Combo assert for "string not null and not empty" - */ - private void assertNotEmpty(final String s) { - assertNotNull(s); - MoreAsserts.assertNotEqual(s, ""); - } - - /** - * Combo assert for "string null or (not null and not empty)" - */ - private void assertNullOrNotEmpty(final String s) { - if (s != null) { - MoreAsserts.assertNotEqual(s, ""); - } - } - - /** - * This is a mock for context. Used to perform a true unit test on SearchableInfo. - * - */ - private class MyMockContext extends MockContext { - - protected Context mRealContext; - protected PackageManager mPackageManager; - - /** - * Constructor. - * - * @param realContext Please pass in a real context for some pass-throughs to function. - */ - MyMockContext(Context realContext, PackageManager packageManager) { - mRealContext = realContext; - mPackageManager = packageManager; - } - - /** - * Resources. Pass through for now. - */ - @Override - public Resources getResources() { - return mRealContext.getResources(); - } - - /** - * Package manager. Pass through for now. - */ - @Override - public PackageManager getPackageManager() { - return mPackageManager; - } - - /** - * Package manager. Pass through for now. - */ - @Override - public Context createPackageContext(String packageName, int flags) - throws PackageManager.NameNotFoundException { - return mRealContext.createPackageContext(packageName, flags); - } - } - -/** - * This is a mock for package manager. Used to perform a true unit test on SearchableInfo. - * - */ - private class MyMockPackageManager extends MockPackageManager { - - public final static int SEARCHABLES_PASSTHROUGH = 0; - public final static int SEARCHABLES_MOCK_ZERO = 1; - public final static int SEARCHABLES_MOCK_ONEGOOD = 2; - public final static int SEARCHABLES_MOCK_ONEGOOD_ONEBAD = 3; - - protected PackageManager mRealPackageManager; - protected int mSearchablesMode; - - public MyMockPackageManager(PackageManager realPM) { - mRealPackageManager = realPM; - mSearchablesMode = SEARCHABLES_PASSTHROUGH; - } - - /** - * Set the mode for various tests. - */ - public void setSearchablesMode(int newMode) { - switch (newMode) { - case SEARCHABLES_PASSTHROUGH: - case SEARCHABLES_MOCK_ZERO: - mSearchablesMode = newMode; - break; - - default: - throw new UnsupportedOperationException(); - } - } - - /** - * Find activities that support a given intent. - * - * Retrieve all activities that can be performed for the given intent. - * - * @param intent The desired intent as per resolveActivity(). - * @param flags Additional option flags. The most important is - * MATCH_DEFAULT_ONLY, to limit the resolution to only - * those activities that support the CATEGORY_DEFAULT. - * - * @return A List<ResolveInfo> containing one entry for each matching - * Activity. These are ordered from best to worst match -- that - * is, the first item in the list is what is returned by - * resolveActivity(). If there are no matching activities, an empty - * list is returned. - */ - @Override - public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) { - assertNotNull(intent); - assertEquals(intent.getAction(), Intent.ACTION_SEARCH); - switch (mSearchablesMode) { - case SEARCHABLES_PASSTHROUGH: - return mRealPackageManager.queryIntentActivities(intent, flags); - case SEARCHABLES_MOCK_ZERO: - return null; - default: - throw new UnsupportedOperationException(); - } - } - - /** - * Retrieve an XML file from a package. This is a low-level API used to - * retrieve XML meta data. - * - * @param packageName The name of the package that this xml is coming from. - * Can not be null. - * @param resid The resource identifier of the desired xml. Can not be 0. - * @param appInfo Overall information about <var>packageName</var>. This - * may be null, in which case the application information will be retrieved - * for you if needed; if you already have this information around, it can - * be much more efficient to supply it here. - * - * @return Returns an XmlPullParser allowing you to parse out the XML - * data. Returns null if the xml resource could not be found for any - * reason. - */ - @Override - public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) { - assertNotNull(packageName); - MoreAsserts.assertNotEqual(packageName, ""); - MoreAsserts.assertNotEqual(resid, 0); - switch (mSearchablesMode) { - case SEARCHABLES_PASSTHROUGH: - return mRealPackageManager.getXml(packageName, resid, appInfo); - case SEARCHABLES_MOCK_ZERO: - default: - throw new UnsupportedOperationException(); - } - } - - /** - * Find a single content provider by its base path name. - * - * @param name The name of the provider to find. - * @param flags Additional option flags. Currently should always be 0. - * - * @return ContentProviderInfo Information about the provider, if found, - * else null. - */ - @Override - public ProviderInfo resolveContentProvider(String name, int flags) { - assertNotNull(name); - MoreAsserts.assertNotEqual(name, ""); - assertEquals(flags, 0); - switch (mSearchablesMode) { - case SEARCHABLES_PASSTHROUGH: - return mRealPackageManager.resolveContentProvider(name, flags); - case SEARCHABLES_MOCK_ZERO: - default: - throw new UnsupportedOperationException(); - } - } - } } diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java new file mode 100644 index 0000000..c299b10 --- /dev/null +++ b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java @@ -0,0 +1,411 @@ +/* + * 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.unit_tests; + +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; +import android.content.pm.ResolveInfo; +import android.content.res.Resources; +import android.content.res.XmlResourceParser; +import android.server.search.SearchableInfo; +import android.server.search.Searchables; +import android.server.search.SearchableInfo.ActionKeyInfo; +import android.test.AndroidTestCase; +import android.test.MoreAsserts; +import android.test.mock.MockContext; +import android.test.mock.MockPackageManager; +import android.test.suitebuilder.annotation.SmallTest; +import android.view.KeyEvent; + +import java.util.ArrayList; +import java.util.List; + +/** + * To launch this test from the command line: + * + * adb shell am instrument -w \ + * -e class com.android.unit_tests.SearchablesTest \ + * com.android.unit_tests/android.test.InstrumentationTestRunner + */ +@SmallTest +public class SearchablesTest extends AndroidTestCase { + + /* + * SearchableInfo tests + * Mock the context so I can provide very specific input data + * Confirm OK with "zero" searchables + * Confirm "good" metadata read properly + * Confirm "bad" metadata skipped properly + * Confirm ordering of searchables + * Confirm "good" actionkeys + * confirm "bad" actionkeys are rejected + * confirm XML ordering enforced (will fail today - bug in SearchableInfo) + * findActionKey works + * getIcon works + */ + + /** + * The goal of this test is to confirm proper operation of the + * SearchableInfo helper class. + * + * TODO: The metadata source needs to be mocked out because adding + * searchability metadata via this test is causing it to leak into the + * real system. So for now I'm just going to test for existence of the + * GoogleSearch app (which is searchable). + */ + public void testSearchableGoogleSearch() { + // test basic array & hashmap + Searchables searchables = new Searchables(mContext); + searchables.buildSearchableList(); + + // test linkage from another activity + // TODO inject this via mocking into the package manager. + // TODO for now, just check for searchable GoogleSearch app (this isn't really a unit test) + ComponentName thisActivity = new ComponentName( + "com.android.googlesearch", + "com.android.googlesearch.GoogleSearch"); + + SearchableInfo si = searchables.getSearchableInfo(thisActivity); + assertNotNull(si); + assertTrue(si.mSearchable); + assertEquals(thisActivity, si.mSearchActivity); + + Context appContext = si.getActivityContext(mContext); + assertNotNull(appContext); + MoreAsserts.assertNotEqual(appContext, mContext); + assertEquals("Google Search", appContext.getString(si.getHintId())); + assertEquals("Google", appContext.getString(si.getLabelId())); + } + + /** + * Test that non-searchable activities return no searchable info (this would typically + * trigger the use of the default searchable e.g. contacts) + */ + public void testNonSearchable() { + // test basic array & hashmap + Searchables searchables = new Searchables(mContext); + searchables.buildSearchableList(); + + // confirm that we return null for non-searchy activities + ComponentName nonActivity = new ComponentName( + "com.android.unit_tests", + "com.android.unit_tests.NO_SEARCH_ACTIVITY"); + SearchableInfo si = searchables.getSearchableInfo(nonActivity); + assertNull(si); + } + + /** + * This is an attempt to run the searchable info list with a mocked context. Here are some + * things I'd like to test. + * + * Confirm OK with "zero" searchables + * Confirm "good" metadata read properly + * Confirm "bad" metadata skipped properly + * Confirm ordering of searchables + * Confirm "good" actionkeys + * confirm "bad" actionkeys are rejected + * confirm XML ordering enforced (will fail today - bug in SearchableInfo) + * findActionKey works + * getIcon works + + */ + public void testSearchableMocked() { + MyMockPackageManager mockPM = new MyMockPackageManager(mContext.getPackageManager()); + MyMockContext mockContext = new MyMockContext(mContext, mockPM); + Searchables searchables; + ArrayList<SearchableInfo> searchablesList; + int count; + + + // build item list with real-world source data + mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_PASSTHROUGH); + searchables = new Searchables(mockContext); + searchables.buildSearchableList(); + // tests with "real" searchables (deprecate, this should be a unit test) + searchablesList = searchables.getSearchablesList(); + count = searchablesList.size(); + assertTrue(count >= 1); // this isn't really a unit test + checkSearchables(searchablesList); + + // build item list with mocked search data + // this round of tests confirms good operations with "zero" searchables found + // This should return either a null pointer or an empty list + mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_MOCK_ZERO); + searchables = new Searchables(mockContext); + searchables.buildSearchableList(); + searchablesList = searchables.getSearchablesList(); + if (searchablesList != null) { + count = searchablesList.size(); + assertTrue(count == 0); + } + } + + /** + * Generic health checker for an array of searchables. + * + * This is designed to pass for any semi-legal searchable, without knowing much about + * the format of the underlying data. It's fairly easy for a non-compliant application + * to provide meta-data that will pass here (e.g. a non-existent suggestions authority). + * + * @param searchables The list of searchables to examine. + */ + private void checkSearchables(ArrayList<SearchableInfo> searchablesList) { + assertNotNull(searchablesList); + int count = searchablesList.size(); + for (int ii = 0; ii < count; ii++) { + SearchableInfo si = searchablesList.get(ii); + assertNotNull(si); + assertTrue(si.mSearchable); + assertTrue(si.getLabelId() != 0); // This must be a useable string + assertNotEmpty(si.mSearchActivity.getClassName()); + assertNotEmpty(si.mSearchActivity.getPackageName()); + if (si.getSuggestAuthority() != null) { + // The suggestion fields are largely optional, so we'll just confirm basic health + assertNotEmpty(si.getSuggestAuthority()); + assertNullOrNotEmpty(si.getSuggestPath()); + assertNullOrNotEmpty(si.getSuggestSelection()); + assertNullOrNotEmpty(si.getSuggestIntentAction()); + assertNullOrNotEmpty(si.getSuggestIntentData()); + } + /* Add a way to get the entire action key list, then explicitly test its elements */ + /* For now, test the most common action key (CALL) */ + ActionKeyInfo ai = si.findActionKey(KeyEvent.KEYCODE_CALL); + if (ai != null) { + assertEquals(ai.mKeyCode, KeyEvent.KEYCODE_CALL); + // one of these three fields must be non-null & non-empty + boolean m1 = (ai.mQueryActionMsg != null) && (ai.mQueryActionMsg.length() > 0); + boolean m2 = (ai.mSuggestActionMsg != null) && (ai.mSuggestActionMsg.length() > 0); + boolean m3 = (ai.mSuggestActionMsgColumn != null) && + (ai.mSuggestActionMsgColumn.length() > 0); + assertTrue(m1 || m2 || m3); + } + + /* + * Find ways to test these: + * + * private int mSearchMode + * private Drawable mIcon + */ + + /* + * Explicitly not tested here: + * + * Can be null, so not much to see: + * public String mSearchHint + * private String mZeroQueryBanner + * + * To be deprecated/removed, so don't bother: + * public boolean mFilterMode + * public boolean mQuickStart + * private boolean mIconResized + * private int mIconResizeWidth + * private int mIconResizeHeight + * + * All of these are "internal" working variables, not part of any contract + * private ActivityInfo mActivityInfo + * private Rect mTempRect + * private String mSuggestProviderPackage + * private String mCacheActivityContext + */ + } + } + + /** + * Combo assert for "string not null and not empty" + */ + private void assertNotEmpty(final String s) { + assertNotNull(s); + MoreAsserts.assertNotEqual(s, ""); + } + + /** + * Combo assert for "string null or (not null and not empty)" + */ + private void assertNullOrNotEmpty(final String s) { + if (s != null) { + MoreAsserts.assertNotEqual(s, ""); + } + } + + /** + * This is a mock for context. Used to perform a true unit test on SearchableInfo. + * + */ + private class MyMockContext extends MockContext { + + protected Context mRealContext; + protected PackageManager mPackageManager; + + /** + * Constructor. + * + * @param realContext Please pass in a real context for some pass-throughs to function. + */ + MyMockContext(Context realContext, PackageManager packageManager) { + mRealContext = realContext; + mPackageManager = packageManager; + } + + /** + * Resources. Pass through for now. + */ + @Override + public Resources getResources() { + return mRealContext.getResources(); + } + + /** + * Package manager. Pass through for now. + */ + @Override + public PackageManager getPackageManager() { + return mPackageManager; + } + + /** + * Package manager. Pass through for now. + */ + @Override + public Context createPackageContext(String packageName, int flags) + throws PackageManager.NameNotFoundException { + return mRealContext.createPackageContext(packageName, flags); + } + } + +/** + * This is a mock for package manager. Used to perform a true unit test on SearchableInfo. + * + */ + private class MyMockPackageManager extends MockPackageManager { + + public final static int SEARCHABLES_PASSTHROUGH = 0; + public final static int SEARCHABLES_MOCK_ZERO = 1; + public final static int SEARCHABLES_MOCK_ONEGOOD = 2; + public final static int SEARCHABLES_MOCK_ONEGOOD_ONEBAD = 3; + + protected PackageManager mRealPackageManager; + protected int mSearchablesMode; + + public MyMockPackageManager(PackageManager realPM) { + mRealPackageManager = realPM; + mSearchablesMode = SEARCHABLES_PASSTHROUGH; + } + + /** + * Set the mode for various tests. + */ + public void setSearchablesMode(int newMode) { + switch (newMode) { + case SEARCHABLES_PASSTHROUGH: + case SEARCHABLES_MOCK_ZERO: + mSearchablesMode = newMode; + break; + + default: + throw new UnsupportedOperationException(); + } + } + + /** + * Find activities that support a given intent. + * + * Retrieve all activities that can be performed for the given intent. + * + * @param intent The desired intent as per resolveActivity(). + * @param flags Additional option flags. The most important is + * MATCH_DEFAULT_ONLY, to limit the resolution to only + * those activities that support the CATEGORY_DEFAULT. + * + * @return A List<ResolveInfo> containing one entry for each matching + * Activity. These are ordered from best to worst match -- that + * is, the first item in the list is what is returned by + * resolveActivity(). If there are no matching activities, an empty + * list is returned. + */ + @Override + public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) { + assertNotNull(intent); + assertEquals(intent.getAction(), Intent.ACTION_SEARCH); + switch (mSearchablesMode) { + case SEARCHABLES_PASSTHROUGH: + return mRealPackageManager.queryIntentActivities(intent, flags); + case SEARCHABLES_MOCK_ZERO: + return null; + default: + throw new UnsupportedOperationException(); + } + } + + /** + * Retrieve an XML file from a package. This is a low-level API used to + * retrieve XML meta data. + * + * @param packageName The name of the package that this xml is coming from. + * Can not be null. + * @param resid The resource identifier of the desired xml. Can not be 0. + * @param appInfo Overall information about <var>packageName</var>. This + * may be null, in which case the application information will be retrieved + * for you if needed; if you already have this information around, it can + * be much more efficient to supply it here. + * + * @return Returns an XmlPullParser allowing you to parse out the XML + * data. Returns null if the xml resource could not be found for any + * reason. + */ + @Override + public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) { + assertNotNull(packageName); + MoreAsserts.assertNotEqual(packageName, ""); + MoreAsserts.assertNotEqual(resid, 0); + switch (mSearchablesMode) { + case SEARCHABLES_PASSTHROUGH: + return mRealPackageManager.getXml(packageName, resid, appInfo); + case SEARCHABLES_MOCK_ZERO: + default: + throw new UnsupportedOperationException(); + } + } + + /** + * Find a single content provider by its base path name. + * + * @param name The name of the provider to find. + * @param flags Additional option flags. Currently should always be 0. + * + * @return ContentProviderInfo Information about the provider, if found, + * else null. + */ + @Override + public ProviderInfo resolveContentProvider(String name, int flags) { + assertNotNull(name); + MoreAsserts.assertNotEqual(name, ""); + assertEquals(flags, 0); + switch (mSearchablesMode) { + case SEARCHABLES_PASSTHROUGH: + return mRealPackageManager.resolveContentProvider(name, flags); + case SEARCHABLES_MOCK_ZERO: + default: + throw new UnsupportedOperationException(); + } + } + } +} + diff --git a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java index 663b7a4..6f89fce 100644 --- a/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java +++ b/tests/FrameworkTest/tests/src/android/widget/AutoCompleteTextViewPopup.java @@ -147,4 +147,56 @@ public class AutoCompleteTextViewPopup // now try moving "down" - nothing should happen since there's no longer an adapter sendKeys("DPAD_DOWN"); } + + /** Test the show/hide behavior of the drop-down. */ + @MediumTest + public void testPopupShow() throws Throwable { + AutoCompleteTextViewSimple theActivity = getActivity(); + final AutoCompleteTextView textView = theActivity.getTextView(); + final Instrumentation instrumentation = getInstrumentation(); + + // Drop-down should not be showing when no text has been entered + assertFalse("isPopupShowing() on start", textView.isPopupShowing()); + + // focus and type + textView.requestFocus(); + instrumentation.waitForIdleSync(); + sendKeys("A"); + + // Drop-down should now be visible + assertTrue("isPopupShowing() after typing", textView.isPopupShowing()); + + // Clear the text + runTestOnUiThread(new Runnable() { + public void run() { + textView.setText(""); + } + }); + instrumentation.waitForIdleSync(); + + // Drop-down should be hidden when text is cleared + assertFalse("isPopupShowing() after text cleared", textView.isPopupShowing()); + + // Set the text, without filtering + runTestOnUiThread(new Runnable() { + public void run() { + textView.setText("a", false); + } + }); + instrumentation.waitForIdleSync(); + + // Drop-down should still be hidden + assertFalse("isPopupShowing() after setText(\"a\", false)", textView.isPopupShowing()); + + // Set the text, now with filtering + runTestOnUiThread(new Runnable() { + public void run() { + textView.setText("a"); + } + }); + instrumentation.waitForIdleSync(); + + // Drop-down should show up after setText() with filtering + assertTrue("isPopupShowing() after text set", textView.isPopupShowing()); + } } |