Loading core/java/android/app/ISearchManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.app; import android.app.SearchableInfo; import android.app.ISearchManagerCallback; import android.content.ComponentName; import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.os.Bundle; Loading @@ -26,6 +27,7 @@ import android.os.Bundle; interface ISearchManager { SearchableInfo getSearchableInfo(in ComponentName launchActivity); List<SearchableInfo> getSearchablesInGlobalSearch(); List<ResolveInfo> getGlobalSearchActivities(); ComponentName getGlobalSearchActivity(); ComponentName getWebSearchActivity(); } core/java/android/app/SearchManager.java +27 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; Loading Loading @@ -373,6 +374,17 @@ public class SearchManager public final static String INTENT_ACTION_SEARCHABLES_CHANGED = "android.search.action.SEARCHABLES_CHANGED"; /** * Intent action to be broadcast to inform that the global search provider * has changed. Normal components will have no need to handle this intent since * they should be using API methods from this class to access the global search * activity * * @hide */ public final static String INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED = "android.search.action.GLOBAL_SEARCH_ACTIVITY_CHANGED"; /** * Intent action broadcasted to inform that the search settings have changed in some way. * Either searchables have been enabled or disabled, or a different web search provider Loading Loading @@ -525,6 +537,21 @@ public class SearchManager } } /** * Returns a list of installed apps that handle the global search * intent. * * @hide */ public List<ResolveInfo> getGlobalSearchActivities() { try { return mService.getGlobalSearchActivities(); } catch (RemoteException ex) { Log.e(TAG, "getGlobalSearchActivities() failed: " + ex); return null; } } /** * Gets the name of the global search activity. * Loading core/java/android/provider/Settings.java +13 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ package android.provider; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.SearchManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; Loading Loading @@ -3489,6 +3490,18 @@ public final class Settings { public static final String SMS_OUTGOING_CHECK_MAX_COUNT = "sms_outgoing_check_max_count"; /** * The global search provider chosen by the user (if multiple global * search providers are installed). This will be the provider returned * by {@link SearchManager#getGlobalSearchActivity()} if it's still * installed. This setting is stored as a flattened component name as * per {@link ComponentName#flattenToString()}. * * @hide */ public static final String SEARCH_GLOBAL_SEARCH_ACTIVITY = "search_global_search_activity"; /** * The number of promoted sources in GlobalSearch. * @hide Loading core/java/android/server/search/SearchManagerService.java +34 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,14 @@ import android.app.SearchManager; import android.app.SearchableInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ResolveInfo; import android.database.ContentObserver; import android.os.Process; import android.provider.Settings; import android.util.Log; import java.util.List; Loading @@ -46,6 +50,8 @@ public class SearchManagerService extends ISearchManager.Stub { // This field is initialized lazily in getSearchables(), and then never modified. private Searchables mSearchables; private ContentObserver mGlobalSearchObserver; /** * Initializes the Search Manager service in the provided system context. * Only one instance of this object should be created! Loading @@ -56,6 +62,8 @@ public class SearchManagerService extends ISearchManager.Stub { mContext = context; mContext.registerReceiver(new BootCompletedReceiver(), new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); mGlobalSearchObserver = new GlobalSearchProviderObserver( mContext.getContentResolver()); } private synchronized Searchables getSearchables() { Loading Loading @@ -100,6 +108,28 @@ public class SearchManagerService extends ISearchManager.Stub { } } class GlobalSearchProviderObserver extends ContentObserver { private final ContentResolver mResolver; public GlobalSearchProviderObserver(ContentResolver resolver) { super(null); mResolver = resolver; mResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY), false /* notifyDescendants */, this); } @Override public void onChange(boolean selfChange) { getSearchables().buildSearchableList(); Intent intent = new Intent(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); mContext.sendBroadcast(intent); } } // // Searchable activities API // Loading @@ -126,6 +156,10 @@ public class SearchManagerService extends ISearchManager.Stub { return getSearchables().getSearchablesInGlobalSearchList(); } public List<ResolveInfo> getGlobalSearchActivities() { return getSearchables().getGlobalSearchActivities(); } /** * Gets the name of the global search activity. */ Loading core/java/android/server/search/Searchables.java +124 −21 Original line number Diff line number Diff line Loading @@ -16,19 +16,23 @@ package android.server.search; import android.Manifest; import android.app.SearchManager; import android.app.SearchableInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; Loading @@ -50,7 +54,10 @@ public class Searchables { private HashMap<ComponentName, SearchableInfo> mSearchablesMap = null; private ArrayList<SearchableInfo> mSearchablesList = null; private ArrayList<SearchableInfo> mSearchablesInGlobalSearchList = null; private ComponentName mGlobalSearchActivity = null; // Contains all installed activities that handle the global search // intent. private List<ResolveInfo> mGlobalSearchActivities; private ComponentName mCurrentGlobalSearchActivity = null; private ComponentName mWebSearchActivity = null; public static String GOOGLE_SEARCH_COMPONENT_NAME = Loading Loading @@ -224,8 +231,11 @@ public class Searchables { } } List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities(); // Find the global search activity ComponentName newGlobalSearchActivity = findGlobalSearchActivity(); ComponentName newGlobalSearchActivity = findGlobalSearchActivity( newGlobalSearchActivities); // Find the web search activity ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity); Loading @@ -235,38 +245,124 @@ public class Searchables { mSearchablesMap = newSearchablesMap; mSearchablesList = newSearchablesList; mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList; mGlobalSearchActivity = newGlobalSearchActivity; mGlobalSearchActivities = newGlobalSearchActivities; mCurrentGlobalSearchActivity = newGlobalSearchActivity; mWebSearchActivity = newWebSearchActivity; } } /** * Returns a sorted list of installed search providers as per * the following heuristics: * * (a) System apps are given priority over non system apps. * (b) Among system apps and non system apps, the relative ordering * is defined by their declared priority. */ private List<ResolveInfo> findGlobalSearchActivities() { // Step 1 : Query the package manager for a list // of activities that can handle the GLOBAL_SEARCH intent. Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); PackageManager pm = mContext.getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); if (activities != null && !activities.isEmpty()) { // Step 2: Rank matching activities according to our heuristics. Collections.sort(activities, GLOBAL_SEARCH_RANKER); } return activities; } /** * Finds the global search activity. * * This is currently implemented by returning the first activity that handles * the GLOBAL_SEARCH intent and has the GLOBAL_SEARCH permission. If we allow * more than one global search activity to be installed, this code must be changed. */ private ComponentName findGlobalSearchActivity() { private ComponentName findGlobalSearchActivity(List<ResolveInfo> installed) { // Fetch the global search provider from the system settings, // and if it's still installed, return it. final String searchProviderSetting = getGlobalSearchProviderSetting(); if (!TextUtils.isEmpty(searchProviderSetting)) { final ComponentName globalSearchComponent = ComponentName.unflattenFromString( searchProviderSetting); if (globalSearchComponent != null && isInstalled(globalSearchComponent)) { return globalSearchComponent; } } return getDefaultGlobalSearchProvider(installed); } /** * Checks whether the global search provider with a given * component name is installed on the system or not. This deals with * cases such as the removal of an installed provider. */ private boolean isInstalled(ComponentName globalSearch) { Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); intent.setComponent(globalSearch); PackageManager pm = mContext.getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); int count = activities == null ? 0 : activities.size(); for (int i = 0; i < count; i++) { ActivityInfo ai = activities.get(i).activityInfo; if (pm.checkPermission(Manifest.permission.GLOBAL_SEARCH, ai.packageName) == PackageManager.PERMISSION_GRANTED) { return new ComponentName(ai.packageName, ai.name); if (activities != null && !activities.isEmpty()) { return true; } return false; } private static final Comparator<ResolveInfo> GLOBAL_SEARCH_RANKER = new Comparator<ResolveInfo>() { @Override public int compare(ResolveInfo lhs, ResolveInfo rhs) { if (lhs == rhs) { return 0; } boolean lhsSystem = isSystemApp(lhs); boolean rhsSystem = isSystemApp(rhs); if (lhsSystem && !rhsSystem) { return -1; } else if (rhsSystem && !lhsSystem) { return 1; } else { Log.w(LOG_TAG, "Package " + ai.packageName + " wants to handle GLOBAL_SEARCH, " + "but does not have the GLOBAL_SEARCH permission."); // Either both system engines, or both non system // engines. // // Note, this isn't a typo. Higher priority numbers imply // higher priority, but are "lower" in the sort order. return rhs.priority - lhs.priority; } } }; /** * @return true iff. the resolve info corresponds to a system application. */ private static final boolean isSystemApp(ResolveInfo res) { return (res.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } /** * Returns the highest ranked search provider as per the * ranking defined in {@link #getGlobalSearchActivities()}. */ private ComponentName getDefaultGlobalSearchProvider(List<ResolveInfo> providerList) { if (providerList != null && !providerList.isEmpty()) { ActivityInfo ai = providerList.get(0).activityInfo; return new ComponentName(ai.packageName, ai.name); } Log.w(LOG_TAG, "No global search activity found"); return null; } private String getGlobalSearchProviderSetting() { return Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY); } /** * Finds the web search activity. * Loading @@ -281,9 +377,9 @@ public class Searchables { PackageManager pm = mContext.getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); int count = activities == null ? 0 : activities.size(); for (int i = 0; i < count; i++) { ActivityInfo ai = activities.get(i).activityInfo; if (activities != null && !activities.isEmpty()) { ActivityInfo ai = activities.get(0).activityInfo; // TODO: do some sanity checks here? return new ComponentName(ai.packageName, ai.name); } Loading @@ -306,11 +402,18 @@ public class Searchables { return new ArrayList<SearchableInfo>(mSearchablesInGlobalSearchList); } /** * Returns a list of activities that handle the global search intent. */ public synchronized ArrayList<ResolveInfo> getGlobalSearchActivities() { return new ArrayList<ResolveInfo>(mGlobalSearchActivities); } /** * Gets the name of the global search activity. */ public synchronized ComponentName getGlobalSearchActivity() { return mGlobalSearchActivity; return mCurrentGlobalSearchActivity; } /** Loading Loading
core/java/android/app/ISearchManager.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package android.app; import android.app.SearchableInfo; import android.app.ISearchManagerCallback; import android.content.ComponentName; import android.content.pm.ResolveInfo; import android.content.res.Configuration; import android.os.Bundle; Loading @@ -26,6 +27,7 @@ import android.os.Bundle; interface ISearchManager { SearchableInfo getSearchableInfo(in ComponentName launchActivity); List<SearchableInfo> getSearchablesInGlobalSearch(); List<ResolveInfo> getGlobalSearchActivities(); ComponentName getGlobalSearchActivity(); ComponentName getWebSearchActivity(); }
core/java/android/app/SearchManager.java +27 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.content.ContentResolver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.ResolveInfo; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; Loading Loading @@ -373,6 +374,17 @@ public class SearchManager public final static String INTENT_ACTION_SEARCHABLES_CHANGED = "android.search.action.SEARCHABLES_CHANGED"; /** * Intent action to be broadcast to inform that the global search provider * has changed. Normal components will have no need to handle this intent since * they should be using API methods from this class to access the global search * activity * * @hide */ public final static String INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED = "android.search.action.GLOBAL_SEARCH_ACTIVITY_CHANGED"; /** * Intent action broadcasted to inform that the search settings have changed in some way. * Either searchables have been enabled or disabled, or a different web search provider Loading Loading @@ -525,6 +537,21 @@ public class SearchManager } } /** * Returns a list of installed apps that handle the global search * intent. * * @hide */ public List<ResolveInfo> getGlobalSearchActivities() { try { return mService.getGlobalSearchActivities(); } catch (RemoteException ex) { Log.e(TAG, "getGlobalSearchActivities() failed: " + ex); return null; } } /** * Gets the name of the global search activity. * Loading
core/java/android/provider/Settings.java +13 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ package android.provider; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.SearchManager; import android.content.ComponentName; import android.content.ContentResolver; import android.content.ContentValues; Loading Loading @@ -3489,6 +3490,18 @@ public final class Settings { public static final String SMS_OUTGOING_CHECK_MAX_COUNT = "sms_outgoing_check_max_count"; /** * The global search provider chosen by the user (if multiple global * search providers are installed). This will be the provider returned * by {@link SearchManager#getGlobalSearchActivity()} if it's still * installed. This setting is stored as a flattened component name as * per {@link ComponentName#flattenToString()}. * * @hide */ public static final String SEARCH_GLOBAL_SEARCH_ACTIVITY = "search_global_search_activity"; /** * The number of promoted sources in GlobalSearch. * @hide Loading
core/java/android/server/search/SearchManagerService.java +34 −0 Original line number Diff line number Diff line Loading @@ -23,10 +23,14 @@ import android.app.SearchManager; import android.app.SearchableInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ResolveInfo; import android.database.ContentObserver; import android.os.Process; import android.provider.Settings; import android.util.Log; import java.util.List; Loading @@ -46,6 +50,8 @@ public class SearchManagerService extends ISearchManager.Stub { // This field is initialized lazily in getSearchables(), and then never modified. private Searchables mSearchables; private ContentObserver mGlobalSearchObserver; /** * Initializes the Search Manager service in the provided system context. * Only one instance of this object should be created! Loading @@ -56,6 +62,8 @@ public class SearchManagerService extends ISearchManager.Stub { mContext = context; mContext.registerReceiver(new BootCompletedReceiver(), new IntentFilter(Intent.ACTION_BOOT_COMPLETED)); mGlobalSearchObserver = new GlobalSearchProviderObserver( mContext.getContentResolver()); } private synchronized Searchables getSearchables() { Loading Loading @@ -100,6 +108,28 @@ public class SearchManagerService extends ISearchManager.Stub { } } class GlobalSearchProviderObserver extends ContentObserver { private final ContentResolver mResolver; public GlobalSearchProviderObserver(ContentResolver resolver) { super(null); mResolver = resolver; mResolver.registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY), false /* notifyDescendants */, this); } @Override public void onChange(boolean selfChange) { getSearchables().buildSearchableList(); Intent intent = new Intent(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); mContext.sendBroadcast(intent); } } // // Searchable activities API // Loading @@ -126,6 +156,10 @@ public class SearchManagerService extends ISearchManager.Stub { return getSearchables().getSearchablesInGlobalSearchList(); } public List<ResolveInfo> getGlobalSearchActivities() { return getSearchables().getGlobalSearchActivities(); } /** * Gets the name of the global search activity. */ Loading
core/java/android/server/search/Searchables.java +124 −21 Original line number Diff line number Diff line Loading @@ -16,19 +16,23 @@ package android.server.search; import android.Manifest; import android.app.SearchManager; import android.app.SearchableInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; Loading @@ -50,7 +54,10 @@ public class Searchables { private HashMap<ComponentName, SearchableInfo> mSearchablesMap = null; private ArrayList<SearchableInfo> mSearchablesList = null; private ArrayList<SearchableInfo> mSearchablesInGlobalSearchList = null; private ComponentName mGlobalSearchActivity = null; // Contains all installed activities that handle the global search // intent. private List<ResolveInfo> mGlobalSearchActivities; private ComponentName mCurrentGlobalSearchActivity = null; private ComponentName mWebSearchActivity = null; public static String GOOGLE_SEARCH_COMPONENT_NAME = Loading Loading @@ -224,8 +231,11 @@ public class Searchables { } } List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities(); // Find the global search activity ComponentName newGlobalSearchActivity = findGlobalSearchActivity(); ComponentName newGlobalSearchActivity = findGlobalSearchActivity( newGlobalSearchActivities); // Find the web search activity ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity); Loading @@ -235,38 +245,124 @@ public class Searchables { mSearchablesMap = newSearchablesMap; mSearchablesList = newSearchablesList; mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList; mGlobalSearchActivity = newGlobalSearchActivity; mGlobalSearchActivities = newGlobalSearchActivities; mCurrentGlobalSearchActivity = newGlobalSearchActivity; mWebSearchActivity = newWebSearchActivity; } } /** * Returns a sorted list of installed search providers as per * the following heuristics: * * (a) System apps are given priority over non system apps. * (b) Among system apps and non system apps, the relative ordering * is defined by their declared priority. */ private List<ResolveInfo> findGlobalSearchActivities() { // Step 1 : Query the package manager for a list // of activities that can handle the GLOBAL_SEARCH intent. Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); PackageManager pm = mContext.getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); if (activities != null && !activities.isEmpty()) { // Step 2: Rank matching activities according to our heuristics. Collections.sort(activities, GLOBAL_SEARCH_RANKER); } return activities; } /** * Finds the global search activity. * * This is currently implemented by returning the first activity that handles * the GLOBAL_SEARCH intent and has the GLOBAL_SEARCH permission. If we allow * more than one global search activity to be installed, this code must be changed. */ private ComponentName findGlobalSearchActivity() { private ComponentName findGlobalSearchActivity(List<ResolveInfo> installed) { // Fetch the global search provider from the system settings, // and if it's still installed, return it. final String searchProviderSetting = getGlobalSearchProviderSetting(); if (!TextUtils.isEmpty(searchProviderSetting)) { final ComponentName globalSearchComponent = ComponentName.unflattenFromString( searchProviderSetting); if (globalSearchComponent != null && isInstalled(globalSearchComponent)) { return globalSearchComponent; } } return getDefaultGlobalSearchProvider(installed); } /** * Checks whether the global search provider with a given * component name is installed on the system or not. This deals with * cases such as the removal of an installed provider. */ private boolean isInstalled(ComponentName globalSearch) { Intent intent = new Intent(SearchManager.INTENT_ACTION_GLOBAL_SEARCH); intent.setComponent(globalSearch); PackageManager pm = mContext.getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); int count = activities == null ? 0 : activities.size(); for (int i = 0; i < count; i++) { ActivityInfo ai = activities.get(i).activityInfo; if (pm.checkPermission(Manifest.permission.GLOBAL_SEARCH, ai.packageName) == PackageManager.PERMISSION_GRANTED) { return new ComponentName(ai.packageName, ai.name); if (activities != null && !activities.isEmpty()) { return true; } return false; } private static final Comparator<ResolveInfo> GLOBAL_SEARCH_RANKER = new Comparator<ResolveInfo>() { @Override public int compare(ResolveInfo lhs, ResolveInfo rhs) { if (lhs == rhs) { return 0; } boolean lhsSystem = isSystemApp(lhs); boolean rhsSystem = isSystemApp(rhs); if (lhsSystem && !rhsSystem) { return -1; } else if (rhsSystem && !lhsSystem) { return 1; } else { Log.w(LOG_TAG, "Package " + ai.packageName + " wants to handle GLOBAL_SEARCH, " + "but does not have the GLOBAL_SEARCH permission."); // Either both system engines, or both non system // engines. // // Note, this isn't a typo. Higher priority numbers imply // higher priority, but are "lower" in the sort order. return rhs.priority - lhs.priority; } } }; /** * @return true iff. the resolve info corresponds to a system application. */ private static final boolean isSystemApp(ResolveInfo res) { return (res.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } /** * Returns the highest ranked search provider as per the * ranking defined in {@link #getGlobalSearchActivities()}. */ private ComponentName getDefaultGlobalSearchProvider(List<ResolveInfo> providerList) { if (providerList != null && !providerList.isEmpty()) { ActivityInfo ai = providerList.get(0).activityInfo; return new ComponentName(ai.packageName, ai.name); } Log.w(LOG_TAG, "No global search activity found"); return null; } private String getGlobalSearchProviderSetting() { return Settings.Secure.getString(mContext.getContentResolver(), Settings.Secure.SEARCH_GLOBAL_SEARCH_ACTIVITY); } /** * Finds the web search activity. * Loading @@ -281,9 +377,9 @@ public class Searchables { PackageManager pm = mContext.getPackageManager(); List<ResolveInfo> activities = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); int count = activities == null ? 0 : activities.size(); for (int i = 0; i < count; i++) { ActivityInfo ai = activities.get(i).activityInfo; if (activities != null && !activities.isEmpty()) { ActivityInfo ai = activities.get(0).activityInfo; // TODO: do some sanity checks here? return new ComponentName(ai.packageName, ai.name); } Loading @@ -306,11 +402,18 @@ public class Searchables { return new ArrayList<SearchableInfo>(mSearchablesInGlobalSearchList); } /** * Returns a list of activities that handle the global search intent. */ public synchronized ArrayList<ResolveInfo> getGlobalSearchActivities() { return new ArrayList<ResolveInfo>(mGlobalSearchActivities); } /** * Gets the name of the global search activity. */ public synchronized ComponentName getGlobalSearchActivity() { return mGlobalSearchActivity; return mCurrentGlobalSearchActivity; } /** Loading