19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.app;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
193c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringertimport android.Manifest;
203c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringertimport android.content.ActivityNotFoundException;
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ComponentName;
22875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.content.ContentResolver;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.DialogInterface;
253c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringertimport android.content.Intent;
263c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringertimport android.content.pm.ActivityInfo;
273c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringertimport android.content.pm.PackageManager;
283c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringertimport android.content.pm.ResolveInfo;
29875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.database.Cursor;
30875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.net.Uri;
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle;
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler;
33875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaenimport android.os.RemoteException;
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.ServiceManager;
353fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringertimport android.text.TextUtils;
368d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringertimport android.util.Log;
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.view.KeyEvent;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
396d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringertimport java.util.List;
406d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This class provides access to the system search services.
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>In practice, you won't interact with this class directly, as search
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * services are provided through methods in {@link android.app.Activity Activity}
468ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * and the {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}
478ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * {@link android.content.Intent Intent}.
488ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * If you do require direct access to the SearchManager, do not instantiate
498ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * this class directly. Instead, retrieve it through
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.Context#getSystemService
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * context.getSystemService(Context.SEARCH_SERVICE)}.
52590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen *
538ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * <div class="special">
548ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * <p>For a guide to using the search dialog and adding search
558ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * suggestions in your application, see the Dev Guide topic about <strong><a
568ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * href="{@docRoot}guide/topics/search/index.html">Search</a></strong>.</p>
578ad6465ca4a54bf124ea65389132fd1084ac291fScott Main * </div>
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class SearchManager
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        implements DialogInterface.OnDismissListener, DialogInterface.OnCancelListener
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
628d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
638d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    private static final boolean DBG = false;
648d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    private static final String TAG = "SearchManager";
658d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is a shortcut definition for the default menu key to use for invoking search.
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * See Menu.Item.setAlphabeticShortcut() for more information.
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static char MENU_KEY = 's';
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is a shortcut definition for the default menu key to use for invoking search.
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * See Menu.Item.setAlphabeticShortcut() for more information.
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static int MENU_KEYCODE = KeyEvent.KEYCODE_S;
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intent extra data key: Use this key with
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getStringExtra
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  content.Intent.getStringExtra()}
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to obtain the query string from Intent.ACTION_SEARCH.
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String QUERY = "query";
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
895f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * Intent extra data key: Use this key with
905f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * {@link android.content.Intent#getStringExtra
915f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     *  content.Intent.getStringExtra()}
925f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * to obtain the query string typed in by the user.
935f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * This may be different from the value of {@link #QUERY}
945f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * if the intent is the result of selecting a suggestion.
955f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * In that case, {@link #QUERY} will contain the value of
965f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * {@link #SUGGEST_COLUMN_QUERY} for the suggestion, and
975f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * {@link #USER_QUERY} will contain the string typed by the
985f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     * user.
995f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert     */
1005f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert    public final static String USER_QUERY = "user_query";
1015f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert
1025f80605a0b866f34c74955e190909bd6ab5d992eBjorn Bringert    /**
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getBundleExtra
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  content.Intent.getBundleExtra()}
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to obtain any additional app-specific data that was inserted by the
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * activity that launched the search.
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String APP_DATA = "app_data";
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
112be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * Intent extra data key: Use {@link android.content.Intent#getBundleExtra
113be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * content.Intent.getBundleExtra(SEARCH_MODE)} to get the search mode used
114be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * to launch the intent.
115be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * The only current value for this is {@link #MODE_GLOBAL_SEARCH_SUGGESTION}.
116be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     *
117be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     * @hide
118be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert     */
119be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert    public final static String SEARCH_MODE = "search_mode";
120be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert
121be5b73c5926cbebd508d8323bdeaafa2e048a93cBjorn Bringert    /**
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getIntExtra content.Intent.getIntExtra()}
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to obtain the keycode that the user used to trigger this query.  It will be zero if the
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * user simply pressed the "GO" button on the search UI.  This is primarily used in conjunction
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * with the keycode attribute in the actionkey element of your searchable.xml configuration
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * file.
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String ACTION_KEY = "action_key";
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
132875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Intent extra data key: This key will be used for the extra populated by the
133875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * {@link #SUGGEST_COLUMN_INTENT_EXTRA_DATA} column.
134875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
135875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public final static String EXTRA_DATA_KEY = "intent_extra_data_key";
136a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen
137a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen    /**
13855f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * Boolean extra data key for {@link #INTENT_ACTION_GLOBAL_SEARCH} intents. If {@code true},
13955f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * the initial query should be selected when the global search activity is started, so
14055f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * that the user can easily replace it with another query.
1413c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     */
14255f3ac5f293e78618995202274f8555f2481994dBjorn Bringert    public final static String EXTRA_SELECT_QUERY = "select_query";
14332d580c360da0a0f15e7a080f4ebd0b7b514fe4cBjorn Bringert
1443c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    /**
145c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * Boolean extra data key for a suggestion provider to return in {@link Cursor#getExtras} to
146c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * indicate that the search is not complete yet. This can be used by the search UI
147c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * to indicate that a search is in progress. The suggestion provider can return partial results
148c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     * this way and send a change notification on the cursor when more results are available.
149c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani     */
150c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani    public final static String CURSOR_EXTRA_KEY_IN_PROGRESS = "in_progress";
151c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani
152c37cb2469578f7d240615affb042e808b32ba5b2Amith Yamasani    /**
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Intent extra data key: Use this key with Intent.ACTION_SEARCH and
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#getStringExtra content.Intent.getStringExtra()}
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * to obtain the action message that was defined for a particular search action key and/or
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * suggestion.  It will be null if the search was launched by typing "enter", touched the the
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * "GO" button, or other means not involving any action key.
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String ACTION_MSG = "action_msg";
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Uri path for queried suggestions data.  This is the path that the search manager
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will use when querying your content provider for suggestions data based on user input
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * (e.g. looking for partial matches).
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Typically you'll use this with a URI matcher.
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_URI_PATH_QUERY = "search_suggest_query";
168b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen
169b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    /**
170b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     * MIME type for suggestions data.  You'll use this in your suggestions content provider
171b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     * in the getType() function.
172b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     */
173b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen    public final static String SUGGEST_MIME_TYPE =
174b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen            "vnd.android.cursor.dir/vnd.android.search.suggest";
175b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen
176b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen    /**
177b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * Uri path for shortcut validation.  This is the path that the search manager will use when
178b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * querying your content provider to refresh a shortcutted suggestion result and to check if it
179b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * is still valid.  When asked, a source may return an up to date result, or no result.  No
180b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * result indicates the shortcut refers to a no longer valid sugggestion.
181b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     *
182b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * @see #SUGGEST_COLUMN_SHORTCUT_ID
183b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     */
184b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    public final static String SUGGEST_URI_PATH_SHORTCUT = "search_suggest_shortcut";
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
187b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen     * MIME type for shortcut validation.  You'll use this in your suggestions content provider
1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * in the getType() function.
1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
190b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen    public final static String SHORTCUT_MIME_TYPE =
191b619c9198efa0108a692d352b0e7eaa534f922f3Karl Rosaen            "vnd.android.cursor.item/vnd.android.search.suggest";
192d4c98c4c450a95b67fe9746675984333b7653713Karl Rosaen
1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Unused - can be null or column can be omitted.</i>
1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_FORMAT = "suggest_format";
1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Required.</i>  This is the primary line of text that
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * will be presented to the user as the suggestion.
2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_TEXT_1 = "suggest_text_1";
2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  then all suggestions will be provided in a two-line format.  The second line of text is in
2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  a much smaller appearance.
2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_TEXT_2 = "suggest_text_2";
2080b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert
2090b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert    /**
2100b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * Column name for suggestions cursor.  <i>Optional.</i> This is a URL that will be shown
2110b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * as the second line of text instead of {@link #SUGGEST_COLUMN_TEXT_2}. This is a separate
2120b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * column so that the search UI knows to display the text as a URL, e.g. by using a different
2130b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * color. If this column is absent, or has the value {@code null},
2140b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     * {@link #SUGGEST_COLUMN_TEXT_2} will be used instead.
2150b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert     */
2160b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert    public final static String SUGGEST_COLUMN_TEXT_2_URL = "suggest_text_2_url";
2170b49ab5cae98d5f27b490b6de35d92e7a63a2e64Bjorn Bringert
2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
220875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  then all suggestions will be provided in a format that includes space for two small icons,
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  one at the left and one at the right of each suggestion.  The data in the column must
222875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  be a resource ID of a drawable, or a URI in one of the following formats:
223875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
224875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <ul>
225875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
226875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
227875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
228875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * </ul>
229875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
230875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
231875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * for more information on these schemes.
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_ICON_1 = "suggest_icon_1";
2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If your cursor includes this column,
236875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  then all suggestions will be provided in a format that includes space for two small icons,
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *  one at the left and one at the right of each suggestion.  The data in the column must
238875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *  be a resource ID of a drawable, or a URI in one of the following formats:
239875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
240875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <ul>
241875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
242875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})</li>
243875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
244875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * </ul>
245875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     *
246875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * See {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)}
247875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * for more information on these schemes.
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_ICON_2 = "suggest_icon_2";
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this element exists at the given row, this is the action that will be used when
2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * forming the suggestion's intent.  If the element is not provided, the action will be taken
2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the android:searchSuggestIntentAction field in your XML metadata.  <i>At least one of
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * these must be present for the suggestion to generate an intent.</i>  Note:  If your action is
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same for all suggestions, it is more efficient to specify it using XML metadata and omit
2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it from the cursor.
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_INTENT_ACTION = "suggest_intent_action";
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this element exists at the given row, this is the data that will be used when
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * forming the suggestion's intent.  If the element is not provided, the data will be taken
2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * from the android:searchSuggestIntentData field in your XML metadata.  If neither source
2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is provided, the Intent's data field will be null.  Note:  If your data is
2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * the same for all suggestions, or can be described using a constant part and a specific ID,
2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * it is more efficient to specify it using XML metadata and omit it from the cursor.
2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_INTENT_DATA = "suggest_intent_data";
2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
271bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
272bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * this element exists at the given row, this is the data that will be used when
273bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * forming the suggestion's intent. If not provided, the Intent's extra data field will be null.
274bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     * This column allows suggestions to provide additional arbitrary data which will be included as
275131234c6f134c586208ec94bfe4ae021b057cf66Mike LeBeau     * an extra under the key {@link #EXTRA_DATA_KEY}.
276bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath     */
277bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath    public final static String SUGGEST_COLUMN_INTENT_EXTRA_DATA = "suggest_intent_extra_data";
278bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath    /**
279479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani     * TODO: Remove
280a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     *
281590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen     * @hide
282875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
283bf23fe062ab4321143717c21827d329e087cc72fSatish Sampath    public final static String SUGGEST_COLUMN_INTENT_COMPONENT_NAME = "suggest_intent_component";
284875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Optional.</i>  If this column exists <i>and</i>
2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * this element exists at the given row, then "/" and this value will be appended to the data
2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * field in the Intent.  This should only be used if the data field has already been set to an
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * appropriate base string.
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_INTENT_DATA_ID = "suggest_intent_data_id";
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Column name for suggestions cursor.  <i>Required if action is
2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH}, optional otherwise.</i>  If this
2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * column exists <i>and</i> this element exists at the given row, this is the data that will be
2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * used when forming the suggestion's query.
2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public final static String SUGGEST_COLUMN_QUERY = "suggest_intent_query";
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
300b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * Column name for suggestions cursor. <i>Optional.</i>  This column is used to indicate whether
301b5041368524045b6714081d14ff3c6b22598aab1Karl Rosaen     * a search suggestion should be stored as a shortcut, and whether it should be refreshed.  If
302b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * missing, the result will be stored as a shortcut and never validated.  If set to
303b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * {@link #SUGGEST_NEVER_MAKE_SHORTCUT}, the result will not be stored as a shortcut.
304b5041368524045b6714081d14ff3c6b22598aab1Karl Rosaen     * Otherwise, the shortcut id will be used to check back for an up to date suggestion using
305b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * {@link #SUGGEST_URI_PATH_SHORTCUT}.
306b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     */
307b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    public final static String SUGGEST_COLUMN_SHORTCUT_ID = "suggest_shortcut_id";
308b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen
309b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    /**
3101c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath     * Column name for suggestions cursor. <i>Optional.</i>  This column is used to specify the
3111c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath     * cursor item's background color if it needs a non-default background color. A non-zero value
3121c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath     * indicates a valid background color to override the default.
3131c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath     *
314590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen     * @hide For internal use, not part of the public API.
3151c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath     */
3161c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath    public final static String SUGGEST_COLUMN_BACKGROUND_COLOR = "suggest_background_color";
317ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau
318ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau    /**
319ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     * Column name for suggestions cursor. <i>Optional.</i> This column is used to specify
320ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     * that a spinner should be shown in lieu of an icon2 while the shortcut of this suggestion
321ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     * is being refreshed.
322ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau     */
323ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau    public final static String SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING =
324ce0959df5ca49cf8f726adddb65978da83e42544Mike LeBeau            "suggest_spinner_while_refreshing";
3251c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath
3261c5fa0f31009502c539c65de99010b63cb617aacSatish Sampath    /**
327b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * Column value for suggestion column {@link #SUGGEST_COLUMN_SHORTCUT_ID} when a suggestion
328b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     * should not be stored as a shortcut in global search.
329b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen     */
330b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    public final static String SUGGEST_NEVER_MAKE_SHORTCUT = "_-1";
331b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen
332b2a5011578d4a64df2f39bdeeedfe9f37e7aecc4Karl Rosaen    /**
3333fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * Query parameter added to suggestion queries to limit the number of suggestions returned.
33486917dbb9554e3e05be4ca8845a409b730120022Bjorn Bringert     * This limit is only advisory and suggestion providers may chose to ignore it.
3353fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     */
3363fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    public final static String SUGGEST_PARAMETER_LIMIT = "limit";
3373fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert
3383fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    /**
33955f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * Intent action for starting the global search activity.
34074708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert     * The global search provider should handle this intent.
34155f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     *
34255f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * Supported extra data keys: {@link #QUERY},
34355f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * {@link #EXTRA_SELECT_QUERY},
34455f3ac5f293e78618995202274f8555f2481994dBjorn Bringert     * {@link #APP_DATA}.
34574708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert     */
34674708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert    public final static String INTENT_ACTION_GLOBAL_SEARCH
34774708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert            = "android.search.action.GLOBAL_SEARCH";
34874708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert
34974708bbdf8d6f172b08343bdc578a20aa4b39148Bjorn Bringert    /**
350875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Intent action for starting the global search settings activity.
351875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * The global search provider should handle this intent.
352875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
353875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    public final static String INTENT_ACTION_SEARCH_SETTINGS
354875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            = "android.search.action.SEARCH_SETTINGS";
3553a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau
3563a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau    /**
3573a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     * Intent action for starting a web search provider's settings activity.
3583a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     * Web search providers should handle this intent if they have provider-specific
3593a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     * settings to implement.
3603a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau     */
3613a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau    public final static String INTENT_ACTION_WEB_SEARCH_SETTINGS
3623a27803b29dc739685e1e2465a0ca697e4b60d14Mike LeBeau            = "android.search.action.WEB_SEARCH_SETTINGS";
363a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen
364a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen    /**
365f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     * Intent action broadcasted to inform that the searchables list or default have changed.
366f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     * Components should handle this intent if they cache any searchable data and wish to stay
367f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     * up to date on changes.
368f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath     */
369f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath    public final static String INTENT_ACTION_SEARCHABLES_CHANGED
370f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath            = "android.search.action.SEARCHABLES_CHANGED";
371d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau
372d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau    /**
373d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau     * Intent action broadcasted to inform that the search settings have changed in some way.
374590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen     * Either searchables have been enabled or disabled, or a different web search provider
375590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen     * has been chosen.
376d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau     */
377d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau    public final static String INTENT_ACTION_SEARCH_SETTINGS_CHANGED
378d4fb7a0d90b16e360b7a7b64cb7a6fd94f084c27Mike LeBeau            = "android.search.action.SETTINGS_CHANGED";
379f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath
380f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath    /**
381a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * If a suggestion has this value in {@link #SUGGEST_COLUMN_INTENT_ACTION},
382a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * the search dialog will take no action.
383a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     *
384590f63433ce786722d263c7e913a88d3101e5cbcKarl Rosaen     * @hide
385a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     */
386a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen    public final static String INTENT_ACTION_NONE = "android.search.action.ZILCH";
387479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani
388875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
3894f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * This means that context is voice, and therefore the SearchDialog should
3904f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * continue showing the microphone until the user indicates that he/she does
3914f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * not want to re-speak (e.g. by typing).
3924f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     *
3934f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     * @hide
3944f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins     */
3954f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins    public final static String CONTEXT_IS_VOICE = "android.search.CONTEXT_IS_VOICE";
3964f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins
3974f22a545552d308377e178d5df5557cfe15252f9Leon Scroggins    /**
398ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III     * This means that the voice icon should not be shown at all, because the
399ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III     * current search engine does not support voice search.
400ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III     * @hide
401ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III     */
402ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III    public final static String DISABLE_VOICE_SEARCH
403ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III            = "android.search.DISABLE_VOICE_SEARCH";
404ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III
405ec721fd1db4d895b342cfb83c651e0b78afac4ddLeon Scroggins III    /**
406875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     * Reference to the shared system search service.
407875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen     */
4088d1538237847baf381787b881141f8c0478bef5bBjorn Bringert    private static ISearchManager mService;
4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private final Context mContext;
4118d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
412d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    /**
413d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * The package associated with this seach manager.
414d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     */
415d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    private String mAssociatedPackage;
416b06ea706530e6d19eb2a1a9a7ae6c5dd77d80af0Dianne Hackborn
4178d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    // package private since they are used by the inner class SearchManagerCallback
4188d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    /* package */ final Handler mHandler;
4198d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    /* package */ OnDismissListener mDismissListener = null;
4208d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    /* package */ OnCancelListener mCancelListener = null;
4218d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
422e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    private SearchDialog mSearchDialog;
4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /*package*/ SearchManager(Context context, Handler handler)  {
4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mContext = context;
4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mHandler = handler;
4278d1538237847baf381787b881141f8c0478bef5bBjorn Bringert        mService = ISearchManager.Stub.asInterface(
4288d1538237847baf381787b881141f8c0478bef5bBjorn Bringert                ServiceManager.getService(Context.SEARCH_SERVICE));
4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
430b06ea706530e6d19eb2a1a9a7ae6c5dd77d80af0Dianne Hackborn
4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Launch search UI.
4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>The search manager will open a search widget in an overlapping
4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * window, and the underlying activity may be obscured.  The search
4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * entry state will remain in effect until one of the following events:
4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <ul>
4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>The user completes the search.  In most cases this will launch
4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * a search intent.</li>
4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>The user uses the back, home, or other keys to exit the search.</li>
4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <li>The application calls the {@link #stopSearch}
4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * method, which will hide the search window and return focus to the
4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * activity from which it was launched.</li>
4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Most applications will <i>not</i> use this interface to invoke search.
4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * The primary method for invoking search is to call
4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.app.Activity#onSearchRequested Activity.onSearchRequested()} or
4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * {@link android.app.Activity#startSearch Activity.startSearch()}.
4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param initialQuery A search string can be pre-entered here, but this
4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * is typically null or empty.
4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param selectInitialQuery If true, the intial query will be preselected, which means that
4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * any further typing will replace it.  This is useful for cases where an entire pre-formed
4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * query is being inserted.  If false, the selection point will be placed at the end of the
4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * inserted query.  This is useful when the inserted query is text that the user entered,
4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * and the user would expect to be able to keep typing.  <i>This parameter is only meaningful
4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * if initialQuery is a non-empty string.</i>
4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param launchActivity The ComponentName of the activity that has launched this search.
4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param appSearchData An application can insert application-specific
4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * context here, in order to improve quality or specificity of its own
4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * searches.  This data will be returned with SEARCH intent(s).  Null if
4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * no extra data is required.
4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param globalSearch If false, this will only launch the search that has been specifically
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * defined by the application (which is usually defined as a local search).  If no default
465cfa419b754332e12f8cd45244c2f3bee9d6a74bbMike LeBeau     * search is defined in the current application or activity, global search will be launched.
4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * If true, this will always launch a platform-global (e.g. web-based) search instead.
4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see android.app.Activity#onSearchRequested
4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #stopSearch
4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void startSearch(String initialQuery,
4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            boolean selectInitialQuery,
4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            ComponentName launchActivity,
4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            Bundle appSearchData,
4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                            boolean globalSearch) {
4763c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (globalSearch) {
4773c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            startGlobalSearch(initialQuery, selectInitialQuery, appSearchData);
4783c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            return;
4793c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
4803c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert
481479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani        ensureSearchDialog();
482479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani
483479ae0a28099eb77299fe0f44d4dfabce3115fb6Amith Yamasani        mSearchDialog.show(initialQuery, selectInitialQuery, launchActivity, appSearchData);
484e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    }
485e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani
486e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    private void ensureSearchDialog() {
487e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mSearchDialog == null) {
488e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog = new SearchDialog(mContext, this);
489e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog.setOnCancelListener(this);
490e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog.setOnDismissListener(this);
491d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        }
492d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    }
493d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen
494d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    /**
4953c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     * Starts the global search activity.
4963c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     */
497e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani    /* package */ void startGlobalSearch(String initialQuery, boolean selectInitialQuery,
4983c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            Bundle appSearchData) {
4993c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        ComponentName globalSearchActivity = getGlobalSearchActivity();
5003c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (globalSearchActivity == null) {
5013c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            Log.w(TAG, "No global search activity found.");
5023c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            return;
5033c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
504a94e7afb28c6bd9af6f2b0142a577086399066b2Bjorn Bringert        Intent intent = new Intent(INTENT_ACTION_GLOBAL_SEARCH);
505b8144a9c18f23c91b836736a2fcea30917153002Bjorn Bringert        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
5063c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        intent.setComponent(globalSearchActivity);
5073c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        // Make sure that we have a Bundle to put source in
5083c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        if (appSearchData == null) {
5093c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert            appSearchData = new Bundle();
5103c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        } else {
5113c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert            appSearchData = new Bundle(appSearchData);
5123c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5133c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        // Set source to package name of app that starts global search, if not set already.
5143c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        if (!appSearchData.containsKey("source")) {
5153c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert            appSearchData.putString("source", mContext.getPackageName());
5163c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        }
5173c24cb77e7c2ab641b9147a02ce997f3356b7b69Bjorn Bringert        intent.putExtra(APP_DATA, appSearchData);
5183c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (!TextUtils.isEmpty(initialQuery)) {
51955f3ac5f293e78618995202274f8555f2481994dBjorn Bringert            intent.putExtra(QUERY, initialQuery);
5203c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5213c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        if (selectInitialQuery) {
52255f3ac5f293e78618995202274f8555f2481994dBjorn Bringert            intent.putExtra(EXTRA_SELECT_QUERY, selectInitialQuery);
5233c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5243c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        try {
5253c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            if (DBG) Log.d(TAG, "Starting global search: " + intent.toUri(0));
5263c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            mContext.startActivity(intent);
5273c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        } catch (ActivityNotFoundException ex) {
5283c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert            Log.e(TAG, "Global search activity not found: " + globalSearchActivity);
5293c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5303c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    }
5313c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert
5323c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    /**
5333c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     * Gets the name of the global search activity.
5343c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     *
53538015f3663dcf3765d0998f8f5398b3068dfc326Bjorn Bringert     * @hide
5363c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert     */
53738015f3663dcf3765d0998f8f5398b3068dfc326Bjorn Bringert    public ComponentName getGlobalSearchActivity() {
5386cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        try {
5396cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return mService.getGlobalSearchActivity();
5406cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        } catch (RemoteException ex) {
5416cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            Log.e(TAG, "getGlobalSearchActivity() failed: " + ex);
5426cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return null;
5433c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert        }
5443c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    }
5453c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert
5463c50ef6f665ab22cdb50c76bb31283e6bac47fc6Bjorn Bringert    /**
547ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     * Gets the name of the web search activity.
548ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *
549ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     * @return The name of the default activity for web searches. This activity
550ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *         can be used to get web search suggestions. Returns {@code null} if
551ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *         there is no default web search activity.
552ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     *
553ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     * @hide
554ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert     */
555ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert    public ComponentName getWebSearchActivity() {
5566cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        try {
5576cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return mService.getWebSearchActivity();
5586cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert        } catch (RemoteException ex) {
5596cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            Log.e(TAG, "getWebSearchActivity() failed: " + ex);
560ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert            return null;
561ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert        }
562ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert    }
563ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert
564ea125f45ebf25494ae190b2f338f359f830674dfBjorn Bringert    /**
565d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * Similar to {@link #startSearch} but actually fires off the search query after invoking
566d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * the search dialog.  Made available for testing purposes.
567d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     *
568d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @param query The query to trigger.  If empty, request will be ignored.
569d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @param launchActivity The ComponentName of the activity that has launched this search.
570d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @param appSearchData An application can insert application-specific
571d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * context here, in order to improve quality or specificity of its own
572d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * searches.  This data will be returned with SEARCH intent(s).  Null if
573d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * no extra data is required.
574d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     *
575d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     * @see #startSearch
576d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen     */
577d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen    public void triggerSearch(String query,
578d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen                              ComponentName launchActivity,
579b782a2f4f0a3072f2677f6f10fb255c77468ae66Bjorn Bringert                              Bundle appSearchData) {
580d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        if (!mAssociatedPackage.equals(launchActivity.getPackageName())) {
581d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen            throw new IllegalArgumentException("invoking app search on a different package " +
582d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen                    "not associated with this search manager");
583d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        }
584d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        if (query == null || TextUtils.getTrimmedLength(query) == 0) {
585d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen            Log.w(TAG, "triggerSearch called with empty query, ignoring.");
586d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen            return;
587d2d6014f715f12f6263f61ba3eeb6f8cba6d0fa6krosaen        }
588e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        startSearch(query, false, launchActivity, appSearchData, false);
589e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        mSearchDialog.launchQuerySearch();
5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Terminate search UI.
5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>Typically the user will terminate the search UI by launching a
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * search or by canceling.  This function allows the underlying application
5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * or activity to cancel the search prematurely (for any reason).
5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * <p>This function can be safely called at any time (even if no search is active.)
6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @see #startSearch
6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6038d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void stopSearch() {
604e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mSearchDialog != null) {
605e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mSearchDialog.cancel();
6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Determine if the Search UI is currently displayed.
6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * This is provided primarily for application test purposes.
6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return Returns true if the search UI is currently displayed.
6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @hide
6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6188d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public boolean isVisible() {
619e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        return mSearchDialog == null? false : mSearchDialog.isShowing();
6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6218d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
623a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * See {@link SearchManager#setOnDismissListener} for configuring your activity to monitor
624a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * search UI state.
6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnDismissListener {
6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
628a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * This method will be called when the search UI is dismissed. To make use of it, you must
629a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * implement this method in your activity, and call
630a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * {@link SearchManager#setOnDismissListener} to register it.
6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onDismiss();
6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
636a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * See {@link SearchManager#setOnCancelListener} for configuring your activity to monitor
637a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen     * search UI state.
6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public interface OnCancelListener {
6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        /**
6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         * This method will be called when the search UI is canceled. To make use if it, you must
642a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * implement this method in your activity, and call
643a058f02b591d971a829cb1e28d48a992e46ad85eKarl Rosaen         * {@link SearchManager#setOnCancelListener} to register it.
6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project         */
6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public void onCancel();
6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set or clear the callback that will be invoked whenever the search UI is dismissed.
6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param listener The {@link OnDismissListener} to use, or null.
6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void setOnDismissListener(final OnDismissListener listener) {
6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mDismissListener = listener;
6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Set or clear the callback that will be invoked whenever the search UI is canceled.
6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     *
6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param listener The {@link OnCancelListener} to use, or null.
6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
6628d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void setOnCancelListener(OnCancelListener listener) {
6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        mCancelListener = listener;
6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6658d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert
6660e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert    /**
6670e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     * @deprecated This method is an obsolete internal implementation detail. Do not use.
6680e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     */
6694a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn    @Deprecated
6708d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void onCancel(DialogInterface dialog) {
671e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mCancelListener != null) {
672e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mCancelListener.onCancel();
673e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        }
6748d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    }
6750e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert
6760e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert    /**
6770e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     * @deprecated This method is an obsolete internal implementation detail. Do not use.
6780e01ea41b215941128a4ea8dee454e6b35a4e798Bjorn Bringert     */
6794a51c20ce607c74914f90fd897f04080121ac13bDianne Hackborn    @Deprecated
6808d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert    public void onDismiss(DialogInterface dialog) {
681e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        if (mDismissListener != null) {
682e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani            mDismissListener.onDismiss();
683e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani        }
6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
6870408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     * Gets information about a searchable activity.
6880408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     *
6890408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     * @param componentName The activity to get searchable information for.
6900408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     * @return Searchable information, or <code>null</code> if the activity does not
6910408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     *         exist, or is not searchable.
6920408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert     */
6930408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert    public SearchableInfo getSearchableInfo(ComponentName componentName) {
6940408675d8770fc55c40631cdfa87d79fc00f0a3cBjorn Bringert        try {
6956cf7a325e6e9e70d9858e21fbb438341332ed254Bjorn Bringert            return mService.getSearchableInfo(componentName);
6968d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert        } catch (RemoteException ex) {
6978d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert            Log.e(TAG, "getSearchableInfo() failed: " + ex);
698875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            return null;
699875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
700875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
7018d1538237847baf381787b881141f8c0478bef5bBjorn Bringert
702875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    /**
70397325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * Gets a cursor with search suggestions.
70497325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     *
70597325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @param searchable Information about how to get the suggestions.
70697325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @param query The search text entered (so far).
70797325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @return a cursor with suggestions, or <code>null</null> the suggestion query failed.
70897325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     *
70997325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     * @hide because SearchableInfo is not part of the API.
71097325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert     */
71197325db8565ad503b86d9a0f602b2d001b5cee13Bjorn Bringert    public Cursor getSuggestions(SearchableInfo searchable, String query) {
7123fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        return getSuggestions(searchable, query, -1);
7133fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    }
7143fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert
7153fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    /**
7163fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * Gets a cursor with search suggestions.
7173fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     *
7183fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @param searchable Information about how to get the suggestions.
7193fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @param query The search text entered (so far).
7203fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @param limit The query limit to pass to the suggestion provider. This is advisory,
7213fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     *        the returned cursor may contain more rows. Pass {@code -1} for no limit.
7223fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @return a cursor with suggestions, or <code>null</null> the suggestion query failed.
7233fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     *
7243fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     * @hide because SearchableInfo is not part of the API.
7253fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert     */
7263fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert    public Cursor getSuggestions(SearchableInfo searchable, String query, int limit) {
727875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (searchable == null) {
728875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            return null;
729875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
730875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
731875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        String authority = searchable.getSuggestAuthority();
732875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (authority == null) {
733875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            return null;
734875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
735875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
736875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        Uri.Builder uriBuilder = new Uri.Builder()
737875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen                .scheme(ContentResolver.SCHEME_CONTENT)
7383fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert                .authority(authority)
7393fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert                .query("")  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
7403fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert                .fragment("");  // TODO: Remove, workaround for a bug in Uri.writeToParcel()
741875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
742875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // if content path provided, insert it now
743875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        final String contentPath = searchable.getSuggestPath();
744875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (contentPath != null) {
745875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            uriBuilder.appendEncodedPath(contentPath);
746875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
747875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
7483fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        // append standard suggestion query path
749875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        uriBuilder.appendPath(SearchManager.SUGGEST_URI_PATH_QUERY);
750875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
751875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // get the query selection, may be null
752875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        String selection = searchable.getSuggestSelection();
753875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // inject query, either as selection args or inline
754875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        String[] selArgs = null;
755875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        if (selection != null) {    // use selection if provided
756875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            selArgs = new String[] { query };
757875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        } else {                    // no selection, use REST pattern
758875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen            uriBuilder.appendPath(query);
759875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        }
760875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
7613fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        if (limit > 0) {
7623fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert            uriBuilder.appendQueryParameter(SUGGEST_PARAMETER_LIMIT, String.valueOf(limit));
7633fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        }
7643fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert
7653fc7c67de192a5baee2b4510fdb464b0fec72dcaBjorn Bringert        Uri uri = uriBuilder.build();
766875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
767875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen        // finally, make the query
7688d1538237847baf381787b881141f8c0478bef5bBjorn Bringert        return mContext.getContentResolver().query(uri, null, selection, selArgs, null);
769875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen    }
770875d50a4b9294b2be33cff6493cae7acd1d07ea7Karl Rosaen
7716d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert    /**
7726d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert     * Returns a list of the searchable activities that can be included in global search.
7736d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert     *
7746d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert     * @return a list containing searchable information for all searchable activities
77513107bb186d72bc80dc5609b20c71b7e77a9784dBjorn Bringert     *         that have the <code>android:includeInGlobalSearch</code> attribute set
77613107bb186d72bc80dc5609b20c71b7e77a9784dBjorn Bringert     *         in their searchable meta-data.
7776d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert     */
7788d1538237847baf381787b881141f8c0478bef5bBjorn Bringert    public List<SearchableInfo> getSearchablesInGlobalSearch() {
7796d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert        try {
7808d1538237847baf381787b881141f8c0478bef5bBjorn Bringert            return mService.getSearchablesInGlobalSearch();
7816d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert        } catch (RemoteException e) {
7828d17f3f24bbda9a9cd7ea08c5925508dc2c011beBjorn Bringert            Log.e(TAG, "getSearchablesInGlobalSearch() failed: " + e);
7836d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert            return null;
7846d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert        }
7856d72e029cb6e5a9cf26aa3314c3dca83614fc91bBjorn Bringert    }
786f9acde27486bcc6eea1092073f7b47c31749efd6Satish Sampath
787e9ce3f01d42769f03f10e70c3244500e92d7eee1Amith Yamasani}
788