diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:45 -0800 |
commit | d83a98f4ce9cfa908f5c54bbd70f03eec07e7553 (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /core/java/android/server/search | |
parent | 076357b8567458d4b6dfdcf839ef751634cd2bfb (diff) | |
download | frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.zip frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.gz frameworks_base-d83a98f4ce9cfa908f5c54bbd70f03eec07e7553.tar.bz2 |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'core/java/android/server/search')
-rw-r--r-- | core/java/android/server/search/SearchManagerService.java | 156 | ||||
-rw-r--r-- | core/java/android/server/search/SearchableInfo.aidl | 19 | ||||
-rw-r--r-- | core/java/android/server/search/SearchableInfo.java | 850 | ||||
-rw-r--r-- | core/java/android/server/search/package.html | 5 |
4 files changed, 0 insertions, 1030 deletions
diff --git a/core/java/android/server/search/SearchManagerService.java b/core/java/android/server/search/SearchManagerService.java deleted file mode 100644 index fe15553..0000000 --- a/core/java/android/server/search/SearchManagerService.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.server.search; - -import android.app.ISearchManager; -import android.content.BroadcastReceiver; -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Handler; -import android.util.Config; - -/** - * 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" - * items, which provides a mapping from individual activities (where a user might have - * invoked search) to specific searchable activities (where the search will be dispatched). - */ -public class SearchManagerService extends ISearchManager.Stub -{ - // general debugging support - private static final String TAG = "SearchManagerService"; - private static final boolean DEBUG = false; - private static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; - - // configuration choices - private static final boolean IMMEDIATE_SEARCHABLES_UPDATE = true; - - // class maintenance and general shared data - private final Context mContext; - private final Handler mHandler; - private boolean mSearchablesDirty; - - /** - * Initialize the Search Manager service in the provided system context. - * Only one instance of this object should be created! - * - * @param context to use for accessing DB, window manager, etc. - */ - public SearchManagerService(Context context) { - mContext = context; - mHandler = new Handler(); - - // Setup the infrastructure for updating and maintaining the list - // of searchable activities. - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_PACKAGE_ADDED); - filter.addAction(Intent.ACTION_PACKAGE_REMOVED); - filter.addAction(Intent.ACTION_PACKAGE_CHANGED); - filter.addDataScheme("package"); - mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); - mSearchablesDirty = true; - - // After startup settles down, preload the searchables list, - // which will reduce the delay when the search UI is invoked. - if (IMMEDIATE_SEARCHABLES_UPDATE) { - mHandler.post(mRunUpdateSearchable); - } - } - - /** - * Listens for intent broadcasts. - * - * The primary purpose here is to refresh the "searchables" list - * if packages are added/removed. - */ - private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - - // First, test for intents that matter at any time - if (action.equals(Intent.ACTION_PACKAGE_ADDED) || - action.equals(Intent.ACTION_PACKAGE_REMOVED) || - action.equals(Intent.ACTION_PACKAGE_CHANGED)) { - mSearchablesDirty = true; - if (IMMEDIATE_SEARCHABLES_UPDATE) { - mHandler.post(mRunUpdateSearchable); - } - return; - } - } - }; - - /** - * This runnable (for the main handler / UI thread) will update the searchables list. - */ - private Runnable mRunUpdateSearchable = new Runnable() { - public void run() { - if (mSearchablesDirty) { - updateSearchables(); - } - } - }; - - /** - * Update the list of searchables, either at startup or in response to - * a package add/remove broadcast message. - */ - private void updateSearchables() { - SearchableInfo.buildSearchableList(mContext); - mSearchablesDirty = false; - - // TODO This is a hack. This shouldn't be hardcoded here, it's probably - // a policy. -// ComponentName defaultSearch = new ComponentName( -// "com.android.contacts", -// "com.android.contacts.ContactsListActivity" ); - ComponentName defaultSearch = new ComponentName( - "com.android.googlesearch", - "com.android.googlesearch.GoogleSearch" ); - SearchableInfo.setDefaultSearchable(mContext, defaultSearch); - } - - /** - * Return the searchableinfo for a given activity - * - * @param launchActivity The activity from which we're launching this search. - * @return Returns a SearchableInfo record describing the parameters of the search, - * or null if no searchable metadata was available. - * @param globalSearch If false, this will only launch the search that has been specifically - * defined by the application (which is usually defined as a local search). If no default - * search is defined in the current application or activity, no search will be launched. - * If true, this will always launch a platform-global (e.g. web-based) search instead. - */ - public SearchableInfo getSearchableInfo(ComponentName launchActivity, boolean globalSearch) { - // final check. however we should try to avoid this, because - // it slows down the entry into the UI. - if (mSearchablesDirty) { - updateSearchables(); - } - SearchableInfo si = null; - if (globalSearch) { - si = SearchableInfo.getDefaultSearchable(); - } else { - si = SearchableInfo.getSearchableInfo(mContext, launchActivity); - } - - return si; - } -} diff --git a/core/java/android/server/search/SearchableInfo.aidl b/core/java/android/server/search/SearchableInfo.aidl deleted file mode 100644 index 9576c2b..0000000 --- a/core/java/android/server/search/SearchableInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.server.search; - -parcelable SearchableInfo; diff --git a/core/java/android/server/search/SearchableInfo.java b/core/java/android/server/search/SearchableInfo.java deleted file mode 100644 index c18675e..0000000 --- a/core/java/android/server/search/SearchableInfo.java +++ /dev/null @@ -1,850 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.server.search; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.PackageManager; -import android.content.pm.ProviderInfo; -import android.content.pm.ResolveInfo; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.os.Bundle; -import android.os.Parcel; -import android.os.Parcelable; -import android.text.InputType; -import android.util.AttributeSet; -import android.util.Log; -import android.util.Xml; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -public final class SearchableInfo implements Parcelable { - - // general debugging support - final static String LOG_TAG = "SearchableInfo"; - - // set this flag to 1 to prevent any apps from providing suggestions - final static int DBG_INHIBIT_SUGGESTIONS = 0; - - // static strings used for XML lookups, etc. - // TODO how should these be documented for the developer, in a more structured way than - // the current long wordy javadoc in SearchManager.java ? - private static final String MD_LABEL_DEFAULT_SEARCHABLE = "android.app.default_searchable"; - private static final String MD_LABEL_SEARCHABLE = "android.app.searchable"; - private static final String MD_SEARCHABLE_SYSTEM_SEARCH = "*"; - private static final String MD_XML_ELEMENT_SEARCHABLE = "searchable"; - private static final String MD_XML_ELEMENT_SEARCHABLE_ACTION_KEY = "actionkey"; - - // class maintenance and general shared data - private static HashMap<ComponentName, SearchableInfo> sSearchablesMap = null; - private static ArrayList<SearchableInfo> sSearchablesList = null; - private static SearchableInfo sDefaultSearchable = null; - - // true member variables - what we know about the searchability - // TO-DO replace public with getters - public boolean mSearchable = false; - private int mLabelId = 0; - public ComponentName mSearchActivity = null; - private int mHintId = 0; - private int mSearchMode = 0; - public boolean mBadgeLabel = false; - public boolean mBadgeIcon = false; - public boolean mQueryRewriteFromData = false; - public boolean mQueryRewriteFromText = false; - private int mIconId = 0; - private int mSearchButtonText = 0; - private int mSearchInputType = 0; - private String mSuggestAuthority = null; - private String mSuggestPath = null; - private String mSuggestSelection = null; - private String mSuggestIntentAction = null; - private String mSuggestIntentData = null; - private ActionKeyInfo mActionKeyList = null; - private String mSuggestProviderPackage = null; - private Context mCacheActivityContext = null; // use during setup only - don't hold memory! - - // Flag values for Searchable_voiceSearchMode - private static int VOICE_SEARCH_SHOW_BUTTON = 1; - private static int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2; - private static int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4; - private int mVoiceSearchMode = 0; - private int mVoiceLanguageModeId; // voiceLanguageModel - private int mVoicePromptTextId; // voicePromptText - private int mVoiceLanguageId; // voiceLanguage - private int mVoiceMaxResults; // voiceMaxResults - - /** - * Set the default searchable activity (when none is specified). - */ - public static void setDefaultSearchable(Context context, - ComponentName activity) { - synchronized (SearchableInfo.class) { - SearchableInfo si = null; - if (activity != null) { - si = getSearchableInfo(context, activity); - if (si != null) { - // move to front of list - sSearchablesList.remove(si); - sSearchablesList.add(0, si); - } - } - sDefaultSearchable = si; - } - } - - /** - * Provides the system-default search activity, which you can use - * whenever getSearchableInfo() returns null; - * - * @return Returns the system-default search activity, null if never defined - */ - public static SearchableInfo getDefaultSearchable() { - synchronized (SearchableInfo.class) { - return sDefaultSearchable; - } - } - - /** - * Retrieve the authority for obtaining search suggestions. - * - * @return Returns a string containing the suggestions authority. - */ - public String getSuggestAuthority() { - return mSuggestAuthority; - } - - /** - * Retrieve the path for obtaining search suggestions. - * - * @return Returns a string containing the suggestions path, or null if not provided. - */ - public String getSuggestPath() { - return mSuggestPath; - } - - /** - * Retrieve the selection pattern for obtaining search suggestions. This must - * include a single ? which will be used for the user-typed characters. - * - * @return Returns a string containing the suggestions authority. - */ - public String getSuggestSelection() { - return mSuggestSelection; - } - - /** - * Retrieve the (optional) intent action for use with these suggestions. This is - * useful if all intents will have the same action (e.g. "android.intent.action.VIEW"). - * - * Can be overriden in any given suggestion via the AUTOSUGGEST_COLUMN_INTENT_ACTION column. - * - * @return Returns a string containing the default intent action. - */ - public String getSuggestIntentAction() { - return mSuggestIntentAction; - } - - /** - * Retrieve the (optional) intent data for use with these suggestions. This is - * useful if all intents will have similar data URIs (e.g. "android.intent.action.VIEW"), - * but you'll likely need to provide a specific ID as well via the column - * AUTOSUGGEST_COLUMN_INTENT_DATA_ID, which will be appended to the intent data URI. - * - * Can be overriden in any given suggestion via the AUTOSUGGEST_COLUMN_INTENT_DATA column. - * - * @return Returns a string containing the default intent data. - */ - public String getSuggestIntentData() { - return mSuggestIntentData; - } - - /** - * Get the context for the searchable activity. - * - * This is fairly expensive so do it on the original scan, or when an app is - * selected, but don't hang on to the result forever. - * - * @param context You need to supply a context to start with - * @return Returns a context related to the searchable activity - */ - public Context getActivityContext(Context context) { - Context theirContext = null; - try { - theirContext = context.createPackageContext(mSearchActivity.getPackageName(), 0); - } catch (PackageManager.NameNotFoundException e) { - // unexpected, but we deal with this by null-checking theirContext - } catch (java.lang.SecurityException e) { - // unexpected, but we deal with this by null-checking theirContext - } - - return theirContext; - } - - /** - * Get the context for the suggestions provider. - * - * This is fairly expensive so do it on the original scan, or when an app is - * selected, but don't hang on to the result forever. - * - * @param context You need to supply a context to start with - * @param activityContext If we can determine that the provider and the activity are the - * same, we'll just return this one. - * @return Returns a context related to the context provider - */ - public Context getProviderContext(Context context, Context activityContext) { - Context theirContext = null; - if (mSearchActivity.getPackageName().equals(mSuggestProviderPackage)) { - return activityContext; - } - if (mSuggestProviderPackage != null) - try { - theirContext = context.createPackageContext(mSuggestProviderPackage, 0); - } catch (PackageManager.NameNotFoundException e) { - // unexpected, but we deal with this by null-checking theirContext - } catch (java.lang.SecurityException e) { - // unexpected, but we deal with this by null-checking theirContext - } - - return theirContext; - } - - /** - * Factory. Look up, or construct, based on the activity. - * - * The activities fall into three cases, based on meta-data found in - * the manifest entry: - * <ol> - * <li>The activity itself implements search. This is indicated by the - * presence of a "android.app.searchable" meta-data attribute. - * The value is a reference to an XML file containing search information.</li> - * <li>A related activity implements search. This is indicated by the - * presence of a "android.app.default_searchable" meta-data attribute. - * The value is a string naming the activity implementing search. In this - * case the factory will "redirect" and return the searchable data.</li> - * <li>No searchability data is provided. We return null here and other - * code will insert the "default" (e.g. contacts) search. - * - * TODO: cache the result in the map, and check the map first. - * TODO: it might make sense to implement the searchable reference as - * an application meta-data entry. This way we don't have to pepper each - * and every activity. - * TODO: can we skip the constructor step if it's a non-searchable? - * TODO: does it make sense to plug the default into a slot here for - * automatic return? Probably not, but it's one way to do it. - * - * @param activity The name of the current activity, or null if the - * activity does not define any explicit searchable metadata. - */ - public static SearchableInfo getSearchableInfo(Context context, - ComponentName activity) { - // Step 1. Is the result already hashed? (case 1) - SearchableInfo result; - synchronized (SearchableInfo.class) { - result = sSearchablesMap.get(activity); - if (result != null) return result; - } - - // Step 2. See if the current activity references a searchable. - // Note: Conceptually, this could be a while(true) loop, but there's - // no point in implementing reference chaining here and risking a loop. - // References must point directly to searchable activities. - - ActivityInfo ai = null; - XmlPullParser xml = null; - try { - ai = context.getPackageManager(). - getActivityInfo(activity, PackageManager.GET_META_DATA ); - String refActivityName = null; - - // First look for activity-specific reference - Bundle md = ai.metaData; - if (md != null) { - refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE); - } - // If not found, try for app-wide reference - if (refActivityName == null) { - md = ai.applicationInfo.metaData; - if (md != null) { - refActivityName = md.getString(MD_LABEL_DEFAULT_SEARCHABLE); - } - } - - // Irrespective of source, if a reference was found, follow it. - if (refActivityName != null) - { - // An app or activity can declare that we should simply launch - // "system default search" if search is invoked. - if (refActivityName.equals(MD_SEARCHABLE_SYSTEM_SEARCH)) { - return getDefaultSearchable(); - } - String pkg = activity.getPackageName(); - ComponentName referredActivity; - if (refActivityName.charAt(0) == '.') { - referredActivity = new ComponentName(pkg, pkg + refActivityName); - } else { - referredActivity = new ComponentName(pkg, refActivityName); - } - - // Now try the referred activity, and if found, cache - // it against the original name so we can skip the check - synchronized (SearchableInfo.class) { - result = sSearchablesMap.get(referredActivity); - if (result != null) { - sSearchablesMap.put(activity, result); - return result; - } - } - } - } catch (PackageManager.NameNotFoundException e) { - // case 3: no metadata - } - - // Step 3. None found. Return null. - return null; - - } - - /** - * Super-factory. Builds an entire list (suitable for display) of - * activities that are searchable, by iterating the entire set of - * ACTION_SEARCH intents. - * - * Also clears the hash of all activities -> searches which will - * refill as the user clicks "search". - * - * This should only be done at startup and again if we know that the - * list has changed. - * - * TODO: every activity that provides a ACTION_SEARCH intent should - * also provide searchability meta-data. There are a bunch of checks here - * that, if data is not found, silently skip to the next activity. This - * won't help a developer trying to figure out why their activity isn't - * showing up in the list, but an exception here is too rough. I would - * like to find a better notification mechanism. - * - * TODO: sort the list somehow? UI choice. - * - * @param context a context we can use during this work - */ - public static void buildSearchableList(Context context) { - - // create empty hash & list - 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 = context.getPackageManager(); - List<ResolveInfo> infoList; - final Intent intent = new Intent(Intent.ACTION_SEARCH); - infoList = pm.queryIntentActivities(intent, PackageManager.GET_META_DATA); - - // analyze each one, generate a Searchables record, and record - if (infoList != null) { - int count = infoList.size(); - for (int ii = 0; ii < count; ii++) { - // for each component, try to find metadata - ResolveInfo info = infoList.get(ii); - ActivityInfo ai = info.activityInfo; - XmlResourceParser xml = ai.loadXmlMetaData(context.getPackageManager(), - MD_LABEL_SEARCHABLE); - if (xml == null) { - continue; - } - ComponentName cName = new ComponentName( - info.activityInfo.packageName, - info.activityInfo.name); - - SearchableInfo searchable = getActivityMetaData(context, xml, cName); - xml.close(); - - if (searchable != null) { - // no need to keep the context any longer. setup time is over. - searchable.mCacheActivityContext = null; - - newSearchablesList.add(searchable); - newSearchablesMap.put(cName, searchable); - } - } - } - - // record the final values as a coherent pair - synchronized (SearchableInfo.class) { - sSearchablesList = newSearchablesList; - sSearchablesMap = newSearchablesMap; - } - } - - /** - * Constructor - * - * Given a ComponentName, get the searchability info - * and build a local copy of it. Use the factory, not this. - * - * @param context runtime context - * @param attr The attribute set we found in the XML file, contains the values that are used to - * construct the object. - * @param cName The component name of the searchable activity - */ - private SearchableInfo(Context context, AttributeSet attr, final ComponentName cName) { - // initialize as an "unsearchable" object - mSearchable = false; - mSearchActivity = cName; - - // to access another activity's resources, I need its context. - // BE SURE to release the cache sometime after construction - it's a large object to hold - mCacheActivityContext = getActivityContext(context); - if (mCacheActivityContext != null) { - TypedArray a = mCacheActivityContext.obtainStyledAttributes(attr, - com.android.internal.R.styleable.Searchable); - mSearchMode = a.getInt(com.android.internal.R.styleable.Searchable_searchMode, 0); - mLabelId = a.getResourceId(com.android.internal.R.styleable.Searchable_label, 0); - mHintId = a.getResourceId(com.android.internal.R.styleable.Searchable_hint, 0); - mIconId = a.getResourceId(com.android.internal.R.styleable.Searchable_icon, 0); - mSearchButtonText = a.getResourceId( - com.android.internal.R.styleable.Searchable_searchButtonText, 0); - mSearchInputType = a.getInt(com.android.internal.R.styleable.Searchable_inputType, - InputType.TYPE_CLASS_TEXT | - InputType.TYPE_TEXT_FLAG_SEARCH | - InputType.TYPE_TEXT_VARIATION_NORMAL); - - setSearchModeFlags(); - if (DBG_INHIBIT_SUGGESTIONS == 0) { - mSuggestAuthority = a.getString( - com.android.internal.R.styleable.Searchable_searchSuggestAuthority); - mSuggestPath = a.getString( - com.android.internal.R.styleable.Searchable_searchSuggestPath); - mSuggestSelection = a.getString( - com.android.internal.R.styleable.Searchable_searchSuggestSelection); - mSuggestIntentAction = a.getString( - com.android.internal.R.styleable.Searchable_searchSuggestIntentAction); - mSuggestIntentData = a.getString( - com.android.internal.R.styleable.Searchable_searchSuggestIntentData); - } - mVoiceSearchMode = - a.getInt(com.android.internal.R.styleable.Searchable_voiceSearchMode, 0); - // TODO this didn't work - came back zero from YouTube - mVoiceLanguageModeId = - a.getResourceId(com.android.internal.R.styleable.Searchable_voiceLanguageModel, 0); - mVoicePromptTextId = - a.getResourceId(com.android.internal.R.styleable.Searchable_voicePromptText, 0); - mVoiceLanguageId = - a.getResourceId(com.android.internal.R.styleable.Searchable_voiceLanguage, 0); - mVoiceMaxResults = - a.getInt(com.android.internal.R.styleable.Searchable_voiceMaxResults, 0); - - a.recycle(); - - // get package info for suggestions provider (if any) - if (mSuggestAuthority != null) { - ProviderInfo pi = - context.getPackageManager().resolveContentProvider(mSuggestAuthority, - 0); - if (pi != null) { - mSuggestProviderPackage = pi.packageName; - } - } - } - - // for now, implement some form of rules - minimal data - if (mLabelId != 0) { - mSearchable = true; - } else { - // Provide some help for developers instead of just silently discarding - Log.w(LOG_TAG, "Insufficient metadata to configure searchability for " + - cName.flattenToShortString()); - } - } - - /** - * Convert searchmode to flags. - */ - private void setSearchModeFlags() { - mBadgeLabel = (0 != (mSearchMode & 4)); - mBadgeIcon = (0 != (mSearchMode & 8)) && (mIconId != 0); - mQueryRewriteFromData = (0 != (mSearchMode & 0x10)); - mQueryRewriteFromText = (0 != (mSearchMode & 0x20)); - } - - /** - * Private class used to hold the "action key" configuration - */ - public class ActionKeyInfo implements Parcelable { - - public int mKeyCode = 0; - public String mQueryActionMsg; - public String mSuggestActionMsg; - public String mSuggestActionMsgColumn; - private ActionKeyInfo mNext; - - /** - * Create one object using attributeset as input data. - * @param context runtime context - * @param attr The attribute set we found in the XML file, contains the values that are used to - * construct the object. - * @param next We'll build these up using a simple linked list (since there are usually - * just zero or one). - */ - public ActionKeyInfo(Context context, AttributeSet attr, ActionKeyInfo next) { - TypedArray a = mCacheActivityContext.obtainStyledAttributes(attr, - com.android.internal.R.styleable.SearchableActionKey); - - mKeyCode = a.getInt( - com.android.internal.R.styleable.SearchableActionKey_keycode, 0); - mQueryActionMsg = a.getString( - com.android.internal.R.styleable.SearchableActionKey_queryActionMsg); - if (DBG_INHIBIT_SUGGESTIONS == 0) { - mSuggestActionMsg = a.getString( - com.android.internal.R.styleable.SearchableActionKey_suggestActionMsg); - mSuggestActionMsgColumn = a.getString( - com.android.internal.R.styleable.SearchableActionKey_suggestActionMsgColumn); - } - a.recycle(); - - // initialize any other fields - mNext = next; - - // sanity check. must have at least one action message, or invalidate the object. - if ((mQueryActionMsg == null) && - (mSuggestActionMsg == null) && - (mSuggestActionMsgColumn == null)) { - mKeyCode = 0; - } - } - - /** - * Instantiate a new ActionKeyInfo from the data in a Parcel that was - * previously written with {@link #writeToParcel(Parcel, int)}. - * - * @param in The Parcel containing the previously written ActionKeyInfo, - * positioned at the location in the buffer where it was written. - * @param next The value to place in mNext, creating a linked list - */ - public ActionKeyInfo(Parcel in, ActionKeyInfo next) { - mKeyCode = in.readInt(); - mQueryActionMsg = in.readString(); - mSuggestActionMsg = in.readString(); - mSuggestActionMsgColumn = in.readString(); - mNext = next; - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mKeyCode); - dest.writeString(mQueryActionMsg); - dest.writeString(mSuggestActionMsg); - dest.writeString(mSuggestActionMsgColumn); - } - } - - /** - * If any action keys were defined for this searchable activity, look up and return. - * - * @param keyCode The key that was pressed - * @return Returns the ActionKeyInfo record, or null if none defined - */ - public ActionKeyInfo findActionKey(int keyCode) { - ActionKeyInfo info = mActionKeyList; - while (info != null) { - if (info.mKeyCode == keyCode) { - return info; - } - info = info.mNext; - } - return null; - } - - /** - * Get the metadata for a given activity - * - * TODO: clean up where we return null vs. where we throw exceptions. - * - * @param context runtime context - * @param xml XML parser for reading attributes - * @param cName The component name of the searchable activity - * - * @result A completely constructed SearchableInfo, or null if insufficient XML data for it - */ - private static SearchableInfo getActivityMetaData(Context context, XmlPullParser xml, - final ComponentName cName) { - SearchableInfo result = null; - - // in order to use the attributes mechanism, we have to walk the parser - // forward through the file until it's reading the tag of interest. - try { - int tagType = xml.next(); - while (tagType != XmlPullParser.END_DOCUMENT) { - if (tagType == XmlPullParser.START_TAG) { - if (xml.getName().equals(MD_XML_ELEMENT_SEARCHABLE)) { - AttributeSet attr = Xml.asAttributeSet(xml); - if (attr != null) { - result = new SearchableInfo(context, attr, cName); - // if the constructor returned a bad object, exit now. - if (! result.mSearchable) { - return null; - } - } - } else if (xml.getName().equals(MD_XML_ELEMENT_SEARCHABLE_ACTION_KEY)) { - if (result == null) { - // Can't process an embedded element if we haven't seen the enclosing - return null; - } - AttributeSet attr = Xml.asAttributeSet(xml); - if (attr != null) { - ActionKeyInfo keyInfo = result.new ActionKeyInfo(context, attr, - result.mActionKeyList); - // only add to list if it is was useable - if (keyInfo.mKeyCode != 0) { - result.mActionKeyList = keyInfo; - } - } - } - } - tagType = xml.next(); - } - } catch (XmlPullParserException e) { - throw new RuntimeException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - return result; - } - - /** - * Return the "label" (user-visible name) of this searchable context. This must be - * accessed using the target (searchable) Activity's resources, not simply the context of the - * caller. - * - * @return Returns the resource Id - */ - public int getLabelId() { - return mLabelId; - } - - /** - * Return the resource Id of the hint text. This must be - * accessed using the target (searchable) Activity's resources, not simply the context of the - * caller. - * - * @return Returns the resource Id, or 0 if not specified by this package. - */ - public int getHintId() { - return mHintId; - } - - /** - * Return the icon Id specified by the Searchable_icon meta-data entry. This must be - * accessed using the target (searchable) Activity's resources, not simply the context of the - * caller. - * - * @return Returns the resource id. - */ - public int getIconId() { - return mIconId; - } - - /** - * @return true if android:voiceSearchMode="showVoiceSearchButton" - */ - public boolean getVoiceSearchEnabled() { - return 0 != (mVoiceSearchMode & VOICE_SEARCH_SHOW_BUTTON); - } - - /** - * @return true if android:voiceSearchMode="launchWebSearch" - */ - public boolean getVoiceSearchLaunchWebSearch() { - return 0 != (mVoiceSearchMode & VOICE_SEARCH_LAUNCH_WEB_SEARCH); - } - - /** - * @return true if android:voiceSearchMode="launchRecognizer" - */ - public boolean getVoiceSearchLaunchRecognizer() { - return 0 != (mVoiceSearchMode & VOICE_SEARCH_LAUNCH_RECOGNIZER); - } - - /** - * @return the resource Id of the language model string, if specified in the searchable - * activity's metadata, or 0 if not specified. - */ - public int getVoiceLanguageModeId() { - return mVoiceLanguageModeId; - } - - /** - * @return the resource Id of the voice prompt text string, if specified in the searchable - * activity's metadata, or 0 if not specified. - */ - public int getVoicePromptTextId() { - return mVoicePromptTextId; - } - - /** - * @return the resource Id of the spoken langauge, if specified in the searchable - * activity's metadata, or 0 if not specified. - */ - public int getVoiceLanguageId() { - return mVoiceLanguageId; - } - - /** - * @return the max results count, if specified in the searchable - * activity's metadata, or 0 if not specified. - */ - public int getVoiceMaxResults() { - return mVoiceMaxResults; - } - - /** - * Return the resource Id of replacement text for the "Search" button. - * - * @return Returns the resource Id, or 0 if not specified by this package. - */ - public int getSearchButtonText() { - return mSearchButtonText; - } - - /** - * Return the input type as specified in the searchable attributes. This will default to - * InputType.TYPE_CLASS_TEXT if not specified (which is appropriate for free text input). - * - * @return the input type - */ - public int getInputType() { - return mSearchInputType; - } - - /** - * Return the list of searchable activities, for use in the drop-down. - */ - public static ArrayList<SearchableInfo> getSearchablesList() { - synchronized (SearchableInfo.class) { - ArrayList<SearchableInfo> result = new ArrayList<SearchableInfo>(sSearchablesList); - return result; - } - } - - /** - * Support for parcelable and aidl operations. - */ - public static final Parcelable.Creator<SearchableInfo> CREATOR - = new Parcelable.Creator<SearchableInfo>() { - public SearchableInfo createFromParcel(Parcel in) { - return new SearchableInfo(in); - } - - public SearchableInfo[] newArray(int size) { - return new SearchableInfo[size]; - } - }; - - /** - * Instantiate a new SearchableInfo from the data in a Parcel that was - * previously written with {@link #writeToParcel(Parcel, int)}. - * - * @param in The Parcel containing the previously written SearchableInfo, - * positioned at the location in the buffer where it was written. - */ - public SearchableInfo(Parcel in) { - mSearchable = in.readInt() != 0; - mLabelId = in.readInt(); - mSearchActivity = ComponentName.readFromParcel(in); - mHintId = in.readInt(); - mSearchMode = in.readInt(); - mIconId = in.readInt(); - mSearchButtonText = in.readInt(); - mSearchInputType = in.readInt(); - setSearchModeFlags(); - - mSuggestAuthority = in.readString(); - mSuggestPath = in.readString(); - mSuggestSelection = in.readString(); - mSuggestIntentAction = in.readString(); - mSuggestIntentData = in.readString(); - - mActionKeyList = null; - int count = in.readInt(); - while (count-- > 0) { - mActionKeyList = new ActionKeyInfo(in, mActionKeyList); - } - - mSuggestProviderPackage = in.readString(); - - mVoiceSearchMode = in.readInt(); - mVoiceLanguageModeId = in.readInt(); - mVoicePromptTextId = in.readInt(); - mVoiceLanguageId = in.readInt(); - mVoiceMaxResults = in.readInt(); - } - - public int describeContents() { - return 0; - } - - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mSearchable ? 1 : 0); - dest.writeInt(mLabelId); - mSearchActivity.writeToParcel(dest, flags); - dest.writeInt(mHintId); - dest.writeInt(mSearchMode); - dest.writeInt(mIconId); - dest.writeInt(mSearchButtonText); - dest.writeInt(mSearchInputType); - - dest.writeString(mSuggestAuthority); - dest.writeString(mSuggestPath); - dest.writeString(mSuggestSelection); - dest.writeString(mSuggestIntentAction); - dest.writeString(mSuggestIntentData); - - // This is usually a very short linked list so we'll just pre-count it - ActionKeyInfo nextKeyInfo = mActionKeyList; - int count = 0; - while (nextKeyInfo != null) { - ++count; - nextKeyInfo = nextKeyInfo.mNext; - } - dest.writeInt(count); - // Now write count of 'em - nextKeyInfo = mActionKeyList; - while (count-- > 0) { - nextKeyInfo.writeToParcel(dest, flags); - } - - dest.writeString(mSuggestProviderPackage); - - dest.writeInt(mVoiceSearchMode); - dest.writeInt(mVoiceLanguageModeId); - dest.writeInt(mVoicePromptTextId); - dest.writeInt(mVoiceLanguageId); - dest.writeInt(mVoiceMaxResults); - } -} diff --git a/core/java/android/server/search/package.html b/core/java/android/server/search/package.html deleted file mode 100644 index c9f96a6..0000000 --- a/core/java/android/server/search/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> - -{@hide} - -</body> |