From 8f4b5a561813ee8c22d2b8e73c33299471d4a3f3 Mon Sep 17 00:00:00 2001
From: Jean-Baptiste Queru Once an application is configured to provide search suggestions, those same suggestions can
+ * easily be made available to the system-wide Quick Search Box, providing faster access to its
+ * content from one central prominent place. See
+ * Exposing Search Suggestions to Quick Search
+ * Box for more details.
+ *
* The primary form of suggestions is known as queried suggestions and is based on query
* text that the user has already typed. This would generally be based on partial matches in
* the available data. In certain situations - for example, when no query text has been typed yet -
@@ -480,6 +488,26 @@ import java.util.List;
* {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}, optional otherwise.
*
*
+ * Once your application is set up to provide search suggestions, making them available to the
+ * globally accessable Quick Search Box is as easy as setting android:includeInGlobalSearch to
+ * "true" in your searchable metadata file. Beyond that, here are some more details of how
+ * suggestions interact with Quick Search Box, and optional ways that you may customize suggestions
+ * for your application.
+ *
+ * Important Note: By default, your application will not be enabled as a suggestion
+ * provider (or "searchable item") in Quick Search Box. Once your app is installed, the user must
+ * enable it as a "searchable item" in the Search settings in order to receive your app's
+ * suggestions in Quick Search Box. You should consider how to message this to users of your app -
+ * perhaps with a note to the user the first time they launch the app about how to enable search
+ * suggestions. This gives your app a chance to be queried for suggestions as the user types into
+ * Quick Search Box, though exactly how or if your suggestions will be surfaced is decided by Quick
+ * Search Box.
+ *
+ * Source Ranking: Once your application's search results are made available to Quick
+ * Search Box, how they surface to the user for a particular query will be determined as appropriate
+ * by Quick Search Box ranking. This may depend on how many other apps have results for that query,
+ * and how often the user has clicked on your results compared to the other apps - but there is no
+ * guarantee about how ranking will occur, or whether your app's suggestions will show at all for
+ * a given query. In general, you can expect that providing quality results will increase the
+ * likelihood that your app's suggestions are provided in a prominent position, and apps that
+ * provide lower quality suggestions will be more likely to be ranked lower and/or not displayed.
+ *
+ * Search Settings: Each app that is available to Quick Search Box has an entry in the
+ * system settings where the user can enable or disable the inclusion of its results. Below the
+ * name of the application, each application may provide a brief description of what kind of
+ * information will be made available via a search settings description string pointed to by the
+ * android:searchSettingsDescription attribute in the searchable metadata. Note that the
+ * user will need to visit this settings menu to enable search suggestions for your app before your
+ * app will have a chance to provide search suggestions to Quick Search Box - see the section
+ * called "Important Note" above.
+ *
+ * Shortcuts: Suggestions that are clicked on by the user may be automatically made into
+ * shortcuts, which are suggestions that have been copied from your provider in order to be quickly
+ * displayed without the need to re-query the original sources. Shortcutted suggestions may be
+ * displayed for the query that yielded the suggestion and for any prefixes of that query. You can
+ * request how to have your app's suggestions made into shortcuts, and whether they should be
+ * refreshed, using the {@link #SUGGEST_COLUMN_SHORTCUT_ID} column:
+ * Elements of search metadata that configure search suggestions being available to Quick Search
+ * Box:
+ * Additional metadata for search action keys. For each action key that you would like to
* define, you'll need to add an additional element defining that key, and using the attributes
* discussed in Action Keys. A simple example is shown here:
@@ -1246,16 +1382,12 @@ public class SearchManager
* result indicates the shortcut refers to a no longer valid sugggestion.
*
* @see #SUGGEST_COLUMN_SHORTCUT_ID
- *
- * @hide pending enabling of global search for third parties
*/
public final static String SUGGEST_URI_PATH_SHORTCUT = "search_suggest_shortcut";
/**
* MIME type for shortcut validation. You'll use this in your suggestions content provider
* in the getType() function.
- *
- * @hide pending enabling of global search for third parties
*/
public final static String SHORTCUT_MIME_TYPE =
"vnd.android.cursor.item/vnd.android.search.suggest";
@@ -1268,7 +1400,7 @@ public class SearchManager
* In addition to the columns below, the suggestion columns are used to pass along the full
* suggestion so it can be shortcutted.
*
- * @hide an implementation detail not part of the public api
+ * @hide
*/
public final static String SEARCH_CLICK_REPORT_AUTHORITY =
"com.android.globalsearch.stats";
@@ -1276,21 +1408,21 @@ public class SearchManager
/**
* The path the write goes to.
*
- * @hide an implementation detail not part of the public api
+ * @hide
*/
public final static String SEARCH_CLICK_REPORT_URI_PATH = "click";
/**
* The column storing the query for the click.
*
- * @hide an implementation detail not part of the public api
+ * @hide
*/
public final static String SEARCH_CLICK_REPORT_COLUMN_QUERY = "query";
/**
* The column storing the component name of the application that was pivoted into.
*
- * @hide an implementation detail not part of the public api
+ * @hide
*/
public final static String SEARCH_CLICK_REPORT_COLUMN_COMPONENT = "component";
@@ -1375,7 +1507,7 @@ public class SearchManager
* {@link #COMPONENT_NAME_KEY}. For use by the global search system only - if other providers
* attempt to use this column, the value will be overwritten by global search.
*
- * @hide an implementation detail not part of the public api
+ * @hide
*/
public final static String SUGGEST_COLUMN_INTENT_COMPONENT_NAME = "suggest_intent_component";
/**
@@ -1400,8 +1532,6 @@ public class SearchManager
* {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut.
* Otherwise, the shortcut id will be used to check back for an up to date suggestion using
* {@link #SUGGEST_URI_PATH_SHORTCUT}.
- *
- * @hide pending reenabling of global search for third parties
*/
public final static String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
@@ -1410,7 +1540,7 @@ public class SearchManager
* cursor item's background color if it needs a non-default background color. A non-zero value
* indicates a valid background color to override the default.
*
- * @hide an implementation detail not part of the public api
+ * @hide For internal use, not part of the public API.
*/
public final static String SUGGEST_COLUMN_BACKGROUND_COLOR = "suggest_background_color";
@@ -1418,8 +1548,6 @@ public class SearchManager
* Column name for suggestions cursor. Optional. This column is used to specify
* that a spinner should be shown in lieu of an icon2 while the shortcut of this suggestion
* is being refreshed.
- *
- * @hide pending reenabling of global search for third parties
*/
public final static String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING =
"suggest_spinner_while_refreshing";
@@ -1427,8 +1555,6 @@ public class SearchManager
/**
* Column value for suggestion column {@link #SUGGEST_COLUMN_SHORTCUT_ID} when a suggestion
* should not be stored as a shortcut in global search.
- *
- * @hide pending reenabling of global search for third parties
*/
public final static String SUGGEST_NEVER_MAKE_SHORTCUT = "_-1";
@@ -1475,8 +1601,6 @@ public class SearchManager
* Intent action for starting a web search provider's settings activity.
* Web search providers should handle this intent if they have provider-specific
* settings to implement.
- *
- * @hide implementation detail only relevent to web search providers
*/
public final static String INTENT_ACTION_WEB_SEARCH_SETTINGS
= "android.search.action.WEB_SEARCH_SETTINGS";
@@ -1491,7 +1615,8 @@ public class SearchManager
/**
* Intent action broadcasted to inform that the search settings have changed in some way.
- * Either searchables have been enabled or disabled.
+ * Either searchables have been enabled or disabled, or a different web search provider
+ * has been chosen.
*/
public final static String INTENT_ACTION_SEARCH_SETTINGS_CHANGED
= "android.search.action.SETTINGS_CHANGED";
@@ -1500,7 +1625,7 @@ public class SearchManager
* If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
* the search dialog will take no action.
*
- * @hide an implentation detail not part of the public api
+ * @hide
*/
public final static String INTENT_ACTION_NONE = "android.search.action.ZILCH";
diff --git a/core/java/android/server/search/Searchables.java b/core/java/android/server/search/Searchables.java
index a2add73dc3b08..c615957367231 100644
--- a/core/java/android/server/search/Searchables.java
+++ b/core/java/android/server/search/Searchables.java
@@ -26,7 +26,6 @@ import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
-import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.util.Log;
@@ -231,16 +230,14 @@ public class Searchables {
: webSearchInfoList.get(ii - search_count);
ActivityInfo ai = info.activityInfo;
// Check first to avoid duplicate entries.
- if (newSearchablesMap.containsKey(new ComponentName(ai.packageName, ai.name))) {
- continue;
- }
- SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai);
- if (searchable != null) {
- newSearchablesList.add(searchable);
- newSearchablesMap.put(searchable.getSearchActivity(), searchable);
- if (searchable.shouldIncludeInGlobalSearch()
- && isWhitelistedForGlobalSearch(pm, searchable.getSearchActivity())) {
- newSearchablesInGlobalSearchList.add(searchable);
+ if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) {
+ SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai);
+ if (searchable != null) {
+ newSearchablesList.add(searchable);
+ newSearchablesMap.put(searchable.getSearchActivity(), searchable);
+ if (searchable.shouldIncludeInGlobalSearch()) {
+ newSearchablesInGlobalSearchList.add(searchable);
+ }
}
}
}
@@ -291,25 +288,6 @@ public class Searchables {
}
}
- /**
- * Determines whether an activity may be included in quick search box. For now this is
- * restricted to system installed apps.
- *
- * TODO: remove when we are ready to enable global search for third party applications.
- *
- * @param pm The package manager.
- * @param searchActivity The component of the search activity.
- * @return True if the search activity may include its search suggestions in quick search box.
- */
- private boolean isWhitelistedForGlobalSearch(PackageManager pm, ComponentName searchActivity) {
- try {
- ActivityInfo ai = pm.getActivityInfo(searchActivity, 0);
- return ((ai.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0);
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-
/**
* Checks if the given activity component is present in the system and if so makes it the
* preferred activity for handling ACTION_WEB_SEARCH.
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 29dc2ea5246e2..a92800d011ee8 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1527,7 +1527,7 @@ public abstract class Layout {
if (bm != null) {
workPaint.set(paint);
Styled.measureText(paint, workPaint, text,
- offset, offset + 1, null);
+ j, j + 2, null);
float wid = (float) bm.getWidth() *
-workPaint.ascent() / bm.getHeight();
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d5f8dcb76bcb5..fd78f83698aa4 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2866,16 +2866,16 @@
when the user clicks a suggestion. Optional attribute. -->
S^7ojO+#8g~Wz8(@3()RgNnvVs
zeP4-ux$(`r@xMc#t~Ez`#E1v?*Gvd04hjC&O%U%2@xrkcyoHOgaY5*7Bh{Ry)1t~<
z#3k(V6EUG~(9s89Ceuamvq@`A@&S_Z#57h|*z?8^Hyr)@E%iX%8N
+ *
+ * {@link #SUGGEST_COLUMN_SHORTCUT_ID}
+ * This column is used to indicate whether a search suggestion should be stored as a
+ * shortcut, and whether it should be validated. Shortcuts are usually formed when the
+ * user clicks a suggestion from Quick Search Box. If missing, the result will be
+ * stored as a shortcut and never refreshed. If set to
+ * {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut.
+ * Otherwise, the shortcut id will be used to check back for for an up to date
+ * suggestion using {@link #SUGGEST_URI_PATH_SHORTCUT}. Read more about shortcut
+ * refreshing in the section about
+ * exposing search suggestions to
+ * Quick Search Box.
+ * No. Only applicable to sources included in Quick Search Box.
+ *
+ *
* {@link #SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING}
+ * This column is used to specify that a spinner should be shown in lieu of an icon2
+ * while the shortcut of this suggestion is being refreshed in Quick Search Box.
+ * No. Only applicable to sources included in Quick Search Box.
+ *
*
- *
+ *
+ * Note that the icon of your app will likely be shown alongside any badge you specify,
+ * to differentiate search in your app from Quick Search Box. The display of this icon
+ * is not under the app's control.
+ *
+ *
* Other Columns
* Finally, if you have defined any Action Keys and you wish
* for them to have suggestion-specific definitions, you'll need to define one
@@ -553,6 +581,68 @@ import java.util.List;
* query text is provided and the SUGGEST_COLUMN_INTENT_DATA values are not suitable for user
* inspection and editing.
*
+ *
+ *
* Exposing Search Suggestions to Quick Search Box
+ *
+ *
+ *
+ * Note that Quick Search Box will ultimately decide whether to shortcut your app's suggestions,
+ * considering these values as a strong request from your application.
+ *
*
* Action Keys
*
@@ -725,7 +815,12 @@ import java.util.List;
* and editing.No
*
*
@@ -869,6 +964,47 @@ import java.util.List;
*
*
*
+ *
+ *
+ *
+ *
+ *
*
+ *
+ *
+ * Attribute Description Required?
+ *
+ * android:includeInGlobalSearch
+ * If true, indicates the search suggestions provided by your application should be
+ * included in the globally accessible Quick Search Box. The attributes below are only
+ * applicable if this is set to true.
+ * Yes
+ *
+ *
+ * android:searchSettingsDescription
+ * If provided, provides a brief description of the search suggestions that are provided
+ * by your application to Quick Search Box, and will be displayed in the search settings
+ * entry for your application.
+ * No
+ *
+ *
+ * android:queryAfterZeroResults
+ * Indicates whether a source should be invoked for supersets of queries it has
+ * returned zero results for in the past. For example, if a source returned zero
+ * results for "bo", it would be ignored for "bob". If set to false, this source
+ * will only be ignored for a single session; the next time the search dialog is
+ * invoked, all sources will be queried. The default value is false.
+ * No
+ *
+ *
+ *
+ * android:searchSuggestThreshold
+ * Indicates the minimum number of characters needed to trigger a source from Quick
+ * Search Box. Only guarantees that a source will not be queried for anything shorter
+ * than the threshold. The default value is 0.
+ * No
+ * false. Optional attribute.. -->
-
*j7L!*lyPFlOiM#;~2^ulbdnW2cL
z{J=gRDFe0_V0fZ*=@sf!o9Voo9f1&
Qa5f<
-<uses-feature android:glEsVersion=["true" | "false"] />
+<uses-feature android:glEsVersion="integer"
+ android:name="string" />
<manifest><uses-sdk>
-element, this element allows an application to specify which potentially variable
-features it requires. In this way, the application
-will not be installed on devices that do not offer the required feature.
For example, an application might specify that it requires a camera with auto-focus capabilities. +If a device does not provide a camera with auto-focus, then it will not allow +installation of the application.
+ +In order to maintain strict device compatibility, it's very important that you use +this element to declare all features that your application uses. Failure to declare +a feature may result your application being installed on a device +that does not support the feature and your application failing.
+ +For some features, there may exist a specfic attribute that allows you to define +a version of the feature, such as the version of Open GL used (declared with +{@code glEsVersion}). Other features that either do or do not +exist for a device, such as camera auto-focus, are declared using the +{@code name} attribute.
+ +Any software or hardware features that may vary among Android-powered +devices will be listed on this page among the attributes below. If you see any features +here that you use in your application, you should include a {@code +<uses-feature>} element for each one. For example, if your application uses the device +camera, then you should include the following in your {@code AndroidManifest.xml}:
+ ++<uses-feature android:name="android.hardware.camera" /> ++ +
If you declare "android.hardware.camera", then your application is considered +compatible with all devices that include a camera, regardless of whether auto-focus is +available or not. If you also use the auto-focus features (available through the {@link +android.hardware.Camera Camera API}), then you need to include an additional +{@code <uses-feature>} element that declares the "android.hardware.camera.autofocus" +feature. Also note that you must still request the {@link android.Manifest.permission#CAMERA +CAMERA permission}. Requesting permission grants your application access to the +appropriate hardware and software, while declaring the features used by +your application ensures proper device compatibility.
+ +Although the {@code <uses-feature>} element is only activated for devices running +API Level 4 or higher, it is safe to include this for applications that declare +a {@code minSdkVersion} +of "3" or lower. Devices running older versions of the platform +will simply ignore this element, but newer devices will recognize it and enforce +installation restrictions based on whether the device supports the feature.
+ +Note: +For each feature required by your application, you must include a new {@code +<uses-feature>} element. Multiple features cannot be declared in one +instance of this element.
-For example, an application might specify that it requires a certain version of Open GL. -If a device does not support that version of Open GL, then it will not allow installation of the application.
@@ -38,6 +84,44 @@ If a device does not support that version of Open GL, then it will not allow ins +| Feature | +Value | +Description | +
|---|---|---|
| Camera | +"{@code android.hardware.camera}" | +The application requires a camera. | +
| "{@code android.hardware.camera.autofocus}" | +The application requires a camera with auto-focus capability. + As a prerequisite, "{@code android.hardware.camera}" must also be declared + with a separate {@code <uses-feature>} element. + | +|
| + Note: Any application that requests the + {@link android.Manifest.permission#CAMERA CAMERA permission} but does not + declare any camera features with the {@code <uses-feature>} element will be assumed + to use all camera features (such as auto-focus). Thus, the application will not + be compatible with devices that do not support all features. Please use + {@code <uses-feature>} to declare only the camera features that your + application needs. + | +||
<uses-sdk android:minSdkVersion="integer" />
+<uses-sdk android:minSdkVersion="integer" + android:maxSdkVersion="integer" + android:targetSdkVersion="integer" />
<manifest>With this attribute set, the application says that is is be able to run on +
With this attribute set, the application says that it is able to run on older versions (down to {@code minSdkVersion}), but was explicitly tested to work with the version specified here. - Specifying this version allows the platform to disable compatibility - code that is not required or enable newer features that are not - available to older applications.
+ Specifying this target version allows the platform to disable compatibility + settings that are not required for the target version (which may otherwise be turned on + in order to maintain forward-compatibility) or enable newer features that are not + available to older applications. This does not mean that you can program different + features for different versions of the platform—it simply informs the platform that you + have tested against the target version and the platform should not perform any extra + work to maintain forward-compatibility with the target version.Introduced in: API Level 4