Merge change 736 into donut
* changes:
CheckedTextView is abstract but can be inflated from XML. Let's be consistent and allow it to be used from Java code as well by making it non-abstract.
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 6c3617a..39eb4f1 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -22,4 +22,5 @@
/** @hide */
interface ISearchManager {
SearchableInfo getSearchableInfo(in ComponentName launchActivity, boolean globalSearch);
+ List<SearchableInfo> getSearchablesInGlobalSearch();
}
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index d7ef103..4fb17c7 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -17,6 +17,7 @@
package android.app;
import static android.app.SuggestionsAdapter.getColumnString;
+
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
@@ -25,8 +26,8 @@
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
@@ -44,7 +45,6 @@
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
-import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
@@ -53,14 +53,14 @@
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.AdapterView.OnItemSelectedListener;
import java.util.ArrayList;
import java.util.WeakHashMap;
@@ -602,44 +602,6 @@
mVoiceButton.setVisibility(visibility);
}
- /*
- * Menu.
- */
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Show search settings menu item if anyone handles the intent for it
- Intent settingsIntent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
- PackageManager pm = getContext().getPackageManager();
- ActivityInfo activityInfo = settingsIntent.resolveActivityInfo(pm, 0);
- if (activityInfo != null) {
- settingsIntent.setClassName(activityInfo.applicationInfo.packageName,
- activityInfo.name);
- String label = getActivityLabel(activityInfo);
- menu.add(Menu.NONE, Menu.NONE, Menu.NONE, label)
- .setIcon(android.R.drawable.ic_menu_preferences)
- .setAlphabeticShortcut('P')
- .setIntent(settingsIntent);
- return true;
- }
- return super.onCreateOptionsMenu(menu);
- }
-
- // TODO: shouldn't this be in PackageManager?
- private String getActivityLabel(ActivityInfo activityInfo) {
- PackageManager pm = getContext().getPackageManager();
- try {
- int labelRes = activityInfo.labelRes;
- if (labelRes == 0) {
- return null;
- }
- Resources r = pm.getResourcesForApplication(activityInfo.applicationInfo);
- return r.getString(labelRes);
- } catch (NameNotFoundException ex) {
- return null;
- }
- }
-
/**
* Listeners of various types
*/
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 76d780a..39f3bcd1 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -30,6 +30,8 @@
import android.server.search.SearchableInfo;
import android.view.KeyEvent;
+import java.util.List;
+
/**
* This class provides access to the system search services.
*
@@ -1655,4 +1657,20 @@
return context.getContentResolver().query(uri, null, selection, selArgs, null);
}
+ /**
+ * Returns a list of the searchable activities that can be included in global search.
+ *
+ * @return a list containing searchable information for all searchable activities
+ * that have the <code>exported</code> attribute set in their searchable
+ * meta-data.
+ *
+ * @hide because SearchableInfo is not part of the API.
+ */
+ public static List<SearchableInfo> getSearchablesInGlobalSearch() {
+ try {
+ return sService.getSearchablesInGlobalSearch();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
}
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java
index f180823..03623d6 100644
--- a/core/java/android/server/search/SearchManagerService.java
+++ b/core/java/android/server/search/SearchManagerService.java
@@ -24,6 +24,8 @@
import android.content.IntentFilter;
import android.os.Handler;
+import java.util.List;
+
/**
* This is a simplified version of the Search Manager service. It no longer handles
* presentation (UI). Its function is to maintain the map & list of "searchable"
@@ -143,5 +145,12 @@
return si;
}
+
+ /**
+ * Returns a list of the searchable activities that can be included in global search.
+ */
+ public List<SearchableInfo> getSearchablesInGlobalSearch() {
+ return mSearchables.getSearchablesInGlobalSearchList();
+ }
}
diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java
index a4a7827..aad7ae2 100644
--- a/core/java/android/server/search/SearchableInfo.java
+++ b/core/java/android/server/search/SearchableInfo.java
@@ -66,6 +66,7 @@
private int mSearchButtonText = 0;
private int mSearchInputType = 0;
private int mSearchImeOptions = 0;
+ private boolean mIncludeInGlobalSearch = false;
private String mSuggestAuthority = null;
private String mSuggestPath = null;
private String mSuggestSelection = null;
@@ -236,6 +237,8 @@
InputType.TYPE_TEXT_VARIATION_NORMAL);
mSearchImeOptions = a.getInt(com.android.internal.R.styleable.Searchable_imeOptions,
EditorInfo.IME_ACTION_SEARCH);
+ mIncludeInGlobalSearch = a.getBoolean(
+ com.android.internal.R.styleable.Searchable_includeInGlobalSearch, false);
setSearchModeFlags();
if (DBG_INHIBIT_SUGGESTIONS == 0) {
@@ -576,6 +579,16 @@
}
/**
+ * Checks whether the searchable is exported.
+ *
+ * @return The value of the <code>exported</code> attribute,
+ * or <code>false</code> if the attribute is not set.
+ */
+ public boolean shouldIncludeInGlobalSearch() {
+ return mIncludeInGlobalSearch;
+ }
+
+ /**
* Support for parcelable and aidl operations.
*/
public static final Parcelable.Creator<SearchableInfo> CREATOR
@@ -606,6 +619,7 @@
mSearchButtonText = in.readInt();
mSearchInputType = in.readInt();
mSearchImeOptions = in.readInt();
+ mIncludeInGlobalSearch = in.readInt() != 0;
setSearchModeFlags();
mSuggestAuthority = in.readString();
@@ -644,6 +658,7 @@
dest.writeInt(mSearchButtonText);
dest.writeInt(mSearchInputType);
dest.writeInt(mSearchImeOptions);
+ dest.writeInt(mIncludeInGlobalSearch ? 1 : 0);
dest.writeString(mSuggestAuthority);
dest.writeString(mSuggestPath);
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
index e338bd2..40d7449 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/core/java/android/server/search/Searchables.java
@@ -44,6 +44,7 @@
private HashMap<ComponentName, SearchableInfo> mSearchablesMap = null;
private ArrayList<SearchableInfo> mSearchablesList = null;
+ private ArrayList<SearchableInfo> mSearchablesInGlobalSearchList = null;
private SearchableInfo mDefaultSearchable = null;
/**
@@ -189,6 +190,8 @@
= new HashMap<ComponentName, SearchableInfo>();
ArrayList<SearchableInfo> newSearchablesList
= new ArrayList<SearchableInfo>();
+ ArrayList<SearchableInfo> newSearchablesInGlobalSearchList
+ = new ArrayList<SearchableInfo>();
final PackageManager pm = mContext.getPackageManager();
@@ -208,6 +211,9 @@
if (searchable != null) {
newSearchablesList.add(searchable);
newSearchablesMap.put(searchable.mSearchActivity, searchable);
+ if (searchable.shouldIncludeInGlobalSearch()) {
+ newSearchablesInGlobalSearchList.add(searchable);
+ }
}
}
}
@@ -219,8 +225,9 @@
// Store a consistent set of new values
synchronized (this) {
- mSearchablesList = newSearchablesList;
mSearchablesMap = newSearchablesMap;
+ mSearchablesList = newSearchablesList;
+ mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList;
mDefaultSearchable = newDefaultSearchable;
}
}
@@ -232,4 +239,11 @@
ArrayList<SearchableInfo> result = new ArrayList<SearchableInfo>(mSearchablesList);
return result;
}
+
+ /**
+ * Returns a list of the searchable activities that can be included in global search.
+ */
+ public synchronized ArrayList<SearchableInfo> getSearchablesInGlobalSearchList() {
+ return new ArrayList<SearchableInfo>(mSearchablesInGlobalSearchList);
+ }
}
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 922dd32..8195dcb 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2785,6 +2785,11 @@
search suggestions. The default value is 0. <i>Optional attribute.</i> -->
<attr name="searchSuggestThreshold" format="integer" />
+ <!-- If provided and <code>true</code>, this searchable activity will be
+ included in any global lists of search targets.
+ The default value is <code>false</code>. <i>Optional attribute.</i>. -->
+ <attr name="includeInGlobalSearch" format="boolean" />
+
</declare-styleable>
<!-- In order to process special action keys during search, you must define them using
diff --git a/data/fonts/DroidSans.ttf b/data/fonts/DroidSans.ttf
index 2537cc3..767c63a 100644
--- a/data/fonts/DroidSans.ttf
+++ b/data/fonts/DroidSans.ttf
Binary files differ
diff --git a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
index d2eb7e7..743c979 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/SearchablesTest.java
@@ -140,35 +140,38 @@
* getIcon works
*/
- public void testSearchableMocked() {
+ public void testSearchablesListReal() {
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 searchables = new Searchables(mockContext);
searchables.buildSearchableList();
// tests with "real" searchables (deprecate, this should be a unit test)
- searchablesList = searchables.getSearchablesList();
- count = searchablesList.size();
+ ArrayList<SearchableInfo> searchablesList = searchables.getSearchablesList();
+ int count = searchablesList.size();
assertTrue(count >= 1); // this isn't really a unit test
checkSearchables(searchablesList);
+ ArrayList<SearchableInfo> global = searchables.getSearchablesInGlobalSearchList();
+ checkSearchables(global);
+ }
- // 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
+ /**
+ * This round of tests confirms good operations with "zero" searchables found
+ */
+ public void testSearchablesListEmpty() {
+ MyMockPackageManager mockPM = new MyMockPackageManager(mContext.getPackageManager());
+ MyMockContext mockContext = new MyMockContext(mContext, mockPM);
+
mockPM.setSearchablesMode(MyMockPackageManager.SEARCHABLES_MOCK_ZERO);
- searchables = new Searchables(mockContext);
+ Searchables searchables = new Searchables(mockContext);
searchables.buildSearchableList();
- searchablesList = searchables.getSearchablesList();
- if (searchablesList != null) {
- count = searchablesList.size();
- assertTrue(count == 0);
- }
+ ArrayList<SearchableInfo> searchablesList = searchables.getSearchablesList();
+ assertNotNull(searchablesList);
+ MoreAsserts.assertEmpty(searchablesList);
+ ArrayList<SearchableInfo> global = searchables.getSearchablesInGlobalSearchList();
+ MoreAsserts.assertEmpty(global);
}
/**