Merge change 640 into donut

* changes:
  Add GLOBAL_SEARCH intent for finding global search provider.
This commit is contained in:
Android (Google) Code Review
2009-04-29 03:38:01 -07:00
4 changed files with 104 additions and 90 deletions

View File

@ -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.

View File

@ -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;
/**
@ -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);
}
/**

View File

@ -16,6 +16,7 @@
package android.server.search;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.Context;
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
* whenever getSearchableInfo() returns null;
@ -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);
@ -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;
}
}

View File

@ -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;
@ -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;
@ -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.
@ -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
@ -226,7 +244,6 @@ public class SearchablesTest extends AndroidTestCase {
* private String mCacheActivityContext
*/
}
}
/**
* 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 XML meta data.