Loading core/java/android/app/SearchManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -1335,6 +1335,15 @@ public class SearchManager public final static String INTENT_ACTION_CURSOR_RESPOND = "android.search.action.CURSOR_RESPOND"; /** * Intent action for finding the global search activity. * The global search provider should handle this intent. * * @hide Pending API council approval. */ public final static String INTENT_ACTION_GLOBAL_SEARCH = "android.search.action.GLOBAL_SEARCH"; /** * Intent action for starting the global search settings activity. * The global search provider should handle this intent. Loading core/java/android/server/search/SearchManagerService.java +0 −18 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Handler; /** Loading Loading @@ -116,23 +115,6 @@ public class SearchManagerService extends ISearchManager.Stub private void updateSearchables() { mSearchables.buildSearchableList(); mSearchablesDirty = false; // TODO SearchableInfo should be the source of truth about whether a searchable exists. // As it stands, if the package exists but is misconfigured in some way, then this // would fail, and needs to be fixed. ComponentName defaultSearch = new ComponentName( "com.android.globalsearch", "com.android.globalsearch.GlobalSearch"); try { mContext.getPackageManager().getActivityInfo(defaultSearch, 0); } catch (NameNotFoundException e) { defaultSearch = new ComponentName( "com.android.googlesearch", "com.android.googlesearch.GoogleSearch"); } mSearchables.setDefaultSearchable(defaultSearch); } /** Loading core/java/android/server/search/Searchables.java +11 −19 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.server.search; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -147,22 +148,6 @@ public class Searchables { } /** * Set the default searchable activity (when none is specified). */ public synchronized void setDefaultSearchable(ComponentName activity) { SearchableInfo si = null; if (activity != null) { si = getSearchableInfo(activity); if (si != null) { // move to front of list mSearchablesList.remove(si); mSearchablesList.add(0, si); } } mDefaultSearchable = si; } /** * Provides the system-default search activity, which you can use * whenever getSearchableInfo() returns null; Loading Loading @@ -199,14 +184,15 @@ public class Searchables { */ public void buildSearchableList() { // create empty hash & list // These will become the new values at the end of the method HashMap<ComponentName, SearchableInfo> newSearchablesMap = new HashMap<ComponentName, SearchableInfo>(); ArrayList<SearchableInfo> newSearchablesList = new ArrayList<SearchableInfo>(); // use intent resolver to generate list of ACTION_SEARCH receivers final PackageManager pm = mContext.getPackageManager(); // use intent resolver to generate list of ACTION_SEARCH receivers List<ResolveInfo> infoList; final Intent intent = new Intent(Intent.ACTION_SEARCH); infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA); Loading @@ -226,10 +212,16 @@ public class Searchables { } } // record the final values as a coherent pair // Find the global search provider Intent globalSearchIntent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); ComponentName globalSearchActivity = globalSearchIntent.resolveActivity(pm); SearchableInfo newDefaultSearchable = newSearchablesMap.get(globalSearchActivity); // Store a consistent set of new values synchronized (this) { mSearchablesList = newSearchablesList; mSearchablesMap = newSearchablesMap; mDefaultSearchable = newDefaultSearchable; } } Loading tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java +84 −53 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.unit_tests; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -25,6 +26,7 @@ import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.RemoteException; import android.server.search.SearchableInfo; import android.server.search.Searchables; import android.server.search.SearchableInfo.ActionKeyInfo; Loading Loading @@ -112,6 +114,17 @@ public class SearchablesTest extends AndroidTestCase { assertNull(si); } /** * Test that there is a default searchable (aka global search provider). */ public void testDefaultSearchable() { Searchables searchables = new Searchables(mContext); searchables.buildSearchableList(); SearchableInfo si = searchables.getDefaultSearchable(); checkSearchable(si); assertTrue(searchables.isDefaultSearchable(si)); } /** * This is an attempt to run the searchable info list with a mocked context. Here are some * things I'd like to test. Loading Loading @@ -172,6 +185,11 @@ public class SearchablesTest extends AndroidTestCase { int count = searchablesList.size(); for (int ii = 0; ii < count; ii++) { SearchableInfo si = searchablesList.get(ii); checkSearchable(si); } } private void checkSearchable(SearchableInfo si) { assertNotNull(si); assertTrue(si.mSearchable); assertTrue(si.getLabelId() != 0); // This must be a useable string Loading Loading @@ -226,7 +244,6 @@ public class SearchablesTest extends AndroidTestCase { * private String mCacheActivityContext */ } } /** * Combo assert for "string not null and not empty" Loading Loading @@ -354,6 +371,20 @@ public class SearchablesTest extends AndroidTestCase { } } @Override public ResolveInfo resolveActivity(Intent intent, int flags) { assertNotNull(intent); assertEquals(intent.getAction(), SearchManager.INTENT_ACTION_GLOBAL_SEARCH); switch (mSearchablesMode) { case SEARCHABLES_PASSTHROUGH: return mRealPackageManager.resolveActivity(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. Loading Loading
core/java/android/app/SearchManager.java +9 −0 Original line number Diff line number Diff line Loading @@ -1335,6 +1335,15 @@ public class SearchManager public final static String INTENT_ACTION_CURSOR_RESPOND = "android.search.action.CURSOR_RESPOND"; /** * Intent action for finding the global search activity. * The global search provider should handle this intent. * * @hide Pending API council approval. */ public final static String INTENT_ACTION_GLOBAL_SEARCH = "android.search.action.GLOBAL_SEARCH"; /** * Intent action for starting the global search settings activity. * The global search provider should handle this intent. Loading
core/java/android/server/search/SearchManagerService.java +0 −18 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.os.Handler; /** Loading Loading @@ -116,23 +115,6 @@ public class SearchManagerService extends ISearchManager.Stub private void updateSearchables() { mSearchables.buildSearchableList(); mSearchablesDirty = false; // TODO SearchableInfo should be the source of truth about whether a searchable exists. // As it stands, if the package exists but is misconfigured in some way, then this // would fail, and needs to be fixed. ComponentName defaultSearch = new ComponentName( "com.android.globalsearch", "com.android.globalsearch.GlobalSearch"); try { mContext.getPackageManager().getActivityInfo(defaultSearch, 0); } catch (NameNotFoundException e) { defaultSearch = new ComponentName( "com.android.googlesearch", "com.android.googlesearch.GoogleSearch"); } mSearchables.setDefaultSearchable(defaultSearch); } /** Loading
core/java/android/server/search/Searchables.java +11 −19 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.server.search; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading Loading @@ -147,22 +148,6 @@ public class Searchables { } /** * Set the default searchable activity (when none is specified). */ public synchronized void setDefaultSearchable(ComponentName activity) { SearchableInfo si = null; if (activity != null) { si = getSearchableInfo(activity); if (si != null) { // move to front of list mSearchablesList.remove(si); mSearchablesList.add(0, si); } } mDefaultSearchable = si; } /** * Provides the system-default search activity, which you can use * whenever getSearchableInfo() returns null; Loading Loading @@ -199,14 +184,15 @@ public class Searchables { */ public void buildSearchableList() { // create empty hash & list // These will become the new values at the end of the method HashMap<ComponentName, SearchableInfo> newSearchablesMap = new HashMap<ComponentName, SearchableInfo>(); ArrayList<SearchableInfo> newSearchablesList = new ArrayList<SearchableInfo>(); // use intent resolver to generate list of ACTION_SEARCH receivers final PackageManager pm = mContext.getPackageManager(); // use intent resolver to generate list of ACTION_SEARCH receivers List<ResolveInfo> infoList; final Intent intent = new Intent(Intent.ACTION_SEARCH); infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA); Loading @@ -226,10 +212,16 @@ public class Searchables { } } // record the final values as a coherent pair // Find the global search provider Intent globalSearchIntent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); ComponentName globalSearchActivity = globalSearchIntent.resolveActivity(pm); SearchableInfo newDefaultSearchable = newSearchablesMap.get(globalSearchActivity); // Store a consistent set of new values synchronized (this) { mSearchablesList = newSearchablesList; mSearchablesMap = newSearchablesMap; mDefaultSearchable = newDefaultSearchable; } } Loading
tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java +84 −53 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.unit_tests; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -25,6 +26,7 @@ import android.content.pm.ProviderInfo; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.content.res.XmlResourceParser; import android.os.RemoteException; import android.server.search.SearchableInfo; import android.server.search.Searchables; import android.server.search.SearchableInfo.ActionKeyInfo; Loading Loading @@ -112,6 +114,17 @@ public class SearchablesTest extends AndroidTestCase { assertNull(si); } /** * Test that there is a default searchable (aka global search provider). */ public void testDefaultSearchable() { Searchables searchables = new Searchables(mContext); searchables.buildSearchableList(); SearchableInfo si = searchables.getDefaultSearchable(); checkSearchable(si); assertTrue(searchables.isDefaultSearchable(si)); } /** * This is an attempt to run the searchable info list with a mocked context. Here are some * things I'd like to test. Loading Loading @@ -172,6 +185,11 @@ public class SearchablesTest extends AndroidTestCase { int count = searchablesList.size(); for (int ii = 0; ii < count; ii++) { SearchableInfo si = searchablesList.get(ii); checkSearchable(si); } } private void checkSearchable(SearchableInfo si) { assertNotNull(si); assertTrue(si.mSearchable); assertTrue(si.getLabelId() != 0); // This must be a useable string Loading Loading @@ -226,7 +244,6 @@ public class SearchablesTest extends AndroidTestCase { * private String mCacheActivityContext */ } } /** * Combo assert for "string not null and not empty" Loading Loading @@ -354,6 +371,20 @@ public class SearchablesTest extends AndroidTestCase { } } @Override public ResolveInfo resolveActivity(Intent intent, int flags) { assertNotNull(intent); assertEquals(intent.getAction(), SearchManager.INTENT_ACTION_GLOBAL_SEARCH); switch (mSearchablesMode) { case SEARCHABLES_PASSTHROUGH: return mRealPackageManager.resolveActivity(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. Loading