/*
 * 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.app;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import android.annotation.StringRes;
import android.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.text.InputType;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Xml;
import android.view.inputmethod.EditorInfo;

import java.io.IOException;
import java.util.HashMap;

/**
 * Searchability meta-data for an activity. Only applications that search other applications
 * should need to use this class.
 * See <a href="{@docRoot}guide/topics/search/searchable-config.html">Searchable Configuration</a>
 * for more information about declaring searchability meta-data for your application.
 *
 * @see SearchManager#getSearchableInfo(ComponentName)
 * @see SearchManager#getSearchablesInGlobalSearch()
 */
public final class SearchableInfo implements Parcelable {

    // general debugging support
    private static final boolean DBG = false;
    private static final String LOG_TAG = "SearchableInfo";

    // static strings used for XML lookups.
    // 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_SEARCHABLE = "android.app.searchable";
    private static final String MD_XML_ELEMENT_SEARCHABLE = "searchable";
    private static final String MD_XML_ELEMENT_SEARCHABLE_ACTION_KEY = "actionkey";

    // flags in the searchMode attribute
    private static final int SEARCH_MODE_BADGE_LABEL = 0x04;
    private static final int SEARCH_MODE_BADGE_ICON = 0x08;
    private static final int SEARCH_MODE_QUERY_REWRITE_FROM_DATA = 0x10;
    private static final int SEARCH_MODE_QUERY_REWRITE_FROM_TEXT = 0x20;

    // true member variables - what we know about the searchability
    private final int mLabelId;
    private final ComponentName mSearchActivity;
    private final int mHintId;
    private final int mSearchMode;
    private final int mIconId;
    private final int mSearchButtonText;
    private final int mSearchInputType;
    private final int mSearchImeOptions;
    private final boolean mIncludeInGlobalSearch;
    private final boolean mQueryAfterZeroResults;
    private final boolean mAutoUrlDetect;
    private final int mSettingsDescriptionId;
    private final String mSuggestAuthority;
    private final String mSuggestPath;
    private final String mSuggestSelection;
    private final String mSuggestIntentAction;
    private final String mSuggestIntentData;
    private final int mSuggestThreshold;
    // Maps key codes to action key information. auto-boxing is not so bad here,
    // since keycodes for the hard keys are < 127. For such values, Integer.valueOf()
    // uses shared Integer objects.
    // This is not final, to allow lazy initialization.
    private HashMap<Integer,ActionKeyInfo> mActionKeys = null;
    private final String mSuggestProviderPackage;

    // Flag values for Searchable_voiceSearchMode
    private static final int VOICE_SEARCH_SHOW_BUTTON = 1;
    private static final int VOICE_SEARCH_LAUNCH_WEB_SEARCH = 2;
    private static final int VOICE_SEARCH_LAUNCH_RECOGNIZER = 4;
    private final int mVoiceSearchMode;
    private final int mVoiceLanguageModeId;       // voiceLanguageModel
    private final int mVoicePromptTextId;         // voicePromptText
    private final int mVoiceLanguageId;           // voiceLanguage
    private final int mVoiceMaxResults;           // voiceMaxResults

    /**
     * Gets the search suggestion content provider authority.
     *
     * @return The search suggestions authority, or {@code null} if not set.
     * @see android.R.styleable#Searchable_searchSuggestAuthority
     */
    public String getSuggestAuthority() {
        return mSuggestAuthority;
    }

    /**
     * Gets the name of the package where the suggestion provider lives,
     * or {@code null}.
     */
    public String getSuggestPackage() {
        return mSuggestProviderPackage;
    }

    /**
     * Gets the component name of the searchable activity.
     *
     * @return A component name, never {@code null}.
     */
    public ComponentName getSearchActivity() {
        return mSearchActivity;
    }

    /**
     * Checks whether the badge should be a text label.
     *
     * @see android.R.styleable#Searchable_searchMode
     *
     * @hide This feature is deprecated, no need to add it to the API.
     */
    public boolean useBadgeLabel() {
        return 0 != (mSearchMode & SEARCH_MODE_BADGE_LABEL);
    }

    /**
     * Checks whether the badge should be an icon.
     *
     * @see android.R.styleable#Searchable_searchMode
     *
     * @hide This feature is deprecated, no need to add it to the API.
     */
    public boolean useBadgeIcon() {
        return (0 != (mSearchMode & SEARCH_MODE_BADGE_ICON)) && (mIconId != 0);
    }

    /**
     * Checks whether the text in the query field should come from the suggestion intent data.
     *
     * @see android.R.styleable#Searchable_searchMode
     */
    public boolean shouldRewriteQueryFromData() {
        return 0 != (mSearchMode & SEARCH_MODE_QUERY_REWRITE_FROM_DATA);
    }

    /**
     * Checks whether the text in the query field should come from the suggestion title.
     *
     * @see android.R.styleable#Searchable_searchMode
     */
    public boolean shouldRewriteQueryFromText() {
        return 0 != (mSearchMode & SEARCH_MODE_QUERY_REWRITE_FROM_TEXT);
    }

    /**
     * Gets the resource id of the description string to use for this source in system search
     * settings, or {@code 0} if none has been specified.
     *
     * @see android.R.styleable#Searchable_searchSettingsDescription
     */
    public int getSettingsDescriptionId() {
        return mSettingsDescriptionId;
    }

    /**
     * Gets the content provider path for obtaining search suggestions.
     * 
     * @return The suggestion path, or {@code null} if not set.
     * @see android.R.styleable#Searchable_searchSuggestPath
     */
    public String getSuggestPath() {
        return mSuggestPath;
    }

    /**
     * Gets the selection for obtaining search suggestions.
     *
     * @see android.R.styleable#Searchable_searchSuggestSelection
     */
    public String getSuggestSelection() {
        return mSuggestSelection;
    }

    /**
     * Gets the optional intent action for use with these suggestions. This is
     * useful if all intents will have the same action
     * (e.g. {@link android.content.Intent#ACTION_VIEW})
     *
     * This can be overriden in any given suggestion using the column
     * {@link SearchManager#SUGGEST_COLUMN_INTENT_ACTION}.
     *
     * @return The default intent action, or {@code null} if not set.
     * @see android.R.styleable#Searchable_searchSuggestIntentAction
     */
    public String getSuggestIntentAction() {
        return mSuggestIntentAction;
    }

    /**
     * Gets the optional intent data for use with these suggestions.  This is
     * useful if all intents will have similar data URIs,
     * but you'll likely need to provide a specific ID as well via the column
     * {@link SearchManager#SUGGEST_COLUMN_INTENT_DATA_ID}, which will be appended to the
     * intent data URI.
     * 
     * This can be overriden in any given suggestion using the column
     * {@link SearchManager#SUGGEST_COLUMN_INTENT_DATA}.
     * 
     * @return The default intent data, or {@code null} if not set.
     * @see android.R.styleable#Searchable_searchSuggestIntentData
     */
    public String getSuggestIntentData() {
        return mSuggestIntentData;
    }

    /**
     * Gets the suggestion threshold.
     * 
     * @return The suggestion threshold, or {@code 0} if not set.
     * @see android.R.styleable#Searchable_searchSuggestThreshold
     */
    public int getSuggestThreshold() {
        return mSuggestThreshold;
    }

    /**
     * Get the context for the searchable activity.
     *
     * @param context You need to supply a context to start with
     * @return Returns a context related to the searchable activity
     * @hide
     */
    @UnsupportedAppUsage
    public Context getActivityContext(Context context) {
        return createActivityContext(context, mSearchActivity);
    }

    /**
     * Creates a context for another activity.
     */
    private static Context createActivityContext(Context context, ComponentName activity) {
        Context theirContext = null;
        try {
            theirContext = context.createPackageContext(activity.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(LOG_TAG, "Package not found " + activity.getPackageName());
        } catch (java.lang.SecurityException e) {
            Log.e(LOG_TAG, "Can't make context for " + activity.getPackageName(), e);
        }
        
        return theirContext;
    }

    /**
     * Get the context for the suggestions provider.
     *
     * @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 suggestion provider
     * @hide
     */
    @UnsupportedAppUsage
    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;
    }

    /**
     * Constructor
     * 
     * Given a ComponentName, get the searchability info
     * and build a local copy of it.  Use the factory, not this.
     * 
     * @param activityContext runtime context for the activity that the searchable info is about.
     * @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
     * @throws IllegalArgumentException if the searchability info is invalid or insufficient
     */
    @UnsupportedAppUsage
    private SearchableInfo(Context activityContext, AttributeSet attr, final ComponentName cName) {
        mSearchActivity = cName;
        
        TypedArray a = activityContext.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_VARIATION_NORMAL);
        mSearchImeOptions = a.getInt(com.android.internal.R.styleable.Searchable_imeOptions, 
                EditorInfo.IME_ACTION_GO);
        mIncludeInGlobalSearch = a.getBoolean(
                com.android.internal.R.styleable.Searchable_includeInGlobalSearch, false);
        mQueryAfterZeroResults = a.getBoolean(
                com.android.internal.R.styleable.Searchable_queryAfterZeroResults, false);
        mAutoUrlDetect = a.getBoolean(
                com.android.internal.R.styleable.Searchable_autoUrlDetect, false);

        mSettingsDescriptionId = a.getResourceId(
                com.android.internal.R.styleable.Searchable_searchSettingsDescription, 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);
        mSuggestThreshold = a.getInt(
                com.android.internal.R.styleable.Searchable_searchSuggestThreshold, 0);

        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)
        String suggestProviderPackage = null;
        if (mSuggestAuthority != null) {
            PackageManager pm = activityContext.getPackageManager();
            ProviderInfo pi = pm.resolveContentProvider(mSuggestAuthority,
                    PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
            if (pi != null) {
                suggestProviderPackage = pi.packageName;
            }
        }
        mSuggestProviderPackage = suggestProviderPackage;

        // for now, implement some form of rules - minimal data
        if (mLabelId == 0) {
            throw new IllegalArgumentException("Search label must be a resource reference.");
        }
    }

    /**
     * Information about an action key in searchability meta-data.
     *
     * @see SearchableInfo#findActionKey(int)
     *
     * @hide This feature is used very little, and on many devices there are no reasonable
     *       keys to use for actions.
     */
    public static class ActionKeyInfo implements Parcelable {

        private final int mKeyCode;
        private final String mQueryActionMsg;
        private final String mSuggestActionMsg;
        private final String mSuggestActionMsgColumn;

        /**
         * Create one object using attributeset as input data.
         * @param activityContext runtime context of the activity that the action key information
         *        is about.
         * @param attr The attribute set we found in the XML file, contains the values that are used to
         * construct the object.
         * @throws IllegalArgumentException if the action key configuration is invalid
         */
        ActionKeyInfo(Context activityContext, AttributeSet attr) {
            TypedArray a = activityContext.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);
            mSuggestActionMsg = a.getString(
                    com.android.internal.R.styleable.SearchableActionKey_suggestActionMsg);
            mSuggestActionMsgColumn = a.getString(
                    com.android.internal.R.styleable.SearchableActionKey_suggestActionMsgColumn);
            a.recycle();

            // sanity check.
            if (mKeyCode == 0) {
                throw new IllegalArgumentException("No keycode.");
            } else if ((mQueryActionMsg == null) && 
                    (mSuggestActionMsg == null) && 
                    (mSuggestActionMsgColumn == null)) {
                throw new IllegalArgumentException("No message information.");
            }
        }

        /**
         * 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.
         */
        private ActionKeyInfo(Parcel in) {
            mKeyCode = in.readInt();
            mQueryActionMsg = in.readString();
            mSuggestActionMsg = in.readString();
            mSuggestActionMsgColumn = in.readString();
        }

        /**
         * Gets the key code that this action key info is for.
         * @see android.R.styleable#SearchableActionKey_keycode
         */
        public int getKeyCode() {
            return mKeyCode;
        }

        /**
         * Gets the action message to use for queries.
         * @see android.R.styleable#SearchableActionKey_queryActionMsg
         */
        @UnsupportedAppUsage
        public String getQueryActionMsg() {
            return mQueryActionMsg;
        }

        /**
         * Gets the action message to use for suggestions.
         * @see android.R.styleable#SearchableActionKey_suggestActionMsg
         */
        @UnsupportedAppUsage
        public String getSuggestActionMsg() {
            return mSuggestActionMsg;
        }

        /**
         * Gets the name of the column to get the suggestion action message from.
         * @see android.R.styleable#SearchableActionKey_suggestActionMsgColumn
         */
        @UnsupportedAppUsage
        public String getSuggestActionMsgColumn() {
            return mSuggestActionMsgColumn;
        }

        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 action key info, or {@code null} if none defined.
     *
     * @hide ActionKeyInfo is hidden
     */
    @UnsupportedAppUsage
    public ActionKeyInfo findActionKey(int keyCode) {
        if (mActionKeys == null) {
            return null;
        }
        return mActionKeys.get(keyCode);
    }

    private void addActionKey(ActionKeyInfo keyInfo) {
        if (mActionKeys == null) {
            mActionKeys = new HashMap<Integer,ActionKeyInfo>();
        }
        mActionKeys.put(keyInfo.getKeyCode(), keyInfo);
    }

    /**
     * Gets search information for the given activity.
     *
     * @param context Context to use for reading activity resources.
     * @param activityInfo Activity to get search information from.
     * @return Search information about the given activity, or {@code null} if
     *         the activity has no or invalid searchability meta-data.
     *
     * @hide For use by SearchManagerService.
     */
    public static SearchableInfo getActivityMetaData(Context context, ActivityInfo activityInfo,
            int userId) {
        Context userContext = null;
        try {
            userContext = context.createPackageContextAsUser("system", 0,
                new UserHandle(userId));
        } catch (NameNotFoundException nnfe) {
            Log.e(LOG_TAG, "Couldn't create package context for user " + userId);
            return null;
        }
        // for each component, try to find metadata
        XmlResourceParser xml = 
                activityInfo.loadXmlMetaData(userContext.getPackageManager(), MD_LABEL_SEARCHABLE);
        if (xml == null) {
            return null;
        }
        ComponentName cName = new ComponentName(activityInfo.packageName, activityInfo.name);
        
        SearchableInfo searchable = getActivityMetaData(userContext, xml, cName);
        xml.close();
        
        if (DBG) {
            if (searchable != null) {
                Log.d(LOG_TAG, "Checked " + activityInfo.name
                        + ",label=" + searchable.getLabelId()
                        + ",icon=" + searchable.getIconId()
                        + ",suggestAuthority=" + searchable.getSuggestAuthority()
                        + ",target=" + searchable.getSearchActivity().getClassName()
                        + ",global=" + searchable.shouldIncludeInGlobalSearch()
                        + ",settingsDescription=" + searchable.getSettingsDescriptionId()
                        + ",threshold=" + searchable.getSuggestThreshold());
            } else {
                Log.d(LOG_TAG, "Checked " + activityInfo.name + ", no searchable meta-data");
            }
        }
        return searchable;
    }

    /**
     * Get the metadata for a given activity
     * 
     * @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;
        Context activityContext = createActivityContext(context, cName);
        if (activityContext == null) return 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) {
                            try {
                                result = new SearchableInfo(activityContext, attr, cName);
                            } catch (IllegalArgumentException ex) {
                                Log.w(LOG_TAG, "Invalid searchable metadata for " +
                                        cName.flattenToShortString() + ": " + ex.getMessage());
                                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) {
                            try {
                                result.addActionKey(new ActionKeyInfo(activityContext, attr));
                            } catch (IllegalArgumentException ex) {
                                Log.w(LOG_TAG, "Invalid action key for " +
                                        cName.flattenToShortString() + ": " + ex.getMessage());
                                return null;
                            }
                        }
                    }
                }
                tagType = xml.next();
            }
        } catch (XmlPullParserException e) {
            Log.w(LOG_TAG, "Reading searchable metadata for " + cName.flattenToShortString(), e);
            return null;
        } catch (IOException e) {
            Log.w(LOG_TAG, "Reading searchable metadata for " + cName.flattenToShortString(), e);
            return null;
        }
        
        return result;
    }

    /**
     * Gets the "label" (user-visible name) of this searchable context. This must be
     * read using the searchable Activity's resources.
     * 
     * @return A resource id, or {@code 0} if no label was specified.
     * @see android.R.styleable#Searchable_label
     *
     * @hide deprecated functionality
     */
    @UnsupportedAppUsage
    public int getLabelId() {
        return mLabelId;
    }

    /**
     * Gets the resource id of the hint text. This must be
     * read using the searchable Activity's resources.
     * 
     * @return A resource id, or {@code 0} if no hint was specified.
     * @see android.R.styleable#Searchable_hint
     */
    public int getHintId() {
        return mHintId;
    }

    /**
     * Gets the icon id specified by the Searchable_icon meta-data entry. This must be
     * read using the searchable Activity's resources.
     * 
     * @return A resource id, or {@code 0} if no icon was specified.
     * @see android.R.styleable#Searchable_icon
     *
     * @hide deprecated functionality
     */
    @UnsupportedAppUsage
    public int getIconId() {
        return mIconId;
    }

    /**
     * Checks if the searchable activity wants the voice search button to be shown.
     *
     * @see android.R.styleable#Searchable_voiceSearchMode
     */
    public boolean getVoiceSearchEnabled() {
        return 0 != (mVoiceSearchMode & VOICE_SEARCH_SHOW_BUTTON);
    }

    /**
     * Checks if voice search should start web search.
     *
     * @see android.R.styleable#Searchable_voiceSearchMode
     */
    public boolean getVoiceSearchLaunchWebSearch() {
        return 0 != (mVoiceSearchMode & VOICE_SEARCH_LAUNCH_WEB_SEARCH);
    }

    /**
     * Checks if voice search should start in-app search.
     *
     * @see android.R.styleable#Searchable_voiceSearchMode
     */
    public boolean getVoiceSearchLaunchRecognizer() {
        return 0 != (mVoiceSearchMode & VOICE_SEARCH_LAUNCH_RECOGNIZER);
    }

    /**
     * Gets the resource id of the voice search language model string.
     *
     * @return A resource id, or {@code 0} if no language model was specified.
     * @see android.R.styleable#Searchable_voiceLanguageModel
     */
    @StringRes
    public int getVoiceLanguageModeId() {
        return mVoiceLanguageModeId;
    }

    /**
     * Gets the resource id of the voice prompt text string.
     *
     * @return A resource id, or {@code 0} if no voice prompt text was specified.
     * @see android.R.styleable#Searchable_voicePromptText
     */
    @StringRes
    public int getVoicePromptTextId() {
        return mVoicePromptTextId;
    }

    /**
     * Gets the resource id of the spoken language to recognize in voice search.
     *
     * @return A resource id, or {@code 0} if no language was specified.
     * @see android.R.styleable#Searchable_voiceLanguage
     */
    @StringRes
    public int getVoiceLanguageId() {
        return mVoiceLanguageId;
    }

    /**
     * The maximum number of voice recognition results to return.
     *
     * @return the max results count, if specified in the searchable
     *         activity's metadata, or {@code 0} if not specified.
     * @see android.R.styleable#Searchable_voiceMaxResults
     */
    public int getVoiceMaxResults() {
        return mVoiceMaxResults;
    }

    /**
     * Gets the resource id of replacement text for the "Search" button.
     *
     * @return A resource id, or {@code 0} if no replacement text was specified.
     * @see android.R.styleable#Searchable_searchButtonText
     * @hide This feature is deprecated, no need to add it to the API.
     */
    public int getSearchButtonText() {
        return mSearchButtonText;
    }

    /**
     * Gets the input type as specified in the searchable attributes. This will default to
     * {@link InputType#TYPE_CLASS_TEXT} if not specified (which is appropriate
     * for free text input).
     * 
     * @return the input type
     * @see android.R.styleable#Searchable_inputType
     */
    public int getInputType() {
        return mSearchInputType;
    }

    /**
     * Gets the input method options specified in the searchable attributes.
     * This will default to {@link EditorInfo#IME_ACTION_GO} if not specified (which is
     * appropriate for a search box).
     * 
     * @return the input type
     * @see android.R.styleable#Searchable_imeOptions
     */
    public int getImeOptions() {
        return mSearchImeOptions;
    }

    /**
     * Checks whether the searchable should be included in global search.
     *
     * @return The value of the {@link android.R.styleable#Searchable_includeInGlobalSearch}
     *         attribute, or {@code false} if the attribute is not set.
     * @see android.R.styleable#Searchable_includeInGlobalSearch
     */
    public boolean shouldIncludeInGlobalSearch() {
        return mIncludeInGlobalSearch;
    }

    /**
     * Checks whether this searchable activity should be queried for suggestions if a prefix
     * of the query has returned no results.
     *
     * @see android.R.styleable#Searchable_queryAfterZeroResults
     */
    public boolean queryAfterZeroResults() {
        return mQueryAfterZeroResults;
    }

    /**
     * Checks whether this searchable activity has auto URL detection turned on.
     *
     * @see android.R.styleable#Searchable_autoUrlDetect
     */
    public boolean autoUrlDetect() {
        return mAutoUrlDetect;
    }

    /**
     * Support for parcelable and aidl operations.
     */
    public static final @android.annotation.NonNull 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];
        }
    };

    /**
     * Instantiates 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.
     */
    SearchableInfo(Parcel in) {
        mLabelId = in.readInt();
        mSearchActivity = ComponentName.readFromParcel(in);
        mHintId = in.readInt();
        mSearchMode = in.readInt();
        mIconId = in.readInt();
        mSearchButtonText = in.readInt();
        mSearchInputType = in.readInt();
        mSearchImeOptions = in.readInt();
        mIncludeInGlobalSearch = in.readInt() != 0;
        mQueryAfterZeroResults = in.readInt() != 0;
        mAutoUrlDetect = in.readInt() != 0;
        
        mSettingsDescriptionId = in.readInt();
        mSuggestAuthority = in.readString();
        mSuggestPath = in.readString();
        mSuggestSelection = in.readString();
        mSuggestIntentAction = in.readString();
        mSuggestIntentData = in.readString();
        mSuggestThreshold = in.readInt();

        for (int count = in.readInt(); count > 0; count--) {
            addActionKey(new ActionKeyInfo(in));
        }

        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(mLabelId);
        mSearchActivity.writeToParcel(dest, flags);
        dest.writeInt(mHintId);
        dest.writeInt(mSearchMode);
        dest.writeInt(mIconId);
        dest.writeInt(mSearchButtonText);
        dest.writeInt(mSearchInputType);
        dest.writeInt(mSearchImeOptions);
        dest.writeInt(mIncludeInGlobalSearch ? 1 : 0);
        dest.writeInt(mQueryAfterZeroResults ? 1 : 0);
        dest.writeInt(mAutoUrlDetect ? 1 : 0);
        
        dest.writeInt(mSettingsDescriptionId);
        dest.writeString(mSuggestAuthority);
        dest.writeString(mSuggestPath);
        dest.writeString(mSuggestSelection);
        dest.writeString(mSuggestIntentAction);
        dest.writeString(mSuggestIntentData);
        dest.writeInt(mSuggestThreshold);

        if (mActionKeys == null) {
            dest.writeInt(0);
        } else {
            dest.writeInt(mActionKeys.size());
            for (ActionKeyInfo actionKey : mActionKeys.values()) {
                actionKey.writeToParcel(dest, flags);
            }
        }

        dest.writeString(mSuggestProviderPackage);

        dest.writeInt(mVoiceSearchMode);
        dest.writeInt(mVoiceLanguageModeId);
        dest.writeInt(mVoicePromptTextId);
        dest.writeInt(mVoiceLanguageId);
        dest.writeInt(mVoiceMaxResults);
    }
}
