Merge change 640 into donut
* changes: Add GLOBAL_SEARCH intent for finding global search provider.
This commit is contained in:
@ -1335,6 +1335,15 @@ public class SearchManager
|
|||||||
public final static String INTENT_ACTION_CURSOR_RESPOND
|
public final static String INTENT_ACTION_CURSOR_RESPOND
|
||||||
= "android.search.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.
|
* Intent action for starting the global search settings activity.
|
||||||
* The global search provider should handle this intent.
|
* The global search provider should handle this intent.
|
||||||
|
@ -22,7 +22,6 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,23 +115,6 @@ public class SearchManagerService extends ISearchManager.Stub
|
|||||||
private void updateSearchables() {
|
private void updateSearchables() {
|
||||||
mSearchables.buildSearchableList();
|
mSearchables.buildSearchableList();
|
||||||
mSearchablesDirty = false;
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package android.server.search;
|
package android.server.search;
|
||||||
|
|
||||||
|
import android.app.SearchManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -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
|
* Provides the system-default search activity, which you can use
|
||||||
* whenever getSearchableInfo() returns null;
|
* whenever getSearchableInfo() returns null;
|
||||||
@ -199,14 +184,15 @@ public class Searchables {
|
|||||||
*/
|
*/
|
||||||
public void buildSearchableList() {
|
public void buildSearchableList() {
|
||||||
|
|
||||||
// create empty hash & list
|
// These will become the new values at the end of the method
|
||||||
HashMap<ComponentName, SearchableInfo> newSearchablesMap
|
HashMap<ComponentName, SearchableInfo> newSearchablesMap
|
||||||
= new HashMap<ComponentName, SearchableInfo>();
|
= new HashMap<ComponentName, SearchableInfo>();
|
||||||
ArrayList<SearchableInfo> newSearchablesList
|
ArrayList<SearchableInfo> newSearchablesList
|
||||||
= new ArrayList<SearchableInfo>();
|
= new ArrayList<SearchableInfo>();
|
||||||
|
|
||||||
// use intent resolver to generate list of ACTION_SEARCH receivers
|
|
||||||
final PackageManager pm = mContext.getPackageManager();
|
final PackageManager pm = mContext.getPackageManager();
|
||||||
|
|
||||||
|
// use intent resolver to generate list of ACTION_SEARCH receivers
|
||||||
List<ResolveInfo> infoList;
|
List<ResolveInfo> infoList;
|
||||||
final Intent intent = new Intent(Intent.ACTION_SEARCH);
|
final Intent intent = new Intent(Intent.ACTION_SEARCH);
|
||||||
infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
|
infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA);
|
||||||
@ -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) {
|
synchronized (this) {
|
||||||
mSearchablesList = newSearchablesList;
|
mSearchablesList = newSearchablesList;
|
||||||
mSearchablesMap = newSearchablesMap;
|
mSearchablesMap = newSearchablesMap;
|
||||||
|
mDefaultSearchable = newDefaultSearchable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.unit_tests;
|
package com.android.unit_tests;
|
||||||
|
|
||||||
|
import android.app.SearchManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
@ -25,6 +26,7 @@ import android.content.pm.ProviderInfo;
|
|||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.content.res.XmlResourceParser;
|
import android.content.res.XmlResourceParser;
|
||||||
|
import android.os.RemoteException;
|
||||||
import android.server.search.SearchableInfo;
|
import android.server.search.SearchableInfo;
|
||||||
import android.server.search.Searchables;
|
import android.server.search.Searchables;
|
||||||
import android.server.search.SearchableInfo.ActionKeyInfo;
|
import android.server.search.SearchableInfo.ActionKeyInfo;
|
||||||
@ -112,6 +114,17 @@ public class SearchablesTest extends AndroidTestCase {
|
|||||||
assertNull(si);
|
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
|
* This is an attempt to run the searchable info list with a mocked context. Here are some
|
||||||
* things I'd like to test.
|
* things I'd like to test.
|
||||||
@ -172,6 +185,11 @@ public class SearchablesTest extends AndroidTestCase {
|
|||||||
int count = searchablesList.size();
|
int count = searchablesList.size();
|
||||||
for (int ii = 0; ii < count; ii++) {
|
for (int ii = 0; ii < count; ii++) {
|
||||||
SearchableInfo si = searchablesList.get(ii);
|
SearchableInfo si = searchablesList.get(ii);
|
||||||
|
checkSearchable(si);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkSearchable(SearchableInfo si) {
|
||||||
assertNotNull(si);
|
assertNotNull(si);
|
||||||
assertTrue(si.mSearchable);
|
assertTrue(si.mSearchable);
|
||||||
assertTrue(si.getLabelId() != 0); // This must be a useable string
|
assertTrue(si.getLabelId() != 0); // This must be a useable string
|
||||||
@ -226,7 +244,6 @@ public class SearchablesTest extends AndroidTestCase {
|
|||||||
* private String mCacheActivityContext
|
* private String mCacheActivityContext
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combo assert for "string not null and not empty"
|
* Combo assert for "string not null and not empty"
|
||||||
@ -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 an XML file from a package. This is a low-level API used to
|
||||||
* retrieve XML meta data.
|
* retrieve XML meta data.
|
||||||
|
Reference in New Issue
Block a user